最近在阿里雲上轉用 skynet built in https 後,出現奇怪的 socket 問題
Author: tomlau10Created Oct 12, 2020Updated Dec 29, 2025
抱歉因為這個問題奇怪非常 無法定位到問題在哪裡,很難作出精簡的描述 請容我用比較長的篇幅做描述
背景
- skynet 版本:
1.3.0rcrelease tag 的 commit - 我們的項目 在國外使用 google kubernetes engine (GKE) 在國內使用阿里雲 container kubernetes (ACK)
- 在早期由於 skynet 框架沒有 https 支援 我們額外用 nodejs 寫了個 https proxy micro service 在另外的 container 跑 並將 server 所有 http / https request 都用 http request + 改 header host 方式 先發到這個 https proxy GKE 及 ACK 2邊也是這樣使用,一直正常
- 針對 http(s) request,我們是有個
httpcskynet service 來集中做管理 並限制並發連接數上限 256 超過的話,http request 會在該 service 排隊處理 不過正常情況下,最大並發連接多數 < 5的 - 到7月左右我們修改了提到的
httpcservice 的代碼 可以直接使用 skynet built in https 去掉 nodejs proxy 的使用 並且測試通過後於8月底server 更新版本推出 奇怪的 socket 情況就開始出現了。。。
問題
- GKE 上的 server 一直正常 (直到今天也正常)
- 但是 ACK 上偶爾會有大量玩家回報 lag / 爆 ping (幾乎是全個服,客服從當前世界頻截圖得出這樣的判斷)
- 不論人多還是人少 / 早上下午或凌晨都曾出現 一開始是週末才出現,嚴重時一天可以爆 ping 幾次 後來是隔天就出現一次
- 當出現問題時,server log 會有一堆 socket error / closed 的 msg
2020-09-13 13:40:54.051721 [:00000013] socket: error on 107963 Connection reset by peer
2020-09-13 13:40:54.057327 [:00000013] socket: error on 107965 Connection reset by peer
2020-09-13 13:40:54.059430 [:00000013] fd = 107963, [Socket Error]
2020-09-13 13:40:54.060925 [:00000013] fd = 107965, [Socket Error]
2020-09-13 13:41:20.986025 [:00000013] socket: error on 108220 Connection reset by peer
2020-09-13 13:41:20.988263 [:00000013] socket: error on 108222 Connection reset by peer
2020-09-13 13:41:20.994423 [:00000013] fd = 108220, [Socket Error]
2020-09-13 13:41:20.996318 [:00000013] fd = 108222, [Socket Error]
...這裡 service 13 是我們的 httpd service
做法是參考 skynet/example/simpleweb.lua
用另外端口來監聽外部 command
eg shutdown / reboot / gm 後台對 server 做操作
且這個端口跟 game client 連接端口不相同
(下個部分再解釋為什麼這 httpd service 會經常有這麼多 socket 嘗試連接)
早期的測試
- 由於 GKE 並沒有出現問題,所以最初懷疑跟
ACK有關 ACK 的 loadbalancer 針對 exposed tcp port 有個 不能關掉的 health check loadbalancer 會不斷做 health check,這解釋了 httpd service 經常都會有 socket connect 而當連接失敗被判 unhealthy,loadbalancer 就會不再 route該端口的 traffic 到該 instance - 上邊的 service 13 socket error log
應該就是 health check 的 connection
而出現 error 感覺
是果不是因即 network 異常,所有 connection 都被 pause / close 了 因此 log 才會出現 error 而並非 health check error 導致 container network 被中斷 - 上點提到 httpd 端口跟 server 端口不相同 若果單純 httpd 端口出異常,理應不影響 game client 端口的 但當爆 ping 情況出現時,總有上述的 error log 相伴 所以暫時能解釋的,要麼是 skynet 框架中的 socket 處理有異常 要麼是 ACK 中 game server container 網絡有異常 單純到這裡來看,後者概率較高 因為同份代碼,在 GKE 下用相近 deployment 方式都沒有異常
- 所以我們試著修改 ACK deployment 中的 health check interval 和加大 unhealthy 判定的 threshold 但完全沒有改善到問題。。。
後期的測試
- 這個問題一直沒進展
直到9月底左右,回想起問題是於8月底更新才出現 背景中提到當時改用了 built in https由於十一假期臨近,想到什麼方式也只能試試 於是抱著測試的心態,revert 了上述改動,轉回原有的 https proxy 方式 結果竟然問題就消失了 - 然後就這樣過了愉快的十一假期
到上週六早上 server 例行重啟前 我嘗試再改回去用 built in https 結果不到一天再次出現爆 ping 情況 ... server log 情況同前
2020-10-10 18:37:14.192075 [:00000013] socket: error on 127594 Connection reset by peer
2020-10-10 18:37:14.200870 [:00000013] socket: error on 127596 Connection reset by peer
2020-10-10 18:37:14.202783 [:00000013] fd = 127594, [Socket Error]
2020-10-10 18:37:14.203821 [:00000013] fd = 127596, [Socket Error]
2020-10-10 20:25:45.290115 [:00000013] socket: error on 135587 Connection reset by peer
2020-10-10 20:25:45.290139 [:00000013] socket closed
2020-10-10 23:18:56.362953 [:00000013] socket: error on 149113 Connection reset by peer
2020-10-10 23:18:56.363672 [:00000013] socket: error on 149115 Connection reset by peer
2020-10-10 23:18:56.363847 [:00000013] fd = 149113, [Socket Error]
2020-10-10 23:18:56.364811 [:00000013] fd = 149115, [Socket Error]
...嚇得我慌忙又換回去 https proxy 的做法
然後週日就又回復正常了
暫時結論
- 貌似只有使用 skynet built in https 時,才會在 ACK 出現這個問題 => skynet 問題,ACK 未必有問題
- 然而 GKE 上同一套代碼,無論運行 https proxy 還是 skynet built in https 都沒事 => skynet 沒問題,是 ACK 問題
- 但以上2點好像又互相予盾
因而無從判斷究竟是單純 skynet https 還是單純 ACK 的問題
又或是 ACK + skynet https 才會出問題。。。
並且目前也沒有進一步訊息判斷
哪一個環節出問題
請問各位有遇過這種奇怪情況嗎? 有沒有 debug 方向建議? 個人還是希望能用上 skynet https 的 這樣 server 架構可以簡潔點,去掉 nodejs https proxy
Source: cloudwu/skynet