处理步骤:
- 止血:遇到问题先不要着急排查原因,首先进行止血,防止系统全面崩溃,也避免造成更多请求失败。一般的止血方案包括
- 扩容:应用集群扩容、redis扩容、mysql在线扩容、kafka分区扩容等。
- 重启:如果是单台机器出现问题,可以重启故障机器,注意不可以大批量一次性重启,多台机器必须分批次重启。
- 排查定位:要快速定位接口的哪一个环节比较慢,可以使用APM工具快速定位,常见工具:skywalking、pinpoint、cat、zipkin。如果没有接入APM,可以在生产环境安装阿里的Arthas,利用trace命令打印接口内部每一步执行耗时,定位能力比较粗糙,遇到方法调用只能一层一层往下找。
优化方案:
- 数据库慢sql:数据库问题可以基于实际情况按下面这些方法去解决,锁表慢sql可以先kill、explain执行计划分析、没加索引就增加索引、索引失效就优化sql、联表查询尽量小表驱动大表、多表联查就分多次查询、查询字段尽量少不用select *、表数据太大就做分库分表或者使用其他类型数据库如ES。
- 调用第三方接口慢:针对自身RT需求向第三方接口提出降RT要求、集成sentinel或hystrix限流熔断框架防止被对方拖垮、写接口可以考虑异步化、循环操作改为单次批量操作减少IO、缓存查询结果。
- redis慢:是否有rekey、大key。热key:上本地缓存、缓存集群进行自主扩容、异步主动更新缓存、bigkey缓存默认值如null避免穿透。大key:拆分大key,或者采用set结构的sismember等方法判断。
- 消息中间件慢:生产端慢:使用阻塞队列接收、批量发消息。消费端慢:扩分区、增加消费节点、增加消费线程、批量消费批量写库。
- 程序逻辑慢:大数据量循环改线程池、无效数据提前过滤、同步改为异步(如使用CompletableFuture异步非阻塞,并行调用RPC接口).
处理步骤:
- 止血:同上面一样,扩容和重启,服务器扩容可以考虑机器置换增大CPU和内存、调整jvm参数等。如果可以快速确认是否线上版本发布引起,如果是,立刻暂停发布,回滚版本。
- 排查问题:dump线程运行情况,定位具体代码位置。
解决方案:
- 新业务导致:暂停新业务流量。
- GC导致:优化对象使用、调整jvm参数、更改垃圾回收器。
- 硬件问题:升级硬件设施。
处理步骤:
- kill锁表线程SQL:找DBAkill锁表的SQL。
- kill慢sql线程:kill影响数据库执行的慢SQL。
- 继续观察数据库监控,如果还是不行需要针对性地关停慢SQL的业务。
解决方案:
- 分析慢sql:拿到导致数据库cpu飙高的SQL,分析是否是慢SQL。
- 加索引、优化慢sql:如果是慢SQL,需要分析是否是未加索引导致,如果缺索引则加索引。如果是索引失效,则需要优化SQL的写法。
- 优化程序:如果是QPS过高导致,则可以优化程序,比如将多个单次执行改为一次批量执行、将大批量一次执行改成小批量多次执行。
处理步骤:
- 分析消息积压原因,可分为三种情况:消息生产端流量过高、broker端分区太少、消费者端消费过慢
解决方案:
- 生产过快:开关限速降级+消息补偿,遇到丢失的消息需要有补偿机制;
- broker端:如果broker分区数比消费者数量少,扩容分区数,如果broker分区8,消费者16,则可扩容8个分区。
- 消费过慢:如果broker分区数比消费者数量多,扩容消费者数,如果broker分区16,消费者10,则可扩容6个消费者。提高消费者程序执行效率,通过升级硬件、优化代码等方式。