线程池异步化技巧

微服务中间件数据库

互联网红包大战元年 ,笔者加入艺龙旅行网,负责的第一个重要系统就是:红包系统

这篇文章,笔者分享艺龙红包领取接口频繁超时,如何巧用线程池异步解决超时问题 。

picture.image

1 系统架构 & 接口事故

picture.image

如图,用户登录艺龙 APP 后,艺龙 APP 会自动调用领取红包的接口 。

红包服务会查询该用户是否满足领取红包的条件,若满足条件,则发送消息到 RabbitMQ , 发送成功后,领取接口返回响应值给前端。

用户服务作为消费者,异步消费 MQ 的消息,将红包虚拟金额保存到用户余额体系里。

从整体流程来看,还是非常简单的,伪代码如下:

picture.image

但笔者刚加入团队时,APP 研发团队的总监经常投诉我们,因为我们的领取接口每隔一段时间后就会超时,重启红包活动后,接口才恢复正常。

首先查看服务器日志,发现日志异常集中于第三步,即:发送消息到 RabbitMQ 。

为什么发送消息到 RabbitMQ 会失败呢 ?

笔者首先想到的是:Linux netstat 命令查看 RabbitMQ 连接状况

2 Linux netstat 命令查看 RabbitMQ 连接

netstat 可以查看服务器当前端口列表及指定端口的连接状态等,参数如下:

picture.image

常用命令:

1 、查看当前所有 tcp 端口

picture.image

2 、查看当前所有 udp 端口

picture.image

3 、显示系统所有端口

picture.image

假如想查看某个应用对应的连接,可以通过 grep pid 来实现,如下图:

picture.image

当笔者在生产环境使用 netstat 命令查看红包服务的连接,发现 RabbitMQ 连接的特别多 ,基本达到了本地的最大句柄数。

于是,笔者开始怀疑 RabbitMQ SDK 封装有问题,我们来一探究竟。

3 RabbitMQ SDK 封装问题

picture.image

如上图,RabbitMQ 工具类发送消息时,首先看本地缓存 longConnection 是否有效,若有效,则直接复用该连接,若连接失效,则重新创建连接,然后通过该连接发送消息。

看到这里,似乎也没有问题呀 ?

但高并发场景下,请求量非常高,确有隐藏的风险,表现在如下两点:

1、获取连接时,通过对象的属性 longConnection 来判断是否过期 , 但我们知道对于多线程来讲,在没有加锁的情况下,并不靠谱。

picture.image

2、创建连接时,极大可能存在并发问题,导致会重复创建多个连接,而且重复的连接并没有引用。

综上,使用架构封装的 RabbitMQ. SDK 在发送消息时,容易产生连接泄露的问题。

当连接数占满之后,再次发送消息时,由于长时间获取不到连接,抛出异常。

那么如何快速解决呢 ?

首先,我们想到的是:让架构团队快速修复 SDK 的 BUG ,但是这个需求时间(研发和测试),于是笔者想到的是线程池异步技巧 来解决这个问题。

4 线程池异步技巧

当 APP 发起领取红包接口后,红包服务开启单独的线程处理该请求,然后直接将响应结果直接返回给前端。

picture.image

伪代码如下:

picture.image

首先,我们定义了一个单线程,领取接口接收到请求后,调用线程池的 execute 方法,直接将响应结果返回给前端,线程池会异步的处理领取红包流程 。

这么做有两点好处:

1、将领取的流程异步化,可以减少领取接口的阻塞,让 Tomcat 线程可以非常顺畅的运行 ;

2、因为是单线程处理领取流程,可以规避 RabbitMQ SDK 连接泄露的 BUG ,同时也可以满足业务需求。

5 总结

艺龙红包 RabbitMQ SDK 的 连接泄漏 BUG 非常隐蔽,笔者通过 netstat 命令定位到红包服务的 RabbitMQ 连接发生了泄露 。

架构团队封装的 RabbitMQ SDK 有两种方案来解决:

1、创建连接时完善加锁的操作 ;

2、使用 commons-pool 这样的框架来创建连接池,提高可维护性。

最后,因为时间的关系,笔者要快速解决问题,采用了异步线程池的模式 ,单线程处理领取流程,可以规避 RabbitMQ SDK 连接泄露的 BUG 。

后欢迎加入苏三的星球,你将获得:智能代码审查AI Agent、智能天气播报AI Agent、SaaS点餐系统(DDD+多租户)、100万QPS短链系统(超过并发)、复杂的商城微服务系统(分布式)、苏三商城系统、苏三AI项目、刷题吧小程序、秒杀系统、码猿简历网站、代码生成工具等11个项目的源代码、开发教程和技术答疑。 系统设计、性能优化、技术选型、底层原理、Spring源码解读、工作经验分享、痛点问题、面试八股文等多个优质专栏。

还有1V1免费修改简历、技术答疑、职业规划、送书活动、技术交流。

扫描下方二维码,可以加入星球:

picture.image

数量有限,先到先得。 目前星球已经更新了6100+篇优质内容,还在持续爆肝中.....

星球已经被官方推荐了3次,收到了小伙伴们的一致好评。戳我加入学习,已有2200+小伙伴加入学习

此外,请加入星球的小伙伴,务必要加一下苏三的微信(备注:星球),我会拉你VIP群,群里有很多专属福利。

picture.image

0
0
0
0
关于作者

文章

0

获赞

0

收藏

0

相关资源
KubeZoo: 轻量级 Kubernetes 多租户方案探索与实践
伴随云原生技术的发展,多个租户共享 Kubernetes 集群资源的业务需求应运而生,社区现有方案各有侧重,但是在海量小租户的场景下仍然存在改进空间。本次分享对现有多租户方案进行了总结和对比,然后提出一种基于协议转换的轻量级 Kubernetes 网关服务:KubeZoo,该方案能够显著降低多租户控制面带来的资源和运维成本,同时提供安全可靠的租户隔离性。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论