nginx做TCP转发TCP代理转发(以及应用层反向代理) 四层或七层负载均衡

nginx做TCP转发TCP代理转发(以及应用层反向代理) 四层或七层负载均衡
20180626 Chenxin
场景:

  1. 大陆通过专线到日本,加快大陆用户体验感.需要搭建大陆和日本的代理转发(客户端->上海转发服->日本转发服->日本aws).
    2.因欧洲,东南亚访问北美游戏服延时较大.希望通过法兰克福和新加坡的代理机转发玩家请求给北美游戏服,降低延时.这样公网直接走aws骨干链路,而不用通过internet的路由.

yum安装失败原因
yum版本nginx version: nginx/1.12.1失败:
yum install nginx
yum安装的,在配置stream的时候,启动会报错:
unknown directive "stream" in /etc/nginx/nginx.conf
也就是无stream模块,故需要编译安装.
我们这里需要使用ngx_stream_core_module模块(用于1.9及其以后版本)

注意事项:TCP代理,代理机会使用自己的端口跟后端机建立连接,应该会存在端口耗尽的问题,也就是最多只能有65535个链接保持.如果超过,需要想其他办法.比如通过增加网卡接口的IP数量.
https://blog.csdn.net/libaineu2004/article/details/79104830 这里讲解的比较深入.包括nginx代理转发TCP.以及haproxy,https://blog.csdn.net/libaineu2004/article/details/79129684

编译安装

编译环境准备
yum -y install gcc gcc-c++ autoconf automake
yum -y install zlib zlib-devel openssl openssl-devel pcre-devel

安装 pcre库是为了使 nginx 支持具备 URI 重写功能的 rewrite 模块,如果不安装 pcre 库,则 nginx 无法使用 rewrite 模块功能。

nginx 在使用HTTPS服务的时候要用到此模块,如果不安装 openssl 相关包,安装 nginx 的过程中会报错。openssl 系统默认已经安装,只需要安装 openssl-devel 即可。

编译,添加tcp支持
说明:参照官方说明,编译参数中添加--with-steam即可,只有在configure时使用了--with-stream参数,编译出来的nginx程序才支持stream方式实现TCP代理.
cd /opt
wget http://nginx.org/download/nginx-1.12.2.tar.gz
tar xzvf nginx-1.12.2.tar.gz
cd nginx-1.12.2
./configure --prefix=/usr/local/nginx --with-stream --with-http_stub_status_module
make
make install

配置文件
/usr/local/nginx/conf/nginx.conf
在末尾添加一个stream模块(它和http等同级),这个模块,类似于http和mail模块,允许我们配置一组监听TCP连接的服务。允许你配置多个服务的TCP连接,通过在upstream的server组中配置proxy_pass指令。

cat /usr/local/nginx/conf/nginx.conf

支持行后注释

worker_processes auto;
worker_cpu_affinity auto;
error_log logs/error.log error;
pid logs/nginx.pid;
worker_rlimit_nofile 653600;

events {
worker_connections 653600; #(1)worker_connections 指定最大可以同时接收的连接数量,这里一定要注意,最大连接数量是和worker processes共同决定的。
multi_accept on; #(2)multi_accept 配置指定nginx在收到一个新连接通知后尽可能多的接受更多的连接
use epoll; #(3)use epoll 配置指定了线程轮询的方法,如果是linux2.6+,使用epoll,如果是BSD如Mac请使用Kqueue
}

stream { #这里的stream为4层.如果是http则为7层的
upstream server80 {
hash $remote_addr consistent; # 保持与客户端的对应关系
server ec2-107-23-101-62.compute-1.amazonaws.com:80 weight=1 max_fails=3 fail_timeout=10s; #weight 默认为1.weight越大,被分配到的概率就越大.这里也支持域名方式.
#server 172.16.1.22:80 weight=1 max_fails=3 fail_timeout=10s;
}
server {
listen 80; #(1)listen指定Nginx将在tcp 1884端口上监听
proxy_connect_timeout 1s; #(2)proxy_connect_timeout指定Nginx与被代理的主机之间建立连接的超时时间。
proxy_timeout 30s; #(3)proxy_timeout指定Nginx与客户端,以及Nginx与被代理的主机之间在两个相邻的读或写数据的操作之间的最大时间间隔。超过此时间间隔而没有数据读或写操作发生,则断开连接。--firecat个人建议时间设置长一点,否则tcp连接会断开.这里默认是10分钟.
proxy_pass server80; #(4)proxy_pass指定了被代理的主机的地址和端口号
}
upstream server8099 {
hash $remote_addr consistent;
server 52.53.76.253:8099 weight=1 max_fails=3 fail_timeout=10s;
}
server {
listen 8099;
proxy_connect_timeout 1s;
proxy_timeout 30s;
proxy_pass server8099;
}

}
检查
编译参数
/usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.12.2
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)
configure arguments: --prefix=/usr/local/nginx --with-stream --with-http_stub_status_module

配置文件语法
/usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
:
管理
启动
/usr/local/nginx/sbin/nginx
或者指定配置文件
/usr/local/nginx-02/sbin/nginx -c /usr/local/nginx-02/conf/nginx.conf

重启
/usr/local/nginx/sbin/nginx -s reload

停止
/usr/local/nginx/sbin/nginx -s stop
/usr/local/nginx-02/sbin/nginx -s stop
或killall nginx

四层反向代理到此结束.

能否根据不同目录分配到不同IP:PORT去
https://segmentfault.com/q/1010000004021226/a-1020000004021315
https://blog.csdn.net/rumengjian/article/details/80451711

