{T}

Nginx

Nginx 是一款轻量级的 Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强,事实上 nginx 的并发能力在同类型的网页服务器中表现较好,中国大陆使用 nginx 的网站有:百度、京东、新浪、网易、腾讯、淘宝等

Nginx 是由伊戈尔·赛索耶夫为俄罗斯访问量第二的 Rambler.ru 站点(俄文:Рамблер)开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日

官网:https://nginx.org/

下载和安装

在 Nginx 的官网的下载页面中(http://nginx.org/en/download.html),就展示了当前 Nginx 版本,并提供了下载的连接

img

在本项目中,我们所学习的Nginx选择的是稳定版本的 1.16 这个版本,我们可以直接从官网下载

安装

安装依赖包

由于 nginx 是基于 c 语言开发的,所以需要安装 c 语言的编译环境,及正则表达式库等第三方依赖库

plain
yum -y install gcc pcre-devel zlib-devel openssl openssl-devel

下载 Nginx 安装包

plain
yum install wget
wget https://nginx.org/download/nginx-1.16.1.tar.gz

wget 命令用来从指定的 URL 下载文件

wget 非常稳定,它在带宽很窄的情况下和不稳定网络中有很强的适应性,如果是由于网络的原因下载失败,wget 会不断的尝试,直到整个文件下载完毕。如果是服务器打断下载过程,它会再次联到服务器上从停止的地方继续下载

执行完 wget 指令后,就会在当前所在目录看到下载下来的文件

解压 nginx 压缩包

plain
tar -zxvf nginx-1.16.1.tar.gz

配置 Nginx 编译环境

plain
cd nginx-1.16.1
./configure --prefix=/usr/local/nginx

说明: --prefix 指定的目录,就是我们安装 Nginx 的目录

编译&安装

plain
make & make install

目录结构

安装完 Nginx 后,我们可以切换到 Nginx 的安装目录(/usr/local/nginx),先来熟悉一下 Nginx 的目录结构

img

上述我们用到的一个指令 tree,该指令可以将我们指定的目录以树状结构展示出来。如果没有这个指令,可以通过以下指令进行安装。

yum install tree

重点目录和文件如下:

目录/文件说明备注
conf配置文件的存放目录
conf/nginx.confNginx的核心配置文件conf下有很多nginx的配置文件,我们主要操作这个核心配置文件
html存放静态资源(html, css, )部署到Nginx的静态资源都可以放在html目录中
logs存放nginx日志(访问日志、错误日志等)
sbin/nginx二进制文件,用于启动、停止Nginx服务

Nginx 命令

Nginx 中,我们的二进制可执行文件(nginx)存放在 sbin 目录下,虽然只有一个可执行文件,但是我们可以通过该指令配合不同的参数达到更加强大的功能。接下来,我们就演示一下 Nginx 常见指令, 在执行下面的指令时,都需要在/usr/local/nginx/sbin/目录下执行

1). 查看版本

shell
./nginx -v

2). 检查配置文件

修改了nginx.conf核心配置文件之后,在启动Nginx服务之前,可以先检查一下conf/nginx.conf文件配置的是否有错误,命令如下:

shell
./nginx -t

3). 启动

shell
./nginx

启动之后,我们可以通过 ps -ef 指令来查看 nginx 的进程是否存在

img

注意: nginx 服务启动后,默认就会有两个进程

启动之后,我们可以直接访问 Nginx 的 80 端口, http://192.168.200.200

img

要想正常访问 Nginx,需要关闭防火墙或开放指定端口号,执行的指令如下:

  • 关闭防火墙

  • systemctl stop firewalld

  • 开放80端口

  • firewall-cmd --zone=public --add-port=80/tcp --permanent

  • firewall-cmd --reload

4). 停止

bash
./nginx -s stop

停止之后,我们可以查看 nginx 的进程

bash
ps -ef|grep nginx

5). 重新加载

当修改了Nginx配置文件后,需要重新加载才能生效,可以使用下面命令重新加载配置文件:

bash
./nginx -s reload

环境变量配置

通过 vim 编辑器,打开/etc/profile文件, 在PATH环境变量中增加nginxsbin目录

img

修改完配置文件之后,需要执行 source /etc/profile 使文件生效。 接下来,我们就可以在任意目录下执行 nginx 的指令

img

Nginx 应用

配置文件结构

nginx 的配置文件(conf/nginx.conf)整体上分为三部分: 全局块、events 块、http 块

区域职责
全局块配置和nginx运行相关的全局配置
events 块配置和网络连接相关的配置
http 块配置代理、缓存、日志记录、虚拟主机等配置

具体结构图如下:

img

在全局块、events 块以及 http 块中,我们经常配置的是 http 块

在 http 块中可以包含多个 server 块,每个 server 块可以配置多个 location 块

部署静态资源

