apollo源码(3)-ConfigService通知配置变化

本文详细介绍了Apollo配置服务中的NotificationControllerV2,它处理客户端的配置变化请求。当配置更新时,通过DeferredResult响应客户端,实现了配置变更的实时通知。文章剖析了pollNotification方法的工作流程,包括解析ApolloConfigNotification、Watch Key的处理以及handleMessage方法的配置变更通知逻辑。
摘要由CSDN通过智能技术生成

1. 概述

  1. 客户端会发起一个Http 请求到 Config Service 的 notifications/v2 接口,也就是NotificationControllerV2  。
  2. NotificationControllerV2 不会立即返回结果,而是通过 Spring DeferredResult 把请求挂起。
  3. 如果在 60 秒内没有该客户端关心的配置发布,那么会返回 Http 状态码 304 给客户端。
  4. 如果有该客户端关心的配置发布,NotificationControllerV2 会调用 DeferredResult 的 setResult 方法,传入有配置变化的 namespace 信息,同时该请求会立即返回。客户端从返回的结果中获取到配置变化的 namespace 后,会立即请求 Config Service 获取该 namespace 的最新配置。

 

2. NotificationControllerV2

1.实现 ReleaseMessageListener 接口,通知 Controller ,仅提供 notifications/v2 接口。

2.1 类的继承结构

 

2.2 客户端请求流程

 

2.3 pollNotification方法

1.客户端请求配置变化入口

@RequestMapping(method = RequestMethod.GET)
 public DeferredResult<ResponseEntity<List<ApolloConfigNotification>>> pollNotification(
 @RequestParam(value = "appId") String appId,
 @RequestParam(value = "cluster") String cluster,
 @RequestParam(value = "notifications") String notificationsAsString,
 @RequestParam(value = "dataCenter", required = false) String dataCenter,
 @RequestParam(value = "ip", required = false) String clientIp) {
 // 解析 notificationsAsString 参数,创建 ApolloConfigNotification 数组。
 List<ApolloConfigNotification> notifications = null;
 try {
 notifications = gson.fromJson(notificationsAsString, notificationsTypeReference);
 } catch (Throwable ex) {
 Tracer.logError(ex);
 }
 if (CollectionUtils.isEmpty(notifications)) {
 throw new BadRequestException("Invalid format of notifications: " + notificationsAsString);
 }

 // 创建 DeferredResultWrapper 对象
 DeferredResultWrapper deferredResultWrapper = new DeferredResultWrapper();
 // Namespace 集合
 Set<String> namespaces = Sets.newHashSet();
 // 客户端的通知 Map 。key 为 Namespace 名,value 为通知编号。
 Map<String, Long> clientSideNotifications = Maps.newHashMap();
 // 过滤并创建 ApolloConfigNotification Map
 Map<String, ApolloConfigNotification> filteredNotifications = filterNotifications(appId, notifications);
 // 循环 ApolloConfigNotification Map ,初始化上述变量。
 for (Map.Entry<String, ApolloConfigNotification> notificationEntry : filteredNotifications.entrySet()) {
 String normalizedNamespace = notificationEntry.getKey();
 ApolloConfigNotification notification = notificationEntry.getValue();
 // 添加到 `namespaces` 中。
 namespaces.add(normalizedNamespace);
 // 添加到 `clientSideNotifications` 中。
 clientSideNotifications.put(normalizedNamespace, notification.getNotificationId());
 // 记录名字被归一化的 Namespace 。因为,最终返回给客户端,使用原始的 Namespace 名字,否则客户端无法识别。
 if (!Objects.equals(notification.getNamespaceName(), normal
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值