Skip to content

测试

关于压力测试

为什么Turms服务端不提供压测报告

对于两个做了相同功能的Java简单函数,我们可以通过JMH轻松地测试它们各自的性能表现。但对于Turms这种稍大的项目而言,不存在这样的银弹。其复杂性主要体现在这么三个方面:

  1. Turms支持多种不同的架构,很多功能也都支持开闭。

    举例来说,我们在配置参数篇章有提到了一些用例甚至不需要做数据存储,那在其他条件相同的情况下,不做存储的应用自然吞吐量比要做存储的快。

    又比如我们在关于消息的可达性、有序性与重复性提到,Turms服务端默认关闭对100%消息必达的支持的,原因是支持100%消息必达是有代价的,它需要至少一个Redis服务端做会话级别的序列号分发工作,每发一条消息都需要请求一个序列号,其吞吐量自然是不如不支持100%消息必达的场景。

    又比如用户登陆时,服务端是否需要进行用户状态推送。对于不需要推送的场景,服务端的压力自然远小于要做推送的场景。

    又比如我们在可观察测性体系-日志篇章有讲到Turms服务端默认并推荐对用户请求进行100%的日志采样,而100%采样需要大量的I/O操作,其吞吐量自然比不过完全不进行采样的操作。

  2. 对于绝大部分的业务请求实现,Turms服务端发给MongoDB的请求绝大多数是用于用户权限校验与数据校验,只有少部分是最终执行用户指示的业务功能。比如如A用户在123群封禁B用户这一操作,就要分别对A用户、B用户与123群三者的状态做校验,全部校验通过了才会封禁B用户。不做这些校验的话,吞吐量自然就会高得多,但除了玩具项目,没有真实项目会不做校验的。

  3. Turms服务端通常会在删除某业务数据时,通过分布式事务删除相关的数据。不用分布式事务自然会比用分布式事务吞吐量高,但这就容易产生脏数据。

  4. Turms提供很多缓存功能,且未来将支持更多缓存功能。缓存是空间换时间的经典例子。以群组成员缓存为例,群组成员发送消息时,Turms服务端需要查询该群组的成员列表。那对于使用了缓存的场景,Turms服务端可以基于本地Map做查询,其吞吐量自然远高于不使用缓存而向数据库发送查询请求的场景,但不使用缓存的场景优势就在于群组列表的实时性高。

  5. 单机与分布式的压测结果也完全不一样。甚至Turms服务端还将支持:在单机部署场景,Turms服务端支持Unix Domain Socket,而无需走TCP连接。

综上,如果Turms只想写个好看的压测报告,Turms服务端可以不做任何数据存储、不保证消息必达、不做用户状态推送、不对用户请求做权限校验、数据校验与日志采样、所有业务操作都不用事务、对所有数据都进行长时间的缓存等等,其最终的吞吐量自然很高,但这样的压测报告就如同空中楼阁,没有多少真实场景会使用这么一套配置。这既是我们做中大型应用的开发人员不太愿意提供简单压测报告的原因,也是我们太不会相信其他中大型应用所提供的压测报告的原因。

对于任何应用的性能表现,我们在看它或快或慢的时候,主要是为了探究“它什么这么快/慢?”。举例来说,我们在研究JVM为什么会占这么多内存时,如果我们只看到了Java极为冗余与普遍的对象头时,我们会感叹“原来是冗余设计问题,是作者的糟糕设计,难怪占这么多内存”,但如果我们又看了JVM对Code Cache的设计与使用,我们又会感叹“原来是空间换时间,是作者的良苦用心,难怪占这么多内存”,评价方向截然不同。

归根到底就是外行看热闹,内行看门道。别说是中大型的应用,就算是小小的Java库,我们在看它的性能报告时,也不能全信。如Log4j2在其性能报告中展示了其优秀的性能表现,但如果我们读过它的源码,会发现Log4j2的实现其实并不高效,而真正把性能做到极致的其实是Turms基于Netty自研的日志实现(具体可查阅自研实现设计文档,与具体代码im.turms.server.common.logging.core.logger.AsyncLogger#doLog),只要对比了二者的源码的实现,就会发现二者在性能优化上不是一个级别的。而Turms为了方便用户看其中的门道,因此文档都写得比较详尽并且关键代码的位置也会标记出来,以方便用户自行评测Turms适不适用于自己的应用场景。

turms-performance-testing项目(预览文档)

尽管Turms没计划提供现成的压测报告,但我们近期会为Turms服务端定制一套分布式压测平台。该平台的UI展示与报告分析会由turms-admin负责,而节点管控与任务执行分别由turms-performance-testing中的Controller节点与Agent节点负责。

特别一提的是:Turms之所以能快速定制与开发众多平台,也得益于我们在基于Turms做二次开发的原因提到的“可控性。Turms项目100%开源,并对很多基础中间件进行了自研,保证了底层技术的可控,避免了项目后期发展动力不足”,因此我们做新项目不会受制于第三方依赖,动力十足。