问题:通过mq给用户发微信通知,使用的是微信的模版消息,要求该消息具有较高的时效性,当前要给5000个用户发送消息,大概30分钟才能发送完毕,预期的要求是1-2分钟.
mq的配置为15个并发消费者,通过观察mq的图形化界面发现消费者消费的速度大约为0.5个每秒,这个速度绝对是有问题.
排查问题的思路如下:
- 添加微信接口耗时统计后发现,微信接口的耗时竟然是递增的,类似于1000ms,1500ms,2000ms这样在递增,微信的接口不可能这么慢的,那一定是我们的代码哪里阻塞了
- 利用排除法,将我们自己的业务逻辑隔离起来观察发现统计处理的耗时结果是一样的,说明问题还是出在了微信的接口调用上
- 因为使用的接口是第三方提供的maven依赖,而且这个依赖的版本已经很老了,我们研究了这个库的源码,竟然有了惊人的发现
第三方依赖如下:
1 |
|
依赖中发送模版消息的源码如下:
1 |
|
1 |
|
1 |
|
起初我还以为是apache HttpClient的TCP连接池配置有什么问题呢,没想到竟然是这样,所有的线程都在串行执行. 找到了原因之后我们可以预估一下时间,(5000个用户*微信接口调用每次400ms/60)结果约等于33分钟,如果15个消费者可以并发消费那么速度可以提高15倍,时间就可以达到大约2分钟.
为了再次确认一下我们可以用jstack打出线程堆栈信息,确认一下其它的线程都在等待同步锁.(这里省略)
后记:因为这个maven依赖太老了,作者已经不维护了,转到了其它项目,我们采用了最新的依赖包,此问题在新的代码中已经得到了解决.