nginx基于TCP的反向代理

时间:2022-06-13 00:31:05

一、4层的负载均衡

  Nginx Plus的商业授权版开始具有TCP负载均衡的功能。从Nginx 1.7.7版本开始加入的,现在变成了一个商业收费版本,想要试用,需要在官网申请。也就是说,Nginx除了以前常用的HTTP负载均衡外,Nginx增加基于TCP协议实现的负载均衡方法。 HTTP负载均衡,也就是我们通常所有“七层负载均衡”,工作在第七层“应用层”。而TCP负载均衡,就是我们通常所说的“四层负载均衡”,工作在“网络层”和“传输层”。例如,LVS(Linux Virtual Server,linux虚拟服务)和F5(一种硬件负载均衡设备),也是属于“四层负载均衡”。

二、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-streamconfiguration 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 http://nginx.org/download/nginx-1.6.3.tar.gz
unzip nginx-1.6.3.tar.gz wget https://github.com/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、nginx.conf文件中配置负载均衡参数

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

1.下载NGINX稳定发行版
https://nginx.org/download/nginx-1.12.1.tar.gz

2.解压并切换到安装目录

tar -zxvf nginx-1.12.1.tar.gz
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/conf/nginx.conf --with-http_stub_status_module --with-http_gzip_static_module --with-stream
make
make install
cd /opt/nginx

4.修改配置文件

vim /opt/nginx/conf/nginx.conf(在配置文件最后行添加如下)
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,然后创建一个新的上游连接,连接到指定服务器。

nginx基于TCP的反向代理

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的反向代理

当Nginx收到任意一方的关闭连接通知,或者TCP连接被闲置超过了proxy_timeout配置的时间,连接将会被关闭。对于TCP长连接,我们更应该选择适当的proxy_timeout的时间,同时,关注监听socke的so_keepalive参数,防止过早地断开连接。

服务健壮性监控

TCP负载均衡模块支持内置健壮性检测,一台上游服务器如果拒绝TCP连接超过proxy_connect_timeout配置的时间,将会被认为已经失效。在这种情况下,Nginx立刻尝试连接upstream组内的另一台正常的服务器。连接失败信息将会记录到Nginx的错误日志中。

nginx基于TCP的反向代理

如果一台服务器,反复失败(超过了max_fails或者fail_timeout配置的参数),Nginx也会踢掉这台服务器。服务器被踢掉60秒后,Nginx会偶尔尝试重连它,检测它是否恢复正常。如果服务器恢复正常,Nginx将它加回到upstream组内,缓慢加大连接请求的比例。

之所“缓慢加大”,因为通常一个服务都有“热点数据”,也就是说,80%以上甚至更多的请求,实际都会被阻挡在“热点数据缓存”中,真正执行处理的请求只有很少的一部分。在机器刚刚启动的时候,“热点数据缓存”实际上还没有建立,这个时候爆发性地转发大量请求过来,很可能导致机器无法“承受”而再次挂掉。以MySQL为例子,我们的mysql查询,通常95%以上都是落在了内存cache中,真正执行查询的并不多。

其实,无论是单台机器或者一个集群,在高并发请求场景下,重启或者切换,都存在这个风险,解决的途径主要是两种:

(1)请求逐步增加,从少到多,逐步积累热点数据,最终达到正常服务状态。
(2)提前准备好“常用”的数据,主动对服务做“预热”,预热完成之后,再开放服务器的访问。

TCP负载均衡原理上和LVS等是一致的,工作在更为底层,性能会高于原来HTTP负载均衡不少。但是,不会比LVS更为出色,LVS被置于内核模块,而Nginx工作在用户态,而且,Nginx相对比较重。

