-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
最近在阿里雲上轉用 skynet built in https 後,出現奇怪的 socket 問題 #1247
Comments
skynet 并没有 1.3.0rc 这个 tag ,不知道准确版本是什么? 另外,8 月份的 a4dc6b9 增加了一个 pause 的特性,这个今天查出来是有 bug 的。因为原意是在客户端到服务器上行流量超过了处理能力后,可以暂停接收数据。但是这个 pause 同时把下行也中断了,导致在 pause 发生时,无法写出数据。 这个 bug 在今天 f3acbe4 修复。 但我看不出这个 bug 和这里有什么关系? 上行过载本身是比较罕见的事情,一般不会触发。如果使用了该版本,可以通过修改 https://github.com/cloudwu/skynet/blob/master/lualib/skynet/socket.lua#L6 BUFFER_LIMIT 为一个极大的数值来避免触发。目前是 128K ,即,如果单条连接上堆积了超过 128K 数据未被读取,那么会主动 pause 上行数据(但 bug 会导致下行写出的数据也同时被 pause )。 你可以去掉 build-in https ,而用最新 skynet 代码,看看是否还有问题。 |
我理解是:玩家走的 https 协议的通道上并没有出错信息,但有 lag 延迟。 看文档介绍,ACK 走的是 http 协议,而不是 https 协议。是不是 ACK 用 http 请求去请求了 https 端口?能不能在 httpd 服务中加入更多的 log 观察 ACK 发送了怎样的数据包? |
想到一种解释: 因为你限制了最大连接数 256 ,如果被占满,会导致 ACK 请求被搁置。一旦超时,ACK 会任务不健康,然后转而不再转发。 建议:
|
確實沒有這個 tag,估計是我看錯 commit msg 成 release tag 了。。。
理解有誤,客戶端是直接用 socket 跟 server 做數據交互
是的
這2個 service 都不是面向客戶端的 以上 2個 service,功能上及代碼上都完全隔離,貌似沒什麼關聯
假如是跟 skynet 有關,2者共通的部分就只有 socket 層 (?) 🤔
同意
按上邊
對方是發一個 HEAD http request 過來 |
我前文表述有誤。。。 經測試後,發現造成 ACK 上的問題 上邊提到我們最初架構是用 nodejs https proxy 但若是直接讓業務邏輯上的 https request 但暫時無法解釋為何相同的代碼 (GKE / ACK 都使用相同 server docker image) |
我觉得你可以在 http.tlshelper 模块内多加一些 log 帮助分析到底发生了什么事情,收发了怎样的数据。 我们最近一年用 skynet 做了一些内部用的非常高负荷高流量高并发连接的服务,暂时没有发现网络层有什么 bug 。我认为可以信任网络层的实现。 倒是在处理高流量复杂的业务时,需要做一些流量控制操作,避免把数据堆积在网络层造成 OOM (out of memory) 问题,这就是最近新添的 api 的作用。 倒是 tls 可以多测试一下。但是有好些朋友使用基于 tsl 的 websocket 服务,似乎没有类似反馈。 我倾向于认为首先是 ACK 出错,导致阿里云判断健康有问题,从而停止了端口转发,继而造成玩家 lag 。 |
啊~ 另外有一個觀察 我們的業務會用到 當 ACK 出現相關 api request 抽風時
卡了良久 (1分鐘左右?) 後會彈出 ssl error syscall
請教一下 |
lts.c 问题需要 @lvzixun 来看。 阻塞一定发生在 lua 层,任何 c 层次的阻塞都会触发监控 log 。这个现象更像是 lts.c 模块需要的网络数据没有收全,导致 block 在 lua 层的 socket.read 上。 |
我建议可以把 https://github.com/cloudwu/skynet/blob/master/lualib/http/tlshelper.lua#L7 这里这个 socket.readfunc 包装一层,单独加上额外的 log ,观察在阻塞发生的时候的数据流。 |
记录一下: 我们在2021.12.15也出现过大量 http/https 调用失败的问题, 具体原因还在查。 skynet 版本: 1.3.0 |
1.3.0 版本 socket 没有 pause/resume 机制,在两端收发不对等时,容易出问题;另外,没有对半关闭状态妥善处理。 ps. skynet 版本更迭很少破坏兼容性,所以提倡尽量用 github 最新版本,勤更新比长期大更新更少出问题。现在没有维护特定稳定版的计划。 |
抱歉因為這個問題奇怪非常
無法定位到問題在哪裡,很難作出精簡的描述
請容我用比較長的篇幅做描述 🙏
背景
1.3.0rc
release tag 的 commit在國外使用 google kubernetes engine (GKE)
在國內使用阿里雲 container kubernetes (ACK)
我們額外用 nodejs 寫了個 https proxy micro service 在另外的 container 跑
並將 server 所有 http / https request 都用 http request + 改 header host 方式
先發到這個 https proxy
GKE 及 ACK 2邊也是這樣使用,一直正常
httpc
skynet service 來集中做管理並限制並發連接數上限 256
超過的話,http request 會在該 service 排隊處理
不過正常情況下,最大並發連接多數 < 5的
httpc
service 的代碼可以直接使用 skynet built in https
去掉 nodejs proxy 的使用
並且測試通過後於
8月底
server 更新版本推出奇怪的 socket 情況就開始出現了。。。
問題
(幾乎是全個服,客服從當前世界頻截圖得出這樣的判斷)
一開始是週末才出現,嚴重時一天可以爆 ping 幾次
後來是隔天就出現一次
這裡
service 13
是我們的 httpd service做法是參考 skynet/example/simpleweb.lua
用另外端口來監聽外部 command
eg shutdown / reboot / gm 後台對 server 做操作
且這個端口跟 game client 連接端口不相同
(下個部分再解釋為什麼這 httpd service 會經常有這麼多 socket 嘗試連接)
早期的測試
ACK
有關ACK 的 loadbalancer 針對 exposed tcp port 有個 不能關掉的 health check
loadbalancer 會不斷做 health check,這解釋了 httpd service 經常都會有 socket connect
而當連接失敗被判 unhealthy,loadbalancer 就會不再 route
該端口
的 traffic 到該 instance應該就是 health check 的 connection
而出現 error 感覺
是果不是因
即 network 異常,所有 connection 都被 pause / close 了
因此 log 才會出現 error
而並非 health check error 導致 container network 被中斷
若果單純 httpd 端口出異常,理應不影響 game client 端口的
但當爆 ping 情況出現時,總有上述的 error log 相伴
所以暫時能解釋的,要麼是 skynet 框架中的 socket 處理有異常
要麼是 ACK 中 game server container 網絡有異常
單純到這裡來看,後者概率較高
因為同份代碼,在 GKE 下用相近 deployment 方式都沒有異常
和加大 unhealthy 判定的 threshold
但完全沒有改善到問題。。。
後期的測試
直到9月底左右,回想起問題是於
8月底更新
才出現背景中提到當時
改用了 built in https
由於十一假期臨近,想到什麼方式也只能試試
於是抱著測試的心態,revert 了上述改動,轉回原有的 https proxy 方式
結果竟然問題就消失了
到上週六早上 server 例行重啟前
我嘗試再改回去用 built in https
結果不到一天再次出現爆 ping 情況 ...
server log 情況同前
嚇得我慌忙又換回去 https proxy 的做法 😑
然後週日就又回復正常了
暫時結論
=> skynet 問題,ACK 未必有問題
=> skynet 沒問題,是 ACK 問題
因而無從判斷究竟是單純 skynet https 還是單純 ACK 的問題
又或是 ACK + skynet https 才會出問題。。。
並且目前也沒有進一步訊息判斷
哪一個環節
出問題請問各位有遇過這種奇怪情況嗎?
有沒有 debug 方向建議?
個人還是希望能用上 skynet https 的
這樣 server 架構可以簡潔點,去掉 nodejs https proxy 🤔
The text was updated successfully, but these errors were encountered: