Nginx Http
代理 HTTP 流量到一组服务器
开始使用 Nginx 开源或 Nginx Plus 加载之前平衡一组服务器的 HTTP 流量,首先,我们需要使用 upstream 指令定义组。该指令放置在 http 上下文中。
组中的服务器使用 server 指令进行配置。让我们看一个例子,下面的配置定义了一个名为 backend 的组,它由三个服务器配置组成,这些配置可以在三个以上的实际服务器中解析。
http { upstream backend { server backend1.example.com weight=5; server backend2.example.com; server 192.0.0.1 backup; } }
为了将请求传递到服务器组,组名在 proxy_pass 指令中指定。在下面的示例中,运行在 Nginx 上的虚拟服务器将所有请求传递给上游后端组。
server { location / { proxy_pass http://backend; } }
以下示例结合了上述两个片段,并展示了如何将 HTTP 请求代理到后端服务器组。该组由三台服务器组成,其中两台是同一应用程序的实例,而第三台是备份服务器。由于上游块中没有指定负载均衡算法,Nginx 使用默认算法,Round Robin。
http { upstream backend { server backend1.example.com; server backend2.example.com; server 192.0.0.1 backup; } server { location / { proxy_pass http://backend; } } }
选择负载均衡方式
Nginx开源支持四种负载均衡方式,Nginx Plus增加了两种方式:
1、循环: 在这种方法中,请求在服务器之间平均分配,并考虑了服务器权重。没有启用它的指令;默认使用此方法。
upstream backend { # no load balancing method is defined for Round Robin server backend1.example.com; server backend2.example.com; }
2.最少连接数: 将请求发送到活动连接数最少的服务器,并考虑服务器权重。
upstream backend { least_conn; server backend1.example.com; server backend2.example.com; }
3. IP Hash: 此方法用于确定应该为下一个请求选择哪个服务器。在这种情况下,要么使用 IPv4 地址的前三个八位字节,要么使用整个 IPv6 地址来计算哈希值。
upstream backend { ip_hash; server backend1.example.com; server backend2.example.com; }
如果其中一台服务器需要暂时从负载平衡轮换中移除,可以添加 down 参数以保留客户端 IP 地址的当前散列。
upstream backend { server backend1.example.com; server backend2.example.com; server backend3.example.com down; }
4.通用哈希: 请求发送到的服务器由用户定义的键确定,键可以是字符串、文本、变量或组合。例如,key 可以是成对的源 IP 地址和端口,或者 key 可以是 URI,如下例所示:
upstream backend { hash $request_uri consistent; server backend1.example.com; server backend2.example.com; }
Nginx Plus 支持另外两种方法:
5.最少时间: 对于每个请求,Nginx 选择平均延迟最低和活动连接数最少的服务器,其中最低平均延迟是根据包含以下哪个参数到least_time 指令来计算的。
- header: 从服务器接收第 1st 字节的时间。
- last_byte: 是时候接受服务器的完整响应了。
- last_byte inflight: 从服务器接收完整响应的时间,考虑到不完整的请求。
upstream backend { least_time header; server backend1.example.com; server backend2.example.com; }
6.随机: 在这种方法中,每个请求都将传递到随机选择的服务器。如果指定了2个参数,1st Nginx考虑服务器权重随机选择两台服务器,然后使用指定的方法选择其中一台:
- Least_conn-最少活动连接数。
- least_time=header- 从服务器接收响应标头的最少平均时间。
- Least_time=last_byte- 从服务器接收完整响应的最短平均时间。
upstream backend { random two least_time=last_byte; server backend1.example.com; server backend2.example.com; server backend3.example.com; server backend4.example.com; }
服务器权重
默认情况下,Nginx 使用权重通过 Round Robin 方法在组内的服务器之间分配请求。服务器指令的权重参数用于设置服务器的权重。默认权重为 1、
upstream backend { server backend1.example.com weight=5; server backend2.example.com; server 192.0.0.1 backup; }
上例中backend1.example.com的权重为5,另外两台服务器的权重默认为1,但IP地址为192.0.0.1的那台被标记为备份服务器除非其他两个服务器都不可用,否则不会接收请求。在这种类型的权重配置中,每 6 个请求中,5 个发送到 backend1.example.com,1 个发送到 backend2.example.com。
服务器慢启动
服务器慢启动用于防止最近恢复的服务器被连接淹没,这可能会超时并导致服务器被标记为失败
在 Nginx Plus 中,慢启动允许上游服务器在恢复或可用后逐渐将其权重从 0 恢复到其标称值。为此,请使用服务器指令的 slow_start 参数。
upstream backend { server backend1.example.com slow_start=30s; server backend2.example.com; server 192.0.0.1 backup; }
启用会话持久性
Nginx Plus 识别用户会话并将给定会话中的所有请求路由到同一个上游服务器。这称为会话持久化。
Nginx Plus 使用三会话持久化方法。这些方法使用 sticky 指令设置。
Sticky cookie
Nginx Plus 包含一个会话 cookie到上游组的第一个响应,并标识发送响应的服务器。客户端的下一个请求包含 cookie 值,Nginx Plus 将请求路由到响应第一个请求的上游服务器。
upstream backend { server backend1.example.com; server backend2.example.com; sticky cookie srv_id expires=1h domain=.example.com path=/; }
在上面的例子中,srv_id参数用于设置cookie的名称。
expires 参数是可选的,它设置浏览器保留 cookie 的时间。
域,它也是一个可选参数,用于定义为其设置 cookie 的域。
路径也是一个可选参数。它定义了设置 cookie 的路径。
Sticky cookie 是最简单的会话持久化方法。
Sticky Route
当 Nginx Plus 收到第一个请求时,它会分配一个路由给客户。所有后续请求都与服务器指令的路由参数进行比较,以识别请求代理到的服务器。路由信息取自 cookie 或请求 URI。
upstream backend { server backend1.example.com route=a; server backend2.example.com route=b; sticky route $route_cookie $route_uri; }
Cookie Learn
首先,Nginx Plus 通过检查请求和响应来查找会话标识符。然后 Nginx Plus"学习"哪个上游服务器对应哪个会话标识符。通常,这些标识符在 HTTP cookie 中传递。如果请求已经"学习"到会话标识符,Nginx Plus 会将请求转发到相应的服务器。
upstream backend { server backend1.example.com; server backend2.example.com; sticky learn create=$upstream_cookie_examplecookie lookup=$cookie_examplecookie zone=client_sessions:1m timeout=1h; }
在上面,其中一台上游服务器通过在响应中设置 cookie EXAMPLECOOKIE 来创建会话。
下一章:Nginx 指令
Nginx 由由配置文件中定义的指令控制的模块组成。指令分为两部分:简单指令: 简单指令由名称和参数组成,以空格分隔并以分号(;) 结尾。块指令: 块指令的结构类似于简单指令,但它不是分号,而是以花括号({和})包围的一组 ...