Nginx 可以作为静态 web 服务器来部署静态资源。这里所说的静态资源是指在服务端真实存在,并且能够直接展示的一些文件,比如常见的 html 页面、css文件、js文件、图片、视频等资源

相对于 Tomcat,Nginx 处理静态资源的能力更加高效,所以在生产环境下,一般都会将静态资源部署到 Nginx 中

将静态资源部署到 Nginx 非常简单,只需要将文件复制到 Nginx 安装目录下的 html 目录中即可

properties
server {
    listen 80;				#监听端口	
    server_name localhost;	#服务器名称
    location / {			#匹配客户端请求url
        root html;			#指定静态资源根目录
        index index.html;	#指定默认首页
    }
}

在资料中,我们提供了一个静态的html文件,我们需要将这个文件部署到nginx中,然后通过nginx访问html静态资源。

1). 将静态资源上传到 /usr/local/nginx/html 目录

img

2). 启动nginx

img

3). 访问

http://192.168.200.200/hello.html

img

http://192.168.200.200 , 访问该地址,访问的是nginx的默认首页

img

4). 配置首页

properties
server {
    listen 80;			
    server_name localhost;
    location / {
        root html;
        index index.html; # 首页配置
    }
}

如果我们需要将 hello.html 作为 nginx 的首页,可以修改 location 的 index 指令,配置为 hello.html,如下:

properties
server {
    listen 80;			
    server_name localhost;
    location / {
        root html;
        # index index.html; # 首页配置
        index hello.html;
    }
}

配置完毕后,我们可以通过指令,来检查配置文件是否配置正确: nginx -t

配置文件修改了,我们需要重新加载一下,才可以生效:nginx -s reload

5). 访问

http://192.168.200.200

反向代理

概念介绍

1). 正向代理

正向代理服务器是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。

正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。

正向代理一般是在客户端设置代理服务器,通过代理服务器转发请求,最终访问到目标服务器。

img

2). 反向代理

反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源,反向代理服务器负责将请求转发给目标服务器。用户不需要知道目标服务器的地址,也无须在用户端作任何设定,对于用户来说,访问反向代理服务器是完全无感知的

img

那么在本小节,我们就是要使用 nginx 来作为反向代理服务器使用。 在 nginx 中,我们可以在 nginx.conf 中配置反向代理

properties
server {
    listen 82;
    server_name localhost;
    location / {
        proxy_pass http://192.168.200.201:8080; 	#反向代理配置,将请求转发到指定服务
    }
}

上述配置的含义为: 当我们访问 nginx 的 82 端口时,根据反向代理配置,会将请求转发到 http://192.168.200.201:8080 对应的服务上

测试

需求: 在 192.168.200.201 这台服务器中部署了 java 应用,运行端口为 8080,并提供了一个可访问的链接/hello。现在我们需要在访问nginx 的 82 端口时,通过 nginx 将请求转发到 192.168.200.201:8080 的服务

img

在 192.168.200.201 部署服务并启动

将资料中提供的 helloworld-1.0-SNAPSHOT.jar 上传到服务器端,并通过指令 java -jar helloworld-1.0-SNAPSHOT.jar 运行服务

img

2). 在192.168.200.200中的nginx.conf中配置反向代理

进入nginx的安装目录,并编辑配置文件nginx.conf:

plain
cd /usr/local/nginx/conf/
vim nginx.conf

在 http 块中,再添加一个 server 块虚拟主机的配置监听 82 端口,并配置反向代理proxy_pass

properties
server {
    listen 82;
    server_name localhost;
    location / {
        proxy_pass http://192.168.200.201:8080; 	#反向代理配置,将请求转发到指定服务
    }
}

img

3). 检查配置文件,并重新加载

plain
nginx -t
nginx -s reload

4). 访问

http://192.168.200.200/hello

关闭防火墙

plain
systemctl stop firewalld

firewall-cmd --zone=public --add-port=82/tcp --permanent

firewall-cmd --reload

负载均衡

概念介绍

早期的网站流量和业务功能都比较简单,单台服务器就可以满足基本需求,但是随着互联网的发展,业务流量越来越大并且业务逻辑也越来越复杂,单台服务器的性能及单点故障问题就凸显出来了,因此需要多台服务器组成应用集群,进行性能的水平扩展以及避免单点故障出现。

**应用集群:**将同一应用部署到多台机器上,组成应用集群,接收负载均衡器分发的请求,进行业务处理并返回响应数据

**负载均衡器:**将用户请求根据对应的负载均衡算法分发到应用集群中的一台服务器进行处理

img

此处的负载均衡器,我们将会使用 Nginx 来实现,而 Nginx 的负载均衡是基于反向代理的,只不过此时所代理的服务器不是一台,而是多台

测试

1). 将资料中提供的两个jar包,上传到192.168.200.201服务器上

jar运行端口请求链接响应数据
img8080/hello8080
img8081/hello8081

