Nginx学习笔记22TCP代理

Nginx有两种方式实现TCP代理功能:

一种是使用nginx_tcp_proxy_module模块,一般用于Nginx早期版本。

一种是使用ngx_stream_core_module模块,用于1.9及其以后版本。

本文介绍使用stream的方式来实现TCP代理。

(1)重新编译Nginx

只有在configure时使用了--with-stream参数,编译出来的nginx程序才支持stream方式实现TCP代理。

./configure --prefix=/opt/nginx   --with-stream

make

make install

(2)配置tcp代理功能

在nginx.conf配置文件中添加stream配置块以及其中的server配置块。

stream {

server {

listen 2001;

proxy_connect_timeout 3s;

proxy_timeout  10s;

proxy_pass  192.168.197.101:2101;

}

}

上述配置中各参数的含义如下:

(a)listen指定Nginx将在tcp 2001端口上监听,proxy_connect_timeout

(b)proxy_connect_timeout指定Nginx与被代理的主机之间建立连接的超时时间。

Syntax: proxy_connect_timeout time;

Default:

proxy_connect_timeout 60s;

Context: stream, server

(c)proxy_timoute指定Nginx与客户端,以及Nginx与被代理的主机之间在两个相邻的读或写数据的操作之间的最大时间间隔。超过此时间间隔而没有数据读或写操作发生,则断开连接。

Syntax: proxy_timeout   timeout;

Default:

proxy_timeout 10m;

Context: stream, server

(d)proxy_pass指定了被代理的主机的地址和端口号。

(3)被代理的TCP服务程序

简单起见,本文使用Java编写了一个功能简单的TCP服务程序作为被代理主机上运行的TCP服务,在端口2101监听。

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.InputStreamReader;

import java.io.PrintWriter;

import java.io.BufferedReader;

import java.net.ServerSocket;

import java.net.Socket;

public class  mytcpserver {

public static void main( String[] args) {

 int port = 2101;

 ServerSocket s= null;

 try {

  if( args.length > 0)

  {

  System.out.println("port argument:"+args[0]);

 try{  

    port =  Integer.parseInt(args[0]);

    if(port < 2000 || port > 65535){

     port = 2101;

   }

  }catch(NumberFormatException ex){

    System.out.println("invalid argument port:");

    ex.printStackTrace();

  }

}

  System.out.println("using port:" + port );

 s = new ServerSocket( port);

  while(true) {

  Socket c = s.accept();

  System.out.println(""+ c.getInetAddress().getHostAddress() +":"+ c.getPort() +" connected.");

  BufferedReader br = null;

  PrintWriter    pw = null;

  try {

    br = new BufferedReader( new InputStreamReader(c.getInputStream()));

    pw = new PrintWriter( c.getOutputStream());

    String  msg;

    while((msg = br.readLine())!= null) {

       System.out.println(msg);

        pw.println(msg);

       pw.flush();

   }

  }catch(Exception e) {

   e.printStackTrace();

  }

  finally{

   if(c != null) {

     System.out.println(""+ c.getInetAddress().getHostAddress() +":"+ c.getPort() +" disconnected.");

   }

   if(br!=null){br.close();br = null;}

   if(pw!=null){pw.close();pw = null;}

   if(c!=null){ c.close();c = null;}

  }

  }

  }catch(Exception ex){

   ex.printStackTrace();

 }

 finally{

   try{

   if(s!=null){ s.close();s = null;}

  }catch(Exception e){

   e.printStackTrace();

  }
}

  System.out.println("QUIT.");

}

}

(4)运行测试。

启动mytcpserver程序(端口2101),启动Nginx程序(端口2001)。在另一台机器上运行telnet 192.168.197.101 2001。

(a)mytcpserver的输出。

java mytcpserver

using port:2101

192.168.197.101:44786 connected.

hello

hello

hello

192.168.197.101:44786 disconnected.

可以看到mytcpserver检测到有客户端(nginx)从44786端口连接上来了。

(b)Nginx的日志输出。

同样可以看到,客户端从20.1.1.11的端口4217连接到了Nginx的2001端口,然后Nginx从44786端口连接到了mytcpserver的2101端口,至此tcp代理连接建立成功。在传递了3次数据后,由于再没有通过telnet输入任何文字,因此Nginx在10秒钟(proxy_timeout)内没有从telnet程序接收到任何数据,断开了连接。在本次通信过程中,telnet程序总共发送了21个字节(hello\r\nhello\r\nhello\r\n),mytcpserver程序总共发送了18个字节(hello\nhello\nhello\n)。

2017/07/11 06:46:38 [info] 3308#0: *39 client 20.1.1.11:4217 connected to 0.0.0.0:2001

2017/07/11 06:46:38 [info] 3308#0: *39 proxy 192.168.197.101:44786 connected to 192.168.197.101:2101

2017/07/11 06:46:56 [info] 3308#0: *39 connection timed out (110: Connection timed out) while proxying connection, client: 20.1.1.11, server: 0.0.0.0:2001, upstream: "192.168.197.101:2101", bytes from/to client:21/18, bytes from/to upstream:18/21

