部署Nginx 代理转发
MeteorCatNginx 现在的代理转发功能已经日趋完善, 可以用来进行大规范的数据负载转发, 比较知名的方案就是 Nginx-Tomcat/Nginx-Jar
的转发负载架构.
常见的 Java 高并发负载也是通过 Nginx 挂起代理转发到不同 Jar 服务进行处理.
Nginx 有两种转发方式:
- HTTP转发: 只针对 HTTP 数据转发, 可以通过设置代理头转发源客户端数据.
- Stream转发: 针对 TCP/UDP 的数据流转发, 目前转发的时候无法识别源IP.
如果仅仅作为流量不需要做任何日志和IP判断可以采用 Stream 转发, 剩下只要不涉及这种情况完全不推荐( 应该采用专门的
HAProxy 转发数据 )
Stream转发
这里说明 Stream 转发两种方式: TCP/UDP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| # 注意 Stream 转发不会涉及 HTTP 模块, 所以不需要在 HTTP 之中编写 http{ ....... } # 这里直接和 http 模块一样, 创建出新的模块 stream { # 这里可以追加其他默认配置, 比如重设日志输出格式 log_format proxy '$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 /var/log/nginx/proxy.log proxy; # 直接手动引入配置, 这里会默认加载目录下所有 xxxx.conf 后缀的配置文件 include /etc/nginx/stream.d/*.conf; }
|
TCP转发
这里就是文件配置, 用于加载主文件获取加载目录下面的配置, 这里演示如何配置 TCP 和 UDP 的转发, 首先是 TCP 转发:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| # 这里假设采用转发 SSH 的 TCP 协议来演示转发端口数据. # sudo vim /etc/nginx/stream.d/ssh.conf upstream ssh_proxy { # 注意这里有几种并发请求分配算法设置, 不含NGINX商业版本算法. # `backup` 这个是备份服务, 当所有的服务器宕机无法访问的时候就会转发到该服务. # 默认轮流算法, 请求会轮流切换分配访问的服务器 server server1.example.com:22; server server2.example.com:22; server server4.example.com:22 backup; # 权重分配算法, 按照权重来选择权重最高的服务器 server server1.example.com:22 weight=3; server server2.example.com:22 weight=5; # 客户端IP的哈希算法, 比较老版本暂时不推荐( 不支持 IPv6 和版本不支持 ) ip_hash; server server1.example.com:22; server server2.example.com:22; # 自动分配最少请求服务器, 这种方式最简单方便 least_conn; server server1.example.com:22; server server2.example.com:22; # 手动哈希分配算法, 对指定的某项客户端配置进行哈希分配服务器( 这里采用访问IP地址 ) # `consistent` 参数可有可无如果设置则默认采用一致性哈希, 能够更快命中某些缓存服务( Memcache/Redis ) hash $remote_addr consistent; server server1.example.com:22; server server2.example.com:22; # 一致性哈希分配, 这里是简化版手动哈希分配( 根据 HTTP-GET 地址哈希比较选择 ) consistent_hash $request_uri; server server1.example.com:22; server server2.example.com:22; # 负载检测分配, 这个方法采用后台服务器转发响应时间作为依赖, 并非可信的完全负载判断. server server1.example.com:22; server server2.example.com:22; fair; # 这里支持的服务器方式可以支持以下方式 # 支持最大错误次数( max_fails=3 ), 每次最大错误的超时时间( fail_timeout=30s ) # 错误判断用于给服务器识别异常从而转发下一级的服务器( 超时/无法访问等情况 ) server server1.example.com:22 max_fails=3 fail_timeout=30s; # 域名服务器 server 127.0.0.1:22 max_fails=3 fail_timeout=30s; # IP服务器 server unix:/tmp/ssh.sock max_fails=3 fail_timeout=30s; # UnixDomain服务器 } # TCP 挂起服务器连接池 server { # 设定监听端口, 可以采用多配置项目, 这里说明几个关键配置 # `reuseport`, 开启了端口快速复用缓解 TIME_WAIT 回收端口请求资源过慢导致请求 # `udp`, 声明该代理的是 UDP 服务 # 以上都是比较简单的配置项, 日常基本上就这些参数配置需要注意 listen 10022 reuseport; # 启用 TCP 的 NODELAY 特性 # 网络默认 TCP 启用 `Nagle` 算法, 该算法通过减少传输的数据包( 读写缓冲区集中发放 ) # # `Nagle` 算法的好处: 减少传输的数据包数量, 将传输数据集中一起统一发送, 从而有效提高网络利用率. # 但是坏处也是明显, 数据并不会实时传输具有数据传输延时的问题( 因为数据必须等到写缓冲区满足条件发送 ) # # `TCP_NODELAY` 禁用 `Nagle` 算法的好处: 直接实时发送对应数据包, 能够有效降低数据传输的延时 # 坏处则是会频繁实时发送数据包, 网络会频繁处于活跃状态导致网络利用率低下. # # 当然如果想要实时传输且提高网络利用率, 则可以采用编写自定义UDP传输协议处理 tcp_nodelay on; # 设定连接的超时时间( CONNECT 状态 ) proxy_connect_timeout 3s; # 设定代理的请求超时时间( WAIT 状态 ) proxy_timeout 15s; # 调用指定的后端服务池 proxy_pass ssh_proxy; } # 也可以直接设置转发配置 server { listen 20022; # 直接简单的转发配置 proxy_pass 127.0.0.1:22; }
|
这里配置方式基本上是常见配置, 剩下可以参考官方文档来配置.
UDP转发
UDP 转发配置基本上也差不多, 所以直接采用简单的配置说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| # 这里假设采用转发 DNS 的 UDP 协议来演示转发端口数据. # sudo vim /etc/nginx/stream.d/dns.conf upstream dns_proxy { # 自动分配最少请求服务器, 这种方式最简单方便 least_conn; server dns1.example.com:53; server dns2.example.com:53; } # 转发 DNS 服务 server { # 设置监听端口和端口重用/UDP转发声明 listen 53 reuseport udp; # 直接简单的转发配置 proxy_pass dns_proxy; }
|
UDP 基本上配置和 TCP 差不多.
HTTP转发
这种方式转发比较常规, 被广泛应用在 Web 应用高并发处理, 能够有效起到负载分流功能( 这种又称 反向代理 ):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| # 注意, 这里只在 http 配置块配置 http{ ...... # 这里一般都是加载 /etc/nginx/conf.d/xxx.conf 之中配置 # 创建代理服务池服务 upstream tomcat_service { # 采用自动分流功能 least_conn; # 假设内网多服务器分流, 设置最大错误和错误时间 server 192.168.1.100:8080 max_fails=2 fail_timeout=15s; server 192.168.1.102:8080 max_fails=2 fail_timeout=15s; server 192.168.1.104:8080 max_fails=2 fail_timeout=15s; server 192.168.1.108:8080 max_fails=2 fail_timeout=15s; # 追加双机宕机备份 server 192.168.1.110:8080 max_fails=2 fail_timeout=15s backup; server 192.168.1.112:8080 max_fails=2 fail_timeout=15s backup; } # 挂起 http 服务器监听 server { # 设置监听端口 listen 80; # 设置服务器访问域名 server_name www.example.com; ...... # 这里需要设置 localhost 块 location / { # 声明代理转发给服务器池 proxy_pass http://tomcat_service; # 设置是否启用服务重定向, 默认 off 不启用代理转发 proxy_redirect off; # 将客户端请求的域名转发给代理的服务器, 让接受代理的服务器可以识别出客户端访问的域名 # 如果采用多端口请求的服务, 需要追加端口信息 `$server_port`, 如下配置: # proxy_set_header Host $host:$server_port; proxy_set_header Host $host; # 将域名追加请求协议头 # `$proxy_add_x_forwarded_for` 该变量会将代理机和客户端IP一起合并( 逗号区分 )发放. # `$remote_addr` 则是直接把客户端IP写入而不会加上代理IP # 两者按需选择 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-real-ip $remote_addr; # 设置 CONNECT(连接) 状态超时时间( 默认单位: 秒,60s ) proxy_connect_timeout 60s; # 设置 SEND(请求发送) 状态超时时间( 默认单位: 秒,60s ) proxy_send_timeout 60s; # 设置 READ(请求发送) 状态超时时间( 默认单位: 秒,60s ) proxy_read_timeout 60s; } } }
|
WebSocket转发
WebSocket 转发则比较特别, 虽然是长连接请求但是内部配置是在 Http 配置块.
Nginx 代理转发要求 1.3+ 版本
配置示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| # 注意, 这里只在 http 配置块配置 http{ ...... # 这里一般都是加载 /etc/nginx/conf.d/xxx.conf 之中配置 # 创建代理服务池服务 upstream websocket_service { # 采用自动分流功能 least_conn; # 假设内网多服务器分流, 设置最大错误和错误时间 server 192.168.1.100:10800 max_fails=2 fail_timeout=15s; server 192.168.1.102:10800 max_fails=2 fail_timeout=15s; } # 挂起 http 服务器监听 server { # 设置监听端口 listen 1080; # 设置服务器访问域名 server_name ws.example.com; ...... # 这里需要设置 localhost 块 location / { # 声明代理转发给服务器池 proxy_pass http://websocket_service; # 将客户端请求的域名转发给代理的服务器, 让接受代理的服务器可以识别出客户端访问的域名 proxy_set_header Host $host:$server_port; # 将域名追加请求协议头 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-real-ip $remote_addr; # 以上都是常规的配置, 之后就是专属的 WebSocket 配置 # 以下三行可以直接简单将 http 请求升级成 ws 请求. proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } }
|