![使用 nginx 的 Websocket 反向代理:服务器日志中出现请求错误,但在浏览器中有效](https://linux22.com/image/683442/%E4%BD%BF%E7%94%A8%20nginx%20%E7%9A%84%20Websocket%20%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%EF%BC%9A%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%97%A5%E5%BF%97%E4%B8%AD%E5%87%BA%E7%8E%B0%E8%AF%B7%E6%B1%82%E9%94%99%E8%AF%AF%EF%BC%8C%E4%BD%86%E5%9C%A8%E6%B5%8F%E8%A7%88%E5%99%A8%E4%B8%AD%E6%9C%89%E6%95%88.png)
情况
我在跑步Etherpad,通过 nginx 代理。Etherpad 使用带有 Socket.io 的 Websockets。
我的 nginx 配置大致如下这个。socket.io 的位置块如下:
rewrite /CustomSubDir/socket.io/(.*) /socket.io/$1 break;
proxy_pass http://localhost:CustomPort/;
proxy_redirect / /CustomSubDir/;
proxy_cookie_path / /CustomSubDir/;
# usual proxy header
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
# websocket
proxy_set_header Accept-Encoding "";
proxy_http_version 1.1;
# http://nginx.org/en/docs/http/websocket.html
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_buffers 8 32k;
proxy_buffer_size 64k;
proxy_buffering off;
令人困惑的是
因此好消息是:一切正常!因此,我并不是在问如何让任何东西正常工作。
最基本的问题是:尽管一切正常,但 nginx 总是向我显示错误消息。
怎么了
nginx 在中显示了这些错误error.log
:
2016/05/24 xx:yy:zz [error] 22197#0: *12059 connect() failed (111: Connection refused) while connecting to upstream, client: SOM.IPA.DDR.EES, server: somedomain.example.com, request: "GET /CustomSubDir/socket.io/?EIO=3&transport=polling&t=1464121868147-3&sid=H2GhIY24t2a40etpAACd HTTP/2.0", upstream: "http://[::1]:CustomPort/socket.io/?EIO=3&transport=polling&t=1464121868147-3&sid=H2GhIY24t2a40etpAACd", host: "somedomain.example.com"
2016/05/24 xx:yy:zz [error] 22197#0: *12070 connect() failed (111: Connection refused) while connecting to upstream, client: SOM.IPA.DDR.EES, server: somedomain.example.com, request: "POST /CustomSubDir/socket.io/?EIO=3&transport=polling&t=1464122037998-5&sid=T-pthraR669TF2cKAACe HTTP/2.0", upstream: "http://[::1]:CustomPort/socket.io/?EIO=3&transport=polling&t=1464122037998-5&sid=T-pthraR669TF2cKAACe", host: "somedomain.example.com"
所以我可以追踪这些请求。原因如下:1. 这些显然是 Websocket 请求。2. 这些是 - 而且很特殊 - POST 请求。
当加载 Etherpad 或在丢失连接后重新连接到 Etherpad 时,只会发出一个请求,这满足了这些要求。我可以在浏览器中清楚地看到它,并且可以实时看到它出现在 nginx 错误日志中。这是我浏览器中的请求:
200 POST https://somedomain.example.com/CustomSubDir/socket.io/?EIO=3&transport=polling&t=1464121868143-2&sid=H2GhIY24t2a40etpAACd
它包含(例如)这个有效载荷:
164:42["message",{"component":"pad","type":"CLIENT_READY","padId":"CENSORED","sessionID":"null","password":null,"token":"t.qbszmj[...]","protocolVersion":2}]
服务器回复是:
HTTP/2.0 200 OK
Server: nginx
Date: Tue, 24 May 2016 xx:yy:zz GMT
Content-Type: text/html
Content-Length: 2
access-control-allow-origin: *
Set-Cookie: io=H2GhIY24t[...]
X-Firefox-Spdy: h2
ok
为什么我可以肯定这是罪魁祸首
我非常确定 POST 请求导致了这种情况。这不仅是因为它是访问 pad 时使用此 URL 的唯一 POST 请求,而且我还可以比较其行为。因为在同一台服务器上我还运行乙醚,其工作原理非常相似,但有一个重要区别:它似乎不使用 POST Websocket 请求。
猜猜怎么着?error.log
是空的。
我的问题
那么我的问题是:
- 当 nginx 在日志中报告请求失败时,我怎样才能在浏览器中看到请求成功(并有正确的服务器回复!)?
- 我该如何摆脱这些错误消息?据我所知,请求没有失败...
答案1
我可以解决我的问题感谢@webzwo0i, WHO让我意识到 GitHub 上的这可能是 IPv4/IPv6 冲突。
因此我再次查看了错误日志并特别注意到了这一点:
“[...] connect() 连接到上游时失败(111:连接被拒绝)[...]”,上游:“http://[::1]:CustomPort/socket.io/[...]”
这是 IPv6 本地主机地址,但 Etherpad/NodeJS 似乎只连接到 IPv4 地址。
因此,更改localhost
nginx 配置中的所有 s127.0.0.1
解决了我的问题。日志中的错误消失了。我还注意到其他一些请求也在日志中导致了相同的错误,因此它并不特定于我描述的请求。