Apollo 源码解析 —— Portal 配置灰度规则
总阅读量:3137次
摘要: 原创出处 http://www.iocoder.cn/Apollo/portal-modify-namespace-branch-gray-rules/ 「芋道源码」欢迎转载,保留摘要,谢谢!
阅读源码最好的方式,是使用 IDEA 进行调试 Apollo 源码,不然会一脸懵逼。
胖友可以点击「芋道源码」扫码关注,回复 git018 关键字
获得艿艿添加了中文注释的 Apollo 源码地址。阅读源码很孤单,加入源码交流群,一起坚持!
1. 概述
老艿艿:本系列假定胖友已经阅读过 《Apollo 官方 wiki 文档》 ,特别是 《Apollo 官方 wiki 文档 —— 灰度发布使用指南》。
本文分享 Portal 配置灰度规则 的流程,整个过程涉及 Portal、Admin Service ,如下图所示:
- 对于一个子 Namespace 仅对应一条有效灰度规则 GrayReleaseRule 记录。每次变更灰度规则时,标记删除老的灰度规则,新增保存新的灰度规则。
- 变更灰度配置完成后,会发布一条 ReleaseMessage 消息,以通知配置变更。
2. GrayReleaseRule
在 apollo-common
项目中,com.ctrip.framework.apollo.common.entity.GrayReleaseRule
,继承 BaseEntity 抽象类,GrayReleaseRule 实体。代码如下:
|
-
appId
+clusterName
+namespaceName
+branchName
四个字段,指向对应的子 Namespace 对象。 -
rules
字段,规则数组,目前将 GrayReleaseRuleItemDTO 数组,JSON 格式化进行存储。详细解析,见 「2.1 GrayReleaseRuleItemDTO」 。字段存储例子如下:[{"clientAppId":"233","clientIpList":["10.12.13.14","20.23.12.15"]}]
-
release
字段,Release 编号。目前有两种情况:- 1、当灰度已经发布,则指向对应的最新的 Release 对象的编号。
- 2、当灰度还未发布,等于 0 。等到灰度发布后,更新为对应的 Release 对象的编号。
-
branchStatus
字段,Namespace 分支状态。在com.ctrip.framework.apollo.common.constants.NamespaceBranchStatus
中,枚举如下:public interface NamespaceBranchStatus {
/**
* 删除
*/
int DELETED = 0;
/**
* 激活(有效)
*/
int ACTIVE = 1;
/**
* 合并
*/
int MERGED = 2;
}
2.1 GrayReleaseRuleItemDTO
com.ctrip.framework.apollo.common.dto.GrayReleaseRuleItemDTO
,GrayRelease 规则项 DTO 。代码如下:
public class GrayReleaseRuleItemDTO { |
-
为什么会有
clientAppId
字段呢?对于公共 Namespace 的灰度规则,需要先指定要灰度的 appId ,然后再选择 IP 。如下图:-
这样设计的初衷是什么?笔者请教了宋老师( Apollo 的作者 ) :
默认公共 namespace 就允许被所有应用使用的,可以认为是一个隐性的关联。
在应用界面上的关联是为了覆盖公共配置使用的。
客户端的 appId 是获取自己的配置,公共配置的获取不需要 appid 。
- 从而实现公用类型的 Namespace ,可以设置对任意 App 灰度发布。双击 666 。
-
3. Portal 侧
3.1 NamespaceBranchController
在 apollo-portal
项目中,com.ctrip.framework.apollo.portal.controller.NamespaceBranchController
,提供 Namespace 分支的 API 。
切换到灰度规则 Tab ,点击【新增规则】按钮。
在弹出框中【灰度的 IP】下拉框会默认展示当前使用配置的机器列表,选择我们要灰度的 IP,点击完成。
![]()
![]()
如果下拉框中没找到需要的IP,说明机器还没从Apollo取过配置,可以点击手动输入IP来输入,输入完后点击添加按钮
![]()
#updateBranchRules(...)
方法, 更新 Namespace 分支的灰度规则。代码如下:
"@permissionValidator.hasOperateNamespacePermission(#appId, #namespaceName)") (value = |
-
- PUT
"apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/rules
接口 。
- PUT
-
@PreAuthorize(...)
注解,调用PermissionValidator#hasOperateNamespacePermission(appId, namespaceName)
方法,校验是否有操作 Namespace 的权限。后续文章,详细分享。 -
com.ctrip.framework.apollo.common.dto.GrayReleaseRuleDTO
,灰度发布规则 DTO ,代码如下:public class GrayReleaseRuleDTO extends BaseDTO {
/**
* App 编号
*/
private String appId;
/**
* Cluster 名字
*/
private String clusterName;
/**
* Namespace 名字
*/
private String namespaceName;
/**
* Branch 名字
*/
private String branchName;
/**
* GrayReleaseRuleItemDTO 数组
*/
private Set<GrayReleaseRuleItemDTO> ruleItems;
/**
* Release 编号
*
* 更新灰度发布规则时,该参数不会传递
*/
private Long releaseId;
} -
调用
NamespaceBranchService#updateBranchGrayRules(...)
方法,更新 Namespace 分支的灰度规则。
3.2 NamespaceBranchService
在 apollo-portal
项目中,com.ctrip.framework.apollo.portal.service.NamespaceBranchService
,提供 Namespace 分支的 Service 逻辑。
#createItem(appId, env, clusterName, namespaceName, ItemDTO)
方法,创建并保存 Item 到 Admin Service 。代码如下:
1: |
- 第 8 至 11 行:设置 GrayReleaseRuleDTO 的创建和修改人为当前管理员。
- 第 13 行:调用
NamespaceBranchAPI#updateBranchGrayRules(...)
方法,更新 Namespace 分支的灰度规则。 - 第 15 行:【TODO 6001】Tracer 日志
3.3 NamespaceBranchAPI
com.ctrip.framework.apollo.portal.api.NamespaceBranchAPI
,实现 API 抽象类,封装对 Admin Service 的 Namespace 分支模块的 API 调用。代码如下:
4. Admin Service 侧
4.1 NamespaceBranchController
在 apollo-adminservice
项目中, com.ctrip.framework.apollo.adminservice.controller.NamespaceBranchController
,提供 Namespace 分支的 API 。
#updateBranchGrayRules(...)
方法,更新 Namespace 分支的灰度规则。代码如下:
1: |
-
第 14 行:调用
#checkBranch(appId, clusterName, namespaceName, branchName)
,校验子 Namespace 是否存在。代码如下:private void checkBranch(String appId, String clusterName, String namespaceName, String branchName) {
// 校验 Namespace 是否存在
// 1. check parent namespace
checkNamespace(appId, clusterName, namespaceName);
// 校验子 Namespace 是否存在。若不存在,抛出 BadRequestException 异常
// 2. check child namespace
Namespace childNamespace = namespaceService.findOne(appId, branchName, namespaceName);
if (childNamespace == null) {
throw new BadRequestException(String.format("Namespace's branch not exist. AppId = %s, ClusterName = %s, "
+ "NamespaceName = %s, BranchName = %s", appId, clusterName, namespaceName, branchName));
}
} -
第 17 行:调用
BeanUtils#transfrom(Class<T> clazz, Object src)
方法,将 GrayReleaseRuleDTO 转换成 GrayReleaseRule 对象。 -
第 19 行:调用
GrayReleaseRuleItemTransformer#batchTransformToJSON(et<GrayReleaseRuleItemDTO> ruleItems)
方法,JSON 化规则为字符串,并设置到 GrayReleaseRule 对象中。代码如下:private static final Gson gson = new Gson();
public static String batchTransformToJSON(Set<GrayReleaseRuleItemDTO> ruleItems) {
return gson.toJson(ruleItems);
}
- 第 21 行:设置 GrayReleaseRule 对象的
branchStatus
为 ACTIVE 。 - 第 23 行:调用
NamespaceBranchService#updateBranchGrayRules(appId, clusterName, namespaceName, branchName, newRules)
方法,更新子 Namespace 的灰度发布规则。详细解析,见 「3.2 NamespaceBranchService」 。 - 第 25 行:调用
MessageSender#sendMessage(message, channel)
方法,发送 Release 消息,从而通知客户端更新配置。
4.2 NamespaceBranchService
在 apollo-biz
项目中,com.ctrip.framework.apollo.biz.service.NamespaceBranchService
,提供 Namespace 分支的 Service 逻辑给 Admin Service 和 Config Service 。
#updateBranchGrayRules(appId, clusterName, namespaceName, branchName, newRules)
方法,更新子 Namespace 的灰度发布规则。代码如下:
1: |
- 第 15 行:调用
GrayReleaseRuleRepository#findTopByAppIdAndClusterNameAndNamespaceNameAndBranchNameOrderByIdDesc(appId, clusterName, namespaceName, branchName)
方法,获得子 Namespace 的灰度发布规则。 - Release Id 相关:
- 第 16 行:调用
ReleaseService#findLatestActiveRelease(appId, branchName, namespaceName)
方法,获得最新的,并且有效的,子 Namespace 的 Release 对象。 - 第 19 行:获得最新的子 Namespace 的 Release 对象的编号。若不存在,则设置为 0 。
- 第 21 行:设置 GrayReleaseRule 的
releaseId
属性。
- 第 16 行:调用
- 第 23 行:调用
GrayReleaseRuleRepository#save(GrayReleaseRule)
方法,保存新的 GrayReleaseRule 对象。 - 第 25 至 29 行:删除老的 GrayReleaseRule 对象。
- 第 31 至 40 行:若需要,调用
ReleaseHistoryService#createReleaseHistory(...)
方法,创建 ReleaseHistory 对象,并保存。其中,ReleaseHistory.operation
属性,为 APPLY_GRAY_RULES 。
4.3 GrayReleaseRuleRepository
com.ctrip.framework.apollo.biz.repository.GrayReleaseRuleRepository
,继承 org.springframework.data.repository.PagingAndSortingRepository
接口,提供 GrayReleaseRule 的数据访问 给 Admin Service 和 Config Service 。代码如下:
public interface GrayReleaseRuleRepository extends PagingAndSortingRepository<GrayReleaseRule, Long> { |
666. 彩蛋
美滋滋,下一篇,灰度发布。