Spring Event 别瞎用!从我司的悲剧中,我总结了6 条最佳实践

本文从实际生产环境中遇到的问题出发,总结了使用Spring Event的6条最佳实践,包括优雅关闭服务的重要性、服务启动阶段事件丢失的解决、强一致性场景的适用性、保证事件处理的可靠性、幂等性订阅者以及Spring Event与MQ的对比。内容深入浅出,对于理解Spring Event的使用有重要指导意义。
摘要由CSDN通过智能技术生成

今天我们重点聊聊使用 Spring Event 最为关键的几个问题。这是我司线上生产环境实际踩坑后,总结的极为宝贵的经验!

Spring Event框架实现了基于事件的发布订阅机制。开发者可以自定义事件,在某些业务场景发布事件,Spring 会将该事件广播给监听该事件的监听者。监听者可以实现Spring 的监听者接口 ApplicationListener注册自己,也可以使用 EventListener注解注册自己。

这是Spring Event 的简短介绍,网上有大量的入门级教程,我在此不过多赘述,进入正文!

1. 为什么说:业务系统一定要先实现优雅关闭服务,才能使用 Spring Event?

Spring 广播消息时,Spring会在 ApplicationContext 中查找所有的监听者,即需要 getBean 获取 bean 实例。然而 Spring 有个限制————ApplicationContext 关闭期间,不得GetBean 否则会报错。.

这个知识点得来不易。它是我们公司在线上环境发生故障后,最终定位的原因,大家一定要重视!

前几天,线上系统出现两条异常日志Get Bean时找不到对应的bean,调用堆栈让我非常迷惑,为什么Get Bean找不到对应的Bean呢? 如下图所示
在这里插入图片描述
堆栈中的信息 解释了原因。Do not request a bean from a BeanFactory in a destroy method implementation

在应用上下文关闭时,不得从上下文中Get Bean。恰好,这个问题出现在服务关闭期间…

由于系统流量较高,日订单几百万,即便在低峰期单机的并发度也是比较高的,所以服务在关闭期间有少量流量进来或未处理完。这个场景下,使用 Spring Event 发布事件,Spring 无法正常广播事件,一定会出现异常,导致处理失败!

大家一定要切记!使用 SpringEvent 之前,一定要先治理服务,确保服务关闭时,先切断入口流量(Http、MQ、RPC),然后再关闭服务,关闭 Spring 上下文!

详细的分析请参考:

https://juejin.cn/post/7281159113882468371

2. 为什么服务启动阶段,Spring Event 事件丢失了?

我们公司遇到的情况是, Kafka conumser 在 init-method 阶段开始消费,然而 Spring EventListener 被注册进 Spring 的时间点滞后于 init-method 时间点,所以 Kafka Consumer 中使用 Sp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cyufeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值