单入口模式网络配置
单入口模式是野火IM部署最复杂最难理解的部署方式,但实际上原理都是一样的,都是每个客户端要连到自己所属的IM服务的对应端口上。区别就是直连模式是用节点的公网IP地址来区分不同服务,单入口模式是通过端口来区分不同的服务。
1. 端口的规划
每个节点都需要3个端口,包括tcp端口,http端口和websocket端口。可以针对节点端口分别编号,比如节点的tcp端口为11881、11882、11883以此类推,节点的http端口10081、10082、10083以此类推,节点的websocket端口18081,18082,18083以此类推。以上端口都可以修改为任意其他端口。
此外还需要80端口来做路由端口,如果web客户端支持https,还需要额外的443端口。
2. 防火墙配置
需要放开NG服务的80端口。每个节点的TCP端口,分别是11881,11882,11883等;每个节点的HTTP端口,分别是10081,10082,10083等;如果有web客户端,每个节点的websocket端口,分别是18081,18082,18083等;如果web客户端是HTTPS的,还需要443端口。需要放开以上所有端口。
3. 配置文件的修改
每个节点的server.ip
都修改为授权地址,local_port
为80保持不变。其他端口按照端口规划配置,比如节点1的配置为
server.ip im.wildfirechat.cn
local_port 80
port 11881
http_port 10081
websocket_port 18081
节点2的配置为
server.ip im.wildfirechat.cn
local_port 80
port 11882
http_port 10082
websocket_port 18082
其他节点以此类推
4. NG的配置
NG的配置包括4部分,1是路由部分配置;2是HTTP代理配置;3是TCP的代理配置;4是Websocket代理配置。分别如下:
4.1. 路由代理配置
路由代理配置是HTTP的,参考配置如下
upstream imserver_cluster {
server 192.168.2.5:80;
server 192.168.2.11:80;
server 192.168.2.15:80;
}
server {
listen 80;
server_name im.wildfirechat.cn;
root html;
index index.html index.htm index.php;
proxy_connect_timeout 10s;
location /route {
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver_cluster;
}
location /api {
proxy_pass http://imserver_cluster;
}
location /robot {
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver_cluster;
}
location /channel {
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver_cluster;
}
}
把授权地址的80端口代理到随机某个服务的80端口,是一对多的关系。
如果有HTTPS的Web客户端,还需要额外添加SSL的支持,参考配置如下:
server {
listen 443 ssl;
server_name im.wildfirechat.cn;
proxy_connect_timeout 10s;
root html;
index index.html index.htm;
ssl_certificate cert/a.pem;
ssl_certificate_key cert/a.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location /route {
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver_cluster;
}
location /api {
proxy_pass http://imserver_cluster;
}
location /im {
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver_cluster;
}
location /robot {
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver_cluster;
}
location /channel {
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver_cluster;
}
}
4.2. HTTP代理配置
需要对每个节点的HTTP端口配置代理,把规划的HTTP端口代理到对应节点的80端口(注意是一对一),节点1的示例配置如下:
upstream imserver1 {
server 192.168.2.5:80;
}
server {
listen 10081;
server_name im.wildfirechat.cn;
root html;
index index.html index.htm index.php;
location /im {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'POST, OPTIONS';
add_header Access-Control-Allow-Headers 'p,cid,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver1;
if ($request_method = 'OPTIONS') {
return 204;
}
}
location /api {
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver1;
}
location /fs {
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://imserver1;
}
}
以此类推,针对每个节点的HTTP都做好配置。
4.3. TCP代理配置
NG需要支持4层代理,安装有stream模块。需要代理每个节点的TCP端口,节点1的示例配置如下:
stream { #stream模块 和http模块是一同等级;做四层代理时需要添加上这个模块;
upstream mqtt_server1 {
server 192.168.2.5:11881;
}
server {
listen 11881 so_keepalive=600s;
proxy_pass mqtt_server1;
tcp_nodelay on;
}
#节点2
#server {
# listen 11882 so_keepalive=600s;
# proxy_pass mqtt_server2;
# tcp_nodelay on;
#}
#
#节点3
#server {
# listen 11883 so_keepalive=600s;
# proxy_pass mqtt_server3;
# tcp_nodelay on;
#}
}
以此类推,针对每个节点的TCP都做好配置。需要注意的是需要会话保持10分钟以上,如果用其他工具注意设置会话保持10分钟。
4.4. Websocket代理配置
如果有JS客户端,需要NG支持websocket的代理,请在nginx.conf的http区域添加下面map块
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
## 其他配置项。。。
}
然后对端口规划的每个websocket端口进行代理,节点1的示例配置如下:
upstream ws_node1 {
server 192.168.2.5:18081;
}
server {
listen 18081;
server_name im.wildfirechat.cn;
root html;
index index.html index.htm;
location / {
proxy_pass http://ws_node1;
proxy_read_timeout 600s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
以此类推,针对每个节点的Websocket都做好配置。
如果web客户端要支持HTTPS,则需要对这个websocket代理加上SSL相关的配置,参加配置如下:
upstream ws_node1 {
server 192.168.2.5:18081;
}
server {
listen 18081 ssl;
server_name im.wildfirechat.cn;
root html;
index index.html index.htm;
ssl_certificate cert/a.pem;
ssl_certificate_key cert/a.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://ws_node1;
proxy_read_timeout 600s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
以此类推,针对每个节点的Websocket secure都做好配置。
这个1808X端口在web客户端不支持https时是Websocket的,在https时是WSS的,只能二选一。因此Web客户端不能同时支持HTTP和HTTPS,只能选一个。
参考专业版IM服务软件包下nginx目录下的single_address目录,里面有个single_address.md。按照此说明即可。
5. 验证
所有操作都在外网进行,检查是否可以从外网连入。
5.1. 检查路由
浏览器打开http://授权地址/api/version
看看是否返回json。
5.2. 检查HTTP
针对每个节点,浏览器打开http://授权地址:节点的HTTP端口/api/version
看看是否返回json。把所有节点都检查一遍。
5.3. 检查TCP
针对每个节点,使用命令:telnet 授权地址 节点的TCP端口
看看是否能够连上,所有节点都检查一遍。
5.4. 检查Web
如果有web客户端,可以用http://docs.wildfirechat.cn/web/wstool/index.html
这个连接检查一下websocket。如果是HTTP的站点,每个节点地址为ws://授权地址:节点的websocket端口
;如果站点是HTTPS的,地址为wss://授权地址:节点的websocket端口
。需要把所有节点都检查一遍。
如果站点是HTTPS的,还需要验证HTTPS的路由是否正确,浏览器打开地址https://授权地址/api/version
看看是否返回json.