我用go协程并发2000进等压力测试的时候,可以正常连接上,但是,2500的时候就会失败,看服务状态,又是正常的。但是用其他工具再去进行连接请求就会失败。
同时 Gateway::getAllClientIdList() 在超过1000并发的时候,可以正常获取,2000并发的时候,获取不到列表。但是 Gateway::getAllClientIdCount() 在2000并发的时候可以获取数字,2500的失败的时候获取的数字是0.
以下是成功的时候,查看到的状态信息:
以下是失败的时候,查看到的状态信息:
我看gateway 进程连接数是1000左右,两个进程就2000出头,是不是跟这个限制有关?我看文档里面有提到:每个Gateway进程可以轻松处理5000-10000连接的请求转发。 似乎我这个进程是缩水到每到个进程 1000 个连接数上线
我看对应进程的限制: cat /proc/322938/limits 里面的 Max open files 是65535。应该不是这里的配置问题。
PS: 我目前把进程数开到16个,连接数10000是相对正常的,15000,就也很容易出问题,同时命令行会打印错误信息:
foreach() argument must be of type array|object, bool given in /home/www/gatewayWorker/vendor/workerman/gateway-worker/src/Lib/Gateway.php on line 504
这是go脚本的代码,每个协程的代码,外层就是简单的循环X次
func newThread(uid string) {
defer wg.Done()
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
u := url.URL{Scheme: "ws", Host: "api-test.ai.cc", Path: "/ws"}
log.Printf("connecting to %s", u.String())
// 连接 websocket
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("dial:", err)
}
defer c.Close()
// 绑定用户
done := make(chan struct{})
// 读取服务器消息
go func() {
defer close(done)
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
return
}
log.Printf("recv: %s", message)
}
}()
// 定时器,隔50秒向服务器发送 ping 消息
ticker := time.NewTicker(time.Second * 50)
defer ticker.Stop()
for {
select {
case <-done:
return
case <-ticker.C: // 定时器到时间 发送消息
err := c.WriteMessage(websocket.TextMessage, []byte(`{"action":"ping"}`))
if err != nil {
log.Println("write:", err)
return
}
case <-interrupt:
log.Println("interrupt")
return
}
}
}
go 脚本并发太高时,会报错并退出
dial:read tcp 192.168.1.119:61404->192.168.1.231:80: i/o timeout
操作系统:almalinux 9.4
nginx: 1.20 , nginx 单进程的连接数已经配置够高了
worker_connections 65535;
Event-Loop: Select
https://www.workerman.net/doc/workerman/appendices/kernel-optimization.html