nginx反向代理

反向代理:反向代理也叫reverse proxy,指的是代理外网用户的请求到内部的指定web服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式
Nginx除了可以在企业提供高可用性能的web服务之外,另外还可以将本身不具备的请求通过某种预定的协议转发给其他服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能。

ngx_http_proxy_module:将客户端的请求以http协议转发至指定服务器进行处理。 
ngx_stream_proxy_module:将客户端的请求以tcp协议转发至指定服务器处理。 
ngx_http_fastcgi_module:将客户端对php的请求以fastcgi协议转发至指定服务器助理。 
ngx_http_uwsgi_module:将客户端对Python的请求以uwsgi协议转发至指定服务器处理。

准备环境

server IP
nginx 172.20.27.10
apache 172.20.27.11

相关指令

1.proxy_pass

将location匹配到的请求向后端服务器转发

[root@nginx servers]# vim /apps/nginx/conf/servers/vs.conf
server {
    server_name www.mylinuxops.com;
    listen 80;
    location /app {
        proxy_pass http://172.20.27.11:80;
#注意:此处http://172.20.27.11:80后不带"/",则后端的apache服务器需要有个与uri相对应的目录。如果带上"/",则后端的服务器上无需创建uri的目录,一般不用带"/"
  }
}

2.在apache服务器上启动服务,创建相关的目录及测试文件

[root@apache1 ~]# systemctl start httpd
[root@apache1 ~]# mkdir /var/www/html/app
[root@apache1 ~]# echo app > /var/www/html/app/index.html

3.测试

[root@nginx servers]# curl -L www.mylinuxops.com/app
app
[root@nginx servers]# curl -L -I www.mylinuxops.com/app
HTTP/1.1 301 Moved Permanently
Server: nginx/1.17.0
Date: Sat, 01 Jun 2019 07:41:38 GMT
Content-Type: text/html; charset=iso-8859-1
Connection: keep-alive
Location: http://172.20.27.11/app/              

HTTP/1.1 200 OK
Date: Sat, 01 Jun 2019 07:41:38 GMT
Server: Apache/2.4.6 (CentOS)                   
Last-Modified: Sat, 01 Jun 2019 07:16:50 GMT
ETag: "4-58a3dea359be6"
Accept-Ranges: bytes
Content-Length: 4
Content-Type: text/html; charset=UTF-8

2.proxy_hide_header field;

用于nginx作为反向代理时,隐藏后端服务器的响应头部信息

[root@nginx servers]# vim /apps/nginx/conf/servers/vs.conf 
server {
    server_name www.mylinuxops.com;
    listen 80;
    location /app {
        proxy_pass http://172.20.27.11:80;
        proxy_hide_header ETag;
  }
}

测试
没有隐藏

[root@nginx servers]# curl -I www.mylinuxops.com/app/
HTTP/1.1 200 OK
Server: nginx/1.17.0
Date: Sat, 01 Jun 2019 07:57:53 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 4
Connection: keep-alive
Last-Modified: Sat, 01 Jun 2019 07:16:50 GMT
ETag: "4-58a3dea359be6"         #显示ETag信息
Accept-Ranges: bytes

隐藏后

[root@nginx servers]# curl -I www.mylinuxops.com/app/
HTTP/1.1 200 OK
Server: nginx/1.17.0
Date: Sat, 01 Jun 2019 07:56:44 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 4
Connection: keep-alive
Last-Modified: Sat, 01 Jun 2019 07:16:50 GMT
Accept-Ranges: bytes

proxy_pass_header field;

默认nginx在响应报文中不传递后端服务器的首部字段Data,server,X-pad,X-Accel等参数,如果要传递的话则要使用proxy_pass_header field声明后端服务器返回的值传递给客户端。

proxy_pass_request_headers

是否将客户端的请求头部转发给后端服务器,可以设置在http,server或location字段,默认为开启

proxy_pass_request_headers;

proxy_set_header;

可以更改或添加客户端的请求头部信息内容并转发至后端服务器,比如后端服务器想要获取客户端的真实IP的时候,就要更改每一个报文的头部。
示例:
未开启前,查看后端apache日志

[root@apache1 ~]# tail -5 /var/log/httpd/access_log 
172.20.27.10 - - [01/Jun/2019:15:54:12 +0800] "HEAD /app/ HTTP/1.0" 200 - "-" "curl/7.29.0"
172.20.27.10 - - [01/Jun/2019:15:56:39 +0800] "GET /app/ HTTP/1.0" 200 4 "-" "curl/7.29.0"
172.20.27.10 - - [01/Jun/2019:15:56:44 +0800] "HEAD /app/ HTTP/1.0" 200 - "-" "curl/7.29.0"
172.20.27.10 - - [01/Jun/2019:15:57:53 +0800] "HEAD /app/ HTTP/1.0" 200 - "-" "curl/7.29.0"
172.20.27.10 - - [01/Jun/2019:16:16:22 +0800] "HEAD /app/ HTTP/1.0" 200 - "-" "curl/7.29.0"
#所有的访问记录的都为nginx服务器的ip

让后端服务器记录IP为客户端IP

1.修改apache的配置文件,对日志格式进行更改

    LogFormat "\"%{X-Forwarded-For}i\" %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

2.修改nginx配置文件

[root@nginx servers]# vim /apps/nginx/conf/servers/vs.conf 
server {
    server_name www.mylinuxops.com;
    listen 80;
    location /app {
        proxy_pass http://172.20.27.11:80;
        proxy_hide_header Location;
        proxy_set_header X-Forwarded-For $remote_addr;
        #添加请求报文头部,加上客户端的IP地址。
  }
}

