做压力测试时,分配的内存是 2.5G,在 1 万个 websocket 连接的情况下,我用 base64 方式广播了一个图片(数据包大小大概是 300K)。每次广播都会引起一个 Gateway 进程的意外终止,多次试验后,出现了 65280、11、9 等终止状态码,65280 貌似是爆内存的意思,另两个是什么意思?
另外,需要的内存量是不是大约是 连接数 乘以 数据包大小?
下面是广播前的状态
---------------------------------------GLOBAL STATUS--------------------------------------------
Workerman version:3.4.5 PHP version:5.6.30
start time:2017-10-12 11:36:01 run 0 days 0 hours
load average: 1.01, 2, 1 event-loop:\Workerman\Events\Event
3 workers 9 processes
worker_name exit_status exit_count
YourAppBusinessWorker 0 0
YourAppGateway 0 0
Register 0 0
---------------------------------------PROCESS STATUS-------------------------------------------
pid memory listening worker_name connections total_request send_fail throw_exception
28540 2M none YourAppBusinessWorker 5 2535 0 0
28539 2M none YourAppBusinessWorker 5 2578 0 0
28538 2M none YourAppBusinessWorker 5 2433 0 0
28542 7.25M websocket://0.0.0.0:8282 YourAppGateway 863 10006 0 0
28546 1.25M text://0.0.0.0:1238 Register 8 10 0 0
28541 2M none YourAppBusinessWorker 5 2473 0 0
28543 7.5M websocket://0.0.0.0:8282 YourAppGateway 912 10006 0 0
28545 43.75M websocket://0.0.0.0:8282 YourAppGateway 5859 10006 0 0
28544 18M websocket://0.0.0.0:8282 YourAppGateway 2386 10006 0 0
http://doc.workerman.net/315185
部分退出码在意义在手册里有写
65280 你这里应该是内存超过php.ini限制,导致致命错误
11 是有coredump,一般是php的bug或者某个php扩展的bug导致
9 是进程被kill掉,一般发生在 restart/stop命令时。由于进程繁忙,进程收到重启或者停止命令后在规定时间内(1秒左右)没有执行退出,主进程会给他发送kill命令,强制杀死(产生9退出码),用来快速完成重启或者停止操作。
每个socket连接操作系统都会给其分配发送缓冲区,当给1万客户端广播大数据时(例如300k),瞬间最差情况会产生1W*300k约3G数据在缓冲区,所以php进程会占用大量的内存,超过php.ini限制(默认128M),导致致命错误(65280退出码)。如果网络流畅带宽足够(需要万兆带宽),网卡是万兆网卡,并且客户端接收速度够快, 则会缓解很多,但是也会有不小的内存占用。服务器瞬间发出去3G的数据还是很考验服务器的性能的,网卡和带宽都必须万兆了,cpu拍脑袋也得至少8核 16核甚至更高吧。
谢谢啦
想问下,如果放宽时间上的要求以减少内存需求,把数据分好几批发送给客户端,有没有好的处理方式?
我能想到的是,把各客户端加入到不同的 group,然后用 定时器 以某个时间间隔调用
sendToGroup