深入理解Apollo核心机制之配置读取——ConfigService定时扫描

概述

之前我们了解了,客户端会每秒(默认)长轮询Config Service,等待通知,然后去主动拉取配置文件。本文主要跟进Config Service主动轮询ReleaseMessage表,并通知对应监听器的源码,最终终止客户端长轮询的源码。附上之前的链接《深入理解Apollo核心机制之配置读取——前言

监听器介绍

Config Service中有一些类实现了ReleaseMessageListener接口,并重写了handleMessage()方法,当ConfigService扫描到有新的配置发布的时候,就会轮询通知所有实现了上述监听器接口的监听器,调用handleMessage()方法。我们要了解的和客户端长轮询的监听器的类便是NotificationControllerV2。其它的监听器在配置发布的时候也有自己的职责,这里不过多介绍,我们只会查看NotificationControllerV2中的handleMessage()方法,了解它在接到通知的时候是如何处理消息的。

监听器注册

监听器结构

ReleaseMessageScanner#afterPropertiesSet() 开启扫描任务

首先看到ReleaseMessageScanner类,这个类就是做这件事情的。我们会发现它会开启一个定时扫描的任务(默认1秒间隔),具体看下面源码。

ReleaseMessageScanner#scanMessages() 扫描条件

ReleaseMessageScanner#scanAndSendMessages() 扫描并发送通知

Config Service会查出”当前最大扫描ID“后500条数据(根据ID升序),如果没有数据,则代表上次扫描之后,没有新的配置发布,如果有新的配置发布则会通知监听器。

必备Tip

客户端发起长轮询是请求NotificationControllerV2的pollNotification接口,经过一系列处理,会将请求的客户端保存下来。(Map形式,key为"{appId}+{clusterName}+{namespaceName}",value为List。所以,根据key就可以拿到一批关注该key(namespace)的客户端集合,最终调用setResult()即可结束长轮询。细节我们下次单独分析客户端长轮询相关的源码,本次只是关注定时扫描方向的源码主干。

下图代码便是该监听器的handleMessage()源码了,它会根据收到的”message",提取appId、clusterName、namespaceName,轮询通知根据key得到的DeferredResultWrapper集合(调用setResult()方法)。从而将通知信息(DeferredResult<ResponseEntity<List>>)返回给客户端。

原文地址:https://www.cnblogs.com/deepSleeping/p/14565697.html