全面详解nginx作为TCP_UDP代理

[最近出差+项目太忙,很长时间没更新,大家谅解]

nginx作为TCP/UDP代理是从1.9.x版本之后新加入的功能,本文以nginx-1.11.6版本作为例子,详细介绍如何配置。

默认nginx使用模块ngx_stream_core_module作为TCP和UDP代理,但是该模块默认是没有编译到nginx中的,因此要想使用TCP和UDP代理功能,必须手动编译这个模块。本位以CentOS 6.5作为基准系统。

本文操作的基准目录为/usr/local/nginx

一、首先下载nginx的源代码

下载完毕后,解压缩到/usr/local/nginx/nginx-1.11.6-src

二、下载pcre(perl compatible regex expression)源代码

nginx编译的时候需要这个源代码(主要是用于配置文件的http请求中的正则判断),注意必须是源代码

下载路径为

ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.39.tar.gz

将该源代码的包解压缩到

/usr/local/nginx/nginx-1.11.6-src/pcre-src/pcre-8.39

三、下载libz,这个包是nginx作为返回response的时候压缩使用的

下载路径为:

将该源代码包解压缩到

/usr/local/nginx/nginx-1.11.6-src/zlib-src/zlib-1.2.8

四、修改libz的configure文件,保证编译的时候能够有执行

在第三步中,下载的libz的源代码目录,解压缩后,里面的configure文件是没有可执行权限的,nginx在make(编译)的时候,会默认调用/bin/sh configure,如果不是可执行权限,那么会导致编译失败,报Permission Denied

在/usr/local/nginx/nginx-1.11.6-src/zlib-src/zlib-1.2.8目录下执行

chmod 777 ./configure

看到该文件变为可执行,即可

五、安装open-ssl

nginx支持https请求的时候,需要open-ssl支持,因此需要安装open-ssl,因为是在Cent OS系统上,我们默认安装的包管理工具是yum,因此执行

yum -y install openssl openssl-devel

六、配置nginx安装的环境变量

在/usr/local/nginx/nginx-1.11.6-src目录下执行

./configure --prefix=/usr/local/nginx/nginx-1.11.6 --with-http_ssl_module --with-pcre=/usr/local/nginx/nginx-1.11.6-src/pcre-src/pcre-8.39 --with-zlib=/usr/local/nginx/nginx-1.11.6-src/zlib-src/zlib-1.2.8 --with-stream --with-stream_realip_module

这个命令在一行上,各个参数(--打头的)以空格分开

其中:

--prefix是指nginx编译好的二进制文件的基础目录

--with-http_ssl_module编译支持HTTPS的功能

--with-pcre指定pcre目录,在第二步骤中,我们已经确定

-with-zlib指定libz目录,在第三步骤中,我们已经确定

--with-stream打开支持TCP/UDP功能

--with-stream_realip_module打开支持TCP/UDP获取请求源IP功能

七、编译和安装

在/usr/local/nginx/nginx-1.11.6-src目录下执行

make && make install

查看/usr/local/nginx/nginx-1.11.6目录,发现该目录下,已经放好了nginx的编译后的文件,其中sbin放的是nginx的可执行文件,conf里面放的是nginx.conf配置文件

八、配置nginx.conf

进入第七步中提到的conf目录

执行,vim nginx.conf并保存

在http元素上方,加入如下代码:

stream {

    upstream backend {

        hash $remote_addr consistent;

        server 192.16.30.12:8080            max_fails=3 fail_timeout=30s;

    }

    server {

        listen 8080;

        proxy_connect_timeout 1s;

        proxy_timeout 3s;

        proxy_pass backend;

    }

}

上方的配置是,起了一个名字叫做backend的负载配置,负载方式使用一致性hash(根据IP地址),该负载配置连接的后台真正提供服务的机器是192.16.30.12,并且访问这个机器的8080端口

server是指,nginx启动了哪个端口监听请求,连接超时时间为1s,代理响应超时时间为3s,使用名字叫做backend的负载配置进行转发

同时,我们在192.16.30.12机器上,启动一个web服务,访问

:8080/brkservlet31/index.jsp

显示一个hello world

假设nginx所在的机器地址为192.16.1.239

那么配置文件修改完毕后,使用

/usr/local/nginx/nginx-1.11.6/sbin/nginx启动

/usr/local/nginx/nginx-1.11.6/sbin/nginx -s reload(在启动状态下重新加载)

然后访问

:8080/brkservlet31/index.jsp

也就能看到这个hello world的效果了,和配置一个http代理是一样的,只不过,这个代理是基于TCP的,无论什么包,都忠实的扔过去与还回来

需要说明的一点,配置基于TCP的端口转发,需要nginx和后台支撑服务器的端口保持一致,也就是如果后台的TCP监听是XXXX,那么nginx也必须是XXXX