1、Gateway隔离问题导致CPU高负载
多个服务请求报错。查看监控,一个服务产生大量请求,占用了gateway大部分CPU资源,其他服务请求占用很少,其他服务经常报错。
添加机器,gateway进行隔离。
每个模块服务应当隔离,各占固定的gateway资源,相互不影响。
2、Gateway服务报错
下发单子时,经常会有一些单子下发不下来,业务日志也没有。查看gateway日志时,发现报错信息。搜索资料,nacos的请求数收到限制,默认100并发,后面改了配置增加到1000。
参考资料后确定大概率是nacos中网关的hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests配置未设置好
gateway的请求数收到限制,默认100并发,后面改了配置增加到1000。
参考资料:
1、 SpringCloud-Hystrix 报 could not acquire a semaphore for execution
3、mysql死锁问题
业务反馈某个接口一直报错,查看日志发现数据库死锁(Deadlock found when trying to get lock; try restarting transaction)。
页面excel导入数据,发现很多失败的。排查结果是mq消费者里面调feign,feign熔断了,于是把消费者放到feign对应的接口所在的项目里,进行本地消费。然后发现存在很多数据库死锁。
排查步骤:
1、使用SHOW ENGINE INNODB STATUS;查询mysql最近一次死锁日志,LATEST DETECTED DEADLOCK块,查看发生死锁的sql
2、去代码里找到执行此段sql的位置
3、在代码里附近找到操作发生死锁sql的同一张表的其他sql
4、查看日志里发生死锁的索引,及其构成
5、对比死锁信息及死锁附近sql进行分析
行锁的兼容矩阵
| Gap | Insert Intention | Record | Next-Key |
Gap | 兼容 | 兼容 | 兼容 | 兼容 |
Insert Intention | 冲突 | 兼容 | 兼容 | 冲突 |
Record | 兼容 | 兼容 | 冲突 | 冲突 |
Next-Key | 兼容 | 兼容 | 冲突 | 冲突 |
表注:横向是已经持有的锁,纵向是正在请求的锁。
死锁产生的必要条件有:1、临界资源 2、循环等待 3、不可剥夺 4、请求并保持 破坏其中一个均可打破死锁。
通过日志分析,事务1获得并持有间隙锁gap1,事务2获得并持有间隙锁gap2,此时事务1执行插入操作,插入的数据在事务2所持有的间隙锁gap2中间,于是等待事务2释放间隙锁gap2,此时事务2执行到了插入操作,同样插入的数据在事务1持有的gap1中间,事务1与事务2形成互相等待对方释放资源,发生死锁。mysql通过策略对事务2进行回滚释放gap2,此时事务1获取到了资源完成了插入操作。
对附近sql进行分析
附近sql就只有这个删除,mysql加锁是对索引进行加锁的,通过explain对sql的执行计划进行分析,删除走的索引就是产生死锁的索引
由于delete语句中的条件无法唯一锁定一条记录,因此会加上间隙锁,与日志分析一致
因此要解决这个问题,去掉间隙锁的占用即可,于是采用先根据条件查询出id,根据id去删除,将间隙锁降级为行锁,减少临界资源的占用即可。
经实际验证,改了以后,批量导入,未产生死锁。