《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》

摘要: 原创出处 http://www.iocoder.cn/Apollo/portal-create-namespace-branch/ 「芋道源码」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

1. 概述

老艿艿:本系列假定胖友已经阅读过 《Apollo 官方 wiki 文档》 ,特别是 《Apollo 官方 wiki 文档 —— 灰度发布使用指南》

本文分享 Portal 创建灰度 的流程,整个过程涉及 Portal、Admin Service ,如下图所示:流程

创建灰度,调用的是创建 Namespace 分支 的 API 。通过创建的子 Namespace ,可以关联其自己定义的 Cluster、Item、Release 等等。关系如下所图所示:关系图

  • 创建 Namespace 分支时:
    • 会创建 Cluster ,指向 Cluster 。
    • 会创建 Namespace ,关联 Namespace 。实际上, Namespace 和 Namespace 无任何数据字段上的关联。
  • Namespace 添加 Item 时,该 Item 指向 Namespace 。虽然,代码实现和 Namespace 是一模一样的。
  • Namespace 发布( 灰度发布 ) 和 Namespace 发布( 普通发布 ) 在代码实现,有一些差距,后续文章分享。

老艿艿:在目前 Apollo 的实现上,胖友可以把分支灰度等价。

  • 所以下文在用词时,选择使用分支
  • 所以下文在用词时,选择使用分支
  • 所以下文在用词时,选择使用分支

🙂 这样的设计,巧妙。

2. Portal 侧

2.1 NamespaceBranchController

apollo-portal 项目中,com.ctrip.framework.apollo.portal.controller.NamespaceBranchController ,提供 Namespace 分支API

首先点击 application namespace 右上角的【创建灰度】按钮。

创建灰度

点击确定后,灰度版本就创建成功了,页面会自动切换到【灰度版本】 Tab 。

灰度版本

#createBranch(...) 方法,创建 Namespace 分支。代码如下:

@RestController
public class NamespaceBranchController {

@Autowired
private NamespaceBranchService namespaceBranchService;

@PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)")
@RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches", method = RequestMethod.POST)
public NamespaceDTO createBranch(@PathVariable String appId,
@PathVariable String env,
@PathVariable String clusterName,
@PathVariable String namespaceName) {
return namespaceBranchService.createBranch(appId, Env.valueOf(env), clusterName, namespaceName);
}

// ... 省略其他接口和属性
}

    • POST "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches 接口
  • @PreAuthorize(...) 注解,调用 PermissionValidator#hasModifyNamespacePermission(appId, namespaceName) 方法,校验是否有修改 Namespace 的权限。后续文章,详细分享。
  • 调用 NamespaceBranchService#createBranch(...) 方法,创建 Namespace 分支

2.2 NamespaceBranchService

apollo-portal 项目中,com.ctrip.framework.apollo.portal.service.NamespaceBranchService ,提供 Namespace 分支Service 逻辑。

#createItem(appId, env, clusterName, namespaceName, ItemDTO) 方法,创建并保存 Item 到 Admin Service 。代码如下:

 1: @Autowired
2: private UserInfoHolder userInfoHolder;
3: @Autowired
4: private AdminServiceAPI.NamespaceBranchAPI namespaceBranchAPI;
5:
6: @Transactional
7: public NamespaceDTO createBranch(String appId, Env env, String parentClusterName, String namespaceName) {
8: // 创建 Namespace 分支
9: NamespaceDTO createdBranch = namespaceBranchAPI.createBranch(appId, env, parentClusterName, namespaceName, userInfoHolder.getUser().getUserId());
10: // 【TODO 6001】Tracer 日志
11: Tracer.logEvent(TracerEventType.CREATE_GRAY_RELEASE, String.format("%s+%s+%s+%s", appId, env, parentClusterName, namespaceName));
12: return createdBranch;
13: }

  • 第 9 行:调用 NamespaceBranchAPI#createBranch(...) 方法,创建 Namespace 分支
  • 第 11 行:【TODO 6001】Tracer 日志

2.3 NamespaceBranchAPI

com.ctrip.framework.apollo.portal.api.NamespaceBranchAPI ,实现 API 抽象类,封装对 Admin Service 的 Namespace 分支模块的 API 调用。代码如下:

NamespaceBranchAPI

3. Admin Service 侧

3.1 NamespaceBranchController

apollo-adminservice 项目中, com.ctrip.framework.apollo.adminservice.controller.NamespaceBranchController ,提供 Namespace 分支API

#createBranch(...) 方法,创建 Namespace 分支。代码如下:

 1: @RestController
2: public class NamespaceBranchController {
3:
4: @Autowired
5: private MessageSender messageSender;
6: @Autowired
7: private NamespaceBranchService namespaceBranchService;
8: @Autowired