Fork me on GitHub
0%

nginx 实现 TCP 代理及其负载均衡之 stream 模块

前面所说的 nginx 负载均衡都是基于 HTTP 七层代理,有时候我们可能需要基于 TCP 四层代理以及负载均衡,在之前我们可能需要编译安装第三方的一个模块 nginx_tcp_proxy_module,并且需要打上一个补丁,具体安装方式可以去参考项目中的描述。

项目地址如下,不过需要注意的是安装这个模块存在兼容性问题,最好使用较低版本的 nginx 去安装,否则很容易出错,所以现在不推荐使用这个进行 TCP 代理。在 nginx 1.9.0 的版本以及更高的版本中,nginx 默认将 ngx_stream_core_module 模块编译进来了,该模块支持 TCP 代理及其负载均衡。下面就主要来介绍一下如何使用它来进行 TCP 代理和负载均衡。

nginx_tcp_proxy_module 项目地址

ngx_stream_core_module 编译安装

由于 nginx 1.9.0 版本以及之后的版本默认将该模块集成进来了,所以我们不需要额外添加,我们只需要在配置时加上 –with-stream 参数来激活这个模块。命令如下:

1
2
3
sudo ./configure --with-stream
sudo make
sudo make install

TCP 代理

将 nginx 配置安装好了之后就可以在 nginx.conf 的配置文件中配置 TCP 代理了,其实也就是在配置文件在加一个和 http 模块平级的 stream 模块,其他配置大部分和 http 代理中的一样,下面是一个简单的 TCP 代理配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
stream {
server {
listen 50001;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass 192.168.1.110:10080;
}
server {
listen 50002;
proxy_connect_timeout 1s;
proxy_timeout 3s;
proxy_pass 192.168.1.111:10080;
}
}

上面是监听本机的 50001 和 50002 端口,并且将其分别代理到 192.168.1.110 和 192.168.1.111 的 10080 端口,而 10080 这个端口 分别是 192.168.1.110 和 192.168.1.111 的 nginx 访问端口,测试情况如下图:

测试结果

TCP 负载均衡

基于 TCP 的负载均衡和 HTTP 的负载均衡配置大致一样,只不过负载均衡策略没有那么多,主要有默认的轮询,加权轮询,最少连接数,最低平均延时,hash 这五种方式,先声明以下测试是在 nginx 版本 1.12.0 上测试的。这里简单说一下我所遇到的坑,我刚开始是在 chrome 浏览器上测试的,发现测试这些策略都是不对的,而且始终访问到后台同一台服务,只是偶尔会变一下,然后使用 Firefox 浏览器测试,发现按 F5 刷新还是始终访问到同一后台服务,然后尝试着按 Ctrl + F5 进行刷新这才按照我们配置的策略进行负载,而回到 chrome 浏览器上也试着按 Ctrl + F5 刷新还是一直访问的后台同一台服务,暂时还不知道是什么原因。有知道的可以告诉我一下,不甚感激。

1.默认配置 ( 轮询 )

1
2
3
4
5
6
7
8
9
10
11
stream {
upstream loadserver {
server 192.168.1.110:10080;
server 192.168.1.111:10080;
}
server {
listen 8000; # 需要监听的端口
proxy_pass loadserver;
}
}

上面的配置就是不加任何负载策略,采用默认的方式,默认的方式就是轮询的方式。

2.加权轮询配置

1
2
3
4
5
6
7
8
9
10
stream {
upstream loadserver {
server 192.168.1.110:10080 weight=3;
server 192.168.1.111:10080;
}
server {
listen 8000; # 需要监听的端口
proxy_pass loadserver;
}
}

这是在轮询策略的基础上给每个后台服务加上权重,权重越大,访问的概率越大,像上面的配置的话就是每访问三次 192.168.1.110 这台服务就会访问一次 192.168.1.111 这台服务。

3.最少连接数配置

1
2
3
4
5
6
7
8
9
10
11
stream {
upstream loadserver {
least_conn;
server 192.168.1.110:10080;
server 192.168.1.111:10080;
}
server {
listen 8000; # 需要监听的端口
proxy_pass loadserver;
}
}

上面是采用一种固定的负载策略,最少连接数策略,也就是选择连接数最少的后台服务。

4.最低平均延时配置

1
2
3
4
5
6
7
8
9
10
11
12
13
stream {
upstream loadserver {
least_time connect;
#least_time first_byte;
#least_time last_byte;
server 192.168.1.110:10080;
server 192.168.1.111:10080;
}
server {
listen 8000; # 需要监听的端口
proxy_pass loadserver;
}
}

上面策略配置表示的是对于每个请求,可通过最低平均延时来选择后台服务,而这个最低平均延时则是看 least_time 指令中指定的参数计算出来的,主要有下面三个参数:

  • connect:连接到后台服务花的时间
  • first_byte:接收到第一个字节花的时间
  • last_byte:接收到最后一个字节花的时间,也就是全部接收完的时间

值得注意的是该策略现在是作为 nginx 商业订阅的一部分提供,也就是需要花钱才能够实现这个功能。

5.hash 配置

1
2
3
4
5
6
7
8
9
10
11
stream {
upstream loadserver {
hash $remote_addr consistent;
server 192.168.1.110:10080;
server 192.168.1.111:10080;
}
server {
listen 8000; # 需要监听的端口
proxy_pass loadserver;
}
}

上面采用的是 hash 算法策略,对客户端的 IP 进行 hash,让每台客户端固定访问到后台的一台服务。

 wechat
扫描上面图中二维码关注微信公众号