基本配置

在conf目录下新建proxy_params文件
带了下面所有的参数,会导致速度比不带参数慢5-8倍,具体是哪一个性能有问题,待验证

  1. #将需要的配置参数放到这,如
  2. proxy_set_header Host $http_host; #添加头信息
  3. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  4. proxy_set_header X-Real-IP $remote_addr;#上流服务器拿不到真是ip,通过设置传过去
  5. #proxy_set_header X-Real-IP $clientRealIp;
  6. proxy_headers_hash_max_size 51200; #设置头部哈希表的最大值,不能小于你后端服务器设置的头部总数
  7. proxy_headers_hash_bucket_size 6400;#设置头部哈希表大小
  8. proxy_connect_timeout 5; #nginx跟后端服务器连接超时时间(代理连接超时)
  9. proxy_read_timeout 60; #后端服务器数据回传时间(代理发送超时)
  10. proxy_send_timeout 5; #连接成功后,后端服务器响应时间(代理接收超时)
  11. proxy_buffer_size 16k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
  12. proxy_buffers 4 64k; #proxy_buffers缓冲区,网页平均在32k以下的设置,语法:数量 大小
  13. proxy_busy_buffers_size 128k; #高负荷下缓冲大小(proxy_buffers*2)
  14. proxy_temp_file_write_size 128k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
  15. proxy_ignore_client_abort on; #不记录499错误(客户端主动关闭错误),仅对代理有效

常见生产上的参数

  1. proxy_set_header Host $http_host; #添加头信息
  2. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  3. proxy_set_header X-Real-IP $remote_addr;#上流服务器拿不到真是ip,通过设置传过去
  1. http{
  2. upstream bakend {
  3. server 192.168.1.10:80 weight=1 max_conns=1000;
  4. server 192.168.1.11:80 weight=2 max_conns=2000;
  5. }
  6. server {
  7. location / {
  8. include proxy_params;#包含所有请求参数
  9. proxy_pass http://backend;
  10. }
  11. }
  12. }
  13. #weight是可选的,这样配置的意思为192.168.1.11的访问量为192.168.1.10的两倍
  14. #max_conns ,控制服务器的连接数

上流失败规则

  1. http{
  2. upstream bakend {
  3. server 192.168.1.10:80 weight=1 max_fails=2 fail_timeout=60s;
  4. server 192.168.1.11:80 weight=2 max_fails=2 fail_timeout=60s;
  5. }
  6. }
  7. #意思是在fail_timeout时间内失败了max_fails次请求后,则认为该上游服务器不可用,然后将该服务地址踢除掉。
  8. #fail_timeout时间后会再次将该服务器加入存活列表,进行重试。

按ip分配服务器

  1. #每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器
  2. http{
  3. upstream resinserver {
  4. ip_hash;
  5. server 192.168.1.10:8080;
  6. server 192.168.1.11:8080;
  7. }
  8. }

按ip分配服务器(CDN)

  1. #每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器
  2. http{
  3. map $http_x_forwarded_for $clientRealIp {
  4. #没有通过代理,直接用 remote_addr
  5. "" $remote_addr;
  6. #有代理,找到第一个ip地址
  7. ~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr;
  8. }
  9. upstream resinserver {
  10. hash $clientRealIp;
  11. server 192.168.1.10:8080;
  12. server 192.168.1.11:8080;
  13. }
  14. }

以上用到的是7层代理(应用层),指的是http
还有一种4层代理(传输层),指的是TCP/UDP

理论上4层要比7层快,因为7层代理需要解析数据包的具体内容,需要消耗额外的cpu。但nginx具体强大的网络并发处理能力, 对于一些慢连接,nginx可以先将网络请求数据缓冲完了一次性转发给上游server,这样对于上游网络并发处理能力弱的服务器(比如tomcat),这样对tomcat来说就是慢连接变成快连接(nginx到tomcat基本上都是可靠内网),从而节省网络数据缓冲时间,提供并发性能。

由于4层代理用的是NAT,所以nginx不知道请求的具体内容,所以nginx啥也干不了。 用7层代理,可以根据请求内容(url,参数,cookie,请求头)做很多事情。

4层代理配置

  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. stream { #类似于7层的http段
  6. upstream ssh_proxy {
  7. server 192.168.56.1:80;
  8. server 192.168.56.2:80;
  9. }
  10. server {
  11. listen 9999;
  12. proxy_pass ssh_proxy;
  13. }
  14. }

注意事项

nginx配置proxy_pass URL末尾加与不加/(斜线)的区别
假设访问路径的 /pss/a.html
加/斜线的情况

  1. location /pss/ {
  2. proxy_pass http://127.0.0.1:8001/;
  3. }
  4. 被代理的真实访问路径为:http://127.0.0.1:8001/a.html

不加/斜线的情况

  1. location /pss/ {
  2. proxy_pass http://127.0.0.1:8001;
  3. }
  4. 被代理的真实访问路径为:http://127.0.0.1:8001/pss/a.html

长连接

  1. upstream http_backend {
  2. server 127.0.0.1:8080;
  3. keepalive 16;
  4. }
  5. server {
  6. location /http/ {
  7. proxy_pass http://http_backend;
  8. proxy_http_version 1.1;
  9. proxy_set_header Connection "";
  10. }
  11. }

有几点要说明:
1. 默认情况下 Nginx 访问后端都是用的短连接(HTTP1.0),一个请求来了,Nginx 新开一个端口和后端建立连接,请求结束连接回收。如果像上面的配置一样设置了长连接,Nginx 会接受客户端的请求,处理完成之后 Nginx 会「继续保持和后端的长连接」,如果并发请求超过了 keepalive 指定的最大连接数,Nginx 会启动新的连接 来转发请求,新连接在请求完毕后关闭,而且新建立的连接是长连接,这可能会造成额外的问题,最后再说。
2. keepalive 指定的 数值 是 Nginx 每个 worker 连接后端的最大长连接数,而不是整个 Nginx 的。 而且这里的后端指的是「所有的后端」,而不是每一个后端(已验证)。

Nginx 和后端的长连接不够用时 Nginx 会新建连接来处理新的请求,而我们的配置已经配置死了 HTTP1.1,建立连接后,后端认为是「长连接」而不会主动关闭连接(一般有个空闲超时),关闭连接由 Nginx 来做了,所以 Nginx 会出现大量的 TIME_WAIT。
而默认情况下,Nginx 用 HTTP1.0 请求后端,后端处理完成后就主动关闭连接,所以 TIME_WAIT 在后端。
那么现在有新的问题了,如果开启了长连接,而长连接又大量不够用,此时 Nginx 存在的 TIME_WAIT 可能会大量占用端口,导致端口用尽,如果用尽,后果很严重。
所以,「慎用 Nginx 的 长连接」。