nginx基于TCP的反向代理的更多相关文章

  1. 【05】Nginx:TCP &sol; 正向 &sol; 反向代理 &sol; 负载均衡

    写在前面的话 在我们日常的工作中,不可能所有的服务都是简单的 HTML 静态网页,nginx 作为轻量级的 WEB 服务器,其实我们将它用于更多的地方还是作为我们网站的入口.不管你是后端接口,还是前端 ...

  2. nginx实现tcp的反向代理

     nginx不仅可以实现http的反向代理,同时也支持TCP的反向代理以SSH为例1.编译的时候需要加入--with-stream这个参数,以加载ngx_stream_core_module这个模块2 ...

  3. Nginx做web服务器反向代理

    实验目的 通过nginx实现反向代理的功能,类似apache反向代理和haproxy反向代理 工作中用nginx做反向代理和负载均衡的也越来越多了 有些公司从web服务器到反向代理,都使用nginx. ...

  4. 【架构师之路】Nginx负载均衡与反向代理—《亿级流量网站架构核心技术》

    本篇摘自<亿级流量网站架构核心技术>第二章 Nginx负载均衡与反向代理 部分内容. 当我们的应用单实例不能支撑用户请求时,此时就需要扩容,从一台服务器扩容到两台.几十台.几百台.然而,用 ...

  5. Nginx插件之openresty反向代理和日志滚动配置案例

    Nginx插件之openresty反向代理和日志滚动配置案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.openresty介绍 1>.Nginx介绍 Nginx是一款 ...

  6. 通过Nginx&plus;tomcat&plus;redis实现反向代理 、负载均衡及session同步

    一直对于负载均衡比较陌生,今天尝试着去了解了一下,并做了一个小的实验,对于这个概念有一些认识,在此做一个简单的总结 什么是负载均衡 负载均衡,英文 名称为Load Balance,指由多台服务器以对称 ...

  7. nginx和tomcat实现反向代理、负载均衡和session共享

    这类的文章很多,nginx和tomcat实现反向代理.负载均衡实现很容易,可以参照http://blog.csdn.net/liuzhigang1237/article/details/8880752 ...

  8. paip&period;基于urlrewrite的反向代理以及内容改写

    paip.基于urlrewrite的反向代理以及内容改写 ---------反向代理 RewriteCond %{REQUEST_URI} !=/process.php RewriteRule  ^( ...

  9. Nginx的安装及反向代理设置

    因为项目的缘故,接触到了Nginx的安装和反向代理设置,和大家分享下. 一.Nginx的下载.安装cd /homewget http://nginx.org/download/nginx-1.0.5. ...

随机推荐

  1. 8、ASP&period;NET MVC入门到精通——View&lpar;视图&rpar;

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 View视图职责是向用户提供界面.负责根据提供的模型数据,生成准备提供给用户的格式界面. 支持多种视图引擎(Razor和ASPX视图引擎是官 ...

  2. JAVA并行框架学习之ForkJoin

    当硬件处理能力不能按照摩尔定律垂直发展的时候,选择了水平发展,多核处理器已经广泛应用.未来随着技术的进一步发展,可能出现成百上千个处理核心,但现有的程序运行在多核心处理器上并不能得到较大性能的提升,主 ...

  3. docker学习资料整理&lpar;持续更新中&period;&period;&rpar;

    docker最近可以说火得一踏糊涂,跟 51大神在交流技术的时候这个东西会多次被提到,当我们还玩vm+linux/freebsd的时候,人家已经上升到更高层次了,这就是差距,感觉好高大上的样子,技术之 ...

  4. 几个国外FMX网站 good

    FireMonkey X –  Amazing overview of FireMonkey FMX Feeds – All your FireMonkey news in one place FMX ...

  5. jstl-按照html的形式输出至页面

    一.按照html的形式输出至页面 <c:out value="${xxx}" default="默认值" escapeXml="false&qu ...

  6. http&colon;&sol;&sol;codeforces&period;com&sol;problemset&sol;problem&sol;847&sol;E

    E. Packmen time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  7. 385cc412a70eb9c6578a82ac58fce14c md5破解

    在线破解很方便,你可能几秒钟就可以破解得到MD5原码...但是在线破解也不是万能的 也有查不到的或者需要收费的(土豪略过这句话)...下面推荐个网站md5.geekzh.com 所有MD5免费查询 E ...

  8. 使用JDBC操作MySQL数据库

    一.JDBC简介 JDBC(Java DataBase Connectivity)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一的访问,它由一组用Java语言编写的类和接口组 ...

  9. eclipse:插件安装总结

    1.SVN插件 首先安装SVNKIT,下载地址:https://svnkit.com/download.php 再安装Subclipse,这个在marketplace安装即可. 2.安装时报错:Una ...

  10. Luogu P3381 &lpar;模板题&rpar; 最小费用最大流

    <题目链接> 题目大意: 给定一张图,给定条边的容量和单位流量费用,并且给定源点和汇点.问你从源点到汇点的最带流和在流量最大的情况下的最小费用. 解题分析: 最小费用最大流果题. 下面的是 ...