concentrate on c/c++ related technology

plan,refactor,daily-build, self-discipline,

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  37 Posts :: 1 Stories :: 12 Comments :: 0 Trackbacks

常用链接

留言簿(9)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

现在nginx的版本已经到了1.9.12,不过在1.9.0的时候,就开始了对TCP代理服务器的支持。
之前也有一些早期的做法,比如就有写了nginx_tcp_module模块的https://github.com/yaoweibin/nginx_tcp_proxy_module,
以及nginx_stream_lua模块的
https://github.com/openresty/stream-lua-nginx-module
本来就想着用这两个的,后来发现已经有支持了,就先来试试看看这个了。
默认的话,nginx是没有开启对tcp的支持的.如果要支持的话,需要用--with-stream去指定。
我这边只要需要三个IP,一个是nginx进程所在的机器,我这边用192.168.1.4表示,
另外两台就是TCP上游业务服务器,我们分别用192.168.1.5和192.168.1.21来表示,
基于这样的考虑是因为nginx充当tcp代理服务器后,自身也会占用一个端口。
并且从目前来说,貌似一个nginx进程也就只能listen一个端口。
我用的版本是nginx 1.9.9.
我在/usr/local/nginx/conf下面新建了nginx_stream_tcp.conf作为本次的测试。
worker_processes auto;
  2 error_log /usr/local/nginx/logs/error.log info;
  3 events {
  4     worker_connections  1024;
  5 }
  6
  7 stream {
  8     upstream loadbalance {
  9 # Specifies a load balancing method for a server group where client-server mapping is based on the hashed key value
 10         hash $remote_addr consistent;
 11 # sets the weight of the server, by default, 1.
 12         server 192.168.1.21:8001 weight=5;
 13 # by default, the parameter is set to 10 seconds.
 14         server 192.168.1.5:9001  max_fails=3 fail_timeout=30s;
 15
 16 
 17     }
 18
 19 server {
 20 # listen 8001.
 21         listen 8001;
 22 # Defines a timeout for establishing a connection with a proxied server.
 23         proxy_connect_timeout 1s;
 24 # Sets the timeout between two successive read or write operations on client or proxied server connections
 25         proxy_timeout 3s;
 26 # Sets the address of a proxied server
 27         proxy_pass loadbalance;
 28     }
 29
 30 }
这个大部分是官网支持的,所以其实我也没有修改太多,就设置了几个IP和端口。
在编译好nginx后,可以用/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx_stream_tcp.conf
就可以起来了,可以通过netstat -tlnp查看是否起来,大致显示这样的:
tcp        0      0 0.0.0.0:8001            0.0.0.0:*               LISTEN      7744/nginx_stream_t
当然也可以通过telnet来查看。
接下来,写个简单的cs程序来验证下吧.

server端:
if __name__ == '__main__':
 import socket
 import commands
 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 sock.bind(('192.168.1.21', 8001))
 sock.listen(5)
 while True:
  connection,address = sock.accept()
  print "connected by",address
  while 1:

    buf = connection.recv(1024)
    if buf != "" :
     print "connection buffer", buf
     connection.sendall(buf)
 connection.close()

client端:
if __name__ == '__main__': 
    import socket
    HOST='192.168.1.4'
    PORT=8001
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.connect((HOST, PORT))
    while 1:
        cmd = raw_input("please input cmd:")
        sock.sendall(cmd)
        data = sock.recv(1024)
        print data
    sock.close()

在client向192.168.1.4发起一个TCP连接时,接下来192.168.1.4会连接到192.168.1.21,
192.168.1.21的server端会显示, connected by ('192.168.1.4',58559)
后面的端口应该是随机的临时端口。
其实它的确起到了转发作用,这个nginx进程相当于一个通用网关,如果有两个client向nginx进程发起连接,一旦nginx那边调度到同一个上游TCP服务器,那么只需要从NGINX进程建立一个TCP连接到上游TCP服务器即可。
之前我自己设计网关的时候,不是依赖于用户的,而是通过静态配置来建立连接的,比如上游逻辑服务器跟网关有连接,那都是在启动服务器的时候,就建立起来了。
这样有个好处就是可以省事,不过也可以采用这种方式,有玩家连接进某个上游TCP服务器才让网关跟这个TCP服务器建立连接,否则无需处理。因为不少时候还是会有不少服务器处于空闲的.

posted on 2016-03-11 08:44 jolley 阅读(810) 评论(0)  编辑 收藏 引用 所属分类: nginx

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理