配置
nginx 支持 websockt,需要添加如下配置
1
2
3
|
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
|
nginx 配置文件修改之前(反向代理后端服务)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$ sudo cat /etc/nginx/conf.d/manager.conf
server {
listen 16002;
server_name _;
charset utf-8;
root /root/manager/dist;
location /api {
proxy_pass http://192.168.120.10:16002;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
|
nginx 支持后端 websocket (websocket地址: ws://192.168.120.10:16002/api/webssh),配置如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
$ sudo cat /etc/nginx/conf.d/manager.conf
server {
listen 16002;
server_name _;
charset utf-8;
root /root/manager/dist;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header Host $host:$server_port;
proxy_set_header X_Forward_For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
location /api {
proxy_pass http://192.168.120.10:16002;
}
}
|
proxt_http_version 1.1;
: 表示反向代理发送的HTTP协议的版本是1.1,HTTP1.1支持长连接
proxy_set_header Upgrade $http_upgrade;
和 proxy_set_header Connection "upgrade";
: 表示 websocket 连接进入的时候,将一个 http 连接升级为 websocket 连接
标准配置
根据 http://nginx.org/en/docs/http/websocket.html 编写一份标准配置文件
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
|
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream wsbackend{
server ip1:port1;
server ip2:port2;
keepalive 1000;
}
server {
listen 20038;
location /{
proxy_http_version 1.1;
proxy_pass http://wsbackend;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3600s;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
|
其中,
1
2
3
4
|
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
|
表示:
- 如果 $http_upgrade 不为 ’’ (空),则 $connection_upgrade 为 upgrade
- 如果 $http_upgrade 为 ’’ (空),则 $connection_upgrade 为 close
1
2
3
4
5
|
upstream wsbackend{
server ip1:port1;
server ip2:port2;
keepalive 1000;
}
|
表示 nginx 负载均衡
- 负载两台服务器(ip1:port1)和(ip2:port2)
- keepalive 1000 表示的是每个nginx进程中上游服务器保持的空闲连接,当空闲连接过多时,会关闭最少使用的空闲连接.当然,这不是限制连接总数的,可以想象成空闲连接池的大小.设置的值应该是上游服务器能够承受的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
server {
listen 80;
location /{
proxy_http_version 1.1;
proxy_pass http://wsbackend;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3600s;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
|
表示的是监听的服务器的配置
- listen 80 表示 nginx 监听的端口
- locations / 表示监听的路径(/表示所有路径,通用匹配,相当于default)
- proxt_http_version 1.1 表示反向代理发送的HTTP协议的版本是1.1,HTTP1.1支持长连接
- proxy_pass http://wsbackend; 表示反向代理的uri,这里可以使用负载均衡变量
- proxy_redirect off; 表示不要替换路径,其实这里如果是/则有没有都没关系,因为default也是将路径替换到proxy_pass的后边
- proxy_set_header Host $host; 表示传递时请求头不变, $host是nginx内置变量,表示的是当前的请求头,proxy_set_header表示设置请求头
- proxy_set_header X-Real-IP $remote_addr; 表示传递时来源的ip还是现在的客户端的ip
- proxy_read_timeout 3600s; 表示两次请求之间的间隔超过 3600s 后才关闭这个连接,默认的60s.自动关闭的元凶
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 表示X-Forwarded-For头不发生改变
- proxy_set_header Upgrade $http_upgrade; 表示设置Upgrade不变
- proxy_set_header Connection $connection_upgrade; 表示如果 $http_upgrade为upgrade,则请求为upgrade(websocket),如果不是,就关闭连接
简化版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
...
location /chat/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
|
问题
- Nginx代理webSocket经常出现中断的解决方案, 如何保持长连接
原因: nginx等待客户端第一次通讯和第二次通讯的时间差,超过了它设定的最大等待时间,简单来说就是,超时,所以就断了webSocket连接。
解决方案一
配置nginx.conf的对应localhost里面的这几个参数
1
2
3
|
proxy_connect_timeout
proxy_read_timeout
proxy_send_timeout
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
http {
server {
location / {
root html;
index index.html index.htm;
proxy_pass http://webscoket;
proxy_http_version 1.1;
proxy_connect_timeout 4s; #配置点1
proxy_read_timeout 60s; #配置点2,如果没效,可以考虑这个时间配置长一点
proxy_send_timeout 12s; #配置点3
proxy_set_header Upgrade $http_upgrade; #这是webSocket的配置,与此解决方案无关
proxy_set_header Connection "Upgrade"; #这是webSocket的配置,与此解决方案无关
}
}
}
|
配置点2: 这个是服务器对客户端等待最大的时间,也就是说,当webSocket使用nginx转发的时候,对于上面的配置点2来说,如果60秒内没有通讯,依然是会断开的,所以,你可以按照你的需求来设定。
解决方案二
发心跳包,原理就是在有效的再读时间内进行通讯,重新刷新再读时间
参考:
https://www.jianshu.com/p/6205c8769e3c
http://nginx.org/en/docs/http/websocket.html