四步轻松玩转微服务敏捷开发
01 微服务敏捷开发不简单
1 安得环境千万套,大庇开发小哥俱欢笑
微服务给大家带来了敏捷开发的特性,基于敏捷开发带来的便利,让我们可以在同一个时间内多个迭代/feature 并行开发。但微服务架构本身也给开发环境带来了一定的复杂性:每个 feature 的修改点都可能会被分散在多个应用中,需要多个应用互相配合才能完成整体的逻辑。这些应用既需要互相配合好,又不能让他们互相影响,故敏捷开发有时候也不是那么容易。
相信实践过微服务敏捷开发的同学曾经都遇到过以下情况:
1.开发接口时,应用无法独立地联调测试,需要依赖于下游的返回,所以一般都需要一个完整的开发环境,这个环境需要包含所有的其他应用。
2.A 同学辛辛苦苦,终于开发好了一个接口,但是部署到开发环境后,发现返回值一直是错的,就是不符合预期,百思不得其解。最终根据日志、arthas 层层跟踪下去,发现原来是另一个同事更新了下游应用的代码,导致原有逻辑发生了变更。
3.A 同学准备开始联调测试了,这时候他要找到开发 B 和 C 吼一嗓子确认:“我要开始测试了哈兄弟们,你们都别动环境,不要重启和 debug 哈”。B 同学 和 C 同学一脸懵逼:“我自己这还有个逻辑没理清楚呢,刚改完代码准备测一发,你这一测试联调我就不能动环境了,我这功能得等到什么时候才能开发好”。
4.排查问题好麻烦啊,要不直接 debug 一下吧,这 IDEA 远程 debug 刚连上去呢,立马就传来了同事的声音:“谁 XX 又在瞎动环境啊,怎么刚刚还能跑的接口现在就出错了”。
以上这些问题显然会影响项目的进度,非常容易造成项目延期。对于此刻的开发小哥哥而言,拥有一套属于自己的独立环境,带来的幸福感也许比有一套属于自己的小房子还大。
2 流量闭环是微服务敏捷开发的基础
上文中提到的问题,其实都是因为没有在开发环境中,精准地控制流量在 feature 环境内流转。
为什么精准地控制流量如此重要?举个最简单的微服务架构图来说明,这里假设应用的调用链路为 A ---> B ---> C ---> D ,现在同时开发两个 feature, feature1 和 feature2 。feature1 需要修改 A 和 C 的代码, feature2 需要修改 B、C 和 D 的代码。
为了方便表述,我们用 A、B、C、D 来代指 A、B、C、D 的线上稳定版本,也叫做基线版本;A1、C1 来代指 feature1 环境中的 A 和 C ;B2、C2、D2 来来代指 feature2 环境中 B、C、D。
那么开发测试 feature1 的同学会要求他的请求,准确地在 A1 ---> B ---> C1 ---> D 中流转。为什么一定要这样,我们来简单分析一下:
1.如果流量走到 A 或者 C 的基线环境,因为他们都没有包含 feature1 相关的代码,所以肯定是无法正常测试和联调 feature1 对应的功能。
2.如果流量走到 B2、D2 环境,大多数情况下是可以正常工作的,因为正常情况下 B2 和 D2 中的修改是不会影响 feature1 的。但是因为 feature1 和 feature2 可能是由不同的同学开发的,或者有不同的开发排期和节奏,他们有自己的开发、重启、debug 节奏,所以大概率还是会出现上文中提到的场景。
综上所述,让流量在 feature 环境内流转非常重要,是微服务敏捷开发的基础。
如何准确地让请求在 feature 环境内流转呢?最简单的办法是每个迭代/feature 的都享有一套独立的完整环境,这套独立的环境包含了整个微服务应用集所有的应用,包含注册中心和接入层,这样就能确保流量在 feature 环境里闭环,不用担心应用之间互相影响。
这个解决方案虽然简单,但是问题也很显而易见,成本比较大。我们假设微服务应用有10 个,每个应用只部署一台,以 java 为例,部署一个 java 应用按 2C4G 的 共享标准型 ECS 进行计算,维护一套环境一年的成本是 10 × 140 × 12 = 16800 元,如果同时有 4 套环境,即只支持两个迭代并行开发,每个迭代只有 2 个 feature,这样一年的成本就是 67200 元,而且我们可以发现,这里面计算公式使用的是乘法,当应用增加和环境增加时,成本的增加是成倍的。
注意,这里只是单纯地计算了应用使用的 ECS 的成本,其他周边的配套设施我们还没有计算,因为我们的开发、联调、测试是需要确保端到端的全流程都是足够顺利的,那这里就还会涉及到 域名/SLB/网关/注册中心这些资源,这些资源一般比较固定,不会需要进行大的修改,但是在多套环境的方案下这些资源也需要维护多套,成本还会进一步上升。
那么,有没有一个比较优雅地方式,既能享受到微服务架构带来的敏捷开发的便利,又不会给日常开发环境的搭建带来很大的成本呢?基于 MSE(微服务引擎 MSE,以下简称 MSE)标签路由功能使用开发环境隔离方案是您的不二之选。
3 如何低成本玩转敏捷开发
什么是 MSE 开发环境隔离,简单地说就是将 feature 环境的隔离方式从简单的物理隔离转为逻辑隔离。借助于 MSE 提供的逻辑隔离,您只需要维护一套完整的基线环境,在增加 feature 环境时,只需要单独部署这个 feature 所涉及到改动的应用即可,而不需要在每个 feature 环境都部署整套的微服务应用及其配套设施。
我们称这唯一的一套完整的环境为基线环境。基线环境包含了所有微服务应用,也包含了服务注册中心、域名、SLB、网关 等其他设施,而 feature 环境中只包含了这个 feature 中需要修改的应用。这样维护 n 套 feature 环境的成本,就变成了加法,而不是原来的乘法,由 n × m 变成了 n + m。差不多相当于零成本增加 feature 环境,这样我们就可以放心地扩容出多套 feature 环境,每个开发小哥哥都可以轻松拥有属于自己的独立环境,尽情地享受微服务敏捷开发。
从上图中我们可以看到,feature1 对应的流量,在发现 feature1 中存在 A1 应用时,一定会去往 A1 节点,A1在调用B的时候发现 feature1 环境中不存在 B1 ,则会将请求发到 基线版本的 B 中;B在调用C时,发现 feature1 环境存在 C1 应用,又会返回到 feature1 环境中,依次类推,确保了流量会在 feature1 环境中闭环。
而且,在这个过程中,您不需要修改任何代码和配置,直接接入 MSE 微服务治理即可使用,不会给您增加任何开发成本。
02 如何使用 MSE 开发环境隔离
1 开通 MSE 微服务治理专业版
登录 MSE治理中心控制台,如果您尚未开通 MSE 微服务治理,请根据提示开通专业版。如果您已经开通了MSE 微服务治理基础版,请根据概览页中右侧的提示,升级到 专业版。
2 部署基线环境/基线环境接入
首先需要将基线环境的所有应用接入到 MSE 中,接入方式与您开发环境中应用部署方式有关。这里我们拿两个典型的场景作为例子进行说明。更多接入场景请参考 MSE 帮助文档 MSE 微服务治理快速入门。
-
阿里云容器服务 ACK
若您的开发环境部署在 阿里云容器服务的 ACK 中,将基线环境接入 MSE 的流程如下:
1.在 ACK 中安装 MSE 治理中心组件
- 登录容器服务控制台。
- 在左侧导航栏单击市场 > 应用目录。
- 在应用目录页面搜索并单击 ack-mse-pilot。
- 在 ack-mse-pilot 页面右侧集群列表中选择集群,然后单击创建。
安装 MSE 微服务治理组件大约需要 2 分钟,请耐心等待。
创建成功后,会自动跳转到目标集群的发布页面,检查安装结果。如果出现以下页面,展示相关资源,则说明安装成功。
2.为 ACK 命名空间中的应用开启 MSE 微服务治理
3.完成上述步骤后,重启/部署基线版本的应用,您的基线环境就已经接入完成。
-
ECS/虚拟机
若您的应用是通过 ECS 或者 虚拟机的方式部署的,请您打开 MSE微服务治理控制台中的应用列表-接入方式-ECS 集群,根据指南里面的提示进行操作。
1.通过Shell脚本方式下载Agent 复制以下命令行并在待治理应用所处的系统中运行。
wget -O- http://mse-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/install.sh | sh # 此命令具体内容会随着您控制台中的选择的 Region 而变化,请注意在控制台中选择机器所在的 Region # 若您的机器不在阿里云环境中,请选择 杭州 Region。
2.接入 MSE Agent
a. 将MseAgent.zip中的所有文件解压到任意目录中。
unzip MseAgent -d /{user.workspace}/ # 说明 “{user.workspace}”是示例路径,请根据具体环境替换为正确的路径。
b. 在应用启动参数上添加AppName以及LicenseKey参数。
java -javaagent:/{user.workspace}/MseAgent/mse-bootstrap-1.7.0-SNAPSHOT.jar
-Dmse.licenseKey=<yourLicenseKey>
-Dmse.appName=<yourAppName>
-Dmse.enable=true -jar A.jar #系统将为您自动生成的 <yourLicenseKey> ,在上文中提到的 ECS接入指南 界面查看,请勿泄露。 #<yourAppName> 为应用名称,同一应用在后续的 feature 环境接入需要保持应用名称一致
注意:各个 Region 的 LicenseKey 值可能不一致,请注意选择正确的 Region,若您的机器不在阿里云环境中,请选择 杭州 Region。
-
验证环境接入成功
完成上述步骤后,您的基线环境就已经部署好了。您可以在 MSE 控制台中找到对应的 Region 查看应用列表,以及应用详情页的节点情况。
3 将应用接入 feature 环境
将应用接入 feature 环境的方式和第二步中的方式基本相同,只不过这里需要额外给应用打上一个标签,将这个应用标记为属于 feature 环境。
同样的,接入 feature 环境的方式也和应用的部署形态相关,这里同样分别以 K8s 和 ECS 方式举例,如何将 A 应用接入到 feature1 环境。
-
K8s 部署方式
如果您的应用是通过 K8s 方式部署,则应用在接入 feature1 环境时需要在 deployment 中的 spec > template > metadata 下的 annotations 增加如下配置:
spec:
template:
metadata:
annotations:
alicloud.service.tag: feature1
-
ECS/虚拟机
如果您的应用是通过 ECS/虚拟机的方式部署,则应用在接入 feature1 环境时需要额外配置 JVM 系统属性(SystemProperty) ,增加的方式为在 Java 启动命令中增加 `-Dalicloud.service.tag=feature1`,完整的启动命令如下:
java -javaagent:/{user.workspace}/MseAgent/mse-bootstrap-1.7.0-SNAPSHOT.jar -Dmse.licenseKey=<yourLicenseKey> -Dmse.appName=<yourAppName> -Dmse.enable=true -Dalicloud.service.tag=feature1 -jar A.jar
-
验证环境接入成功
完成上述操作后,登录 MSE 控制台,找到刚才启动的应用,在详情页面查看实例详情,可以确认节点的 ip 和标签是否符合预期。
4 轻松开始联调和测试
假设我们发往网关的请求是 http 请求,希望这个请求再 feature1 中完成闭环,只需要在请求的 header 中添加 x-mse-tag=feature1 即可,流量会自动在 feature1 环境内完成闭环。注意这里的 key 为 x-mse-tag 为固定值,feature1 则需要和环境的标签(即上文中配置的 alicloud.service.tag)保持一致。
如果您的请求来源为 Dubbo,则需要在 RpcContext 中增加 Attachment ,内容也是 x-mse-tag=feature1。
特别地,如果您的网关应用不属于 Java 体系,则需要在网关层配置一下规则,目前已经支持 MSE云原生网关,Nginx,K8s Ingress 等,详细的接入方式可以参考 MSE 全链路灰度配置 。
03 更进一步 IDEA 接入 feature 环境
上文中提到过,开发联调过程中,将应用部署到联调环境也是需要成本的,能不能直接在 IDEA 里面把正在开发的微服务跑起来呢?这样岂不是就可以直接愉快地快速部署和 debug 了?当然可以!而且操作起来还非常简单!
将 IDEA 启动的应用直接接入到 feature 环境中也不复杂,只需要简单几步即可实现。
注意:使用此特性的前提条件为,您本机的网络与开发环境其他应用能够正常通讯。
1 安装 CloudToolkit 插件
安装最新版本的 Cloud Toolkit,安装详情请参考官网:https://www.aliyun.com/product/cloudtoolkit
2 配置 MSE 参数
点击 IDEA 的 Tools 中找到 Preference ,找到 Alibaba Cloud Toolkit 中 Microservice 下的 MSE ,点击 开启微服务治理,并安装下图的方式进行配置即可。
对以下几个参数做一下说明:
LicenseKey
您阿里云账号对应的 MSE 产品的 LicenseKey ,请在 https://mse.console.aliyun.com/#/msc/app/accessType 中的选择 ECS 集群,在 安装 MSE Agent 章节找到 LicenseKey 的值。
注意:请您做好 LicenseKey 的保密工作。
注意:各个 Region 的 LicenseKey 值可能不一致,请选择对应的 Region,并和基线环境接入的 Region 保持一致。
App Name
应用在接入 MSE 时所使用的应用名,请根据实际业务情况进行配置,注意这个值需要和本次所启动的应用保持一致。
Tag
此应用所属的环境 Tag,基线不用填,其他请根据实际业务情况进行填写。如果此应用属于 feature1 环境,请填写 feature1。
Agent 地址
选择自己应用所在的地域,需要和 LienseKey 所在的地域、以及基线环境接入的地域 都保持一致。
开启 RPC 灰度 ✅
支持对 Spring Cloud 和 Dubbo 近5年内的所有版本的流量进行精准控制。默认情况下请开启,除非您明确知道关闭此选项的使用场景,否则请勿关闭此选项。
开启标签染色 ✅
推荐开启,开启后经过此应用的流量就只会在对应的 Tag 环境中流转。
开启消息灰度 ✅
请根据业务实际情况选择是否开启,目前仅支持 RocketMQ 4.2 及以上版本。
3 验证应用是否接入成功
1.使用常见的 IDEA 启动应用的方式进行启动
2.登录 MSE 控制台,选择对应 Region ,找到刚才填写的应用名,点击此应用名,如果在应用详情中发现了本地对应的 IP 和 Tag ,表明接入成功。.
注意,第一第二步只需要执行一次,若 AppName 和 Tag 发生了变更,则根据实际情况进行调整。
4 接入成功
现在,您可以在 IDEA 中尽情地享受本地开发部署和 debug 的快感。