美文网首页服务器程序员
使用Nginx转发TCP/UDP

使用Nginx转发TCP/UDP

作者: 胖宝宝王 | 来源:发表于2017-09-06 23:49 被阅读6257次

环境

  • OS: Centos6-x86_64
  • Nginx: 1.12.1

编译安装Nginx

从1.9.0开始,nginx就支持对TCP的转发,而到了1.9.13时,UDP转发也支持了。提供此功能的模块为ngx_stream_core。不过Nginx默认没有开启此模块,所以需要手动安装。

cd /usr/local/src
wget http://nginx.org/download/nginx-1.12.1.tar.gz
tar zxf nginx-1.12.1.tar.gz
cd nginx-1.12.1
./configure --prefix=/usr/local/nginx --with-stream --without-http
make && make install

Note:由于是传输层转发,本着最小化原则,就关闭了http功能。


配置Nginx

TCP转发

目标:通过3000端口访问本机Mysql(其中mysql使用yum安装,默认配置文件)

/usr/local/nginx/conf/nginx.conf配置如下:

user  nobody;
worker_processes  auto;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    use epoll;
    worker_connections  1024;
}


stream {
    server {
        listen 3000;
        proxy_pass 127.0.0.1:3306;

    # 也支持socket
    # proxy_pass unix:/var/lib/mysql/mysql.socket;
    }
}

首先,先通过3306端口访问mysql:

image.png

然后,启动Nginx:

image.png

最后使用3000端口访问mysql:

image.png

UDP转发

目标: 发送UDP数据到3000端口,3001端口可以接收

/usr/local/nginx/conf/nginx.conf配置如下:

user  nobody;
worker_processes  auto;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    use epoll;
    worker_connections  1024;
}


stream {
    server {
        listen 3000 udp;
        proxy_pass 127.0.0.1:3001;

    }
}

这里写一个my_socket_server.py侦听在3001端口,用于接收UDP数据:

# coding=utf-8

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

sock.bind(('127.0.0.1', 3001))

print ('start server on [%s]:%s' % ('127.0.0.1', 3001))

while True:
    data, addr = sock.recvfrom(1024)
    print ('Received from %s:%s' % (addr,data))
    sock.sendto(b'Hello, %s!' % data, addr)

再写一个my_socket_client.py用于向Nginx侦听的3000端口发送数据:

# coding=utf-8

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

while True:
    data = raw_input('Input msg: ')
    if len(data) == 0:
        continue
    s.sendto(data.encode(), ('127.0.0.1', 3000))
    print (s.recv(1024).decode('utf-8'))

同时运行两个脚本,在client端发送数据:

4.gif

UDP转发遇到的一个坑

修改下client脚本,改为连续发送2000个数据包:

# coding=utf-8

import socket


s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

for data in range(2000):
    s.sendto(str(data).encode(), ('127.0.0.1', 3000))
    print (s.recv(1024).decode('utf-8'))

然后运行client脚本,发现经常会遇到如下情况:

image.png

由图可知只成功了511个。

查看文档得知listen指令有个backlog参数,此参数在Linux系统中默认为511:

image.png

悲剧的是backlog参数和udp参数不能同时使用。如果哪位朋友有好的解决办法,请赐教!!!!

相关文章

  • 使用Nginx转发TCP/UDP

    环境 OS: Centos6-x86_64 Nginx: 1.12.1 编译安装Nginx 从1.9.0开始,ng...

  • Nginx的TCP和UDP反向代理

    Nginx的Stream模块支持TCP和UDP转发 nginx从1.9.0版本开始,新增了ngx_stream_c...

  • nginx负载均衡和http代理与tcp-udp代理

    nginx自1.9.0开始提供tcp/udp的反向代理功能 web负载和代理 tcp/udp端口代理

  • 利用Nginx进行端口转发

    使用Nginx的server方式进行转发,只能转发URL,无法转发其他TCP应用,需要用到stream方式,在Ng...

  • SwiftSocketSever

    接受消息转发消息ProtocolBuffer TCP/UDP的概念和区分 进行Socket 编程,常见使用的协议U...

  • 使用Nginx配置TCP负载均衡

    Nginx是比较不错的开源Web服务器之一,但它也可以用作TCP和UDP负载均衡器。使用Nginx作为HAProx...

  • nginx的tcp/udp代理

    nginx的tcp/udp代理 nginx从1.9.0版本开始,新增了ngx_stream_core_module...

  • socket注意事项

    Socket TCP 和 UDP最大的区别就是:UDP 套接字没有 listen TCP 套接字使用recv()/...

  • nginx tcp转发

    ./configure --prefix=/home/ocdc/nginx --sbin-path=/home/o...

  • nginx TCP转发

    背景 项目中需要将局域网SSL协议数据转发到后台。 1.SSL SSL位于应用层和传输层之间,它可以为任何基于TC...

网友评论

  • 山东大葱哥:不错,可以突破阿里云rds的内网访问了.
    山东大葱哥: @山东大葱哥 外网是按流量收费得,呵呵
    胖宝宝王:我记得rds是可以申请外网地址吧!还有个办法是用iptables做转发:grin:

本文标题:使用Nginx转发TCP/UDP

本文链接:https://www.haomeiwen.com/subject/rpzvjxtx.html