Apollo 源码解析 —— Portal 灰度全量发布
摘要: 原创出处 http://www.iocoder.cn/Apollo/portal-publish-namespace-branch-to-master/ 「芋道源码」欢迎转载,保留摘要,谢谢!
- 1. 概述
- 2. Portal 侧
- 2.1 NamespaceBranchController
- 2.2 NamespaceBranchService
- 2.3 ReleaseAPI
- 3. Admin Service 侧
- 3.1 ReleaseController
- 3.2 ReleaseService
- 3.3 NamespaceBranchService
- 3.4 ClusterService
- 666. 彩蛋
1. 概述
老艿艿:本系列假定胖友已经阅读过 《Apollo 官方 wiki 文档》 ,特别是 《Apollo 官方 wiki 文档 —— 灰度发布使用指南》。
本文接 《Apollo 源码解析 —— Portal 灰度发布》 ,分享灰度全量发布。
我们先来看看官方文档对灰度全量发布的使用指南,来理解下它的定义和流程。
如果灰度的配置测试下来比较理想,符合预期,那么就可以操作【全量发布】。
全量发布的效果是:
- 灰度版本的配置会合并回主版本,在这个例子中,就是主版本的 timeout 会被更新成 3000
- 主版本的配置会自动进行一次发布
- 在全量发布页面,可以选择是否保留当前灰度版本,默认为不保留。
我选择了不保留灰度版本,所以发布完的效果就是主版本的配置更新、灰度版本删除。点击主版本的实例列表,可以看到10.32.21.22和10.32.21.19都使用了主版本最新的配置。
灰度发布2
灰度全量发布,和 《Apollo 源码解析 —— Portal 发布配置》 ,差异点在于,多了一步配置合并,所以代码实现上,有很多相似度。整体系统流程如下:
流程
2. Portal 侧
2.1 NamespaceBranchController
在 apollo-portal
项目中,com.ctrip.framework.apollo.portal.controller.NamespaceBranchController
,提供 Namespace 分支的API 。
#merge(...)
方法,灰度全量发布,合并子 Namespace 变更的配置 Map 到父 Namespace ,并进行一次 Release 。代码如下:
1: @PreAuthorize(value = "@permissionValidator.hasReleaseNamespacePermission(#appId, #namespaceName)")
2: @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/merge", method = RequestMethod.POST)
3: public ReleaseDTO merge(@PathVariable String appId, @PathVariable String env,
4: @PathVariable String clusterName, @PathVariable String namespaceName,
5: @PathVariable String branchName, @RequestParam(value = "deleteBranch", defaultValue = "true") boolean deleteBranch,
6: @RequestBody NamespaceReleaseModel model) {
7: // 若是紧急发布,但是当前环境未允许该操作,抛出 BadRequestException 异常
8: if (model.isEmergencyPublish() && !portalConfig.isEmergencyPublishAllowed(Env.fromString(env))) {
9: throw new BadRequestException(String.format("Env: %s is not supported emergency publish now", env));
10: }
11: // 合并子 Namespace 变更的配置 Map 到父 Namespace ,并进行一次 Release
12: ReleaseDTO createdRelease = namespaceBranchService.merge(appId, Env.valueOf(env), clusterName, namespaceName, branchName,
13: model.getReleaseTitle(), model.getReleaseComment(),
14: model.isEmergencyPublish(), deleteBranch);
15:
16: // 创建 ConfigPublishEvent 对象
17: ConfigPublishEvent event = ConfigPublishEvent.instance();
18: event.withAppId(appId)
19: .withCluster(clusterName)
20: .withNamespace(namespaceName)
21: .withReleaseId(createdRelease.getId())
22: .setMergeEvent(true)
23: .setEnv(Env.valueOf(env));
24: // 发布 ConfigPublishEvent 事件
25: publisher.publishEvent(event);
26: return createdRelease;
27: }
- POST
/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/merge
接口,Request Body 传递 JSON 对象。 @PreAuthorize(...)
注解,调用PermissionValidator#hasReleaseNamespacePermissio(appId, namespaceName)
方法,校验是否有发布配置的权限。后续文章,详细分享。- 第 7 至 10 行:校验若是紧急发布,但是当前环境未允许该操作,抛出 BadRequestException 异常。
- 第 11 至 14 行:调用
NamespaceBranchService#merge(...)
方法,合并子 Namespace 变更的配置 Map 到父 Namespace ,并进行一次 Release 。 - 第 16 至 25 行:创建 ConfigPublishEvent 对象,并调用
ApplicationEventPublisher#publishEvent(event)
方法,发布 ConfigPublishEvent 事件。这部分,我们在后续文章分享。 - 第 26 行:返回 ReleaseDTO 对象。
2.2 NamespaceBranchService
在 apollo-portal
项目中,com.ctrip.framework.apollo.portal.service.NamespaceBranchService
,提供 Namespace 分支的Service 逻辑。
#merge(...)
方法,调用 Admin Service API ,合并子 Namespace 变更的配置 Map 到父 Namespace ,并进行一次 Release 。代码如下:
1: @Autowired
2: private AdminServiceAPI.NamespaceBranchAPI namespaceBranchAPI;
3: @Autowired
4: private ReleaseService releaseService;
5:
6: public ReleaseDTO merge(String appId, Env env, String clusterName, String namespaceName,
7: String branchName, String title, String comment,
8: boolean isEmergencyPublish, boolean deleteBranch) {
9: // 计算变化的 Item 集合
10: ItemChangeSets changeSets = calculateBranchChangeSet(appId, env, clusterName, namespaceName, branchName);
11: // 合并子 Namespace 变更的配置 Map 到父 Namespace ,并进行一次 Release
12: ReleaseDTO mergedResult = releaseService.updateAndPublish(appId, env, clusterName, namespaceName, title, comment,
13: branchName, isEmergencyPublish, deleteBranch, changeSets);
14: // 【TODO 6001】Tracer 日志
15: Tracer.logEvent(TracerEventType.MERGE_GRAY_RELEASE, String.format("%s+%s+%s+%s", appId, env, clusterName, namespaceName));
16: return mergedResult;
17: }
第 10 行:调用
#calculateBranchChangeSet(appId, env, clusterName, namespaceName, branchName)
方法,计算变化的 Item 集合。详细解析,见 「2.2.1 calculateBranchChangeSet」 。第12 至 13 行:调用
ReleaseService#updateAndPublish(...)
方法,调用 Admin Service API ,合并子 Namespace 变更的配置 Map 到父 Namespace ,并进行一次 Release 。代码如下:@Autowired
private AdminServiceAPI.ReleaseAPI releaseAPI;
public ReleaseDTO updateAndPublish(String appId, Env env, String clusterName, String namespaceName,
String releaseTitle, String releaseComment, String branchName,
boolean isEmergencyPublish, boolean deleteBranch, ItemChangeSets changeSets) {
return releaseAPI.updateAndPublish(appId, env, clusterName, namespaceName, releaseTitle, releaseComment, branchName,
isEmergencyPublish, deleteBranch, changeSets);
}- 方法内部,调用
ReleaseAPI#updateAndPublish(...)
方法,调用 Admin Service API ,合并子 Namespace 变更的配置 Map 到父 Namespace ,并进行一次 Release 。©著作权归作者所有:来自51CTO博客作者mb5ff80520dfa04的原创作品,如需转载,请注明出处,否则将追究法律责任更多相关文章
- Apollo 源码解析 —— Portal 配置灰度规则
- Apollo 源码解析 —— Portal 创建灰度
- MySQL中自增ID起始值修改方法
- Python3版本下创建计算给定日期范围内工作日方法
- 芋道 Spring Boot JPA 入门(二)之基于方法名查询
- DoDAF2.0方法论探究
- http协议请求方法都有哪些?网络安全学习提升
- 【前端词典】8 个提高 JS 性能的方法
- AngularJS 日期时间选择组件(附详细使用方法)
随机推荐
- 方法内部,调用