nginx-5:负载均衡

参考:https://blog.csdn.net/qq_29677867/article/details/90114076

 

  使用 nginx 做负载均衡的两大模块:

  • upstream 定义负载节点池
  • location 模块进行 URL 匹配
  • proxy 模块发送请求给 upstream 定义的节点池

 

一、upstream 模块解读

  nginx 的负载均衡功能依赖于 ngx_http_upstream_module 模块,所支持的代理方式有 proxy_pass(一般用于反向代理),fastcgi_pass(一般用于和动态程序交互),memcached_pass,proxy_next_upstream,fastcgi_next_pass,memcached_next_pass。

  upstream 模块应该放在 http{} 标签内。

  模块写法:

  upstream backend {

    ip_hash;

    server xx1.xx.com                  weight=5;

    server xx2.xx.com:8800;

    server back1.xx.com:8800       backup;

    server back2.xx.com:8800       backup;

  }

  例如:

  

 

 

 

  语法解释:

 

1. nginx 默认支持四种调度算法 

  • 轮询(rr),每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器故障,故障系统自动清除,使用户访问不受影响
  • 轮询权值(weight)越大,分配到的访问几率越高,主要用于后端每个服务器性能不均的情况
  • ip_hash,每个请求按访问 IP 的 hash 结果分配,这样来自同一个 ip 的固定访问一个后端服务器,主要解决动态网站 session 共享的问题(如果 ip 不易获得,像手机端访问)
  • url_hash,按照访问的 URL 的 hash 结果来分配请求,使每个 URL 定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率,nginx 本身不支持,如果想使用需要安装 nginx 的 hash 软件包
  • fair,这个算法可以依据页面大小和加载时间长短智能的进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配,默认不支持,如果想使用需要安装 upstream_fair 模块
  • least_conn,最少连接数,哪个机器连接数少就分发

 

2. server 模块的写法

  server IP 调度状态

 

  server 指令指定后端服务器 IP 地址和端口,同时还可以设定每个后端服务器在负载均衡调度中的状态。

  • down  表示当前的 server 暂时不参与负载均衡
  • backup  预留的备份服务器,当其他所有的非 backup 服务器出现故障或者忙的时候,才会请求 backup 机器,因为这条机器的压力最小
  • max_fails  允许请求失败的次数,默认是1,当超过最大次数时,返回 proxy_next_upstream 模块定义的错误。0 表示禁止失败尝试,企业场景 2-3次,京东 1 次,根据业务需求去配置
  • fail_timeout,在经历了 max_fails 次失败后,暂停服务的时间。京东 3s,根据业务需求配置。常规业务 2-3 秒合理

 

  例:如果 max_fails 是 5,他就检测 5 次,如果 5 次都是 502,。那么他就会根据 fail_timeout 的值,等待 10 秒,再去检测。

 

  server 如果接域名,需要内网有 DNS 服务器,或者在负载均衡的 hosts 文件做域名解析。server 后面还可以直接接 IP 或 IP 加端口。

 

3. 长连接 keepalive

  

 

 

   通过该指令配置了每个 worker 进程与上游服务器可缓存的空闲连接的最大数量。当超出这个数量时,最近最少使用的连接将被关闭。keepalive 指令不限制 worker 进程与上游服务器的总连接。

  

 

 

  •  如果是 http1.0 需要配置发送 “Connection:Keep-Alive” 请求头
  • 上游服务器不能忘记开启长连接支持

 

  连接池配置建议:

  • 总长连接数是 “空闲连接池” + “释放连接池” 的长连接总数
  • 首先,长连接配置不会限制 worker 进程可以打开的总连接数(超了的作为短连接)。另外连接池要根据场景合理进行设置:空闲连接池太小,连接不够用,需要不断建连接;空闲连接池太大,空闲连接太多,还没使用就超时;建议只对小报文开启长连接。

 

二、location 模块解读

  location 作用:基于一个指令设置 URI。

 

1. 基本语法

  

 

 

  •  =  精确匹配,如果找到匹配 = 号的内容,立即停止搜索,并立即处理请求(优先级最高)
  •  ~  区分大小写
  •  ~ *   不区分大小写
  • ^~  值匹配字符串,不匹配正则表达式
  • @   指定一个命名的 location,一般用于内部重定义请求,location @name {...}

 

  匹配是有优先级的,不是按照 nginx 的配置文件进行。

  例子:

  

 

 

   结论:

  • /   匹配 A
  • /index.html   匹配 B
  • /documents/dd.html   匹配 C
  • /images/1.hif   匹配 D
  • /documents/1.jpg   匹配的是 E

  匹配的顺序, =  >  ^~   >   完全相等   >   ~*   >   空   >   /   。工作中尽量将 “ = ” 放在前面。

 

