通常,我们使用 Nginx 为后端 WEB服务做反向代理或负载均衡,但如果我们的后端服务,并不是HTTP/HTTPS 协议,而是 TCP 协议或 WebSocket 协议呢

说到 TCP 协议服务的反向代理,有个出名的软件是 HAProxy,HAProxy 在 TCP 代理方面更专注一些。但由于我的服务器已经大量在使用 Nginx,没必要再安装额外的软件,所以准备用 Nginx 来进行反代。

但是我直接反代后遇到无法正常链接

报错提示:

1
WebSocket connection to 'wss://tiktok.com/?app=index&session=NEW' failed

发现是因为 WebScoket 协议如需要通过 Nginx 代理,就需要 location 节点增加以下节点即可正常建立连接

1
2
3
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

一个是启用 HTTP 1.1,因为 Nginx 对 HTTP 的反向代理,默认使用 HTTP 1.0 连接到后端,那样没法保持长连接,后端作出 HTTP 响应后,连接就被掐断了,所以启用 HTTP 1.1 以支持长连接。

而对于 Upgrade 和 Connection,为什么要让 Nginx 加这个请求头,对于 WebSocket 协议,客户端不是已经加了 Upgrade 和 Connection 请求头了吗?

那是因为根据 HTTP 协议规范,Upgrade 和 Connection 属于 hop-by-hop 请求头,Nginx 作为中间的代理,按照规范不能直接转发 hop-by-hop header ,所以需要进行强制修改。

所以我们需要在 Nginx 配置文件中添加即可

修改后的 Nginx 配置文件

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
#PROXY-START/

location ^~ /
{
proxy_pass http://127.0.0.1:8080;

#新增支持 WebScoket 节点
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header 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;
proxy_set_header REMOTE-HOST $remote_addr;

#Persistent connection related configuration

add_header X-Cache $upstream_cache_status;

#Set Nginx Cache


set $static_fileDHgaY5Zk 0;
if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )
{
set $static_fileDHgaY5Zk 1;
expires 12h;
}
if ( $static_fileDHgaY5Zk = 0 )
{
add_header Cache-Control no-cache;
}
}

#PROXY-END/