开启访问日志
stream {
log_format main '$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/access.log main;

upstream server9989 {
    hash $remote_addr consistent;
    server 192.168.1.16:9989 weight=1 max_fails=3 fail_timeout=10s;
}
server {
    listen 9989;
    proxy_connect_timeout 1s;
    proxy_timeout 30s;
    proxy_pass server9989;
}

}
session保持(七层) 或 始终连接后端固定某服务器(四层) (可以不看)
缘由:
根据客户端所处位置,自动分配对应地理位置的战斗服给它.

七层方式
参考: https://www.oschina.net/question/12_24613
这里只适用于HTTP模块(ip_hash要配置在http块里),不适用于stream模块,会报[emerg] "ip_hash" directive is not allowed here
ip_hash(访问ip)
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
upstream favresin{
ip_hash;
server 10.0.0.10:8080;
server 10.0.0.11:8080;
}
其他说明
七层http有三种hash方式。
consistent_hash $remote_addr:可以根据客户端ip映射
consistent_hash $request_uri: 根据客户端请求的uri映射
consistent_hash $args:根据客户端携带的参数进行映射.

四层方式(TCP代理 socket转发)
可以通过stream方式,启动多个端口来解决.
需要客户端指定不同的端口.
stream {
log_format main '$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/access.log main;
#第一套server
upstream server9989 {
hash $remote_addr consistent; #保持客户端访问后端固定某台服务器
server 18.182.73.153:9989 weight=1 max_fails=3 fail_timeout=10s;
}
server {
listen 9989;
proxy_connect_timeout 1s;
proxy_timeout 30s;
proxy_pass server9989;
}
#第二套server
upstream server9990 {
hash $remote_addr consistent;
server 18.182.73.153:9989 weight=1 max_fails=3 fail_timeout=10s;
}
server {
listen 9990;
proxy_connect_timeout 1s;
proxy_timeout 30s;
proxy_pass server9990;
}
}

配置示例(不用看)
2019/02/12
上海,日本 转发服

上海
cat nginx.conf
worker_processes auto;
worker_cpu_affinity auto;
error_log logs/error.log error;
pid logs/nginx.pid;
worker_rlimit_nofile 653600;

events {
worker_connections 653600; #(1)worker_connections 指定最大可以同时接收的连接数量,这里一定要注意,最大连接数量是和worker processes共同决定的。
multi_accept on; #(2)multi_accept 配置指定nginx在收到一个新连接通知后尽可能多的接受更多的连接
use epoll; #(3)use epoll 配置指定了线程轮询的方法,如果是linux2.6+,使用epoll,如果是BSD如Mac请使用Kqueue
}

stream {
log_format main '$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/access.log main;

#fight-match server-01
upstream server9989 {
    hash $remote_addr consistent;
    server 192.168.1.59:9989 weight=100 max_fails=3 fail_timeout=10s;
}
server {
    listen 9989;
    proxy_connect_timeout 1s;
    proxy_timeout 30s;
    proxy_pass server9989;
}

#fight-match server-02
#upstream server9990 {
#    hash $remote_addr consistent;
#    server 192.168.1.16:9990 weight=1 max_fails=3 fail_timeout=10s;
#}
#server {
#    listen 9990;
#    proxy_connect_timeout 1s;
#    proxy_timeout 30s;
#    proxy_pass server9990;
#}

#gateway
#upstream server9979 {
#    hash $remote_addr consistent;
#    server 192.168.1.59:9979 weight=100 max_fails=3 fail_timeout=10s;
#}
#server {
#    listen 9979;
#    proxy_connect_timeout 1s;
#    proxy_timeout 30s;
#    proxy_pass server9979;
#}

}

日本
cat nginx.conf
worker_processes auto;
worker_cpu_affinity auto;
error_log logs/error.log error;
pid logs/nginx.pid;
worker_rlimit_nofile 653600;

events {
worker_connections 653600; #(1)worker_connections 指定最大可以同时接收的连接数量,这里一定要注意,最大连接数量是和worker processes共同决定的。
multi_accept on; #(2)multi_accept 配置指定nginx在收到一个新连接通知后尽可能多的接受更多的连接
use epoll; #(3)use epoll 配置指定了线程轮询的方法,如果是linux2.6+,使用epoll,如果是BSD如Mac请使用Kqueue
}

stream {
log_format main '$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/access.log main;

#fight-match server-01
upstream server9989 {
    hash $remote_addr consistent;
    #xinjiapo 这里不行,客户端拿到A,而gameCenter可能分配的是B,会报1002
    #server 13.229.15.29:9989 weight=1 max_fails=3 fail_timeout=10s;
    #server 18.136.38.137:9989 weight=1 max_fails=3 fail_timeout=10s;
    #riben
    server 18.182.73.153:9989 weight=1 max_fails=3 fail_timeout=10s;
}
server {
    listen 9989;
    proxy_connect_timeout 1s;
    proxy_timeout 30s;
    proxy_pass server9989;
}

#fight-match server-02
#upstream server9990 {
#    hash $remote_addr consistent;
#    server 18.182.73.153:9989 weight=1 max_fails=3 fail_timeout=10s;
#}
#server {
#    listen 9990;
#    proxy_connect_timeout 1s;
#    proxy_timeout 30s;
#    proxy_pass server9990;
#}


#gateway
#upstream server9979 {
#    hash $remote_addr consistent;
#    server xbzj-taihe-bei-vpc-01-nlb-01-c7535ce71d33ace2.elb.us-east-1.amazonaws.com:9979 weight=100 max_fails=3 fail_timeout=10s;
#}
#server {
#    listen 9979;
#    proxy_connect_timeout 1s;
#    proxy_timeout 30s;
#    proxy_pass server9979;
#}

}

posted @ 2020-04-21 14:47  ChanixChen  阅读(6143)  评论(0编辑  收藏  举报