三、proxy_pass 模块解决

  proxy_pass 指令属于 ngx_http_proxy_module 模块,此模块可以将请求转发到另一台服务器。

  写法:proxy_pass   http://localhost:8800/ctx/;

  

 

 

  •  proxy_set_header:当后端 web 服务器上也配置有多个虚拟主机时,需要用该 Header 来区分反向代理哪个主机名,proxy_set_header host $host;
  • proxy_set_header    X-Forwarded-For:如果后端 web 服务器上的程序需要获取用户 IP,从该 Header 头获取。proxy_set_header  X-Forwarded-For  $remote_addr;

 

1. 配置后端服务器接收前端真是 IP

  配置如下:

  log_format   commonlog  '$remote_addr  -  $remmote_user [$time_local] "$request" '

            ' $status  $body_bytes_sent "$http_referer" '

            ' "$http_user_agent" "$http_x_forwarded_for" ';

 

2. proxy_pass 相关的优化参数

  • client_max_body_size 10m;   允许客户端请求的最大的单个文件字节数
  • client_body_buffer_size  128k;   缓冲区代理缓冲用户端请求的最大字节数,可以理解为先保存到本地再传给用户
  • proxy_connect_timeout  600;   跟后端服务器连接的超时时间,发起握手等候响应超时时间
  • proxy_read_timeout  600;   连接成功后,等待后端服务器响应时间,其实已经进入后端的排队之中等候处理
  • proxy_send_timeout  600;   后端服务器回传数据时间,就是在规定时间之内,后端服务器必须传完所有的数据
  • proxy_buffer_size  8k;    代理请求缓存区,这个缓存区会保存用户的头信息以供 nginx 进行规则处理,一般只要设置能保存下头信息即可
  • proxy_buffers 4  32k;   同上,告诉 nginx 保存单个页面使用的空间大小,假设网页大小平均在 32k 以下的话
  • proxy_busy_buffers_size  64k;   如果系统很忙的时候可以申请更大的 proxy_buffers,官方推荐(proxy_buffers*2)
  • proxy_max_temp_file_size  1024m;   当 proxy_buffers 放不下后端服务器的响应内容时,会将一部分保存到硬盘的临时文件中,这个值用来设置最大临时文件大小,默认是 1024m,它与 proxy_cache 没有关系。大于这个值,将从 upstream 服务器传回。设置 0 表示禁用
  • proxy_temp_file_write_size   64k;   proxy 缓存临时文件大小 
  • proxy_temp_path   可以在编译时指定写到哪个目录

 

四、健康检查

  nginx 提供了 health_check 语句来提供复制(upstream)时的健康检查机制(设置在 location 上下文中)

  支持的参数有:

  • interval=time:设置两次健康检查之间的间隔,默认是 5s
  • fails=number:设置将服务器视为不健康的连续检查次数,默认是 1 次
  • passes=number:设置一个服务器被视为健康的连续检查次数,默认是 1 次
  • uri=uri:定义健康检查的请求 URI,默认为“/”
  • match=name:指定匹配配置块的名字,用测试响应是否通过做健康检测。默认为测试返回状态码为 2xx 和 3xx

 

  一个简单的设置如下,将使用默认值:

  location   /   {

    proxy_pass   http://backend;

    health_check;

  }

  我们可以专门定义一个 API 用于健康检查:/api/health_check,并只返回 HTTP 状态码为 200。并设置两次检查之间的间隔值为 1 秒。这样,health_check 语句的配置如下:

  health_check  uri="/api/health_check"   interval;

  匹配 match 的方法

  

 

 

  match 例子举例

  • status  200;   status 等于 200
  • status  ! 500;   status 不是 500
  • status  200  204;   status 是 200 或 204
  • status ! 301 302;   status 不是 301 或 302
  • status  200-399;   status 在 200 到 399 之间
  • status  ! 400-599;   status 不在 400 到 599 之间
  • status 301-303 307;   status 是 301,302,303 或 307
  • header Content-Type = text/html;   “Content-Type” 的值是 text/html
  • header Content-Type != text/html;   “Content-Type” 不是text/html
  • header Connection ~ close;   “Connection”  包含 close
  • header Connection !~ close;   “Connection” 不包含 close
  • header Host;   请求头包含“Host”
  • header ! X-Accel-Redirect;   请求头不包含 “X-Accel-Redirect”
  • body ~ "Welcome to nginx!";   body 包含 “Welcome to nginx!”
  • body !~ "Welcome to nginx!";   body 不包含 “Welcome to nginx!”

 

五、其他

  只允许使用 GET、HEAD、POST 方法去请求

  if ($request_method !~ ^(GET|HEAD|POST)$ ) {

    return 444;

  }

 

posted @ 2020-08-20 14:50  停不下的时光  阅读(176)  评论(0编辑  收藏  举报