做 IM 很有挑战性的事,我认为也是很有意义的一件事,只有对系统架构、网络、系统内核等等都要有一些了解才能做出一个高可用高性能的 IM 系统。
当时设计参考了
https://github.com/Terry-Mao/goim,简化了 Logic,增加了离线消息持久化,最终性能比毛大佬 bench 差一丢丢,调整内核参数和各级缓存之后,每个用户不到 5K 内存开销,1H1G 的阿里云承载 8 万用户。
消息网关别用 python (当然你有 6 倍以上的硬件预算的话洒洒水啦。
tornado 真不太行,高并发干不过 async,做 web 又不像其他线程模型的框架什么东西都能往里放,放到现在来看更像是教科书级的东西。正好去年我也做了一个 im 项目,调研了下 ws 的实现性能差异。总之 IO 密集型的东西最好还是了解下 go 或者 java,c 之流。
bench i7 2600k 8G @
2coretarget i7 2600k 8G @
1core-s 客户端数量、每秒 echo1 下、测试 30 秒
同时可以参考下
https://github.com/uNetworking/uWebSocketstornado
bench -a 0.0.0.0:8888 -s 1000 -i 1 -d 30
Total Sent: 29182 , Total Received: 29182 , Bytes Sent 817096 , Bytes Received: 817096 , Average RTT: 8.147407ms , Connection Error: 0 , Write Error: 0 , Read Error: 0 , Message Mismatch: 0
bench -a 0.0.0.0:8888 -s 2000 -i 1 -d 30
Total Sent: 52960 , Total Received: 52960 , Bytes Sent 1482880 , Bytes Received: 1482880 , Average RTT: 77.962957ms , Connection Error: 0 , Write Error: 0 , Read Error: 0 , Message Mismatch: 0
bench -a 0.0.0.0:8888 -s 4000 -i 1 -d 30
2018/04/14 22:35:58 Total Sent: 48032 , Total Received: 48032 , Bytes Sent 1344896 , Bytes Received: 1344896 , Average RTT: 1.004519955s , Connection Error: 464 , Write Error: 0 , Read Error: 0 , Message Mismatch: 0
asynicio
bench -a 0.0.0.0:8888 -s 2000 -i 1 -d 30
Total Sent: 57703 , Total Received: 57703 , Bytes Sent 1615684 , Bytes Received: 1615684 , Average RTT: 11.979018ms , Connection Error: 0 , Write Error: 0 , Read Error: 0 , Message Mismatch: 0
bench -a 0.0.0.0:8888 -s 4000 -i 1 -d 30
Total Sent: 88348 , Total Received: 88348 , Bytes Sent 2473744 , Bytes Received: 2473744 , Average RTT: 90.734413ms , Connection Error: 492 , Write Error: 0 , Read Error: 0 , Message Mismatch: 0
gorilla
bench -a 0.0.0.0:8888 -s 8000 -i 1 -d 30
Total Sent: 231759 , Total Received: 231759 , Bytes Sent 6489252 , Bytes Received: 6489252 , Average RTT: 17.459239ms , Connection Error: 0 , Write Error: 0 , Read Error: 0 , Message Mismatch: 0
bench -a 0.0.0.0:8888 -s 16000 -i 1 -d 30
Total Sent: 420935 , Total Received: 420935 , Bytes Sent 11786180 , Bytes Received: 11786180 , Average RTT: 36.99979ms , Connection Error: 0 , Write Error: 0 , Read Error: 0 , Message Mismatch: 0
bench -a 0.0.0.0:8888 -s 20000 -i 1 -d 30
Total Sent: 486466 , Total Received: 486466 , Bytes Sent 13621048 , Bytes Received: 13621048 , Average RTT: 79.126184ms , Connection Error: 1059 , Write Error: 0 , Read Error: 0 , Message Mismatch: 0
openresty
bench -a 0.0.0.0:8888 -s 20000 -i 1 -d 30
Total Sent: 559234 , Total Received: 559234 , Bytes Sent 15658552 , Bytes Received: 15658552 , Average RTT: 20.53849ms , Connection Error: 0 , Write Error: 0 , Read Error: 0 , Message Mismatch: 0
bench -a 0.0.0.0:8888 -s 30000 -i 1 -d 30
Total Sent: 485620 , Total Received: 485620 , Bytes Sent 13597360 , Bytes Received: 13597220 , Average RTT: 193.790583ms , Connection Error: 1769 , Write Error: 0 , Read Error: 0 , Message Mismatch: 5
uWebSockets
bench -a 0.0.0.0:8888 -s 20000 -i 1 -d 30
Total Sent: 562872 , Total Received: 562872 , Bytes Sent 15760416 , Bytes Received: 15760416 , Average RTT: 15.233624ms , Connection Error: 0 , Write Error: 0 , Read Error: 0 , Message Mismatch: 0
bench -a 0.0.0.0:8888 -s 30000 -i 1 -d 30
Total Sent: 464767 , Total Received: 464767 , Bytes Sent 13013476 , Bytes Received: 13013476 , Average RTT: 12.200729ms , Connection Error: 13107 , Write Error: 0 , Read Error: 0 , Message Mismatch: 0
python 当然写起来最舒服就是慢! go 则是很好的选择 channel goroutine 语言层面控制力非常给力,openresty 简直让 nginx 为所欲为,lua 写起来也非常非常爽,甚至我还在上面写 api,一旦要做 co 或者 worker 之间 sync、event、lock、share 就有点智障了。。