1

我的服务器通过 gcp https lb 负载平衡到后端服务器,后端服务器使用 pm2 start -i 选项不同的端口,并使用 haproxy 将它们分发到这些节点。

连接日志 使用代码从服务器获取的日志。

io.on('connection', (socket) => {
    console.debug("connection!", socket.id);
}

每两次,服务器连接失败。

下面是通过 haproxy -d 的日志。

失败

成功

此日志是失败后成功

00000041:http-in.clireq[000a:ffffffff]: GET /socket.io/?EIO=3&transport=websocket&sid=rf3JvyUz2KCKV4KDAABS HTTP/1.1
00000041:http-in.clihdr[000a:ffffffff]: User-Agent: websocket-sharp/1.0
00000041:http-in.clihdr[000a:ffffffff]: Host: mydomain.com
00000041:http-in.clihdr[000a:ffffffff]: Upgrade: websocket
00000041:http-in.clihdr[000a:ffffffff]: Sec-WebSocket-Key: 9JCkV46YNC66nIUaZQZl9w==
00000041:http-in.clihdr[000a:ffffffff]: Sec-WebSocket-Version: 13
00000041:http-in.clihdr[000a:ffffffff]: X-Cloud-Trace-Context: 1210ae7f3bb6e56c817e7f5ad30e1d24/17748396103009389644
00000041:http-in.clihdr[000a:ffffffff]: Connection: Upgrade
00000041:http-in.clihdr[000a:ffffffff]: Via: 1.1 google
00000041:http-in.clihdr[000a:ffffffff]: X-Forwarded-For: source ip, dest ip
00000041:http-in.clihdr[000a:ffffffff]: X-Forwarded-Proto: https
00000041:websockets.srvrep[000a:000b]: HTTP/1.1 400 Bad Request
00000041:websockets.srvhdr[000a:000b]: Connection: close
00000041:websockets.srvhdr[000a:000b]: Content-type: text/html
00000041:websockets.srvhdr[000a:000b]: Content-Length: 18
00000041:websockets.srvcls[000a:adfd]
00000041:websockets.clicls[adfd:adfd]
00000041:websockets.closed[adfd:adfd]
00000042:http-in.accept(0007)=000a from [130.211.3.23:53189] ALPN=<none>
00000042:http-in.clireq[000a:ffffffff]: GET /socket.io/?EIO=3&transport=websocket&sid=xmZEqtHokEmBfs2QAABT HTTP/1.1
00000042:http-in.clihdr[000a:ffffffff]: User-Agent: websocket-sharp/1.0
00000042:http-in.clihdr[000a:ffffffff]: Host: mydomain.com
00000042:http-in.clihdr[000a:ffffffff]: Upgrade: websocket
00000042:http-in.clihdr[000a:ffffffff]: Sec-WebSocket-Key: 8PKkFxEv3c3KqIUW8dQbLA==
00000042:http-in.clihdr[000a:ffffffff]: Sec-WebSocket-Version: 13
00000042:http-in.clihdr[000a:ffffffff]: X-Cloud-Trace-Context: de0fa56d1689317bb9212879da8edfcb/11012650454108009103
00000042:http-in.clihdr[000a:ffffffff]: Connection: Upgrade
00000042:http-in.clihdr[000a:ffffffff]: Via: 1.1 google
00000042:http-in.clihdr[000a:ffffffff]: X-Forwarded-For: source ip, dest ip
00000042:http-in.clihdr[000a:ffffffff]: X-Forwarded-Proto: https
00000042:websockets.srvrep[000a:000b]: HTTP/1.1 101 Switching Protocols
00000042:websockets.srvhdr[000a:000b]: Upgrade: websocket
00000042:websockets.srvhdr[000a:000b]: Connection: Upgrade
00000042:websockets.srvhdr[000a:000b]: Sec-WebSocket-Accept: tW86o/zu95tHQayPP7IlGNXi96s=

没有区别,但有两个结果。我不知道为什么 400 bad request

haproxy.cfg

global
  maxconn 4096

defaults
  mode http
  balance roundrobin
  option redispatch
  option forwardfor

  timeout connect 5s
  timeout queue 5s
  timeout client 50s
  timeout server 50s

frontend http-in
  bind *:80
  default_backend servers

  # Any URL beginning with socket.io will be flagged as 'is_websocket'
  acl is_websocket path_beg /socket.io
  acl is_websocket hdr(Upgrade) -i WebSocket
  acl is_websocket hdr_beg(Host) -i ws

  # The connection to use if 'is_websocket' is flagged
  use_backend websockets if is_websocket

backend servers
  server server1 10.168.0.50:80
#  server server2 [Address]:[Port]

backend websockets
  balance source
  option http-server-close
  option forceclose

  cookie io prefix indirect nocache # using the `io` cookie set upon handshake

  server ws-server1 10.168.0.50:5000 weight 1 maxconn 1024 cookie ws-server1 check
  server ws-server2 10.168.0.50:5001 weight 1 maxconn 1024 cookie ws-server2 check
  #server ws-server3 10.168.0.50:5002 weight 1 maxconn 1024 check

我使用 cookie SRVNAME 插入选项和服务器名称 SA、SB

但 socket.io 文档读取更改 cookie io 前缀间接 nocache 和服务器名称 ws-server1, ws-server2

我的测试:

客户端使用长轮询和 websocket

testClient 给选项 {transports: ['websocket']} 总是成功.. 但真正的客户端不只使用 websocket 选项

我不知道为什么会失败。

如果仅使用 ws-server1 连接将始终成功。但 ws-server2 有时使用连接失败。我猜是粘性会话问题。我尝试 haproxy.cfg 添加 cookie 选项,但问题没有解决。

我怎么解决这个问题?

4

0 回答 0