<h2><center>Nginx功能</center></h2>

------

## 一：Nginx Proxy代理

### 1. 正向代理

​	**正向代理的过程隐藏了真实的请求客户端，服务器不知道真实的客户端是谁，客户端请求的服务都被代理服务器代替请求。**常说的代理也就是正向代理，正向代理代理的是请求方，也就是客户端。

![](http://182.92.143.66:40072/directlink/img/nginx/image-202502220002.png)

### 2. 反向代理

​	**反向代理的过程隐藏了真实的服务器，客户不知道真正提供服务的人是谁，客户端请求的服务都被代理服务器处理。反向代理代理的是响应方，也就是服务端；**请求www.baidu.com时这www.baidu.com就是反向代理服务器，真实提供服务的服务器有很多台，反向代理服务器会把我们的请求分转发到真实提供服务的各台服务器。Nginx就是性能非常好的反向代理服务器，用来做负载均衡。

![](http://182.92.143.66:40072/directlink/img/nginx/image-202502220003.png)

### 3. Nginx Proxy

模块：ngx_http_proxy_module

代理配置：

```shell
代理
Syntax: 	proxy_pass URL;				   #代理的后端服务器URL
Default: 	—
Context: 	location, if in location, limit_except

缓冲区
Syntax:    proxy_buffering on | off;
Default:    proxy_buffering on;			   #缓冲开关
Context: 	http, server, location
proxy_buffering开启的情况下，nignx会把后端返回的内容先放到缓冲区当中，然后再返回给客户端
（边收边传，不是全部接收完再传给客户端)。

Syntax:   	proxy_buffer_size size;
Default: 	proxy_buffer_size 4k|8k;	   #缓冲区大小
Context: 	http, server, location

Syntax: 	proxy_buffers number size;
Default: 	proxy_buffers 8 4k|8k;		   #缓冲区数量
Context: 	http, server, location

Syntax:    	proxy_busy_buffers_size size;
Default: 	proxy_busy_buffers_size 8k|16k;#忙碌的缓冲区大小控制同时传递给客户端的buffer数量
Context: 	http, server, location

头信息
Syntax: 	proxy_set_header field value;
Default: 	proxy_set_header Host $proxy_host; #设置真实客户端地址
            proxy_set_header Connection close;
Context: 	http, server, location

超时
Syntax: 	proxy_connect_timeout time;
Default: 	proxy_connect_timeout 60s;				#链接超时
Context: 	http, server, location

Syntax: 	proxy_read_timeout time;
Default: 	proxy_read_timeout 60s;
Context: 	http, server, location
```

启用 nginx proxy 代理：

- nginx-1作为应用服务器，ip地址为：192.168.159.130
- nginx-2作为代理服务器，ip地址为：192.168.159.131

```shell
nginx-2的配置文件:
# vim /etc/nginx/conf.d/test.conf
server {
	listen 80;
	server_name http://192.168.159.131;
	
	location / {
		proxy_pass http://192.168.159.130:8080;
		proxy_redirect default;
		proxy_set_header Host $http_host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
		
		proxy_connect_timeout 30;
		proxy_send_timeout 60;
		proxy_read_timeout 60;
	}
}


使用PC客户端访问nginx-2服务器地址
浏览器中输入http://192.168.159.131:80，成功则访问到的是nginx-1服务器页面
```

nginx proxy 具体配置详解：

```shell
proxy_pass ：真实服务器的地址，可以是ip也可以是域名和url地址
proxy_redirect ：如果真实服务器使用的是的真实     IP:非默认端口。则改成IP：默认端口。
proxy_set_header：重新定义或者添加发往后端服务器的请求头
proxy_set_header X-Real-IP ：启用客户端真实地址（否则日志中显示的是代理在访问网站）
proxy_set_header X-Forwarded-For：记录代理地址

proxy_connect_timeout：:后端服务器连接的超时时间发起三次握手等候响应超时时间
proxy_send_timeout：后端服务器数据回传时间就是在规定时间之内后端服务器必须传完所有的数据
proxy_read_timeout ：nginx接收upstream（上游/真实） server数据超时, 默认60s, 如果连续的60s内没有收到1个字节, 连接关闭。像长连接

proxy_buffering on;开启缓存
proxy_buffer_size：proxy_buffer_size只是响应头的缓冲区
proxy_buffers 4 128k; 内容缓冲区域大小
proxy_busy_buffers_size 256k; 从proxy_buffers划出一部分缓冲区来专门向客户端传送数据的地方
proxy_max_temp_file_size 256k;超大的响应头存储成文件
```



## 二：Nginx负载均衡

​	随着网站、应用访问量的增加，一台服务器已经不能满足应用的需求，而需要多台服务器集群，这时就会用到负载均衡。

### 1. 负载均衡配置

```shell
upstream testapp {
    server 192.168.159.130:80;
    server 192.168.159.131:80;
}
server {
    listen 80;
    server_name 192.168.159.132;
    location / {
        proxy_pass http://testapp;   #请求转向 testapp 定义的服务器列表
    }
}
```

### 2. 负载均衡算法

- 轮询：每个请求按时间顺序逐一分配到不同的后端服务器
- ip_hash：每个请求按访问IP的hash结果分配，同一个IP客户端固定访问一个后端服务器。
- url_hash：按访问url的hash结果来分配请求，使每个url定向到同一个后端服务器。
- fair：这是比上面两个更加智能的负载均衡算法。按后端服务器的响应时间来分配请求，响应时间短的优先分配。

注意：

​	Nginx本身是不支持 fair的，如果需要使用这种调度算法，必须下载Nginx的 upstream_fair模块。

### 3. 配置实例

1. 热备：如果你有2台服务器，当一台服务器发生事故时，才启用第二台服务器给提供服务。服务器处理请求的顺序：AAAAAA突然A挂啦，BBBBBBBBBBBBBB.....

   ```shell
   upstream testapp {
       server 192.168.159.130:80;
       server 192.168.159.131:80 backup;  #热备
   }
   ```

   

2. 轮询：nginx默认就是轮询其权重都默认为1，服务器处理请求的顺序：ABABABABAB....

   ```shell
   upstream testapp {
       server 192.168.159.130:80;
       server 192.168.159.131:80;
   }
   ```

   

3. 加权轮询：跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置，则默认为1。下面服务器的请求顺序为：BBABBABBABBABB....

   ```shell
   upstream testapp {
       server 192.168.159.130:80 weight=1;
       server 192.168.159.131:80 weight=2;
   }
   ```

   

4. ip_hash:nginx会让相同的客户端ip请求相同的服务器。

   ```shell
   upstream testapp {
       server 192.168.159.130:80;
       server 192.168.159.131:80;
   	ip_hash;
   }
   ```

   

5. nginx负载均衡配置状态参数

   ```shell
   - down，表示当前的server暂时不参与负载均衡。
   - backup，预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候，才会请求backup机器，因此这台机器的压力最轻。
   - max_fails，允许请求失败的次数，默认为1。当超过最大次数时，返回proxy_next_upstream 模块定义的错误。
   - fail_timeout，在经历了max_fails次失败后，暂停服务的时间单位秒。max_fails可以和fail_timeout一起使用。
   ```

   ```shell
   实例：
   upstream testapp {
       server 192.168.159.130:80 weight=2 max_fails=2 fail_timeout=2;
       server 192.168.159.131:80 weight=1 max_fails=2 fail_timeout=1;
   }
   ```

   

## 三：Nginx会话保持

​	Nginx会话保持主要有以下几种实现方式。

### 1. ip_hash

​	ip_hash使用源地址哈希算法，将同一客户端的请求总是发往同一个后端服务器，除非该服务器不可用。

```shell
upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com down;
}
```

​	ip_hash简单易用，但有如下问题：

- 当后端服务器宕机后，session会丢失。
- 来自同一局域网的客户端会被转发到同一个后端服务器，可能导致负载均衡。



### 2. sticky_cookie_insert —— 基于cookie实现

​	使用sticky_cookie_insert启用会话亲缘关系，让来自同一客户端的请求被传递到一组服务器的同一台服务器。与ip_hash不同之处在于，它不是基于IP来判断客户端的，而是基于cookie来判断。第三方模块---sticky模块，可以避免上述ip_hash中来自同一局域网的客户端和前段代理导致负载失衡的情况。

```bash
编译安装sticky模块，#给yum安装的nginx添加模块
[root@test ~]# yum install -y pcre* openssl* gcc gcc-c++ make  安装编译环境
[root@test ~]# wget  https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/08a395c66e42.zip  #下载sticky模块
[root@test ~]# nginx -v
nginx version: nginx/1.26.1
[root@test ~]# wget  http://nginx.org/download/nginx-1.26.1.tar.gz #下载yum安装nginx对应版本的源码包
[root@test ~]# yum install -y unzip #安装解压工具
[root@test ~]# unzip 08a395c66e42.zip #解压模块包
[root@test ~]# mv nginx-goodies-nginx-sticky-module-ng-08a395c66e42/ nginx-sticky-module-ng/
[root@test ~]# tar xzvf nginx-1.26.1.tar.gz -C /usr/local/ #解压nginx的源码包
[root@test ~]# cd /usr/local/nginx-1.26.1/
[root@test nginx-1.26.1]# nginx -V #查看yum安装nginx所有模块
[root@test nginx-1.26.1]# ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=/root/nginx-sticky-module-ng
[root@test nginx-1.26.1]# make && make install

配置基于cookie会话保持
[root@test conf.d]# vim upstream.conf
upstream test {
        server 192.168.198.130;
        server 192.168.198.131;
        sticky;
}

[root@test conf.d]# vim proxy.conf
server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        proxy_pass http://test;
    }
}
[root@test conf.d]# nginx -t
[root@test conf.d]# nginx -s reload

或者：
upstream test {
        server 192.168.198.130;
        server 192.168.198.131;
        sticky expires=1h domain=testpm.com path=/;
}

说明：
expires：设置浏览器中保持cookie的时间 
domain：定义cookie的域 
path：为cookie定义路径
```



## 四：Nginx动静分离

​	为了加快网站的解析速度，可以把动态页面和静态页面由不同的服务器来解析，加快解析速度。降低原来单个服务器的压力。一般来说，都需要将动态资源和静态资源分开，将静态资源部署在Nginx上，当一个请求来的时候，如果是静态资源的请求，就直接到nginx配置的静态资源目录下面获取资源，如果是动态资源的请求，nginx利用反向代理的原理，把请求转发给后台应用去处理，从而实现动静分离。

### 1. 准备环境

|     服务器      |        要求        |
| :-------------: | :----------------: |
| 192.168.159.130 |       static       |
| 192.168.159.131 | 动静分离、upstream |
| 192.168.159.132 |        php         |

### 2. 静态资源配置

```bash
[root@test ~]# vim /etc/nginx/conf.d/test.conf
server {
    listen 80;
    server_name 192.168.159.130;
    location ~ \.(html|jpg|png|js|css|gif|bmp|jpeg)$  {
        root /usr/share/nginx/web;
        index index.html index.htm;
        expires 1d; #为客户端设置静态资源缓存时间
    }
}

测试：
[root@test ~]# curl 192.168.159.130:80/index.html
web1
```

```ini
expires功能说明---（为客户端配置缓存时间）

　　nginx缓存的设置可以提高网站性能，对于网站的图片，尤其是新闻网站，图片一旦发布，改动的可能是非常小的，为了减小对服务器请求的压力，提高用户浏览速度，我们可以通过设置nginx中的expires，让用户访问一次后，将图片缓存在用户的浏览器中，且时间比较长的缓存。

原理：当nginx设置了expires后，例如设置为：expires 10d; 那么用户在10天内请求的时候，都只会访问浏览器中的缓存，而不会去请求nginx。

需要注意的是，这种缓存方式只能在用户不对浏览器强制刷新的情况下生效，如果用户通过url来进行访问，是可以访问到缓存的。
```



### 3. 动态资源配置

```bash
[root@test ~]# vim /etc/nginx/conf.d/test.conf
server {
    listen 80;
    server_name 192.168.159.132;

    root /usr/share/nginx/php;
    index index.php index.html index.htm;

    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

编辑php测试页面
[root@test ~]# vim /usr/share/nginx/php/index.php
<?php
    phpinfo();
?>

测试：
浏览器上192.168.159.132
```



### 4. 配置代理

```bash
[root@test ~]# vim /etc/nginx/conf.d/test.conf
upstream static {
    server 192.168.159.130:80 weight=1 max_fails=1 fail_timeout=60s;
}

upstream php {
    server 192.168.159.132:80 weight=1 max_fails=1 fail_timeout=60s;
}

server {
    listen 80;
    server_name 192.168.159.131;
	
	#动态资源加载
    location ~ \.(php|jsp)$ {
        proxy_pass http://php;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    
    #静态资源加载
    location ~ \.(html|jpg|png|css|js)$ {
        proxy_pass http://static;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

测试：
[root@test ~]# curl 192.168.159.131:80/index.html
web1
[root@test ~]# curl 192.168.159.131:80/index.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<style type="text/css">
body {background-color: #fff; color: #222; font-family: sans-serif;}...

当访问静态页面的时候location 匹配到 (html|jpg|png|js|css) 通过转发到静态服务器，静态服务通过location的正则匹配来处理请求。

当访问动态页面时location匹配到 .\php 结尾的文件转发到后端php服务处理请求。
```



### 5. 配置php

1. 安装php

```bash
[root@test ~]# rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm
[root@test ~]# rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
[root@test ~]# yum install php71w-xsl php71w php71w-ldap php71w-cli php71w-common php71w-devel php71w-gd php71w-pdo php71w-mysql php71w-mbstring php71w-bcmath php71w-mcrypt -y
[root@test ~]# yum install -y php71w-fpm
```

2. 启动服务

```bash
[root@test ~]# systemctl start php-fpm
[root@test ~]# systemctl enable php-fpm
```

​	PHP-FPM(FastCGI Process Manager：FastCGI进程管理器)是一个PHP FastCGI管理器。它提供了更好的PHP进程管理方式，可以有效控制内存和进程、可以平滑重载PHP配置。在日常运维中，我们主要将PHP-FPM 的配置文件分为主配置文件和 pool配置文件(每个pool配置文件通常对应一个Nginx虚拟主机)。

3. php的优化

```bash
主配置文件 php-fpm.conf，常用配置如下:
设置php-fpm最大进程数
[root@nginx-yum2 ~]# vim /etc/php-fpm.conf
[global]
...
;动态方式下开启的php-fpm进程的最大数量
process.max = 2048
;设置 fpm 在后台运行
daemonize = yes
; 设置进程可以打开的文件描述符数量
rlimit_files = 65535
; 设置FPM 的事件处理机制
events.mechanism = epoll
;  加载pool 配置
include = /etc/fpm.d/*.conf

设置进程池
[root@nginx-yum2 ~]# vim /etc/php-fpm.d/www.conf
[www]
...
; 设置动态dynamic进程池/静态static
pm = dynamic
; 设置每个进程可处理的请求数，当进程达到这个请求数量后会自动释放在重新生成新的进程。避免内存泄漏等情况
pm.max_requests = 1500
; 终止请求超时时间。一个请求若处理大于20s ，则会自动kill掉。避免进程堆积
request_terminate_timeout = 20
; 限制 FPM 允许解析的脚本扩展名. 这里不限制，FPM可以解析任何扩展名的文件
security.limit_extensions = ""

修改php上传文件的大小
[root@nginx-yum2 ~]# vim /etc/php.ini
max_execution_time = 0 #默认的该脚本最久执行时间为30秒.就是说超过30秒,该脚本就停止执行，0为不限制时间
post_max_size = 150M #默认POST数据大小为8M，可以按实际情况修改
upload_max_filesize = 100M #默认上传文件最大为2M，可以按实际情况修改。
注：另外要说明的是,post_max_size 大于 upload_max_filesize 为佳
```

```ini
通过 expires 指令设置的缓存，主要是针对客户端浏览器的。如果我们能将静态资源的缓存设置在服务器端，当多个用户访问同一个资源时，缓存命中率及系统的性能将大大提升。
proxy_cache介绍：当nginx作为反向代理时，通常只有动态的请求，也就是不同的用户访问的同一个url看到的内容是不同的，这个时候才会交由上游服务器处理，但是有些内容可能是一段时间内是不会变化的，这个时候为了减轻上游服务器的压力，那么就让nginx把上游返回的内容缓存一段时间，比如缓存一天，在一天之内即是上游服务器内容发生了变化也不管，nginx只返回缓存到的内容给用户。

proxy_cache--实现服务器端缓存，主要设置在反向代理上面
```

```ini
配置nginx反向代理upstream，并实现服务器端缓存时间
upstream static {
        server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=60s;
        }
upstream php {
        server 10.0.105.200:80 weight=1 max_fails=1 fail_timeout=60s;
        }

proxy_cache_path /tmp/proxy_cache levels=1:2 keys_zone=proxy_cache:64m inactive=1d max_size=128m;

        server {
        listen      80;
        server_name     localhost
        #动态资源加载
        location ~ \.(php|jsp)$ {
            proxy_pass http://php;
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                }
        #静态资源加载
        location ~ .*\.(html|jpg|png|css|js)$ {
            proxy_pass http://static;
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_cache proxy_cache;    #配置设置的缓存空间名称
            proxy_cache_valid 200 302 304 30d ; #根据响应码设置缓存时间，超过这个时间即使缓存文件中有缓存数据，nginx也会回源请求新数据。
            proxy_cache_key $host$uri$is_args$args; #对不同用户的请求展示不同的内容
                }
        }
        
 参数详解：
proxy_cache_path      缓存文件路径
levels                设置缓存文件目录层次；levels=1:2 表示两级目录
keys_zone             设置缓存名字和共享内存大小.【在使用的地方要使用缓存名】
inactive              在指定缓存时间内没人访问则被删除
max_size              最大缓存空间，如果缓存空间满，默认覆盖掉缓存时间最长的资源。
```

