记一次解决线上压力的过程
条评论业务描述:用户扫二维码,关注公众号后推送微信图文消息。用户分享自己的二维码拉取下线关注公众号。拉满N个后,可获得低价商品购买权。这里面涉及:新建账户、修改账户、关系绑定、获取微信鉴权()
问题抛出:生产环境,用户反馈,无法收到微信推送的消息,或者等了很久都没有收到消息,商城访问速度慢。
云里雾里的解决:
研发到我这里,查看日志。日志提供的信息有限,无法判断问题所在。通过在线监控各项指标,发现网络带宽和数据库服务器的机器资源占满。于是,紧急升级带宽和服务器配置。问题有所缓解但是没有得到解决。
于是,在java源代码里增加日志代码,在线查看log。发现线程配置使用的是默认,于是增加配置(包括jdbc连接数、spring的多线程配置)。和消息无关的几个服务,都在硬件升级和jdbc扩容后无压力。
监控日志过程中可以观察到(打印出了当前active的线程数,maxPoolSize的线程数),在服务刚启动的时候,线程的创建和销毁速度正常,active慢慢增加到50左右,出现严重的线程等待。也就是多不管corePoolSize线程数设置多少(线程慢慢增大到设置的200—->500—->1000),达到以后,销毁速度是没有什么改善的。也就是说生产速度比消费速度快很多(约5:1)的关系。
1 | <!-- 核心线程数 --> |
日志,发现部分日志之间的时间间隔很长,15s以上。
在有限日志的情况下,增加日志密度,重新发布。每一个业务执行过程都打标记日志。
最后定位到性能瓶颈2个地方:
1、微信鉴权,取用户微信昵称头像
2、发送微信文本消息
暂未解决:
1、高流量下的数据库死锁
2、高流量下的数据错误
基于以上内容,临时处理为:
1、去掉创建用户过程中的取用户微信昵称头像动作,仅取用户唯一标识openid
2、发送微信文本消息的动作,改为异步方式。
完成以上改造后,日志监控active的线程数稳定在10左右。恢复正常,用户体验得到改善。
本次处理过程全程参与,虽然只是提供一些支持(用我电脑,协助查日志,参与分析,发布代码),但是有所体会。如下:
1、计算线程处理是顺序的,所以一个任务线放入一个线程中处理,子任务的任何一个性能瓶颈都会影响这个任务线程的处理性能;
2、没有强逻辑关联的任务,可以异步处理。比如发消息交给active-mq。
3、定位性能瓶颈光靠猜测是没有实际意义的,需要足够多的log日志去定位和判断。
4、核心和重点业务性能测试要提前做。