3.再次测试

[root@apache1 ~]# tail -1 /var/log/httpd/access_log 
"-" 172.20.136.96 - - [01/Jun/2019:16:43:06 +0800] "GET /app/ HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"

#日志记录的客户端的地址

proxy_connect_timeout

配置nginx服务器与后端服务器尝试建立连接的超时时间,默认为60秒

server {
    server_name www.mylinuxops.com;
    listen 80;
    location /app {
        proxy_pass http://172.20.27.11:80;
        proxy_hide_header Location;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_connect_timout 60s;
        #用户发来请求与后端建立连接一旦超过60s,后端服务器没有响应,就告诉用户超时了,这个值不宜设置的过长
  }
}

proxy_read_time;

配置nginx服务器向后端服务器或服务器组发起read请求后,等待的超时间,默认为60s

    proxy_read_times 60s;

porxy_write_time;

配置nginx向后端服务器或服务器组发起write请求后,等待的超时时间,默认为60s

    proxy_write_times 60s;

proxy_http_version

nginx作为反向代理向后端服务器发起请求时所使用的http协议版本

    proxy_http_version

proxy_ignore_client_about off;

当客户端网络中断请求时,nginx服务器中断其对后端服务器的请求。即如果此项设置为ON开启,则服务器会忽略客户端中断并一直等待代理服务执行返回,如果设置为off,则客户端中断后Nginx也会中断客户端的请求并立即记录499日志,默认为off。此项无需开启,开启后可能会造成大量的无用连接。

proxy_ignore_client_about

以下4个值一般设置最小值和最大值一样避免进程向内核申请内存而产生不必要的开销

proxy_headers_hash_bucket_size 512k;

当配置了proxy_hide_header和proxy_set_header的时候,用于设置nginx保存HTTP报文头的hash表的上限。

proxy_headers_hash_max_size 512k;

设置proxy_headers_hash_bucket_size的大可用空间

server_namse_hash_bucket_size 512k;

server_name hash表申请空间大小

server_names_hash_max_szie   512;

设置服务器名称hash表的上限大小

反向代理的缓存功能

反向代理的缓存是将后端服务器的静态资源存在本地当用户再次访问此资源时就直接由nginx服务器进行返回。缓存功能默认关闭

1.proxy_cache zone | off;

指明调用的缓存,或关闭缓存的机制,可以作用在http,server,location字段

2.proxy_cache_key string;

缓存中用于键的内容,默认为$scheme$proxy_host$request_uri;

proxy_cache_key $scheme$proxy_host$request_uri;

3.proxy_cache_valid [code..] time;

针对后端返回的响应码做缓存,缓存时间多久,可以做用在http,server,location中

proxy_cache_valid 200 302 10m;
proxy_cache_valid 404      1m;
#需要注意的时错误的响应码缓存不能设置太长,否则错误页面修复后,用户还是无法访问到正常的页面

4.proxy_path_path

定义可以用于proxy功能的缓存,可以作用在http字段

    proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
path #定义缓存保存路径,proxy_cache会自动创建   
levels=1:2:2 #定义缓存目录结构层次,1:2:2可以生成2^4x2^8x2^8=1048576个目录
keys_zone=proxycache:500m #指内存中缓存的大小,主要用于存放key和metadata(如:使用次数)      
inactive=120s; #缓存有效时间     
max_size=1g; #大磁盘占用空间,磁盘存入文件内容的缓存空间大值

proxy_cache_use_stale;

在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端,

proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默认是off

添加头部报文信息

nginx基于模块ngx_http_headers_module可以实现对头部保卫呢添加指定的key与值。

Syntax: add_header name value [always];
Default: — 
Context: http, server, location, if in location

示例:
在报文头头部添加自定义头部

server {
    server_name www.mylinuxops.com;
        proxy_cache proxycache;
        proxy_cache_key $request_uri;
        proxy_cache_valid 200 302 301 10m;
        proxy_cache_valid any 1m;
    listen 80;
    location /app {
        proxy_pass http://172.20.27.20:80;
        proxy_hide_header Location;
        proxy_http_version 1.0;
        add_header X-via $server_addr;
        add_header X-Cache $upstream_cache_status;
        add_header X-accel $server_name;
  }
}

测试访问查看头部信息

[root@localhost ~]# curl -I www.mylinuxops.com/app/
HTTP/1.1 200 OK
Server: nginx/1.17.0
Date: Sat, 01 Jun 2019 12:52:38 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 595
Connection: keep-alive
Last-Modified: Sat, 01 Jun 2019 12:30:34 GMT
ETag: "253-58a424c2c8384"
X-via: 172.20.27.10
X-Cache: MISS               #启用了缓存,第一次未命中
X-accel: www.mylinuxops.com
Accept-Ranges: bytes

[root@localhost ~]# curl -I www.mylinuxops.com/app/
HTTP/1.1 200 OK
Server: nginx/1.17.0
Date: Sat, 01 Jun 2019 12:52:40 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 595
Connection: keep-alive
Last-Modified: Sat, 01 Jun 2019 12:30:34 GMT
ETag: "253-58a424c2c8384"
X-via: 172.20.27.10
X-Cache: HIT                #第二次命中缓存
X-accel: www.mylinuxops.com
Accept-Ranges: bytes