nginx基于TCP的反向代理
⼀、4层的负载均衡
Nginx Plus的商业授权版开始具有TCP负载均衡的功能。从Nginx 1.7.7版本开始加⼊的,现在变成了⼀个商业收费版本,想要试⽤,需要在官⽹申请。也就是说,Nginx除了以前常⽤的HTTP负载均衡外,Nginx增加基于TCP协议实现的负载均衡⽅法。 HTTP负载均衡,也就是我们通常所有“七层负载均衡”,⼯作在第七层“应⽤层”。⽽TCP负载均衡,就是我们通常所说的“四层负载均衡”,⼯作在“⽹络层”和“传输层”。例
如,LVS(Linux Virtual Server,linux虚拟服务)和F5(⼀种硬件负载均衡设备),也是属于“四层负载均衡”。
nginx和网关怎么配合使用⼆、nginx的TCP的反向代理
通常我们使⽤Nginx的upstream做基于http/https端⼝的7层负载均衡,tcp/udp端⼝的四层负载均衡⼀般⽤LVS或者Haproxy来做。
有两种⽅式:
1、使⽤第三⽅模块nginx_tcp_proxy_module,需要在编译时增加tcp代理模块【nginx_tcp_proxy_module】
2、nginx从1.9.0开始,新增加了⼀个stream模块,⽤来实现四层协议的转发、代理或者负载均衡等。这完全就是抢HAproxy份额的节奏,鉴于nginx在7层负载均衡和web service上的成功,和nginx良好的框架,stream模块前景⼀⽚光明。
nginx-1.9.0 已发布,该版本增加了 stream 模块⽤于⼀般的 TCP 代理和负载均衡。
The ngx_stream_core_module module is available since version 1.9.0. This module is not built by default, it should be enabled with the --
with-stream configuration parameter.
ngx_stream_core_module 这个模块在1.90版本后将被启⽤。但是并不会默认安装,需要在编译时通过指定 –with-stream 参数来激活这个模块。
其他改进包括:
Change: 删除过时的 aio 和 rtsig 事件处理⽅法
Feature: 可在 upstream 块中使⽤ “zone” 指令
Feature: 流模块,⽀持 TCP 代理和负载均衡
Feature: ngx_http_memcached_module ⽀持字节范围
Feature: Windows 版本⽀持使⽤共享内存,带随机化地址空间布局.
Feature: “error_log” 指令可在 mail 和 server 级别
Bugfix: the “proxy_protocol” parameter of the “listen” directive did not work if not specified in the first “listen” directive for a listen
socket.
所以,我们如果需要⽤到这个功能,就需要加上 –with-stream 参数重新编译nginx。
在了解了实现⽅法后,再了解下安装⽅案:
⾼版本的nginx(1.10以上?)不⽀持第三⽅模块nginx_tcp_proxy_module的安装;
⾼版本的nginx有⾃带tcp负载均衡配置(stream模块),但是health_check功能只供商业⽤户使⽤,第三⽅tcp⼼跳检测模块还没有适配上(2018.5);
低版本的nginx可以⽤第三⽅模块nginx_tcp_proxy_module实现tcp负载均衡并且⽀持⽤check进⾏⼼跳检测,打补丁安装第三⽅模块
nginx_tcp_proxy_module来实现tcp负载均衡和⼼跳检测;
⾼版本nginx + nginx_tcp_proxy_module(第三⽅模块不⽀持) --> ⾼版本nginx stream(虽然可转发,但health_check暂不可⽤,未见适配的第三⽅⼼跳检测模块) --> 低版本的nginx(安装第三⽅模块实现tcp负载均衡)。
所以可⾏的还只有低版本的nginx(安装第三⽅模块实现tcp负载均衡)。--来源⽹络未经验证
三、nginx_tcp_proxy_module安装及使⽤
nginx tcp代理功能由nginx_tcp_proxy_module模块提供,同时监测后端主机状态。该模块包括的模块有: ngx_tcp_module, ngx_tcp_core_module, ngx_tcp_upstream_module, ngx_tcp_proxy_module, ngx_tcp_upstream_ip_hash_module。
3.1、安装步骤:
cd /app
wget /download/nginx-1.6.
unzip nginx-1.6.
wget github/yaoweibin/nginx_tcp_proxy_module/archive/master.zip
unzip master
cd /app/nginx-1.6.3
patch -p1 </app/nginx_tcp_proxy_module-master/tcp.patch
./configure --add-module=/app/nginx_tcp_proxy_module-master
make
make install
3.2、f⽂件中配置负载均衡参数
tcp {
upstream server {
server 10.100.138.15:8787;
server 10.100.138.30:8787;
#check interval 健康检查时间间隔,单位为毫秒
#rise 检查⼏次正常后,将server加⼊以负载列表中
#fall 检查⼏次失败后,从负载队列移除server
#timeout 检查超时时间,单位为毫秒
check interval=3000 rise=2 fall=5 timeout=1000;
}
server {
listen 8787;
proxy_pass server;
so_keepalive on;
tcp_nodelay on;
}
}
客户端的长连接会断开,没有进展。
TCP负载均衡原理上和LVS等是⼀致的,⼯作在更为底层,性能会⾼于原来HTTP负载均衡不少。但是,不会⽐LVS更为出⾊,LVS被置于内核模块,⽽Nginx⼯作在⽤户态,⽽且,Nginx相对⽐较重。
四、nginx stream安装及使⽤
环境:centOS7.3_1611 物理服务器⼀台
Nginx版本:1.12.1
2.解压并切换到安装⽬录
tar -zxvf nginx-1.12.
cd nginx-1.12.1
3.编译安装
yum -y install gcc gcc-c++ autoconf automake
yum -y install zlib zlib-devel openssl openssl-devel pcre-devel
./configure --prefix=/opt/nginx --sbin-path=/opt/nginx/sbin/nginx --conf-path=/opt/nginx/f --with-http_stub_status_module --with-http_gzip_static_module --with-stream make
make install
cd /opt/nginx
4.修改配置⽂件
vim /opt/nginx/f(在配置⽂件最后⾏添加如下)
stream {
upstream NAME1 {
hash $remote_addr consistent;
server 10.22.0.7:5000 max_fails=3 fail_timeout=30s;
server 10.22.0.8:5000 max_fails=3 fail_timeout=30s;
}
upstream NAME2 {
hash $remote_addr consistent;
server 192.168.5.8:8080 max_fails=3 fail_timeout=30s;
}
server{
listen 8080;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass NAME1;
}
server{
listen 60000;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass NAME2;
}
}
解析:
如上配置⽂件的含义为
将端⼝8080反向代理NAME1组的serverIP:PORT,最⼤失败次数为3,超时时间为30秒;
将端⼝60000反向代理NAME2组的serverIP:PORT,最⼤失败次数为3,超时时间为30秒。
5.检测语法
/opt/nginx/sbin/nginx -t
6.开启NGINX
/opt/nginx/sbin/nginx
7.重启NGINX
/
opt/nginx/sbin/nginx -s reload
这⾥推荐使⽤reload⽽不是restart。
8.访问IP:PORT验证是否⽣效
stream core ⼀些变量
(注意:变量⽀持是从 nginx 1.11.2版本开始的)
$binary_remote_addr
⼆进制格式的客户端地址
$bytes_received
从客户端接收到的字节数
$bytes_sent
发往客户端的字节数
$hostname
连接域名
$msec
毫秒精度的当前时间
$nginx_version
nginx 版本
$pid
worker进程号
$protocol
通信协议(UDP or TCP)
$remote_addr
客户端ip
$remote_port
客户端端⼝
$server_addr
接受连接的服务器ip,计算此变量需要⼀次系统调⽤。所以避免系统调⽤,在listen指令⾥必须指定具体的服务器地址并且使⽤参数bind。
$server_port
接受连接的服务器端⼝
$session_time
毫秒精度的会话时间(版本1.11.4开始)
$status
会话状态(版本1.11.4开始), 可以是⼀下⼏个值:
200
成功
400
不能正常解析客户端数据
403
禁⽌访问
500
服务器内部错误
502
⽹关错误,⽐如上游服务器⽆法连接
503
服务不可⽤,⽐如由于限制连接等措施导致
$time_iso8601
ISO 8601时间格式
$time_local
普通⽇志格式的时间戳
五、TCP负载均衡的执⾏原理
当Nginx从监听端⼝收到⼀个新的客户端链接时,⽴刻执⾏路由调度算法,获得指定需要连接的服务IP,然后创建⼀个新的上游连接,连接到指定服务器。
TCP负载均衡⽀持Nginx原有的调度算法,包括Round Robin(默认,轮询调度),哈希(选择⼀致)等。同时,调度信息数据也会和健壮性检测模块⼀起协作,为每个连接选择适当的⽬标上游服务器。如果使⽤Hash负载均衡的调度⽅法,你可以使⽤$remote_addr(客户端IP)来达成简单持久化会话(同⼀个客户端IP的连接,总是落到同⼀个服务server上)。
和其他upstream模块⼀样,TCP的stream模块也⽀持⾃定义负载均和的转发权重(配置“weight=2”),还有backup和down的参数,⽤于踢掉失效的上游服务器。max_conns参数可以限制⼀台服务器的TCP连接数量,根据服务器的容量来设置恰当的配置数值,尤其在⾼并发的场景下,可以达到过载保护的⽬的。
Nginx监控客户端连接和上游连接,⼀旦接收到数据,则Nginx会⽴刻读取并且推送到上游连接,不会做TCP连接内的数据检测。Nginx维护⼀份内
存缓冲区,⽤于客户端和上游数据的写⼊。如果客户端或者服务端传输了量很⼤的数据,缓冲区会适当增加内存的⼤⼩。
当Nginx收到任意⼀⽅的关闭连接通知,或者TCP连接被闲置超过了proxy_timeout配置的时间,连接将会被关闭。对于TCP长连接,我们更应该选择适当的proxy_timeout的时间,同时,关注监听socke的so_keepalive参数,防⽌过早地断开连接。
服务健壮性监控
TCP负载均衡模块⽀持内置健壮性检测,⼀台上游服务器如果拒绝TCP连接超过proxy_connect_timeout配置的时间,将会被认为已经失效。在这种情况下,Nginx⽴刻尝试连接upstream组内的另⼀台正常的服务器。连接失败信息将会记录到Nginx的错误⽇志中。
如果⼀台服务器,反复失败(超过了max_fails或者fail_timeout配置的参数),Nginx也会踢掉这台服务器。服务器被踢掉60秒后,Nginx会偶尔尝试重连它,检测它是否恢复正常。如果服务器恢复正常,Nginx将它加回到upstream组内,缓慢加⼤连接请求的⽐例。
之所“缓慢加⼤”,因为通常⼀个服务都有“热点数据”,也就是说,80%以上甚⾄更多的请求,实际都会被阻挡在“热点数据缓存”中,真正执⾏处理的请求只有很少的⼀部分。在机器刚刚启动的时候,“热点数据缓存”实际上还没有建⽴,这个时候爆发性地转发⼤量请求过来,很可能导致机器⽆
法“承受”⽽再次挂掉。以MySQL为例⼦,我们的mysql查询,通常95%以上都是落在了内存cache中,真正执⾏查询的并不多。
其实,⽆论是单台机器或者⼀个集,在⾼并发请求场景下,重启或者切换,都存在这个风险,解决的途径主要是两种:
(1)请求逐步增加,从少到多,逐步积累热点数据,最终达到正常服务状态。
(2)提前准备好“常⽤”的数据,主动对服务做“预热”,预热完成之后,再开放服务器的访问。
TCP负载均衡原理上和LVS等是⼀致的,⼯作在更为底层,性能会⾼于原来HTTP负载均衡不少。但是,不会⽐LVS更为出⾊,LVS被置于内核模块,⽽Nginx⼯作在⽤户态,⽽且,Nginx相对⽐较重。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论