消息处理性能优化之路

应全哥之邀,写一篇消息处理时遇到的坎,以供大家参考,如有不足,请多见谅。

1 项目背景

统一旅客出行项目需要处理的数据量大约每天300万条,每秒大概需要处理40条数据,在一定的服务器资源下,每条数据的处理时间,成为项目的关键。项目将通过ESB从中航信采集回来的旅客数据写入到rocketMQ,启用多线程消费消息。

2 踩过的坑

2.1 采集过来的报文数据为xml格式,将其转换为JavaBean,加密敏感数据后,将其再转换为xml数据,输出到kibana。我们使用的是javax的JAXBContext进行xml与JavaBean的转换,封装在一个工具类,转换时直接调用,处理一个消息约耗时1-2s。

2.2 为了在自己电脑测试方便,设置logback将sql以及报文信息打印在控制台以及本地文件中,部署到Rancher时未考虑到宿主机的本地容量,接收了一个星期的数据,宿主机终于崩了,崩了。。

3 解决方案

3.1 针对2.1的问题,进行代码的单步调试,发现在进行xml和JavaBean之间的转换时稍微卡了一下,遂将其耗时打印出来看下,一个转换居然耗时约600毫秒,再细看工具类,贴出代码,每次转换都要实例化JAXBContext,经测试发现此步骤十分耗时,几乎占用了转换的所有时间。

耗时的原因

全哥建议使用jackson的xml转换工具,遂进行jackson的代码和性能测试,经测试,发现jackson工具和JAXBContext一样,实例化时十分耗时,jackson更甚,约耗时3-4秒,jackson有个缺陷是xml里有的属性JavaBean里不能缺失,否则报错,还有一个更大的问题在于jackson的JavaBean与xml属性映射注解与JavaBean完全不同,要想更换工具的话需要将之前N个JavaBean注解全部改掉,工作量很大。jackson的好处也是有的,一个最好的地方在于实例化时不用指定JavaBean的Class类型,一次实例化可以通用多种数据结构类型。

经过权衡,不采用jackson,将将原来静态的XML工具类保留,以供其他模块使用。另起一个xml类专门处理报文数据,注入到springBean,实例化一次,多次使用,贴出代码。

注入springBean
xml工具专门处理Trace报文

最后的结果,是xml与JavaBean的转换在1ms左右,基本不耗时间,处理一条数据的时间大概200ms,大大提升了消息处理的性能。

最后经过全哥的建议,每条消息200ms的速度可能大部分的开销还是耗在数据库IO上,以后量太大了可能还是承受不住,优化的方向可以考虑小批量数据处理和作缓存等。

3.2 针对2.2的问题,去掉sql调试日志等控制台输出以及日志文件的输出,只将日志输出到kibana,据说kibana日志数据是写到外挂磁盘的,不会再让宿主机崩掉。

你可能感兴趣的:(消息处理性能优化之路)