必须用受检异常强制下线通知,因为其编译期检查可确保notifydownstream()被显式处理,避免因跳过通知导致生产事故;配合布尔开关ispreparingtooffline控制请求准入,并与注册中心disable操作联动,通知失败时异常冒泡而非静默。

用布尔开关配合受检异常,不是为了“加一层判断”,而是把下线通知这件事从可选动作变成编译期强制动作——不处理通知逻辑,代码就编译不过。
为什么需要受检异常来约束下线通知
微服务下线常被跳过通知环节,原因很现实:开发觉得“只是临时下个实例”“下游应该自己轮询注册中心”。但生产事故往往就出在“没人主动告诉别人我要走了”。Java 的受检异常(Exception 及其子类)会在编译时强制调用方显式处理,正好用来兜住这个关键契约。
核心实现模式:下线开关 + 通知契约接口
定义一个带语义的布尔开关(如 isPreparingToOffline),再配套一个必须实现的通知方法,该方法声明抛出受检异常:
- 开关设为 true 时,表示服务已进入“准备下线”状态,此时任何业务入口(如 Controller、MessageListener)都应拒绝新请求
- 配套的 notifyDownstream() 方法必须返回 void,且声明 throws OfflineNotificationRequiredException(自定义受检异常)
- 调用方若不 try-catch 或 throws,编译直接失败
典型落地结构示例
以 Spring Boot 微服务为例:
- 定义受检异常:public class OfflineNotificationRequiredException extends Exception
- 注入一个 OfflineCoordinator 组件,含 prepareOffline()(置开关为 true)和 notifyDownstream()(含 throws 声明)
- 在 Actuator 的 /actuator/offline 端点中,先调 prepareOffline(),再调 notifyDownstream() —— 若没写通知逻辑,此处编译报错或运行时报未处理异常
- 同时在关键入口(如 @RestControllerAdvice)拦截请求,检查开关为 true 时,主动 throw 新的业务异常(如 ServiceOfflineException),避免静默失败
与注册中心联动的关键细节
这个模式真正起效,要和注册中心行为对齐:
- 开关置为 true 后,必须同步触发注册中心的 disable 操作(如 Nacos 的 enabled=false、Eureka 的 cancel)
- 通知方法里应包含向依赖方发消息(如 RocketMQ 事件)、更新配置中心开关、调用下游迁移检查接口等具体动作
- 如果通知失败(比如 MQ 发送超时),不能吞掉异常——让受检异常向上冒泡,触发回滚或告警,而不是假装“通知成功了”











