nginx反向代理

Posted 一叶知秋~~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nginx反向代理相关的知识,希望对你有一定的参考价值。

nginx反向代理

反向代理:reverse proxy,可代理外网用户的请求到内部的指定web服务器,并将数据返回给用户

nginx除了可以在企业提供高性能的web服务之外,另外还可以将本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是nginx服务器与其他服务器进行通信的一种规范

主要在不同的场景使用以下模块实现不同的功能:

ngx_http_proxy_module: 将客户端请求以http协议转发至后端服务器
ngx_http_fastcgi_module:将客户端对php请求以fastcgi协议转发至后端
ngx_http_uwsgi_module:将客户端对Python请求以uwsgi协议转发至后端
ngx_stream_proxy_module:将客户端请求以tcp协议转发至后端服务器

 生产环境部署结构:

 同构异构代理

 数据库程序员在调用数据库时,不要直接连接后台数据库的IP地址,连接的是nginx反向代理的IP地址,如果后端服务器的IP地址修改后,只需要修改nginx反向代理的IP地址即可。

nginx反向代理

ngx_http_proxy_module模块:

转发请求至另一台主机

proxy_pass URL;

注意:proxy_pass后面路径不带uri时,会将location的uri传递(附加)给后端主机

server {
...
server_name HOSTNAME;
location /uri/ {
proxy_pass http://host[:port];    ##注意:最后没有/,如果有/就会直接访问此uri下的文件,而不是location目录下的文件
}
...
}

上面示例:http://HOSTNAME/uri --> http://host/uri ,功能类似 root

如果上面示例中有 /,即:http://host[:port]/ 此方式较少使用

意味着:http://HOSTNAME/uri --> http://host/ 即置换,功能类似 alias

实现反向代理动静分离

原理:客户端访问网页时,nginx作为反向代理,实际访问的是后端服务器的网页资源,而此反向代理,在后端进行log日志分析时,只能分析到nginx服务器IP地址访问的页面,客户端访问的IP地址无法知道,而nginx反向代理的log日志可以分析到客户端访问的IP地址。

1、环境准备:

机器名称

IP配置

服务角色

备注

nginx

IP:192.168.37.27

  

反向代理服务器

开启代理功能

设置监控,调度

客户端

IP:192.168.37.17

客户端

stasic-srv 组

后端

IP:192.168.37.37

后端服务器

stasic-srv 组

后端

IP:192.168.37.47

后端服务器

defautl-srv 组

 

 2、配置nginx反向代理文件

[root@centos27site1]#vim /etc/nginx/conf.d/test.conf 
server  {
    listen 80;
    server_name www.magedu.net;
    root /data/site1/;
    location ~* ^.*\\.(jpg|gif.bmp|jpeg) {   将静态格式的文件都代理到37后端服务器上
        proxy_pass http://192.168.37.37; 默认访问的是80端口
    }
    location /api {
        proxy_pass http://192.168.37.47:80;    将动态的文件都代理到47后端服务器上                                                                                                     
    }
    access_log  /var/log/nginx/access_json.log  access_json;
}

3、37后端准备相关的静态图片,并启动httpd服务

[root@centos37~]#yum install httpd -y
[root@centos37~]#systemctl start httpd
[root@centos37~]#cp /usr/share/pixmaps/faces/legacy/sky.jpg  /var/www/html/

 4、47后端服务器安装httpd服务,并准备api相关文件和页面,在客户端访问的api,实际是后端47的api文件。

[root@centos_47~]#yum  install httpd  -y
[root@centos_47~]#sysetmctl start httpd
[root@centos_47~]#mkdir /var/www/html/api
[root@centos_47~]#echo /var/www/html/api/192.168.37.47 > /var/www/html/api/index.html

  5、验证效果,此时客户端访问设定好动静分离的页面,就会显示不同的效果。

[root@centos17apps]#curl www.magedu.net/api/
/var/www/html/api/192.168.37.47
[root@centos17apps]#curl -I www.magedu.net/sky.jpg  访问图片头部   
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Sun, 15 Dec 2019 12:29:18 GMT
Content-Type: image/jpeg
Content-Length: 2964
Connection: keep-alive
Keep-Alive: timeout=65
Last-Modified: Sun, 15 Dec 2019 10:18:26 GMT
ETag: "b94-599bb6a623ff2"
Accept-Ranges: bytes

 总结:当nginx服务器连接服务器的端口号修改和后端服务器的端口不一致时(如nginx服务器修改为8000,而后端httpd服务端的端口是80),访问网页就会提示502网关错误,说明后端nginx调度器连接不到端服务器(httpd),后端就会提示此时的端口号与ngixn访问的端口号不一致。

 示例:

[root@centos27site1]#vim /etc/nginx/conf.d/test.conf 
server  {
    listen 80;
    server_name www.magedu.net;
    root /data/site1/;
    location ~* ^.*\\.(jpg|gif.bmp|jpeg) {   将静态格式的文件都代理到37后端服务器上
        proxy_pass http://192.168.37.37;
    }
    location /api {
        proxy_pass http://192.168.37.47:8000;    将nginx调度器的端口号改为8000,而后端httpd的端口还是80,在网页上访问就会提示502网关错误。                                                                                                     
    }
    access_log  /var/log/nginx/access_json.log  access_json;
}

当防火墙设置DROP策略,丢弃nginx反向代理访问的网页,就会出现504的超时页面。

示例:在47后端服务器上设置防火墙策略,丢弃nginx反向代理的请求。

[root@centos_47~]#iptables -A INPUT -s 192.168.37.27  -j DROP

 然后客户端通过nginx反向代理访问页面,此时就会提示504的连接超时信息,说明nginx和后端的httpd服务的端口一致。

[root@centos17apps]#curl www.magedu.net/api/
<html>
<head><title>504 Gateway Time-out</title></head> 说明连接超时了
<body>
<center><h1>504 Gateway Time-out</h1></center>
<hr><center>nginx/1.16.1</center>
</body>
</html>

 

实现后端服务器抓取到客户端IP地址 

proxy_set_header;
#可以更改或添加客户端的请求头部信息内容并转发至后端服务器,比如在后端服务器想要获取客户端的真实IP的
时候,就要更改每一个报文的头部,如下:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_set_header HOST $remote_addr;
#添加HOST到报文头部,如果客户端为NAT上网那么其值为客户端的共用的公网IP地址。

请求报文的标准格式如下:
X-Forwarded-For: client1, proxy1, proxy2

 1、在nginx服务端先修改配置文件,有多少个nginx做反向代理,就在每台主机上进行配置。

vim /etc/nginx/conf.d/test.conf

server  {
    listen 80;
    server_name www.magedu.net;
    root /data/site1/;
    location ~* ^.*\\.(jpg|gif.bmp|jpeg) {
        proxy_pass http://192.168.37.37;
    }
    location /api {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    加入此项,就会获取客户端访问的IP地址,方便log日志分析                                                                          
        proxy_pass http://192.168.37.47;
    }
    access_log  /var/log/nginx/access_json.log  access_json;
}

 

  重新启动nginx服务:nginx  -s reload

  2、修改后端Httpd服务的配置文件,添加定义的X-Rorwarded-For,用来分析客户端访问的日志。

   vim  /etc/httpd/conf/httpd.conf

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

修改完之后重新启动httpd服务,systemctl restart httpd  

3、开始测试结果,在客户端进行访问后端的页面。

[root@centos17apps]#curl  http://www.magedu.net/api/
/var/www/html/api/192.168.37.47

 4、后端httpd服务开始跟踪log信息

反向代理示例--缓存功能

proxy_cache_path;
定义可用于proxy功能的缓存;Context: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];
示例:在http配置定义缓存信息 proxy_cache_path /var/cache/nginx/proxy_cache #定义缓存保存路径,proxy_cache会自动创建 levels=1:2:2 #定义缓存目录结构层次,1:2:2可以生成2^4x2^8x2^8=1048576个目录 keys_zone=proxycache:20m #指内存中缓存的大小,主要用于存放key和metadata(如:使用次数) inactive=120s; #缓存有效时间 max_size=1g; #最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
proxy_cache zone | off; 默认off
指明调用的缓存,或关闭缓存机制;Context:http, server, location
proxy_cache_key string; 缓存中用于“键”的内容 默认值:proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time; 定义对特定响应码的响应内容的缓存时长 定义在http{...}中 示例: proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m;

示例:在http配置定义缓存信息,此三项在生产中可以定义缓存信息,如缓存的空间大小,缓存有效时间,缓存的目录层次。

proxy_cache_path /var/cache/nginx/proxy_cache
levels=1:2:2 keys_zone=proxycache:20m
inactive=120s max_size=1g;
说明:proxycache:20m 指内存中缓存的大小,主要用于存放key和metadata(如:使用次数)
max_size=1g 指磁盘存入文件内容的缓存空间最大值

生产中配置此四项,缓存页面,可以提高访问速度:调用缓存功能,需要定义在相应的配置段,如server{...};

proxy_cache proxycache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 301 1h;
proxy_cache_valid any 1m;

 实现反向代理缓存功能

1、在ngixn反向代理修改配置文件

  vim /etc/nginx/nginx.conf

[root@centos27site1]#vim /etc/nginx/nginx.conf
proxy_cache_path /var/cache/nginx/proxy_cache  levels=1:2:2 keys_zone=proxycache:20m inactive=120s max_size=1g; 

 vim /etc/nginx/conf.d/test.conf