我们在测试时,并没有那么多服务器,我们可以在一台服务器中启动多个服务,运行在不同的端口号上进行测试。

2). 运行上传上来的两个 jar 包,运行端口分别是 8080 , 8081

由于我们执行 java -jar 指令会占用前台窗口,所以我们可以开启两个窗口进行测试。

img

img

3). 在 nginx 中配置负载均衡

打开 nginx 的配置文件 nginx.conf 并增加如下配置:

properties
#upstream 指令可以定义一组服务器
upstream targetserver{	
    server 192.168.200.201:8080;
    server 192.168.200.201:8081;
}

server {
    listen       8080;
    server_name  localhost;
    location / {
        proxy_pass http://targetserver;
    }
}

具体的配置位置如下:

img

4). 重新加载nginx配置文件,访问

shell
nginx -s reload

测试时,我们直接访问nginx的8080端口(http://192.168.200.200:8080), 此时 nginx 会根据负载均衡策略,将请求转发到后面的两台服务器

img

在上述的测试过程中,我们看到请求均衡的转发到了8080和8081,因为模式的负载均衡策略是轮询

注意: 上述所有涉及到的端口号,都需要在对应的服务器的防火墙中开放,或者彻底关闭防火墙

负载均衡策略

处理上述默认的轮询策略以外,在 Nginx 中还提供了其他的负载均衡策略

名称说明特点
轮询默认方式
weight权重方式根据权重分发请求,权重大的分配到请求的概率大
ip_hash依据ip分配方式根据客户端请求的IP地址计算hash值, 根据hash值来分发请求, 同一个IP发起的请求, 会发转发到同一个服务器上
least_conn依据最少连接方式哪个服务器当前处理的连接少, 请求优先转发到这台服务器
url_hash依据url分配方式根据客户端请求url的hash值,来分发请求, 同一个url请求, 会发转发到同一个服务器上
fair依据响应时间方式优先把请求分发给处理请求时间短的服务器

权重的配置:

properties
#upstream指令可以定义一组服务器
upstream targetserver{	
    server 192.168.200.201:8080 weight=10;
    server 192.168.200.201:8081 weight=5;
}

上述配置的 weight 权重是相对的,在上述的配置中,效果就是,在大数据量的请求下,最终 8080 接收的请求数是 8081 的两倍

阿里云 nginx 配置

nginx
user  root;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

pid       /usr/local/nginx/logs/nginx.pid;



events {
  worker_connections  1024;
}


http {
  include       mime.types;
  default_type  application/octet-stream;

  #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
  #                  '$status $body_bytes_sent "$http_referer" '
  #                  '"$http_user_agent" "$http_x_forwarded_for"';

  #access_log  logs/access.log  main;

  sendfile        on;
  #tcp_nopush     on;

  #keepalive_timeout  0;
  keepalive_timeout  65;

  #gzip  on;

  server {
    listen       80;
    server_name  121.40.77.89;

    #charset koi8-r;

    #access_log  logs/host.access.log  main;

    # location / {
    #     root   html;
    #     index  index.html index.htm;
    # }
    location / {
      root /usr/local/webfront-zzy/user-center;
      index index.html index.htm;
    }

    location /group1/M00 { 
      root /home/fastdfs/fdfs_storage/data; 
      ngx_fastdfs_module; 
    }
    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   html;
    }


    location /music-next/ {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-Nginx-Proxy true;
      proxy_pass http://127.0.0.1:9002/;
    }

    location /yapi/ {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-Nginx-Proxy true;
      proxy_pass http://127.0.0.1:9091/;
    }

    location /youtobeclone-backend/ {
      proxy_set_header X-Real-IP $remote_addr;
      # 后端的Web服务器可以通过 X-Forwarded-For 获取用户真实 IP
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      # 获取真实的请求主机名
      proxy_set_header Host  $http_host;
      # 标识该请求由 nginx 转发
      proxy_set_header X-Nginx-Proxy true;

      # 代理到本地的 3000 端口服务
      proxy_pass    http://127.0.0.1:7001/;
    }
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
  }


  # another virtual host using mix of IP-, name-, and port-based configuration
  #
  #server {
  #    listen       8000;
  #    listen       somename:8080;
  #    server_name  somename  alias  another.alias;

  #    location / {
  #        root   html;
  #        index  index.html index.htm;
  #    }
  #}


  # HTTPS server
  #
  #server {
  #    listen       443 ssl;
  #    server_name  localhost;

  #    ssl_certificate      cert.pem;
  #    ssl_certificate_key  cert.key;

  #    ssl_session_cache    shared:SSL:1m;
  #    ssl_session_timeout  5m;

  #    ssl_ciphers  HIGH:!aNULL:!MD5;
  #    ssl_prefer_server_ciphers  on;

  #    location / {
  #        root   html;
  #        index  index.html index.htm;
  #    }
  #}

}