📖 本章预览
本章为预览版本,展示部分核心内容。完整内容包含详细源码解析、实战代码和面试要点,加入知识星球即可解锁全部章节。
第八章:Naming 服务推送机制
服务实例变更后,如何通知所有订阅者?本章深入拆解 Naming 推送的延迟合并引擎。
8.1 推送触发链路全景
实例注册/注销/健康状态变更
│
▼
ClientServiceIndexesManager.addPublisherIndexes()
│ 发布 ServiceChangedEvent
▼
NamingSubscriberServiceV2Impl.onEvent() ← 推送入口
│ 创建 PushDelayTask,提交到延迟引擎
▼
PushDelayTaskExecuteEngine ← 延迟合并引擎
│ 等待延迟窗口(默认 500ms)
│ 窗口内多次变更合并为一次
▼
PushExecuteTask.run() ← 实际推送
│ ① 从 ServiceStorage 组装 ServiceInfo
│ ② 从 subscriberIndexes 获取所有订阅者
│ ③ 遍历订阅者,逐个推送
▼
PushExecutorRpcImpl.doPushWithCallback()
│ 通过 gRPC 长连接推送 NotifySubscriberRequest
▼
客户端收到推送,更新本地缓存
8.2 NamingSubscriberServiceV2Impl——推送入口
@Service
public class NamingSubscriberServiceV2Impl extends SmartSubscriber {
private final PushDelayTaskExecuteEngine delayTaskEngine;
@Override
public List<Class<? extends Event>> subscribeTypes() {
return Arrays.asList(
ServiceEvent.ServiceChangedEvent.class,
ServiceEvent.ServiceSubscribedEvent.class
);
}
@Override
public void onEvent(Event event) {
if (event instanceof ServiceChangedEvent) {
// 服务变更 → 推送给该服务的所有订阅者
Service service = ((ServiceChangedEvent) event).getService();
delayTaskEngine.addTask(service,
new PushDelayTask(service, PushConfig.getInstance().getPushTaskDelay()));
} else if (event instanceof ServiceSubscribedEvent) {
// 新订阅 → 只推送给这个新订阅者
ServiceSubscribedEvent subscribedEvent = (ServiceSubscribedEvent) event;
delayTaskEngine.addTask(subscribedEvent.getService(),
new PushDelayTask(subscribedEvent.getService(),
PushConfig.getInstance().getPushTaskDelay(),
subscribedEvent.getClientId()));
}
}
}
8.3 PushDelayTaskExecuteEngine——延迟合并引擎(核心)
8.3.1 为什么需要延迟合并
假设一个服务在 100ms 内有 10 个实例注册(比如 K8s 滚动发布),如果每次都推送:
- 产生 10 次推送
- 前 9 次推送的数据都是"不完整"的
延迟合并后:
- 等 500ms 延迟窗口结束
- 只推送 1 次,包含所有 10 个实例
- 减少 90% 的推送量,且数据更完整
🔒 解锁完整内容
本章剩余内容需要解锁后查看
以上仅为本章部分预览内容,完整内容包含更多深度源码解析、实战代码和面试要点。
加入知识星球你将获得:
- ✅ 全部 17 章完整内容 + 持续更新
- ✅ 配套源码 + 实战项目
- ✅ 一对一答疑 + 面试辅导
- ✅ 简历优化 + 内推机会
📚 本章完整目录
以下为本章完整目录结构,加入知识星球即可解锁全部内容。