青蛙学Linux—Nginx实现反向代理
反向代理,Reverse Proxy,是指通过代理服务器来接收来自Internet上的请求,然后将这些请求转发给内部网络的服务器,并将内部服务器返回的结果回传给Internet上请求的客户端。此时代理服务器对外就表现为一个服务器。当一个代理服务器能够代理外部网络上的访问请求来访问内部网络时,这种代理服务的方式称为反向代理服务。
反向代理的工作方式如下图所示:
1、一个简单的反向代理实例
通过Nginx可以非常简单的实现反向代理的功能。Nginx通过调用proxy_pass模块来实现反向代理。
一个简单的反向代理实例
当前环境:
- 主机A:IP地址为192.168.0.110,Nginx版本为1.14.2
- 主机B:IP地址为192.168.0.106,Nginx版本为1.14.2
我们将主机A设置为代理服务器,主机B为后端服务器;使用IP地址直接进行访问,没有设置域名解析。
以下为未配置反向代理时主机A上的Nginx配置(仅展示部分server和location配置):
server { listen 80; server_name localhost 192.168.0.110; charset utf-8; location / { root /myweb; index index.html index.htm; } }
此时访问http://192.168.0.110,看到的页面如下:
通过页面标识出IP地址以方便的辨别当前访问的主机。
再来看下主机B上的Nginx配置(也仅展示部分server和location配置):
server { listen 80; server_name localhost 192.168.0.106; charset utf-8; location / { root /myweb; index index.html index.htm; } }
此时访问http://192.168.0.106,看到的页面如下:
主机A和主机B的Nginx服务正常,页面能够正常访问,接下来配置反向代理(也仅展示主机A上location部分):
location / { proxy_pass http://192.168.0.106; # 调用proxy_pass模块把所有对主机A的请求转发给主机B }
此时访问http://192.168.0.110,看到的页面如下:
此时提供服务的主机即为主机B,表示反向代理的配置已经成功了。
如果后端提供服务的主机端口号不是默认的80端口,可配置为:
proxy_pass http://xxx:port
2、反向代理的一些优化参数
在生产环境中对于代理性能要求很高的环境下,我们可以在配置反向代理时添加以下一些参数以优化反向代理的性能:
proxy_redirect off; # 当后端服务器返回重定向或刷新请求时不重设http头 proxy_connect_timeout 90; # 与后端服务器连接的超时时间 proxy_send_timeout 90; # 后端服务器数据传回的超时时间 proxy_read_timeout 90; # 连接成功后等候后端服务器处理的时间 proxy_buffer_size 4k; # 设置一个缓冲的大小 proxy_buffers 4 32k; # 设置缓冲区的数量和大小 proxy_busy_buffers_size 64k; # 系统忙时使用缓冲区的大小 proxy_temp_file_write_size 64k; # 缓存临时文件的大小
# 让后端服务器获取客户端的真实IP地址、主机名等信息 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
3、URL中部分代理的实现
上面的例子中,我们把整个站点都进行了反向代理到后端的服务器,而Nginx还可以实现对于站点中的一部分进行反向代理。
部分代理可以分为以下三种情况
前端部分后端全站
配置如下(仅展示server和location的相关部分配置):
server{ server_name xxx; location /uri/ { proxy_pass http://aaa; } }
此时,访问类似http://xxx/uri/test.html的URL时,将会被代理到http://aaa/uri/test.html。
前端部分后端部分
配置如下(仅展示server和location的相关部分配置):
server{ server_name xxx; location /uri/ { proxy_pass http://aaa/new_uri/; } }
此时,访问类似http://xxx/uri/test.html的URL时,将会被代理到http://aaa/new_uri/test.html。
一种特殊情况
配置如下(仅展示server和location的相关部分配置):
server{ server_name xxx; location /uri/ { proxy_pass http://aaa/; } }
这种情况与第一种情况的区别仅在于后端服务器的结尾是否加/,但此时却与第一种情况有很大的不同,访问类似http://xxx/uri/test.html的URL时,将会被代理到http://aaa/test.html。