前文我们聊了下 nginx 作为反向代理服务器, 代理后端动态应用服务器的配置, 回顾请参考 https://www.cnblogs.com/qiuhom-1874/p/12430543.html; 今天我们来聊一聊 nginx 作为反向代理服务器, 代理一组服务器的配置 (负载均衡); 前边我们只说到了 nginx 怎么去代理后端服务器响应客户端的请求, 它在响应客户端请求的流程是这样的, 用户请求发送到 nginx 代理服务器上, 此时 nginx 服务器扮演的就是服务端的角色, 客户端是无法感知后端服务器的存在, 而用户的报文被 nginx 接收后, nginx 代理服务器它会把用户的请求报文拆开看, 用户请求的资源, 然后把用户的请求资源, 拿到自己的 location 中进行匹配, 如果匹配到了, 就按照匹配到的 location 中定义的代理规则进行代理, 在这之前 nginx 首先会看自己的缓存是否存在用户请求的资源, 如果有, 它就从缓存中响应用户, 如果没有, 它就扮演客户端的角色, 重新对用户请求重新封装请求报文, 发送给后端服务器, 后端服务器收到请求后, 把对应资源响应给 nginx 代理服务器, nginx 会把后端服务器响应的资源, 先缓存一份 (如果允许缓存的话), 然后在封装响应报文, 响应客户端; 从这样一个过程来看, nginx 它既当服务器角色, 又当客户端角色, 而且 nginx 是可以把用户的报文拆开, 然后再封装; 这是 nginx 作为代理服务器代理后端服务器响应客户端请求的一个过程 (后端服务器是一个的情况); 如果后端服务器有多个, 都是提供者相同的服务, 此时我们该怎么把客户端的请求代理到后端多台服务器呢?
首先我们来了解下 nginx 的 upstream 模块, nginx 的 upstream 模块有两个, 一个是基于 http 协议的 upstream, 它主要是基于 http 协议定义后端服务器组, 还有一个就是基于 tcp 协议的 upstream, 它主要是基于 tcp 协议定义后端服务器组; 我们先说 nginx 的 http 里的 upstream 模块吧!!!
一, ngx_http_upstream_module: 此模块用于定义一组服务器, 然后被 proxy_pass,fastcgi_pass,uwsgi_pass,scgi_pass 和 memcached_pass 指令引用的服务器组. 意思很简单, 就是把相同的多台服务器归并成一组服务器, 然后 nginx 基于各种协议的代理, 把请求代理到该组上, 从而实现把用户请求代理到后端多台服务器上
1,upstream name {......}: 此指令只能用于 http 配置段中, 意思是定义一组后端服务器组;
2,server address [parameters]: 此指令用于 upstream 配置段中, 表示定义 upstream 配置段中的 server 成员, 以及相关的参数; 其中地址的格式支持 IP 地址加端口的形式, 支持 unix path 路径, 也支持主机名或域名加端口的形式; parameters 表示参数, 常用的参数有 weight=number 权重, 默认是 1,max_fails=number 表示失败尝试最大次数; 超出此处指定的次数, nginx 将失败的 server 标记为不可用; fail_timeout=time 表示设置将服务器标记为不可用状态的超时时长; max_conns 表示当前的服务器的最大并发连接数; backup 表示将服务器标记为 "备用", 既所有服务器均不可用时, 此服务器才会被启用, 有点类似 LVS 里的 sorry server 的角色; down 表示将服务器标记为 "不可用"
3,least_conn: 此指令表示最少连接调度算法, 当 server 拥有不同的权重时表示 wlc 算法
4,ip_hash: 此指令类似 lvs 里的 sh 算法 (源地址哈希算法), 同一客户端地址始终调度到同一台服务器上;
5,hash key [consistent]: 基于指定的 key 的 hash 表示实现对请求的调度, 此处的 key 可以是文本, 变量, 或者二者的组合; 作用是将请求分类, 将同一类请求发往同一个 upstream 的 server 进行响应;
6,keepalive connections: 为每个 worker 进程保留的空闲的长连接数量;
示例:
定义一组服务器名为 webserver
提示: upstream 只能用于定义在 http 配置段中, 它表示定义一组服务器, 名为 webserver , 后续调度直接将用户请求代理到该组上即可;
提示: 以上配置表示将用户访问 www.proxy.com 时将用户请求代理到 webserver 这个组上的服务器, 默认情况下是轮询的;
提示: 可以看到客户端的请求是可以通过 nginx 把请求代理到后端一组服务器上, 从上面的响应结果来看, 我们不配置任何权重, 它默认就是轮询的 (当然上面的结果也有重复的, 这个还不太清楚为什么会重复, 可能是每个报文的响应速度不一样吧, 但总的响应是一样的每个后端服务器各占一半); 当然我们也是可以给不同的服务器加上不同的权重, 此时 nginx 作为调度器就是使用的加权轮询, 如下配置
提示: 以上配置表示 192.168.0.20 这台服务器的权重是 5,0.22 的权重是 2, 意思就是 7 个请求中, 0.20 处理 5 个请求, 0.22 处理 2 个请求;
假如我们后端服务器有一台服务出现故障, nginx 会不会把用户的请求调度到出现故障的服务器上呢? 我们知道在 lvs 做调度器时, 前端 lvs 会把用户的请求调度到出现故障的服务器上, 我们需要借助 keepalived 或者其他辅助服务去实现对后端服务器做健康状态监测, 才能把用户的请求不调度到有故障的后端服务器上, nginx 会不会呢?
提示: 可以看到 nginx 不会把用户的请求调度到有故障的服务器上, 这是因为 nginx 自身就有对后端服务器做健康状态监测的机制, 能够及时的发现后端服务器的健康状态, 及时的将服务不可用的后端主机从集群中下线, 当然这种下线是当服务不可用时, 自动触发的动作, 我们也可以人为的把后端服务器标记为不可用状态, 通常在做灰度发布时可能用到, 直接在服务器后面明确用 down 来标记该服务器, 不接受任何请求;
提示: 以上配置表示把 0.22 这台主机从 webserver 组中下线, 下线的意思就是不再往上调度请求; 当然此时的组中服务器就只用 0.20 这一台主机, 用户请求也只能调度到这台上, 所以用户不管怎么请求, nginx 都只会把请求调度到 0.20 这台后端主机上;
假如后面的两台主机都宕机了, 此时用户访问我们的网站会不会像 lvs 那样, 有 sorry server 来给用户说 sorry 呢?
提示: 可以看到当后端主机全部宕机后, 没有像 lvs 里的有 sorry server 出来给用户说 sorry 或者响应客户端请求的; 在 nginx 里 sorry server 里的配置很简单, 只需要在服务器的后面打上 backup 的标签即可
提示: 以上配置表示把 127.0.0.1:80 作为 sorry server , 意思是组里的正常被代理的主机全部宕机后, 这台主机才会被调度, 当组里主机有一台恢复正常, 这台主机就不被调度, 用户请求将调度到正常的那一台主机上;
提示: 可以看到当后端主机全部宕机后, sorry server 就会被调度;
提示: 当后端主机恢复时, sorry server 就不会被调度, 用户的请求将会被代理至恢复的那台主机上;
以上就是 nginx 作为负载均衡的常用配置, 接下来我们在说说调度算法
基于源地址 hash 算法
提示: 以上配置表示同一源地址的客户端请求将会调度到后端某一台 server 上进行响应
提示: 可以看到同一客户段始终被调度到一台 server 上进行响应, 这种就叫做源地址绑定; 除了以上 ip_hash; 来指定绑定源地址, 还可以通过 hash key 来指定, 以上配置等同 hash $remote_addr;
基于用户请求的 uri 进行绑定, 用户请求同一 uri 始终调度到某一 server 上响应, 这样做的好处可以使缓存命中提高;
提示: 以上配置表示绑定用户请求的 rui, 不同的用户请求同一 rui 时, nginx 会始终把同一 rui 的请求调度到同一台 server 上进行响应;
提示: 可以看到同一客户端请求不同的 uri 时, 会根据请求的 uri 随机调度到某一台 server 上进行响应; 从上面的配置实例我们可以知道我们把什么当作 key 来 hash, 就可以实现基于什么来绑定后端服务器, 比如基于用户请求的 uri 当作 hash 对象, 那么用户请求同一 uri 就会被调度到同一 server 上进行响应, 如果基于用户源 ip 地址当作 hash 对象, 那么同一源 IP 地址的用户, 不论请求什么 uri 都会被调度到同一 server 进行响应; 按这个逻辑我们可以绑定用户的信息来做调度;
以上就是 nginx 作为七层代理 http 请求的负载均衡的常用配置; 总结一点 nginx 作为负载均衡使用其中核心的思想就是把同类服务的服务器先归并到一个组里, 然后基于不同协议的代理来把用户的请求反代到该组上, 然后基于某种调度算法来实现把用户请求调度到某一台 server 进行响应;
来源: https://www.cnblogs.com/qiuhom-1874/p/12458159.html