记录一次高并发引起的生产事故的溯源记录

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 记录一次高并发引起的生产事故的溯源记录

一次高并发抢购活动引起的生产事故的过程分析记录

1.在日志中观察到的很多dubbo超时报错

Caused by: com.alibaba.dubbo.remoting.TimeoutException: Waiting server-side response timeout. 

排查过程:数据库sql负载偏高,有接口直接查sql没有加缓存的,数据库瓶颈没办法,一个sql延迟几十毫秒,并发上来之后,就会把整体往后拖了

原因分析:

1.执行sql没有超时时间,慢就慢了,但是rpc接口和对外接口是有timeout的,单个dubbo服务是的线程池数量是有上限的,

2.每个rpc接口调用1个sql,一个sql延迟100ms,就算一个rpc调用100ms,比如这个进程给的线程数是100,那么一秒钟1000ms/200ms * 100 = 500次,也就是这个rpc接口的性能是500次/秒,恰好能够没有线程阻塞等待处理完毕,当501并发时第501个就会阻塞100ms才能进到rpc中执行代码处理,最后因为sql的超时导致了调用dubbo provider进程阻塞,继而导致rpc外层调用的consumer超时,接口返回异常。

将sql全部优化之后,发现在高并发的时候日志中还是有超时的报错,看问题还是一样的,最后排查发现是因为A服务对外提供了一个按id查唯一信息的rpc接口,B服务中有逻辑为了获取多个id的信息,循环进行多次rpc调用。所以如果B服务获取的id信息越多对应的rpc循环调用的次数也就越多,从而B的这个业务操作会更加耗时,最后导致超时问题的出现。

最后把这里优化掉,改成一次rpc调用从A服务中批量拿到全部的数据后再在B服务这里分组依次获取。

2.修复上面的问题后发现又出现了dubbo线程池满了的报错

[DUBBO] Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-ip:70882, Pool Size: 400 (active: 400, core: 400, max: 400, largest: 400), Task: 8640430 (completed: 8640030), Executor status:(isShutdown:false, isTerminated:false, isTerminating:false), in dubbo://ip:70882!, dubbo version: 2.6.2, current host: ip

dubbo线程池满了,我们通过重新设置线程池大小dubbo.provider.threads = 1000

3.调大线程池后又出现了另外一个问题,Redis连接数跑满了

org.springframework.data.redis.RedisConnectionFailureException: No reachable node in cluster; nested exception is redis.clients.jedis.exceptions.JedisNoReachableClusterNodeException: No reachable node in cluster

redis连接数跑满了,这个问题寻找了好久,最终发现是Jedis的版本问题版本问题,导致链接没有释放,连接泄露,我们通过升级jedis版本到2.10.2就解决了这个问题。

详情见这里https://blog.csdn.net/RL_LEEE/article/details/99831991

4.修复了上面的问题后,又出现了redis连接池跑满了问题

org.springframework.dao.InvalidDataAccessApiUsageException: Could not get a resource since the pool is exhausted; nested exception is redis.clients.jedis.exceptions.JedisExhaustedPoolException: Could not get a resource since the pool is exhausted

redis连接池数量太小了,我们通过增大spring.redis.jedis.pool.max-idle = 100,spring.redis.jedis.pool.max-active = 100,这两个配置重新进行了调整。

5.连接池跑满了的问题解决了,紧接着又出现了热点Key的分布不均匀的问题

redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException: Too many Cluster redirections?

这个是一个热点大Key的问题,把一个在高峰期会频繁访问的对象全部缓存成一个大对象放到redis里面,最终导致这个对象的大小超过了5MB,因为redis是单线程,每次读取5MB然后再进行传输,会导致网络io上升,并发数上来后,很容易把热点Key所在的节点给压挂。

解决方法就是将整存整取的大对象,分拆为多个小对象。可以尝试将对象分拆成几个key-value, 使用multiGet获取值,这样分拆的意义在于分拆单次操作的压力,将操作压力平摊到多个redis实例中,降低对单个redis的IO影响。这里可以参见我另外一篇文章https://www.cnblogs.com/lingyejun/p/12539694.html

6.最终,将上面的问题都解决了之后事故得以最终解决,特此记录,备忘。

如果对您有帮助,请不要忘了给翎野君点赞。


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
打赏
0
0
0
0
12
分享
相关文章
睿哲信息:网站又崩了?互联网黑天鹅事件频发,这些事企业不得不防!
2023年B站崩了两次,一次是三月份,B站手机盒电脑端当天无法查看视频详情页,到了8月份,B站又崩了一次,许多网站反馈B站图片无法加载,视频无法打开,一直在缓冲。无独有偶,3月份腾讯旗下的微信和QQ登也出现了业务崩溃,微信语音对话、朋友圈、微信支付、QQ文件传输、QQ空间登多个功能都无法启用。
171 3
|
7月前
|
应急响应处置现场流程 - 文件痕迹排查笔记07
应急响应处置现场流程 - 文件痕迹排查笔记07
120 8
稳定性摸排问题之数据对账的目的是什么
稳定性摸排问题之数据对账的目的是什么
|
10月前
|
哪些因素影响网络交易商品(服务)的安全性?
【5月更文挑战第14天】哪些因素影响网络交易商品(服务)的安全性?
76 0
|
10月前
|
记录一次网络安全应急响应溯源过程
网络安全应急响应是一种组织在发生网络安全事件时采取的行动,旨在迅速应对和缓解潜在的威胁,最大程度地减少损失并恢复正常的网络运行状态
241 0
时间溯源的系统设计思路
用不可变的Event Log替代状态表 CRUD。从而实现更好的可靠性,可扩展性与可维护性。我认为是 Application/Schema Design 的一种 paradigm shift
95 0
面试官问你:日亿万级请求日志收集如何不影响主业务?你怎么回复
数据收集 上篇详细讨论了写缓存的架构解决方案,它虽然可以减少数据库写操作的压力,但也存在一些不足。比如需要长期高频插入数据时,这个方案就无法满足,接下来将围绕这个问题逐步提出解决方案。