Nginx stream功能完整介绍请参考:

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

时间: 2024-10-09 14:40:19

Nginx学习笔记22TCP代理的相关文章

nginx学习笔记之基于端口的虚拟主机基于主机名的虚拟主机root、alias、index配置

nginx学习笔记之基于端口的虚拟主机基于主机名的虚拟主机root.alias.index配置 实验环境: centos 测试节点IP:172.16.3.101 基于端口的虚拟主机: vim /etc/nginx/nginx.conf # 向里面的http {}里面加入如下内容   server { # server定义一个虚拟主机         listen 8080; # 监听本机所有IP端口8080         server_name www.test.com; # 虚拟主机名为:w

Java学习笔记——动态代理

所谓动态,也就是说这个东西是可变的,或者说不是一生下来就有的.提到动态就不得不说静态,静态代理,个人觉得是指一个代理在程序中是事先写好的,不能变的,就像上一篇"Java学习笔记--RMI"中的远程代理,其中客户端服务对象就是一个远程服务对象的代理,这个代理可以使得客户在操作时感觉像在操作本地对象一样,远程对象对于客户是透明的.我们可以看出这里的远程代理,是在程序中事先写好的,而本节我们要讨论的远程代理,是由JVM根据反射机制,在程序运行时动态生成的.(以上是本人的理解,如果有不正确的地

nginx学习笔记之三:nginx作为反向代理服务器

nginx不仅能作为web server,还具有反向代理.负载均衡和缓存的功能 一.nginx的反向代理和负载均衡功能 1.proxy模块 nginx通过proxy模块实现将客户端的请求代理至上游服务器,此时nginx与上游服务器的连接是通过http协议进行的.nginx在实现反向代理功能时的最重要指令为 proxy_pass,它能够并能够根据URI.客户端参数或其它的处理逻辑将用户请求调度至上游服务器上(upstream server). ⑴proxy_pass URL; 设置后端服务器的协议

【Nginx学习笔记】03_nginx配置动静态资源分离

使用版本:nginx/1.9.4:  /usr/local/nginx/conf/nginx.conf 关键配置代码如下: #配置nginx服务器所反向代理的应用服务器列表,weight参数配置权重, 权重越大,访问率越高 upstream proxy_tomcats{      server localhost:10001 weight=1;      server localhost:10002 weight=2;      server localhost:10003 weight=3;

Nginx学习笔记03虚拟机与代理

1.1. 虚拟机 使用Nginx的配置文件中的server结点,可以很方便的在一个nginx实例中支持多个虚拟机. 前提条件:主机有多个域名. 本次试验中用到的主机192.168.197.101有三个域名: ng.coe2coe.me 计划指向的网站目录为nginx目录下的html目录 ng101a.coe2coe.me 计划指向的网站目录为nginx目录下的host目录下的ng101a.coe2coe.me目录. 首页内容中含有主机名称ng101a.coe2coe.me. ng101b.coe

Nginx学习笔记二基本配置

1.Nginx的配置文件默认在Nginx程序安装目录的conf二级目录下,主配置文件为nginx.conf.假设您的Nginx安装 在/usr/local/webserver/nginx/目录下,那么默认的主配置文件则为/usr/local/webserver/nginx/nginx.conf.2.Nginx配置参数:(1)user www www 指定使用的用户和用户所在的组(2)worker_processes 8 指定工作衍生进程数(一般等于CPU的总核数或总核数的两倍,如两个四核CPU,

Nginx学习笔记六Nginx的模块开发

1.Nginx配置文件主要组成:main(全局配置)这部分的指令将影响其他所有部分.server(虚拟主机配置)这部分指令主要用于指定虚拟主机域名,IP和端口.upstream(主要为反向代理,负载均衡相关配置)这部分指令用于设置反向代理及后端服务 器的负载均衡.location(目录匹配配置)这部分指令用于匹配网页位置(例如,根目录"/","/images",等 等). location部分会继承server部分的指令,而server部分会继承main部分的指令.

Nginx学习笔记(一)

一.Nginx的特点与作用 Nginx可以更快地响应请求. Web和反向代理服务器 支持非常多的服务器软件特性 处理静态资源 用作反向代理 用作负载均衡 二.Nginx编译安装 2.1 准备工作 操作系统:CentOS7.3 IP地址:10.0.0.110 yum install -y gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel 2.2 添加用户 useradd -r nginx 2.3 编译安装 ./configure -

Nginx学习之反向代理WebSocket配置实例

写在开始去年,做过一款竞赛打分的APP.具体需求,同组教师之间可以相互通信,及时通知同组人员,其他组员做了那些操作(当然,这只是针对特定操作) 写在开始 去年,做过一款竞赛打分的APP.具体需求,同组教师之间可以相互通信,及时通知同组人员,其他组员做了那些操作(当然,这只是针对特定操作). 实现方案 采用目前比较成熟的WebSocket技术,WebSocket协议为创建客户端和服务器端需要实时双向通讯的webapp提供了一个选择.其为HTML5的一部分,WebSocket相较于原来开发这类app