nginx-- Configuring TCP OR UDP Load Balancing

46 篇文章 2 订阅
9 篇文章 1 订阅

nginx------ tcp and udp 代理

Introduction

nginx 反向代理一般都是7层代理,进行http/https 协议层的转发;说起4层代理,一般想到的都是lvs 和 haproxy 这些;目前nginx新版本已经支持 4层 (tcp,udp) 代理;

在Nginx1.9.0版本之前,TCP代理一般会使用Haproxy或Nginx的第三方包nginx_tcp_proxy_module。但Nginx在1.9.0版本之后加入了ngx_stream_proxy_modulea,它提供了TCP代理,只需在编译Nginx时加入----ngx_stream_proxy_module即可。

在1.9.13版本之后,Nginx加入了对UDP(UserDatagramProtocol)代理的支持,因此可以使用Nginx来代理DNS的UDP端口;

Install

[root@network-test nginx-1.19.2]# ./configure --help
# --with-stream 开启tcp/udp 代理;一般是初次安装的时候使用;
# --with-stream=dynamic  动态开启tcp/udp;存量已安装的nginx 下动态支持
# 这次使用动态升级的方法,在原始参数后面添加 –with-stream=dynamic
./configure --prefix=/usr/local/nginx --add-module=../ngx_devel_kit --add-module=../set-misc-nginx-module --with-stream=dynamic
# make编译 ,切记不要install,执行install 会有覆盖的情况,可能会影响存量的业务或配置,需要注意
make
# 当前目录objs中会存在 编译好的 ngx_stream_module.so
ll objs/ngx_stream_module.so
# 将对于文件cp 到 存量已安装的目录
mkdir /usr/local/nginx/modules
cp objs/ngx_stream_module.so  /usr/local/nginx/modules/
# 编辑 nginx.conf ; reload 或 重启服务
# load_module  modules/ngx_stream_module.so;
[root@network-test nginx]# head -n 30 conf/nginx.conf | grep -v '^$'
load_module  modules/ngx_stream_module.so;
#user  nobody;
worker_processes  1;
error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
stream {
        upstream tcp_backed {
                hash $remote_addr consistent;
                server 127.0.0.1:9090 weight=4 max_fails=3 fail_timeout=30s;
        }
        server {
                listen 9999;
                proxy_connect_timeout 1s;
                proxy_timeout 3s;
                proxy_pass tcp_backed;
        }
}






Configuring TCP OR UDP Load Balancing

TCP代理在stream指令块内进行声明,位于main内,和http指令块同级。

反向代理的upstream支持DNS域名(如ip_hash、socket)配置、权重即故障转移(如max_fails)配置。

当proxy_pass代理TCP时,没有http://前缀,注意配置时不要写错。

支持和HTTP一样的连接超时参数proxy_timeout、proxy_connect_timeout。

在实操这里时,需要提到一点是,一般4层代理是没有转发日志的;比如lvs ;nginx 这里使用tcp/udp 代理时是可以配置转发日志的;

配置方法:

在nginx.conf stream 中配置对应log_farmart;

stream {

    log_format tcp_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 logs/tcp-access.log tcp_proxy ;
    open_log_file_cache off;
    #include /etc/nginx/conf.d/*.stream;

    upstream tcp_backed {
        hash $remote_addr consistent;
        server 127.0.0.1:9090 weight=4 max_fails=3 fail_timeout=30s;
    }
    # proxy_bind $remote_addr transparent;
    server {
        listen 9999;
        proxy_connect_timeout 1s;
        proxy_timeout 3s;
        proxy_pass tcp_backed;
    }
}

配置经验

  • 测试发现nginx会等待session结束才会记录到日志文件;
  • session日志只是tcp层面的记录,包括session时间,发送接收字节数等等;
  • session内部发送日志(比如一个socket连接建立起来以后,多次发送心跳数据)需要在应用层面才能记录;

常见指令:

TCP代理还包含其他很多指令,下面将介绍一些常用的指令。

指令:proxy_bind
语法:proxy_bind address [transparent] | off;
默认值:无
环境:stream、server
含义:如果此配置为off,则表示请求将会使用系统自动分配的本地IP地址,即后端服务看不到用户的真实IP地址;
如果配置为“proxy_bind $remote_addr transparent;”,则后端服务可以看到用户的真实IP地址。

为了使参数生效,需要以超级用户权限运行Nginx的worker进程,并配置核心路由表以截获反向代理服务器的网络流量。

查看nginx upstream 服务的业务日志,在proxy_bind address off 的配置下,upstream 服务日志显示为 nginx 本地ip:

