Apollo 源码解析 —— Config Service 配置读取接口

本文详细解析Apollo配置服务中ConfigController的queryConfig接口,以及ConfigService的相关实现,包括配置读取、灰度发布、Namespace处理和配置合并。通过对源码的深入分析,展示了如何从Apollo获取配置信息以及内部处理逻辑。
摘要由CSDN通过智能技术生成

点击上方“芋道源码”,选择“设为星标

管她前浪,还是后浪?

能浪的浪,才是好浪!

每天 8:55 更新文章,每天掉亿点点头发...

源码精品专栏

 

摘要: 原创出处 http://www.iocoder.cn/Apollo/config-service-config-query-api/ 「芋道源码」欢迎转载,保留摘要,谢谢!

  • 1. 概述

  • 2. ConfigController

    • 2.1 构造方法

    • 2.2 queryConfig

    • 2.3 tryToGetClientIp

    • 2.4 mergeReleaseConfigurations

  • 3. ConfigService

    • 3.1 AbstractConfigService

    • 3.3 DefaultConfigService

    • 3.4 ConfigServiceWithCache

  • 4. ApolloConfig

  • 666. 彩蛋


1. 概述

老艿艿:本系列假定胖友已经阅读过 《Apollo 官方 wiki 文档》  。

本文接 《Apollo 源码解析 —— Config Service 通知配置变化》 一文,分享 Config Service 配置读取的接口的实现。在上文,我们看到通知变化接口返回通知相关的信息,而不包括配置相关的信息。所以 Config Service 需要提供配置读取的接口

???? 为什么不在通知变化的同时,返回最新的配置信息呢?老艿艿请教了作者,下一篇文章进行分享。

OK,让我们开始看看具体的代码实现。

2. ConfigController

com.ctrip.framework.apollo.configservice.controller.ConfigController ,配置 Controller ,提供 configs/{appId}/{clusterName}/{namespace:.+} 接口,提供配置读取的功能。

2.1 构造方法

private static final Splitter X_FORWARDED_FOR_SPLITTER = Splitter.on(",").omitEmptyStrings().trimResults();

private static final Type configurationTypeReference = new TypeToken<Map<String, String>>() {}.getType();

@Autowired
private ConfigService configService;
@Autowired
private AppNamespaceServiceWithCache appNamespaceService;
@Autowired
private NamespaceUtil namespaceUtil;
@Autowired
private InstanceConfigAuditUtil instanceConfigAuditUtil;
@Autowired
private Gson gson

2.2 queryConfig

  1: @RequestMapping(value = "/{appId}/{clusterName}/{namespace:.+}", method = RequestMethod.GET)
  2: public ApolloConfig queryConfig(@PathVariable String appId, @PathVariable String clusterName,
  3:                                 @PathVariable String namespace,
  4:                                 @RequestParam(value = "dataCenter", required = false) String dataCenter,
  5:                                 @RequestParam(value = "releaseKey", defaultValue = "-1") String clientSideReleaseKey,
  6:                                 @RequestParam(value = "ip", required = false) String clientIp,
  7:                                 @RequestParam(value = "messages", required = false) String messagesAsString,
  8:                                 HttpServletRequest request, HttpServletResponse response) throws IOException {
  9:     String originalNamespace = namespace;
 10:     // 若 Namespace 名以 .properties 结尾,移除该结尾,并设置到 ApolloConfigNotification 中。例如 application.properties => application 。
 11:     // strip out .properties suffix
 12:     namespace = namespaceUtil.filterNamespaceName(namespace);
 13:     // 获得归一化的 Namespace 名字。因为,客户端 Namespace 会填写错大小写。
 14:     //fix the character case issue, such as FX.apollo <-> fx.apollo
 15:     namespace = namespaceUtil.normalizeNamespace(appId, namespace);
 16: 
 17:     // 若 clientIp 未提交,从 Request 中获取。
 18:     if (Strings.isNullOrEmpty(clientIp)) {
 19:         clientIp = tryToGetClientIp(request);
 20:     }
 21: 
 22:     // 解析 messagesAsString 参数,创建 ApolloNotificationMessages 对象。
 23:     ApolloNotificationMessages clientMessages = transformMessages(messagesAsString);
 24: 
 25:     // 创建 Release 数组
 26:     List<Release> releases = Lists.newLinkedList();
 27:     // 获得 Namespace 对应的 Release 对象
 28:     String appClusterNameLoaded = clusterName;
 29:     if (!ConfigConsts.NO_APPID_PLACEHOLDER.equalsIgnoreCase(appId)) {
 30:         // 获得 Release 对象
 31:         Release currentAppRelease = configService.loadConfig(appId, clientIp, appId, clusterName, namespace, dataCenter, clientMessages);
 32:         if (currentAppRelease != null) {
 33:             // 添加到 Release 数组中。
 34:             releases.add(currentAppRelease);
 35:             // 获得 Release 对应的 Cluster 名字
 36:             // we have cluster search process, so the cluster name might be overridden
 37:             appClusterNameLoaded = currentAppRelease.getClusterName();
 38:         }
 39:     }
 40:     // 若 Namespace 为关联类型,则获取关联的 Namespace 的 Release 对象
 41:     // if namespace does not belong to this appId, should check if there is a public configuration
 42:     if (!namespaceBelongsToAppId(appId, namespace)) {
 43:         // 获得 Release 对象
 44:         Release publicRelease = this.findPublicConfig(appId, clientIp, clusterName, namespace, dataCenter, clientMessages);
 45:         // 添加到 Release 数组中
 46:         if (!Objects.isNull(publicRelease)) {
 47:             releases.add(publicRelease);
 48:         }
 49:     }
 50:     // 若获得不到 Release ,返回状态码为 404 的响应
 51:     if (releases.isEmpty()) {
 52:         response.sendError(HttpServletResponse.SC_NOT_FOUND, String.format("Could not load configurations with appId: %s, clusterName: %s, namespace: %s",
 53:                 app
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值