server  {
    listen 80;
    server_name www.magedu.net;
    root /data/site1/;

    proxy_cache proxycache;        #定义缓存文件名称
    proxy_cache_key $request_uri;  
    proxy_cache_valid 200 302 301 1h;
    proxy_cache_valid any 1m;  

                                                                                                                                                 
    location ~* ^.*\\.(jpg|gif.bmp|jpeg) {
        proxy_pass http://192.168.37.37;
    }
    location /api {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://192.168.37.47;
    }
    access_log  /var/log/nginx/access_json.log  access_json;
}

 在nginx服务端新建一个缓存目录文件 

[root@centos27site1]#mkdir /var/cache/nginx

重启nginx服务,就会生成缓存目录:nginx -s reload 

 2、在客户端访问页面,此时就会记录缓存。

[root@centos17apps]#curl www.magedu.net/api/test.html

 3、在nginx查看新建的缓存目录文件结构

   

实现隐藏后端服务器特定的响应首部

proxy_hide_header field;
用于隐藏后端服务器特定的响应首部,默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等
示例:
proxy_hide_header Etag; 隐藏指定的头部信息。

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

 1、在客户端访问时,此时会有指定的文件头部暴露,我们可以将其进行隐藏。

  

  2、在nginx方向代理服务器上修改配置文件:vim /etc/nginx/conf.d/test.conf

server  {
    listen 80;
    server_name www.magedu.net;
    root /data/site1/;

    proxy_hide_header Etag;    隐藏指定的首部信息                                                                                                                   


    proxy_cache proxycache;
    proxy_cache_key $request_uri;
    proxy_cache_valid 200 302 301 1h;
    proxy_cache_valid any 1m;


    location ~* ^.*\\.(jpg|gif.bmp|jpeg) {
        proxy_pass http://192.168.37.37;
    }
    location /api {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://192.168.37.47;
    }
    access_log  /var/log/nginx/access_json.log  access_json;
}

 

 重启nginx服务:nginx  -s reload

 3、此时客户端访问后端文件时,就不会暴露指定的首部信息。

 

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 ...
# 在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端

proxy_cache_methods GET | HEAD | POST ...;
# 对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存

 添加头部报文信息

ngx_http_headers_module模块
向代理服务器给客户端的响应报文添加自定义首部,或修改指定首部的值

add_header name value [always];
添加自定义首部
  add_header X-Via $server_addr;
  add_header X-Cache $upstream_cache_status;
  add_header X-Accel $server_name;

add_trailer name value [always];
添加自定义响应信息的尾部, 1.13.2版后支持

实现添加头部报文信息

1、在nginx反向带路服务器,修改配置文件,添加指定的报文头部信息。

 vim  /etc/nginx/conf.d/test.conf

server  {
    listen 80;
    server_name www.magedu.net;
    root /data/site1/;

    proxy_hide_header Etag;     
    add_header X-Cache $upstream_cache_status;
                                                                                                                   
    
    proxy_cache proxycache;
    proxy_cache_key $request_uri;
    proxy_cache_valid 200 302 301 1h;
    proxy_cache_valid any 1m;


    location ~* ^.*\\.(jpg|gif.bmp|jpeg) {
        proxy_pass http://192.168.37.37;
    }
    location /api {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://192.168.37.47;
    }
    access_log  /var/log/nginx/access_json.log  access_json;
}

 重新加载nginx服务:nginx  -s reload

 2、在客户端验证效果,查看此时后端服务器的版本号以及此时的缓存命中效果:

ngx_http_headers_module  

proxy_connect_timeout time;
定义与后端服务器建立连接的超时时长,如超时会出现502错误,默认为60s,一般不建议超出75s

proxy_send_timeout time;
对后端服务器send,将请求发送给后端服务器的超时时长;默认为60s

proxy_read_timeout time;
从后端服务器read,等待后端服务器发送响应报文的超时时长,默认为60s

proxy_ignore_client_abort off;
当客户端网络中断请求时,nginx服务器中断其对后端服务器的请求。即如果此项设置为on开启,则服务器会忽略客户端中断并一直等着代理服务执行返回,如果设置为off,则客户端中断后nginx也会中断客户端请求并立即记录499日志,默认为off

proxy_http_version 1.0;
用于设置nginx提供代理服务的HTTP协议的版本,默认http 1.0

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

proxy_headers_hash_max_size 512;
设置proxy_headers_hash_bucket_size的最大可用空间

server_namse_hash_bucket_size 512;
server_name hash表申请空间大小

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

  

 

 

 

 

  

  

 

  

  

  

 

  

 

以上是关于nginx反向代理的主要内容,如果未能解决你的问题,请参考以下文章

Nginx反向代理实现负载均衡配置图解

Nginx反向代理websocket配置实例

Nginx websocket反向代理

三nginx的反向代理

nginx的反向代理和配置

nginx反向代理访问很慢,我做了负载均衡,现在几乎无法访问,有谁能帮我解决一下,万分感谢。