Nginx TCP 负载均衡:stream 模块配置

发布时间 2023-07-07 16:59:18作者: 武平宁

工作上遇到需要用nginx做负载均衡,参考了前同事留下的作业顺利搞定,感觉这块很有意义写篇文档记录。

参考:nginx tcp负载均衡(Stream模块)配置说明
参考:利用nginx进行TCP负载均衡实战

直接上配置

user  nginx;
worker_processes  2;

error_log  /var/log/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

stream {
        log_format proxy '$remote_addr [$time_local] '
                 '$protocol $status $bytes_sent $bytes_received '
                 '$session_time "$upstream_addr" '
                 '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';

        access_log /var/log/nginx/access.log proxy;


        upstream stream_backend {
                least_conn;    ## 默认是轮询算法,这里修改为:least-connected :对于每个请求,nginx选择当前连接数最少的server来处理

                server 192.168.230.25:10014 max_fails=2 fail_timeout=30s;
                server 192.168.230.61:10014 max_fails=2 fail_timeout=30s;

        server {
                listen          443 ssl;
                proxy_protocol on;
                ssl_certificate        keys/xx.pem;
                ssl_certificate_key    keys/xx.pem;
                proxy_pass    stream_backend;
                proxy_timeout 3600s;
                proxy_connect_timeout 10s;
        }
}

这个配置比较好理解,项目上有需要也可以直接用。

stream 模块介绍

参考:NGINX Stream模块原理及代码分析

从1.9.0开始,NGINX增加了stream模块用来实现四层协议的转发、代理和负载均衡。

与著名的四层LB软件lvs相比,stream 模块(开源版)无论从功能还是性能上,都有一定的差距,实现也相对简单。从性能上来说,stream模块在应用层实现四层的转发,需要与两端建立起socket连接,然后两端的数据收发进行代理转发。因此,大量的数据从内核态到用户态再从用户态到内核态传递。这些数据copy加上系统调度的开销,使得它的性能与纯内核态转发的lvs相比,有一定差距。

在用户态做四层的proxy,从原理上讲主要有如下步骤:

  • 创建一个socket 监听client连接。

  • Client连接到来以后,使用load balancer算法选取一个正确的upstream 服务器并且建立socket连接。

  • 把从client收到的数据转发给upstream server,同时把upstream server收到的数据转发给client。