[toc]
nginx四层负载均衡
1.nginx四层负载均衡简介
-
nginx从1.9.0版本开始,新增了
ngx_stream_core_module
模块,使nginx支持四层负载均衡。默认编译的时候该模块并未编译进去,需要编译的时候添加--with-stream
,使其支持stream代理。 -
负载平衡是指在多个后端服务器之间有效地分配网络流量。
-
nginx可以代理和负载平衡传输控制协议(TCP)通信。TCP是许多流行的应用程序和服务的协议,例如LDAP,MySQL和RTMP。
-
nginx可以代理和负载均衡UDP流量。UDP(用户数据报协议)是许多流行的非事务性应用程序的协议,例如DNS,syslog和RADIUS。
2.先决条件
- 需要模块
--with-stream
的支持 - 通过TCP或UDP进行通信的应用程序,数据库或服务
- 上游服务器,每个服务器运行应用程序,数据库或服务的相同实例
3.官方配置示例
3.1 配置反向代理
首先,需要配置反向代理,以便NGINX可以将TCP连接或UDP数据报从客户端转发到上游组或代理服务器。
3.1.1 创建一个顶级stream{}
块:
stream {
# ...
}
server {}
在顶级stream
{}
上下文中为每个虚拟服务器定义一个或多个配置块。
3.1.2 在server
{}
每个服务器的配置块中,包括listen
用于定义服务器侦听的IP地址或端口的指令。
对于UDP通信,还包括udp
参数。由于TCP是stream
上下文的默认协议,因此tcp
该listen
指令没有参数:
stream {
server {
listen 12345;
# ...
}
server {
listen 53 udp;
# ...
}
# ...
}
3.1.3 配置proxy_pass
指令以定义代理服务器或服务器将流量转发到的上游组
stream {
server {
listen 12345;
#TCP流量将转发到"stream_backend"上游组
proxy_pass stream_backend;
}
server {
listen 12346;
#TCP流量将被转发到指定的服务器
proxy_pass backend.example.com:12346;
}
server {
listen 53 udp;
#UDP流量将转发到"dns_servers"上游组
proxy_pass dns_servers;
}
# ...
}
3.1.4 配置代理绑定
如果代理服务器具有多个网络接口,则可以选择将NGINX配置为在连接到上游服务器时使用特定的源IP地址。如果将NGINX之后的代理服务器配置为接受来自特定IP网络或IP地址范围的连接,这可能很有用
包括proxy_bind
指令和相应网络接口的IP地址
stream {
# ...
server {
listen 127.0.0.1:12345;
proxy_pass backend.example.com:12345;
proxy_bind 127.0.0.1:12345;
}
}
3.1.5 配置缓冲
可以调整两个内存缓冲区的大小,NGINX可以在其中放置来自客户端和上游连接的数据。如果数据量很小,则可以减少缓冲区,这可以节省内存资源。如果有大量数据,则可以增加缓冲区大小以减少套接字读/写操作的数量。在一个连接上接收到数据后,NGINX将读取该数据并通过另一连接转发该数据。缓冲区由proxy_buffer_size
伪指令控制:
stream {
# ...
server {
listen 127.0.0.1:12345;
proxy_pass backend.example.com:12345;
proxy_buffer_size 16k;
}
}
3.2 配置TCP或UDP负载平衡
3.2.1 创建一组服务器
upstream{}
在顶级stream
{}
上下文中定义一个或多个配置块,并为上游组(例如,stream_backend
TCP服务器和dns_servers
UDP服务器)设置名称:
确保上游组的名称由proxy_pass
指令引用,就像上面为反向代理配置的指令一样。
stream {
upstream stream_backend {
# ...
}
upstream dns_servers {
# ...
}
# ...
}
3.2.2 在服务器组中添加后端真实服务器(上游服务器)
在该upstream
{}
块内,server
为每个上游服务器添加一个指令,指定其IP地址或主机名(可以解析为多个IP地址)和一个必需的端口号。请注意,并未为每个服务器定 义协议,因为该协议是由在前面创建listen
的server
块中的指令中包含的参数为整个上游组定义的。
stream {
upstream stream_backend {
server backend1.example.com:12345;
server backend2.example.com:12345;
server backend3.example.com:12346;
# ...
}
upstream dns_servers {
server 192.168.136.130:53;
server 192.168.136.131:53;
# ...
}
# ...
}
3.2.3 配置上游服务器组的负载均衡算法
3.2.3.1 轮询 Round Robin
默认情况下,NGINX使用Round Robin算法来负载均衡流量,将其顺序地定向到已配置的上游组中的服务器。因为它是默认方法,所以没有round‑robin
指令。只需在顶级上下文中创建配置块并添加上一步中所述的指令。upstream {} stream {} server
3.2.3.2 最少连接
NGINX选择当前活动连接数量较少的服务器。
3.2.3.3 哈希 hash
NGINX根据用户定义的密钥(例如,源IP地址($remote_addr
))选择服务器:
upstream stream_backend {
hash $remote_addr;
server backend1.example.com:12345;
server backend2.example.com:12345;
server backend3.example.com:12346;
}
该Hash
负载平衡方法也可以用来配置会话持久性。由于哈希函数基于客户端IP地址,因此除非服务器关闭或不可用,否则来自给定客户端的连接将始终传递到同一服务器。指定一个可选consistent
参数以应用ketama一致性哈希方法:
hash $remote_addr consistent;
3.2.4 为每个上游服务器指定服务器特定的参数,包括最大连接数,服务器权重等(可选)
upstream stream_backend {
hash $remote_addr consistent;
server backend1.example.com:12345 weight=5;
server backend2.example.com:12345;
server backend3.example.com:12346 max_conns=3;
}
upstream dns_servers {
least_conn;
server 192.168.136.130:53;
server 192.168.136.131:53;
# ...
}
另一种方法是将流量代理到单个服务器而不是上游组。如果您通过主机名标识服务器,并配置主机名以解析为多个IP地址,则NGINX使用该Round Robin
算法对IP地址之间的流量进行负载平衡。在这种情况下,您必须在proxy_pass
指令中指定服务器的端口号,并且不得在IP地址或主机名之前指定协议
stream {
# ...
server {
listen 12345;
proxy_pass backend.example.com:12345;
}
}
3.3 配置TCP健康检查
3.3.1 简介
- nginx TCP健康检查可以持续测试TCP上游服务器, 避免出现故障的服务器,并可以将恢复的服务器正常地添加到负载平衡组中
3.3.2 前提条件
已在stream
上下文中配置了TCP服务器的上游组**
stream {
#...
upstream stream_backend {
server backend1.example.com:12345;
server backend2.example.com:12345;
server backend3.example.com:12345;
}
#...
}
已经配置了将TCP连接传递到服务器组的服务器
stream {
#...
server {
listen 12345;
proxy_pass stream_backend;
}
#...
}
3.3.3 被动TCP运行状况检查
如果连接上游服务器的尝试超时或导致错误,NGINX可以将服务器标记为不可用,并在指定的时间内停止向其发送请求。要定义NGINX认为上游服务器不可用的条件,请在server
指令中包含以下参数
fail_timeout
–在指定的连接尝试次数内必须失 败的时间,才能将服务器视为不可用。同样,NGINX将服务器标记为不可用后的时间。max_fails
–在指定时间内NGINX认为服务器不可用的失败尝试次数。
默认值为10
秒数和1
尝试次数。因此,如果连接尝试超时或在10秒钟内至少失败一次,NGINX会将服务器标记为10秒钟不可用。该示例显示了如何在30秒内将这些参数设置为2个失败
upstream stream_backend {
server backend1.example.com:12345 weight=5;
server backend2.example.com:12345 max_fails=2 fail_timeout=30s;
server backend3.example.com:12346 max_conns=3;
}
3.3.3.1 服务器缓慢启动(只有nginx plus可以使用)
最近恢复的上游服务器很容易被连接淹没,这可能导致服务器再次标记为不可用。慢速启动允许上游服务器在恢复或可用后将其权重从零逐渐恢复到其标称值。这可以通过slow_start
上游server
指令的参数来完成
upstream backend {
server backend1.example.com:12345 slow_start=30s;
server backend2.example.com;
server 192.0.0.1 backup;
}
请注意,如果组中只有一台服务器,则将slow_start
忽略该参数,并且永远不会将服务器标记为不可用。慢速启动是NGINX Plus独有的
3.4 配置UDP健康检查
3.4.1 前提条件
已配置上下文中的上游服务器组来处理UDP网络流量(DNS,RADIUS,系统日志),例如:stream {}
stream {
#...
upstream dns_upstream {
server 192.168.136.130:53;
server 192.168.136.131:53;
server 192.168.136.132:53;
}
#...
}
已经配置了将UDP数据报传递到上游服务器组的服务器
stream {
#...
server {
listen 53 udp;
proxy_pass dns_upstream;
proxy_timeout 1s;
proxy_responses 1;
error_log logs/dns.log;
}
#...
}
3.4.2 被动UDP健康检查
如果服务器回复错误或超时,则NGINX可以将服务器标记为不可用,并在一段时间内停止向其发送UDP数据报。
max_fails
使用上游服务器的参数设置在特定时间段内连续失败的连接尝试次数(默认值为1
)。
时间段由fail_timeout
参数设置(默认值为10
秒)。该参数还设置了NGINX标记服务器后认为服务器不可用的时间。
因此,如果连接尝试超时或在10秒内至少失败一次,NGINX会将服务器标记为10秒钟不可用。该示例显示了如何在60秒内将这些参数设置为2个失败:
upstream dns_upstream {
server 192.168.136.130:53 fail_timeout=60s;
server 192.168.136.131:53 fail_timeout=60s;
}