本报告次要分为两局部,性能测试和音讯可靠性测试。前者次要关注吞吐,延时,同时在线用户等,即通常所说的性能指标。后者次要模仿实在环境(比方离线,在线,弱网)音讯通道的可靠性。
先说论断,对于容量和性能:
性能及容量总结
服务器资源: 8核16G内存, 6个机械磁盘,每个磁盘100G, 用于mongo分片,10MB带宽。
容量:用户容量10万以上,音讯条数10亿条。
性能评估:同时在线用户10万,每秒钟发送音讯900条,音讯延时1秒(从发送者收回音讯到接管到音讯)
可靠性总结
启动sdk,模仿50个用户在线、离线状况,音讯可靠性100%。
发送10万音讯,有3条失败,其余音讯都能被对方准确收到,并胜利落地本地db。对于失败的3条音讯,接管方的确没有收到,零碎音讯是统一的。
我的项目介绍
OpenIM是由前微信技术专家打造的开源的即时通讯组件。Open-IM包含IM服务端和客户端SDK,是一套整体的解决方案,代码开源,所有可控,
github地址:https://github.com/OpenIMSDK/...
开发者核心: https://doc.rentsoft.cn/#/
在单机的状况下,模仿线上用户发消息流程,在线用户量和音讯量达到一定量级后,零碎CPU、内存、磁盘占用、以及音讯时延状况。以确定用户群体达到一定量级后,对服务器资源的事后评估。本次测试并不极限测试,一是因为生产环境原本都会有用户量和音讯量的限度,二是因为OpenIM的音讯模型,音讯发送首先都会通过websocket入库kafka,实践上发送音讯的写入性能是两者的组合,而音讯发送的真正瓶颈理论在mongodb的随机读写。
测试过程
服务器资源: 腾讯云主机(香港)1台:linux Ubuntu 18.04.4零碎,4核8G内存,单块机械硬盘。5Mb带宽。
测试条件:去掉音讯入库mysql(因mysql仅用于治理后盾,不影响线上用户服务)。日志级别调整为4或更低。kafka设置2个分区,msg_transfer 2个。
测试流程:1个客户端(成都,window pc,4核16G内存)启动1万个协程,模仿用户与服务器建设websocket长连贯,间隔时间为随机50-100秒之间。两个客户端共模仿2万用户同时在线,发送音讯,察看音讯流转各个模块的解决能力,共计2500万条音讯,察看零碎内存、磁盘资源应用状况。
测试论断和剖析
| 关注指标 | 测试后果 |
| 同时在线人数 | 20000个 |
| 网关接管音讯速度 | 150条/s(因为瓶颈不在此,成心管制发送速度,以确保kafka能被疾速生产入mongodb) |
| mongodb解决写入 | 300条/s (收件箱模型,导致音讯一拆为二) |
| CPU使用率 | 约50% |
| 内存使用率 | 约4G(mongo内存限度2G,因为每个文档存储5k条音讯,理论理论索引量很小。 redis只存了用户seq映射关系,根本不占内存) |
| 发送音讯响应时长 | 均匀70毫秒 |
| 发送过程时延 | 平约1秒 |
| 磁盘空间 | mongo中5000万条音讯占用10G磁盘,因为一拆为二的缘故,mongo的50000万条音讯,理论为2500万条音讯。<br/> |
mongodb数据状况
redis数据状况
磁盘状态
<img src="C:\Users\Administrator\Desktop\OpenIM\官网相干\技术文章\OpenIM测试报告\磁盘.png" alt="磁盘" style="zoom:50%;" />
资源占用剖析
(1)redis内存耗费极小,一个用户一条数据(包含token和seq),和用户量成正比,3万用户占用几十M内存。
(2)mongodb如果去掉cache,内存耗费极小,每个document寄存5000条音讯,与用户量和音讯量成正比,3万用户,2500万音讯,索引才950K(更好的形式查看mongo耗费cache之外的内存)
(3)2500万音讯,磁盘空间占用10G。
(4)每秒钟150条音讯,cpu整体占用50%,即2核。
性能剖析
(1)性能瓶颈在mongodb写入操作,1条音讯,须要依照发送者和接收者拆分2次,mongodb写入2次,将来能够针对mongodb读写进一步优化。
(2)对于cpu耗费较大的模块,将来做一次整体优化。
(3)性能很安稳,不会随着数据量减少而升高。机械磁盘iops 达到200根本达到了设施的极限
单机性能预估
服务器资源: 8核16G内存, 6个磁盘,每个磁盘100G, 用于mongo分片,10MB带宽。
性能评估:同时在线用户10万,每秒钟发送音讯900条,音讯延时1秒(从发送者收回音讯到接管到音讯)
| 模块 | 性能状况 | 阐明 |
| msg_gateway | 部署多个 | ,同时在线5万*2=10万 |
| mongodb | 6分片,每个磁盘对应一个分片 | 1800条/每秒音讯入库 |
| CPU使用率 | 约100% | 须要优化模块 缩小cpu耗费 |
| 内存使用率 | 小于8G(mongo内存限度2G) | 如果内存充裕能够减少mongodb的cache大小 |
| 发送音讯响应时长 | 均匀70ms | |
| 发送过程时延 | 平约1s | 从发送者到接收者 |
| 10亿条音讯,磁盘空间 | 占用40*100G磁盘,每个磁盘大略占用70G空间 | 对于群聊属于扩散写,磁盘耗费较大。整体要思考磁盘空间充裕 |
将来工作优化
(1)mongo集群部署,反对上亿用户同时在线,千亿级音讯;
(2)简化集群部署;
(3)数据备份、复原工具;
以上次要对服务端性能做了一个大抵测试,但一套残缺的IM解决方案,不仅仅是服务端的工作。实际上,客户端重要性毋庸置疑,具体包含如何利用seq和服务端同步音讯,如果保障音讯收发的时序,如何回调客户端(会话扭转、新增,新音讯),音讯落地本地db,seq同步,音讯推拉如何联合以确保音讯收发可靠性。
音讯可达率(可靠性)测试
相比于性能测试,实际上,音讯的可达性(可靠性)更为重要。所以,咱们在做性能测试的同时,也要对音讯的可达性(可靠性)进行测试,如果不能保障音讯收发的正确性,再高的性能也是徒劳。本文重点总结对于OpenIM对于音讯可达性测试的计划、过程以及后果。先说论断,OpenIM音讯可达率100%,大家能够放心使用在生产环境中。seq对齐和同步机制,保障了OpenIM的音讯可达性是业界当先的。
音讯可达性(可靠性)的定义
IM音讯零碎的可靠性,通常就是指音讯投递的可靠性,即咱们常常听到的“音讯必达”,通常用音讯的不失落和不反复两个技术指标来示意。确保音讯被发送后,能被接收者收到。因为网络环境的复杂性,以及用户在线的不确定性,音讯的可靠性(不失落、不反复)无疑是IM零碎的外围指标,也是IM零碎实现中的难点之一。总体来说,IM零碎的音讯“可靠性”,通常就是指聊天音讯投递的可靠性(精确的说,这个“音讯”是狭义的,因为还存用户看不见的各种指令和告诉,包含但不限于进群退群告诉、好友增加告诉等,为了不便形容,统称“音讯”)。
从音讯发送者和接收者用户行为来讲,音讯“可靠性”应该分为以下几种状况:
(1)发送失败,对于这种状况IM零碎必须要感知到,明确反馈发送方。如果此音讯没有发送胜利,发送方能够抉择重试或者稍后再试。
(2)发送胜利,如果接管方处在“在线”状态,应该立刻收到此音讯。如果接管方处在“离线”状态不能收到音讯,一旦上线则立即收到音讯。
(3)音讯不能反复,用数学术语示意:“有且仅有这条音讯”,如果反复了,可能表白的意思就变了。 总之,一个商用 IM零碎,必须蕴含音讯“可靠性”逻辑,能力谈根本可用,这是IM零碎最根本也是最外围的逻辑。
模仿场景&测试计划
互联网实在场景简单,但客户端大体能够分为两种状况:(1)发送音讯时,接管方在线,能收到音讯;(2)发送音讯时接管方不在线,登录后能收到离线音讯。咱们用测试程序模仿互联网客户端各种场景,依照登录、发送音讯、接管音讯的状况,把测试客户端分为以下2种类型:
(1)启动测试时离线,随机sleep 0-60 秒后登录,发送音讯,且接管音讯
(2)启动测试时离线,随机sleep 0-60 秒后登录,不发送音讯,只接管音讯
test.ReliabilityTest(oneClientSendMsgNum, intervalSleepMs, imIP, randSleepMaxSecond, testClientNum)
在理论测试中共计50个客户端,约25个(50%概率)客户端不发送只接管音讯,约25个(50%概率)客户端发送且接管音讯 。
发送模式:每个客户端随机抉择其余客户端作为音讯接收者;
测试预期: 每一条发送胜利的MsgID,都能在接管的音讯列表中找到,同样,每一条接管到的MsgID,都能在发送胜利的音讯列表中找到。
具体做法:(1)音讯发送胜利后,通过OnSuccess回调,记录MsgID; 收到新音讯后回调OnRecvNewMessage,记录MsgID;(2)周期性比照两个音讯列表,确认是否完全一致;
测试后果
| 发送音讯客户端 | 接管音讯客户端 | 预设发送音讯总量 | 发送胜利条数 | 发送失败条数 | 接管音讯条数 | |
| 25个 | 50个 | 100000条 | 99997 | 3 | 99997 | |
发送数据100000条,其中失败3条,9999997条胜利,接管方胜利接管9999997条音讯(接管方胜利接管到音讯,写入本地db,并能触发音讯回调)
每一条发送胜利的音讯,对方都能精确接管到,无论接管方在音讯发送时的登录状态是在线还是离线。
每一条发送失败的音讯,对方都不会收到。
测试程序
main/main.gointervalSleepMs := 1randSleepMaxSecond := 30imIP := "127.0.0.1" //OpenIM iponeClientSendMsgNum := 4000 //每个客户端发送的音讯条数testClientNum := 50 //同时启动压测客户端数量func main() {reliabilityTest()}
注意事项:
(1)管制压力,因为sdk须要写本地db,客户端会成为压力瓶颈。
(2)压测客户端日志会影响测试性能。
老本比照
此表格是某IM云平台的价格,如果依照10万月活,存储三年音讯来算,大略每年须要领取15万。而采纳OpenIM只须要洽购云主机,每年老本约0.8万。