直接配置该参数后,抓包看的话,是可以看到向RS 转发的ip 从 nginx 本身的ip 变成了 client 真实ip;

不过在开启时,可能出现后端RS 无法正常响应的情况;需要以超级用户权限运行Nginx的worker进程,并配置核心路由表以截获反向代理服务器的网络流量。 代理服务器上需要配置iptables 以及对应路由表信息;上游服务器也要指向对应的网关;

这部分的配置,也找到了一些文档;不过部署的测试环境,一直没调通 o(╥﹏╥)o ;所以这部分暂时不细写;

指令:proxy_download_rate
语法:proxy_download_rate rate;
默认值:proxy_download_rate 0;
环境:stream、server
含义:设置后端服务器读取数据的速度。速度定义为字节每秒。
默认值为0,表示禁用限速。
限速设置的值对每个连接都有效。


指令:proxy_next_upstream
语法:proxy_next_upstream on | off;
默认值:proxy_next_upstream on;
环境:stream、server
含义:当无法与当前的后端服务器建立连接时,该指令用来确定是否将客户端连接传递给下一台后端服务器。这可能会受到尝试次数(proxy_next_upstream_tries)和时间(proxy_next_upstream_timeout)的影响。


指令:proxy_next_upstream_timeout
语法:proxy_next_upstream_timeout  time;
默认值:proxy_next_upstream_timeout 0;
环境:stream、server
含义:设置传递连接到下一台后端服务器的时间。默认值为0,表示关闭这个限制。


指令:proxy_next_upstream_tries
语法:proxy_next_upstream_tries number;
默认值:proxy_next_upstream_tries 0;
环境:stream、server
含义:设置传递连接到下一台后端服务器的尝试次数。默认值为0,表示关闭这个限制。


指令:proxy_pass
语法:proxy_pass address;
默认值:无
环境:server
含义:设置被代理的服务器地址。地址可以是一个域名,也可以是IP地址加端口号。从Nginx1.11.3版本开始支持配置变量,如“proxy_pass $upstream;”。


指令:resolver
语法:resolver address ... [valid=time] [ipv6=on|off];
环境:stream、server含义:在进行DNS解析时,该指令用于对upstream中出现的域名进行IP地址解析,然后将请求代理到解析到的IP地址上;
Valid=time表示DNS解析后的缓存时间,使用缓存时间可以减少DNS解析的次数;
关于ipv6=on|off,如果设置为on,则表示在查询IPv4(Internet Protocol version 4,互联网协议版本4)无果后会继续查询IPv6(Internet Protocol Version 6,互联网协议版本6),如果不需要查找IPv6,可以配置为off,以缩短查找时间。


指令:resolver_timeout
语法:resolver_timeout time;
默认值:resolver_timeout 30s;
执行阶段:stream、server
含义:设置解析DNS的超时时间,如果超时,DNS会使用上一次解析到的IP地址。


指令:proxy_protocol_timeout
语法:proxy_protocol_timeout timeout;
默认值:proxy_protocol_timeout 30s;
环境:stream、server
含义:设置读取proxy协议头的时间。如果在所设置的时间内没有发送完整的报头,则关闭连接。

实战经验

1.指令nginx_tcp_proxy_module和ngx_stream_core_module都可以在TCP代理中使用。其中ngx_stream_core_module包含有关日志记录的一些常用变量,通过这些日志信息可以分析每个TCP请求的情况。

2.在做TCP代理时,Nginx代理节点服务器可能不止一台,可以使用DNS轮询或LVS(LinuxVirtualServer,Linux虚拟服务器)等功能对Nginx进行负载均衡。

3.Redis属于单核服务,所以在一台服务器上启动多个Redis实例是很正常的。如果多个Redis从库部署在同一台服务器上,可以通过TCP代理进行转发,否则会因为端口不一致,导致配置非常烦琐。

引用资料

相关nginx 官网链接和参考资料:

https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/

http://nginx.org/en/docs/stream/stream_processing.html

http://nginx.org/en/docs/stream/ngx_stream_log_module.html#open_log_file_cache

http://nginx.org/en/docs/stream/ngx_stream_core_module.html

http://nginx.org/en/docs/varindex.html

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_bind

https://github.com/vislee/leevis.com/issues/142

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_bind

https://www.nginx.com/blog/ip-transparency-direct-server-return-nginx-plus-transparent-proxy/

https://pengpengxp.github.io/archive/before-2018-11-10/2017-06-27-使用nginx的proxy_bind选项配置透明的反向代理.html#tproxy_sum

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值