反向代理(reverse proxy) 方式是指用代理服务器来接受Internet上的连接请求, 然后将
请求转发给内部网络中的上游服务器, 并将从上游服务器上得到的结果返回给Internet上请求
连接的客户端, 此时代理服务器对外的表现就是一个Web服务器。 充当反向代理服务器也是
Nginx的一种常见用法(反向代理服务器必须能够处理大量并发请求)
由于Nginx具有“强悍”的高并发高负载能力, 因此一般会作为前端的服务器直接向客户端提供静态文件服务。 但也有一些复杂、 多变的业务不适合放到Nginx服务器上, 这时会用Apache、 Tomcat等服务器来处理。 于是, Nginx通常会被配置为既是静态Web服务器也是反向代理服务器 , 不适合Nginx处理的请求就会直接转发到上游服务器中处理。
与其他反向代理服务器相比的不同点:
当客户端发来HTTP请求时, Nginx并不会立刻转发到上游服务器, 而是先把用户的请求(包括HTTP包体) 完整地接收到Nginx所在服务器的硬盘或者内存中, 然后再向上游服务器发起连接, 把缓存的客户端请求转发到上游服务器。 而Squid等代理服务器则采用一边接收客户端请求, 一边转发到上游服务器的方式。
缺点是延长了一个请求的处理时间,并增加了用于缓存请求内容的内存和磁盘空间。 而优点则是降低了上游服务器的负载, 尽量把压力放在Nginx服务器上。
Nginx的这种工作方式为什么会降低上游服务器的负载呢? 通常, 客户端与代理服务器之间的网络环境会比较复杂, 多半是“走”公网, 网速平均下来可能较慢, 因此, 一个请求可能要持续很久才能完成。 而代理服务器与上游服务器之间一般是“走”内网, 或者有专线连接, 传输速度较快。
Squid等反向代理服务器在与客户端建立连接且还没有开始接收HTTP包体时, 就已经向上游服务器建立了连接。 例如, 某个请求要上传一个1GB的文件, 那么每次Squid在收到一个TCP分包(如2KB) 时, 就会即时地向上游服务器转发。 在接收客户端完整HTTP包体的漫长过程中, 上游服务器始终要维持这个连接, 这直接对上游服务器的并发处理能力提出了挑战。
Nginx则不然, 它在接收到完整的客户端请求(如1GB的文件) 后, 才会与上游服务器建立连接转发请求, 由于是内网, 所以这个转发过程会执行得很快。 这样, 一个客户端请求占用上游服务器的连接时间就会非常短, 也就是说, Nginx的这种反向代理方案主要是为了降低上游服务器的并发压力。
作为代理服务器, 一般都需要向上游服务器的集群转发请求。 这里的负载均衡是指选择一种策略, 尽量把请求平均地分布到每一台上游服务器上。使得每台服务器的资源得到合理应用。
nginx的负载均衡算法默认使用基于权重的轮询算法。
语法:upstream name {…}
默认:无
上下文:http
upstream块定义了一个上游服务器的集群, 便于反向代理中的proxy_pass使用。
例子:
upstream orderService{
#可以配置域名,也可以配置域名加端口号,这里没有端口号就是默认80端口。
server orderService1.example.com;
server orderService2.example.com;
server orderService3.example.com;
}
这里的server不是server块,而是一个配置项。
语法:server name [parameters]
上下文:upstream
server配置项指定了一台上游服务器的名字, 这个名字可以是域名、 IP地址端口、 UNIX
句柄等, 在其后还可以跟下列参数。
weight = number :配置向这台上游服务器进行请求转发的权重。默认为1,是为了使用轮询算法的负载均衡配置的,比如有三台上游服务器集群,权重分别为1、2、3,则如果6个请求,就会有1个请求转发到权重为1的服务器上,2个请求转发到权重为2的服务器上。3个请求转发到权重为3的服务器上。
max_fails=number :该选项与fail_timeout配合使用,指在fail_timeout时间内,如果向当前的上游服务器转发失败的次数超过number次,则认为在当前的fail_timeout时间段内这台上游服务器不可用。 max_fails默认为1, 如果设置为0, 则表示不检查失败次数。
fail_timeout=time: fail_timeout表示该时间段内转发失败多少次后就认为上游服务器暂时不可用, 用于优化反向代理功能。 它与向上游服务器建立连接的超时时间、 读取上游服务器的响应超时时间等完全无关。 fail_timeout默认为10秒。
down: 表示所在的上游服务器永久下线, 只在使用ip_hash配置项时才有用。
backup: 在使用ip_hash配置项时它是无效的。 它表示所在的上游服务器只是备份服务
器, 只有在所有的非备份上游服务器都失效后, 才会向所在的上游服务器转发请求。
语法:ip_hash;
默认:无
上下文:upstream
在有些场景下, 我们可能会希望来自某一个用户的请求始终落到固定的一台上游服务器中。 例如, 假设上游服务器会缓存一些信息, 如果同一个用户的请求任意地转发到集群中的任一台上游服务器中, 那么每一台上游服务器都有可能会缓存同一份信息, 这既会造成资源的浪费, 也会难以有效地管理缓存信息。 ip_hash就是用以解决上述问题的, 它首先根据客户端的IP地址计算出一个key, 将key按照upstream集群里的上游服务器数量进行取模, 然后以取模后的结果把请求转发到相应的上游服务器中。 这样就确保了同一个客户端的请求只会转发到指定的上游服务器中。比如没有使用分布式session,而是只在某台节点上保存了某个客户端的session,则使用ip_hash就可以确保每次访问都会到同一台节点上。
ip_hash与weight(权重) 配置不可同时使用。 如果upstream集群中有一台上游服务器暂时不可用, 不能直接删除该配置, 而是要down参数标识, 确保转发策略的一贯性。
变量名 | 意义 |
---|---|
$upstream_addr | 处理请求的上游服务器地址,也就是转发到的上游服务器地址 |
$upstream_cache_status | 表示是否命中缓存,取值范围MISS、EXPIRED、UPDATING、STALE、HIT |
$upstream_status | 上游服务器返回的HTTP响应状态码 |
$upstream_response_time | 上游服务器的响应时间,进度到毫秒 |
$upstream_http_$HEADER | HTTP的头部值,比如 upstream_http_token 表示 token头 |
可以在access_log的日志格式中加入这些变量。
介绍反向代理的基本配置项。
语法:proxy_path URL
默认:无
上下文:location 、if
此配置项将当前请求反向代理到URL参数指定的服务器上, URL可以是主机名或IP地址加端口的形式。
例子:
proxy_pass http://localhost:8080/uri
还可以使用上面负载均衡配置的upstream
upstream orderService{
....
}
server{
location / {
proxy_pass http://orderService
}
}
用户还可以把http转换为更加安全的https。
proxy_path https://192.168.18.125
默认请求下是不会转发HTTP的Host请求头的,也就是上游服务器默认是获取不到客户端的Host的值。如果需要转发,可以这样配置:
proxy_set_header Host $host;
语法:proxy_method method;
默认:无。
上下文:http、server、location
此配置表示转发时的协议方法名。
例子:
proxy_method POST;
上面配置,无论客户端无论以什么请求方法到nginx上,nginx都会以Post方法转发到上游服务器。
语法:proxy_hide_header header
默认:无
上下文:http、server、location
Nginx会将上游服务器的响应转发给客户端, 但默认不会转发以下HTTP头部字段:
Date、 Server、 X-Pad和X-Accel-*。 使用proxy_hide_header后可以任意地指定哪些HTTP头部
字段不能被转发。 例如:
proxy_hide_header Cache-Control;
proxy_hide_header MicrosoftOfficeWebServer;
上面配置表示nginx转发上游服务器返回的响应给客户端时,不转发Cache-Control和MicrosoftOfficeWebServer头。
语法:proxy_pass_header header
默认:无
上下文:http、server、location
与proxy_hide_header功能相反, proxy_pass_header会将原来禁止转发的header设置为允许
转发。
例子:
proxy_pass_header X-Accel-Redirect;
语法:proxy_pass_request_body on|off
默认:proxy_pass_request_body on
上下文:http、server、location
作用为确定是否向上游服务器发送HTTP包体部分。
语法:proxy_pass_request_headers on|off
默认:proxy_pass_request_headers on
上下文:http、server、location
作用为确定是否向上游服务器转发HTTP请求头部。