开发指南 - support.huaweicloud.com · 默认配置包含了处理链、负载均衡策略等。...
TRANSCRIPT
微服务云应用平台
开发指南
文档版本 01
发布日期 2019-06-19
华为技术有限公司
版权所有 © 华为技术有限公司 2019。 保留一切权利。
非经本公司书面许可,任何单位和个人不得擅自摘抄、复制本文档内容的部分或全部,并不得以任何形式传播。 商标声明
和其他华为商标均为华为技术有限公司的商标。本文档提及的其他所有商标或注册商标,由各自的所有人拥有。 注意
您购买的产品、服务或特性等应受华为公司商业合同和条款的约束,本文档中描述的全部或部分产品、服务或特性可能不在您的购买或使用范围之内。除非合同另有约定,华为公司对本文档内容不做任何明示或默示的声明或保证。
由于产品版本升级或其他原因,本文档内容会不定期进行更新。除非另有约定,本文档仅作为使用指导,本文档中的所有陈述、信息和建议不构成任何明示或暗示的担保。
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 i
目 录
1 Java SDK.....................................................................................................................................11.1 概述.............................................................................................................................................................................................. 11.2 Java-Chassis 开发..................................................................................................................................................................... 21.2.1 应用接入 ServiceComb 引擎.............................................................................................................................................. 21.2.2 灰度发布.................................................................................................................................................................................. 51.2.3 负载均衡.................................................................................................................................................................................. 71.2.4 限流........................................................................................................................................................................................ 131.2.5 降级........................................................................................................................................................................................ 141.2.6 熔断........................................................................................................................................................................................ 181.2.7 错误注入................................................................................................................................................................................ 181.2.8 使用调用链........................................................................................................................................................................... 211.2.9 使用仪表盘........................................................................................................................................................................... 211.2.10 文件上传............................................................................................................................................................................. 221.2.11 文件下载............................................................................................................................................................................. 241.2.12 Reactive.............................................................................................................................................................................. 261.2.13 AK/SK 加密存储................................................................................................................................................................ 301.3 Spring Cloud 开发................................................................................................................................................................. 321.3.1 应用接入 ServiceComb 引擎............................................................................................................................................321.3.2 使用注册中心....................................................................................................................................................................... 341.3.3 使用分布式配置服务.......................................................................................................................................................... 361.3.4 接入分布式事务引擎 DTM............................................................................................................................................... 381.3.5 使用路由管理....................................................................................................................................................................... 421.3.6 路由管理规则说明.............................................................................................................................................................. 441.4 在 Spring Boot 中使用 CSE................................................................................................................................................. 451.4.1 背景介绍................................................................................................................................................................................ 451.4.2 CSE 提供的组件说明.......................................................................................................................................................... 461.4.3 Java 应用方式开发步骤..................................................................................................................................................... 471.4.4 Web 开发方式开发步骤.................................................................................................................................................... 491.4.5 Java 应用方式和 Web 开发方式的差异........................................................................................................................ 501.4.6 Spring MVC 模式的差异................................................................................................................................................... 501.5 使用 CSE-Codegen 插件.......................................................................................................................................................511.5.1 CSE-Codegen 插件概述.................................................................................................................................................... 521.5.2 使用 CSE-Codegen 插件开发微服务..............................................................................................................................52
微服务云应用平台开发指南 目 录
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 ii
2 Go SDK..................................................................................................................................... 572.1 概述............................................................................................................................................................................................ 572.2 工作原理................................................................................................................................................................................... 582.3 开发指导................................................................................................................................................................................... 582.3.1 定义微服务........................................................................................................................................................................... 582.3.2 注册中心................................................................................................................................................................................ 602.3.3 配置中心................................................................................................................................................................................ 612.3.4 协议服务器........................................................................................................................................................................... 622.3.5 处理链.................................................................................................................................................................................... 632.3.6 Invoker...................................................................................................................................................................................642.3.7 负载均衡策略....................................................................................................................................................................... 652.3.8 负载均衡过滤器................................................................................................................................................................... 672.3.9 使用 Archaius 管理动态配置........................................................................................................................................... 672.3.10 路由策略............................................................................................................................................................................. 692.3.11 限流...................................................................................................................................................................................... 732.3.12 容错...................................................................................................................................................................................... 742.3.13 熔断降级............................................................................................................................................................................. 752.3.14 传输层配置......................................................................................................................................................................... 752.3.15 Metrics................................................................................................................................................................................ 752.3.16 TLS........................................................................................................................................................................................ 762.3.17 契约管理............................................................................................................................................................................. 762.3.18 Java 和 Go 互相调用........................................................................................................................................................ 772.4 自定义功能............................................................................................................................................................................... 772.4.1 Log.......................................................................................................................................................................................... 772.4.2 Handler................................................................................................................................................................................. 782.4.3 Go-Archaius......................................................................................................................................................................... 792.4.4 Protocol................................................................................................................................................................................. 812.5 运维............................................................................................................................................................................................ 812.5.1 指标监控................................................................................................................................................................................ 812.5.2 日志采集与查看................................................................................................................................................................... 822.5.3 熔断定位................................................................................................................................................................................ 84
3 Mesh 指南................................................................................................................................ 863.1 简介............................................................................................................................................................................................ 863.2 配置............................................................................................................................................................................................ 873.2.1 简介........................................................................................................................................................................................ 883.2.2 ak/sk(公有云使用)........................................................................................................................................................ 883.2.3 定制 Cipher 加解密工具.................................................................................................................................................... 883.2.4 对接服务中心和配置中心................................................................................................................................................. 903.2.5 微服务信息定义................................................................................................................................................................... 903.2.6 负载均衡与重试................................................................................................................................................................... 913.2.7 熔断降级................................................................................................................................................................................ 923.2.8 限流........................................................................................................................................................................................ 95
微服务云应用平台开发指南 目 录
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 iii
3.2.9 监控........................................................................................................................................................................................ 963.2.10 TLS........................................................................................................................................................................................ 973.2.11 路由规则........................................................................................................................................................................... 1003.2.12 错误注入........................................................................................................................................................................... 1053.2.13 契约配置........................................................................................................................................................................... 1053.3 Admin API............................................................................................................................................................................. 1063.3.1 简介...................................................................................................................................................................................... 1063.3.2 健康检查............................................................................................................................................................................. 1063.3.3 Mesher 版本信息..............................................................................................................................................................1073.3.4 路由信息............................................................................................................................................................................. 1083.3.5 Metric 信息........................................................................................................................................................................ 1103.4 多协议接入............................................................................................................................................................................ 1123.4.1 gRPC.................................................................................................................................................................................... 1123.5 多语言接入............................................................................................................................................................................ 1123.5.1 nodejs 接入 Mesher........................................................................................................................................................ 1123.5.2 PHP 接入 Mesher............................................................................................................................................................. 1123.5.3 .NET 接入 Mesher............................................................................................................................................................ 1123.6 运维......................................................................................................................................................................................... 1173.6.1 日志查看............................................................................................................................................................................. 117
4 远程调试................................................................................................................................. 1204.1 概述......................................................................................................................................................................................... 1204.2 下载安装................................................................................................................................................................................. 1234.3 操作指南................................................................................................................................................................................. 1254.3.1 调试准备............................................................................................................................................................................. 1254.3.2 开始调试............................................................................................................................................................................. 1304.4 常见错误处理........................................................................................................................................................................ 1354.4.1 Eclipse 插件错误提示及处理......................................................................................................................................... 1354.4.2 CloudDebug 内部错误日志说明及处理方法............................................................................................................. 1364.5 缩略语..................................................................................................................................................................................... 137
5 Eclipse ServiceStage 插件使用指南................................................................................... 1385.1 快速开始................................................................................................................................................................................. 1385.2 应用管理................................................................................................................................................................................. 1395.3 应用模型和契约管理........................................................................................................................................................... 143
6 应用绑定的中间件配置信息说明...........................................................................................156
7 DTM Client SDK 开发指南...................................................................................................1587.1 概述......................................................................................................................................................................................... 1587.2 接口说明................................................................................................................................................................................. 1607.3 开发环境搭建........................................................................................................................................................................ 1637.4 Demo 样例参考.................................................................................................................................................................... 164
8 servicestage-maven-plugin 使用指南.............................................................................. 169
微服务云应用平台开发指南 目 录
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 iv
8.1 工具介绍................................................................................................................................................................................. 1698.2 使用指南................................................................................................................................................................................. 171
9 移动应用 QuickAPP 开发指南..............................................................................................1759.1 概述......................................................................................................................................................................................... 1759.2 阅读须知................................................................................................................................................................................. 1769.3 创建移动后端........................................................................................................................................................................ 1769.4 开发工具设置........................................................................................................................................................................ 1789.5 加载 Quick App 样例.......................................................................................................................................................... 1819.6 导入示例数据........................................................................................................................................................................ 1829.7 连接移动后端........................................................................................................................................................................ 1849.8 在移动设备上运行 APP.......................................................................................................................................................1869.9 (可选)设置 Android 模拟器......................................................................................................................................... 1899.10 (可选)在模拟器中运行移动应用...............................................................................................................................1979.11 (可选)使用 Quick App 构建移动应用程序............................................................................................................ 2009.12 (可选)开始开发自己的移动应用...............................................................................................................................204
微服务云应用平台开发指南 目 录
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 v
1 Java SDK
1.1 概述
使用CSE Java SDK开发微服务,可以 大化的简化开发门槛,提升产品上线速度。同时可以获得微服务运行时高可靠性保证、运行时动态治理等一系列开箱即用的能力。
CSE Java SDK 100% 兼容 ServiceComb Java Chassis。本文主要描述CSE Java SDK的扩展和易用性增强内容,以及与其他开发框架集成,在公有云上部署等主题,使用CSE Java SDK开发第一个微服务请参考“环境准备”。
为了描述简单,本文会使用CSE指代CSE Java SDK,使用ServiceComb指代ServiceComb Java Chassis。
版本获取
1. profiles中增加如下配置。<profile> <id>MyProfile</id> //id自定义 <repositories> <repository> <id>HuaweiCloudSDK</id> <url>https://mirrors.huaweicloud.com/repository/maven/huaweicloudsdk/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories></profile>
2. 在mirrors节点中增加:<mirror> <id>huaweicloud</id> <mirrorOf>*,!HuaweiCloudSDK</mirrorOf> <url>https://mirrors.huaweicloud.com/repository/maven/</url></mirror>
3. 新增activeProfiles配置。<activeProfiles> <activeProfile>MyProfile</activeProfile> //跟步骤1中的MyProfile保持一致</activeProfiles>
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 1
1.2 Java-Chassis 开发
1.2.1 应用接入 ServiceComb 引擎CSE Java SDK 100% 兼容 ServiceComb Java Chassis,并对其进行更加友好的封装,更加专注于业务逻辑,以简化用户业务开发。将ServiceComb Java Chassis部署到CSE,并使用CSE提供的能力,只需要对microservice.yaml进行适当的配置,以及在pom中添加额外的依赖,不涉及任何代码修改。
● microservice.yaml{project}/src/main/resources/microservice.yaml
说明
microservice.yaml中默认配置服务中心、配置中心、仪表盘地址为公有云地址,其他合营云请根据实际情况配置。
● pom.xml{project}/pom.xml
前提条件● 已获取AK/SK,请参考下载AK/SK。
● 已获取项目名,如未获取请参考查看项目名。
配置应用 AK/SK 密钥
微服务连接公有云上的CSE服务中心、配置中心、仪表盘时,需要提供AK/SK秘钥信息,否则无法通过认证。
步骤1 若应用通过在ServiceStage创建的容器应用的方式,CSE将自动从应用所在集群获取认证信息,无需配置AKSK密钥信息,请跳过步骤2和步骤3。
步骤2 获取AK/SK方式
1. 注册并登录管理控制台。
2. 鼠标放至右上角用户名,单击“我的凭证”。
3. 在“管理访问密钥”页签,单击“新增访问密钥”,进入“新增访问密钥”页面。
4. 输入登录密码、短信或者邮箱验证码,单击“确定”,下载密钥,请妥善保管。
步骤3 配置项。cse: credentials: accessKey: ak #结合用户实际值ak和加解密扩展进行配置我的凭证 secretKey: sk #结合用户实际值sk和加解密扩展进行配置 akskCustomCipher: default #用户扩展解密com.huawei.paas.foundation.auth.credentials.AKSKCipher的实现类的name值, 默认default表示明文,无须加解密
该配置项配置了应用的AK/SK密钥信息,为了信息的安全,请用户对AK/SK密钥加密后进行配置。扩展AK/SK解密方式请参考如何扩展AK/SK解密方式。
----结束
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 2
一键式配置
公有云版本提供了一键式简化配置的方式,让基于开源版本开发的应用快速切换为云上应用,直接使用公有云提供的灰度发布、服务治理等功能。
增加和管理依赖关系(pom.xml) 增加依赖管理
<dependencyManagement> <dependencies> <dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>cse-dependency</artifactId> <version>2.3.58</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
并引入依赖<dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>cse-solution-service-engine</artifactId></dependency>
开发者只需要配置对cse-solution-service-engine依赖,就完成了公有云的所有配置。这个依赖关系主要给开发者做了如下事情:
● 引入相关依赖的组件。
● 增加默认配置项。默认配置包含了处理链、负载均衡策略等。
可以通过查看pom内容,以及这个jar包里面的microservice.yaml文件查看引入的组件和增加的配置项。在下面的章节中,详细解释上云增加的组件以及他们的作用,使开发者更加深入的了解各种技术细节。
接入方式
ServiceComb 引擎提供了两种接入方式
● 配置引擎名字,通过服务发现的方式,自动发现连接服务中心与配置中心,接入ServiceComb引擎。适用于 CSE Java SDK(2.3.63及更高版本)。
● 配置服务中心与配置中心地址,直接接入ServiceComb引擎。
配置引擎名字接入 ServiceComb 引擎
CSE Java SDK开发的应用接入ServiceComb引擎,只需要配置引擎名字,便可以通过服务发现的方式自动连接服务中心与配置中心。不需要再手动配置服务中心和配置中心地址。
步骤1 登录ServiceStage控制台,选择“工具下载 > 微服务框架”,使用Java SDK创建并下载一个helloworldprovider工程。
步骤2 解压,并在Eclipse导入Maven工程。
步骤3 修改配置,此处按照使用公有云服务中心的方式配置。
修改src/main/resources目录下的microservice.yaml文件,用于存放配置信息。cse: credentials: project: Project //引擎所在项目或子项目名称,默认为cn-north-1;若无法解析,则配置为
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 3
default,可能导致token认证失败。获取方法见本章节前提条件。servicecomb: engine: engineName: engineName //请填写正确的ServiceComb专享版引擎 引擎名字. 如果要使用逻辑多租引擎 Cloud Service Engine,这里可以填写 default
步骤4 修改代码,作为后期验证的输出。
在src/main/java/com/service/helloworldprovider/controller/helloworldproviderDelegate.java中打印一句“Welcome”,示例如下:
public class helloworldproviderDelegate {
public String helloworld(String name){ return "Welcome, " + name; }}
请修改测试用例,将测试用例方法中的内容注释掉,文件位置为src/test/java/com/service/helloworldprovider.controller/Testhelloworldprovider.java。
步骤5 在Eclipse中选中目标工程运行“Run as > Maven install”。
说明
由于网络原因,首次在apache中央仓库下载某些依赖包可能失败,因此首次导入时,可多次执行maven install下载全量依赖包。
步骤6 在helloworldproviderApplication.java上右键执行“Run as > Java Application”。
步骤7 选择“基础设施 > 微服务引擎”,单击目标引擎的“查看控制台”,在“服务目录”页面下就可以看到helloworldprovider微服务。
步骤8 使用浏览器访问http://127.0.0.1:8087/{Service Name}/helloworld?name="Tom",窗口中打印以下内容,表明服务已在正常运行。
说明
创建本地工程时,如果自定义了Bath Path,请将{Service Name}替换为自定义的Bath Path。
"Welcome, \"Tom\""
----结束
配置服务中心、配置中心地址接入 ServiceComb 引擎
连接服务中心
服务中心实现注册和发现,在公有云查看微服务目录,都需要微服务连接上服务中心。
● 增加依赖关系(pom.xml)如果连接服务中心使用https协议或AK/SK认证,该jar依赖必选。如果是http协议,并不包含token验证,则无需引入<groupId>com.huawei.paas.cse</groupId><artifactId>foundation-auth</artifactId>
● 启用配置(microservice.yaml)cse: service: registry: address: https://cse.cn-north-1.myhuaweicloud.com:443 #根据实际地址配置服务中心地址
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 4
该配置项配置了服务中心的地址。
其中,address可以在公有云“工具下载 > 微服务框架”页面查到对应的服务中心地址,修改协议(http/https)、主机名(可能使用域名)和端口号。
连接配置中心
配置中心实现配置下发,连接配置中心是使用治理、灰度发布等功能的前提。
● 增加依赖关系(pom.xml)如果连接配置中心使用https协议或AK/SK认证,该jar依赖必选。如果是http协议,并不包含token验证,则无需引入。
com.huawei.paas.cse foundation-auth
连接配置中心该jar必选
org.apache.servicecomb config-cc
● 启用配置(microservice.yaml)cse: config: client: serverUri: https://cse.cn-north-1.myhuaweicloud.com:443
该配置项配置了配置中心的地址。
其中,serverUri可以在公有云“工具下载 > 微服务框架”页面查到对应配置中心地址,修改协议(http/https)、主机名(可能使用域名)和端口号。
1.2.2 灰度发布
场景描述
用户可以通过使用灰度发布,实现版本的平滑过渡升级。案例请参考Weathermap天气预报Demo。
注意事项
1. 若要使用灰度发布功能,需要微服务对接配置中心。
2. 灰度规则如果是自定义规则,那么匹配的参数可以是接口定义的参数,也可以是context参数。
– 配置接口定义参数的示例代码如下:// 服务接口public interface Compute { int add(int a, int b);}// 调用服务@RpcReference(microserviceName = "hello", schemaId = "codeFirstCompute")public static Compute compute;
public static void main(String[] args) throws Exception { Log4jUtils.init(); BeanUtils.init(); System.out.println("a=1, b=2, result=" + compute.add(1, 2));}
灰度规则配置示例如下:{ "policyType": "RULE",
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 5
"ruleItems": [ { "groupName": "test", "groupCondition": "version=0.0.2", "policyCondition": "a<15" } ]}
须知
灰度规则中过滤的接口参数必须是在接口方法参数表中直接定义的,不能选择一个对象类型参数的某个字段做过滤。
– 配置context参数的示例代码如下:InvocationContext invocation = new InvocationContext();invocation.addContext("ta", "tvalue");ContextUtils.setInvocationContext(invocation);
由于context参数只能是String类型的,所以相对应的自定义灰度规则只能过滤String类型的参数,示例如下:{ "policyType": "RULE", "ruleItems": [ { "groupName": "test", "groupCondition": "version=0.0.2", "policyCondition": "ta~tva*" } ]}
配置说明
灰度发布功能需要配置maven依赖和在Consumer端配置负载均衡。
1. 增加依赖关系(pom.xml)<dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>cse-handler-cloud-extension</artifactId></dependency>
2. 添加服务依赖版本规则,就是消费端对服务端依赖的版本范围。由于客户端默认只会下载 新版本的微服务实例,在启用灰度发布的时候,灰度规则默认只应用于 新版本,灰度发布的效果可能和实际的预期效果不同。如果一个微服务需要支持灰度发布,建议增加如下配置项:cse: references: servicename: # servicename是依赖的微服务的名称,下同 version-rule: 0.0.1+
3. 配置灰度规则,在microservice.yaml文件中增加如下配置:cse: darklaunch: policy: servicename: "{\"policyType\":\"RULE\",\"ruleItems\":[{\"groupName\":\"test\",\"groupCondition\":\"version=0.0.2\",\"policyCondition\":\"age<15\"}]}"
灰度规则的内容本身是一个Json串,以上示例中的配置表示的含义是:一个名为test的灰度规则配置,将参数中age < 15的请求发送给版本为0.0.2的微服务。灰度规则格式化后是这样的:{ "policyType": "RULE",
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 6
"ruleItems": [ { "groupName": "test", "groupCondition": "version=0.0.2", "policyCondition": "age<15" } ]}
各项配置含义如下:
– policyType:有RULE/RATE两种取值。RULE表示自定义规则,RATE表示百分比权重。
– ruleItems:灰度规则配置项。
– groupName:灰度规则分组名称。
– groupCondition:灰度规则作用域,当前支持按版本号配置,表示此灰度规则适用于哪个版本的微服务。当灰度规则作用域包含多个版本号时,使用英文逗号分隔版本号,例如"groupCondition": "version=0.0.2,0.0.1"。
– policyCondition:灰度规则。如果policyType=RATE,则此配置项为一个数字,例如policyCondition=80表示流量有80%的概率流到此版本的微服务;如果policyType=RULE,则policyCondition填写自定义的规则,现在支持=、>、<、~(~表示模糊匹配,例如name~a*表示匹配所有name参数以a开头的值),如果是context参数,由于context参数都是string类型,所以这些操作符对应的是string操作。
须知
目前灰度发布的自定义策略,支持的数据类型只包含String和Integer。 使用灰度发布涉及业务提前规划,在做规划的时候,如果基于请求参数,请使用String或者Integer两种类型的参数。
1.2.3 负载均衡
场景描述
CSE Java SDK提供了基于Ribbon的负载均衡方案,用户可以通过配置文件配置负载均衡策略,当前支持随机、顺序、基于响应时间的权值等多种负载均衡路由策略。
配置说明
负载均衡策略在microservice.yaml文件中配置,配置项为cse.loadbalance.[MicroServiceName].[property name],其中若省略MicroServiceName,则为全局配置;若指定MicroServiceName,则为针对特定微服务的配置。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 7
表 1-1 配置项说明
配置项 默认值 取值范围 是否必选
含义 注意
cse.loadbalance.strategy.name
RoundRobin
RoundRobin(轮询)
Random(随机)
WeightedResponse(服务器响应时间权值)
SessionStickiness(会话保持)
否 负载均衡路由策略
-
cse.loadbalance.SessionStickinessRule.sessionTimeoutInSeconds
30 Integer 否 客户端闲置时间,超过限制后选择后面的服务器。
暂不支持微服务配置。e.g.cse.loadbalance.SessionStickinessRule.sessionTimeoutInSeconds,不能配置为cse.loadbalance.DemoService.SessionStickinessRule.sessionTimeoutInSeconds
cse.loadbalance.SessionStickinessRule.successiveFailedTimes
5 Integer 否 客户端失败次数,超过后会切换服务器
暂不支持微服务配置
cse.loadbalance.retryEnabled
FALSE Boolean 否 负载均衡捕获到服务调用异常,是否进行重试
-
cse.loadbalance.retryOnNext
0 Integer 否 尝试新的服务器的次数
-
cse.loadbalance.retryOnSame
0 Integer 否 同一个服务器尝试的次数
-
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 8
配置项 默认值 取值范围 是否必选
含义 注意
cse.loadbalance.isolation.enabled
FALSE Boolean 否 是否开启故障实例隔离功能
-
cse.loadbalance.isolation.enableRequestThreshold
20 Integer 否 当实例的调用总次数达到该值时开始进入隔离逻辑门槛
-
cse.loadbalance.isolation.continuousFailureThreshold
- Integer 否 当请求实例连续出错达到此阈值时触发实例隔离
若配置了此项则覆盖实例故障百分比的配置,否则按照实例故障百分比触发隔离。
由于按请求错误率触发实例隔离在请求次数较多时不易触发也不易恢复,因此建议使用此配置项代替实例故障百分比配置。
请求实例成功时会将连续错误次数请零以保证实例快速恢复。
cse.loadbalance.isolation.errorThresholdPercentage
20 Integer,区间为(0,100]
否 实例故障隔离错误百分比
-
cse.loadbalance.isolation.singleTestTime
10000 Integer 否 故障实例单点测试时间
单位为ms
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 9
配置项 默认值 取值范围 是否必选
含义 注意
cse.loadbalance.transactionControl.policy
com.huawei.paas.cse.loadbalance.filter.SimpleTransactionControlFilter
- 否 动态路由分流策略
框架提供了简单的分流机制,开发者也可以实现自定义的分流过滤策略
cse.loadbalance.transactionControl.options
- key/valuepairs
否 针对SimpleTransactionControlFilter分流策略的配置项,可添加任意项过滤标签
-
示例代码
负载均衡策略配置在src\main\resources\microservice.yaml文件中。
● 配置处理链:cse: # other configurations omitted handler: chain: Consumer: default: loadbalance
● 增加路由策略:cse: # other configurations omitted loadbalance: strategy: name: RoundRobin
自定义路由策略
用户可以在CSE Java SDK提供的路由策略框架下根据业务需要,通过编程的方式来开发路由策略。实施步骤如下:
步骤1 实现接口com.netflix.loadbalancer.IRule中定义的接口方法。路由选择逻辑在publicServer choose(Object key)方法中实现。 LoadBalancerStats是一个封装了负载均衡器当前运行状态的一个结构。通过获取stats中各个实例的运行指标,在choose方法中,判定将当前请求路由到哪个实例上进行处理。处理风格可以参照org.apache.servicecomb.loadbalance.SessionStickinessRule。
步骤2 定义一个负载均衡规则工厂类,实现接口ExtensionsFactory。
其中,boolean isSupport(String key, String value)方法用于确定此工厂是否支持microservice.yaml文件中配置的规则(key值为
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 10
Configuration.PROP_RULE_STRATEGY_NAME,value值为自定义的规则名称);IRule createLoadBalancerRule(String ruleName)方法用于获取对应的规则。具体实现方式参考org.apache.servicecomb.loadbalance.RuleNameExtentionsFactory,该实现类需要打上@Component注解以保证能够被引用。
步骤3 通过CSE Java SDK配置该负载均衡策略,假如是AbcRule。则配置如下: cse: loadbalance: strategy: name: AbcRule
----结束
过滤器机制
handler-loadbalance模块提供了Filter机制,用来过滤选择provider实例,CSE JavaSDK提供的Filter有IsolationServerListFilter和ZoneAwareServerListFilterExt,用户也可自行扩展Filter。
使用ZoneAwareServerListFilterExt选择provider实例
ZoneAwareServerListFilterExt使得consumer实例可以优先选择和自己处于同一region和zone的provider实例进行调用。
说明
这里的region和zone是一般性的概念,用户可以自定确定其业务含义以便应用于资源隔离的场景中。关于公有云ServiceStage中的实例隔离层次关系,参见微服务实例之间的逻辑隔离关系。
步骤1 Provider端配置。
启动两个provider实例,其中一个provider实例的microservice.yaml文件中增加如下配置:
cse: # config region and zone information datacenter: name: myDC region: my-Region availableZone: my-Zone
步骤2 Consumer端配置。
在Consumer端的microservice.yaml文件中增加如下配置:
cse: loadbalance: # add zone aware filter serverListFilters: zoneAware serverListFilter: zoneAware: className: org.apache.servicecomb.loadbalance.filter.ZoneAwareServerListFilterExt # config region and zone information datacenter: name: myDC region: my-Region availableZone: my-Zone
步骤3 使Consumer调用provider。
由于ZoneAwareServerListFilterExt的存在,Consumer实例会优先选择和自己同一个region和availableZone下的Provider实例进行调用。如果没有region和zone都相同的
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 11
provider实例,则选择region相同的实例;如果还是没有符合条件的实例,则选择任一可用实例做调用。
----结束
开发自定义过滤器
用户可以开发自定义的过滤器来满足自己的业务场景,步骤如下:
1. 实现ServerListFilterExt接口,过滤provider实例列表的逻辑在List<T>getFilteredListOfServers(List<T> servers)方法中实现。
2. 确保编译的filter实现类在classpath下。
3. 在microservice.yaml文件中增加filter配置。
示例开发
现在假设用户需要为每个Consumer和Provider实例配置各自的优先级,从低到高为0~9,高优先级的Provider实例只可以调用平级或低优先级的consumer实例,以此为前提开发一个示例。
1. 开发一个Filter,实现ServerListFilterExt接口,代码如下:package org.servicecombexam.loadbalance.filter;// import is omittedpublic class ExamFilter implements ServerListFilterExt { public static final String PRIORITY_LEVEL = "priorityLevel"; @Override public List<Server> getFilteredListOfServers(List<Server> servers) { List<Server> result = new ArrayList<>(); String priority = RegistryUtils.getMicroserviceInstance().getProperties().get(PRIORITY_LEVEL); for (Server server : servers) { if (priorityMatched(priority, server)) { result.add(server); } } return result; } /** * if the priority level is not specified, it will be regarded as 0 * @return whether a server can be invoked by this consumer instance, according to priority level */ private boolean priorityMatched(String priority, Server server) { String serverPriority = ((CseServer) server).getInstance().getProperties().get(PRIORITY_LEVEL); if (!StringUtils.isEmpty(priority) && !StringUtils.isEmpty(serverPriority)) { return priority.compareTo(serverPriority) >= 0; } if (StringUtils.isEmpty(serverPriority)) { return true; }
return false; }}
2. 在Provider的microservice.yaml文件中配置优先级等级:instance_description: properties: # instance_description.properties下的是实例级配置项,本示例将优先级配置放在这里存储。实验中会启动三个实例,优先级分别为0~2 priorityLevel: 2
3. 在Consumer的microservice.yaml文件中配置优先级等级和Filter:instance_description: properties: # consumer优先级等级为1,可以调用优先级为0或1的provider实例
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 12
priorityLevel: 1cse: loadbalance: serverListFilters: priorityFilter # filter名称,可以以','分隔配置多个filter serverListFilter: priorityFilter: # 此处配置的filter名称需要与cse.loadbalance.serverListFilters中配置的相符 className: org.servicecombexam.loadbalance.filter.ExamFilter # 自定义filter的类名
4. 令Consumer调用Provider进行验证,可以发现只有优先级为0和1的Provider实例会被调用,而优先级为2的Provider实例不会被调用。
1.2.4 限流
场景描述
● 用户在Provider端使用限流策略,可以限制指定微服务向其发送请求的频率,达到限制每秒钟 大请求数量的效果。
● 用户在Consumer端使用限流策略,可以限制发往指定微服务的请求的频率。
注意事项
1. 限流策略的控制并不是绝对精确的,可能会有少量误差。
2. provider端的流量控制是业务层面的功能,不是安全意义上的流量控制,如需防止DDoS攻击,需要结合其他的一系列措施。
3. 流量控制是微服务级的,不是进程级的。
配置说明-Provider
限流策略配置在microservice.yaml文件中,相关配置项见表1-2。要开启服务提供者端的限流策略,还需要在处理链中配置服务端限流handler,并添加pom依赖。
● microservice.yaml配置示例如下:cse: handler: chain: Provider: default: qps-flowcontrol-provider
● 添加handler-flowcontrol-qps的pom依赖:<dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>handler-flowcontrol-qps</artifactId> <version>1.0.0.B003</version></dependency>
表 1-2 QPS 流控配置项说明
配置项 默认值 取值范围 是否必选
含义 注意
cse.flowcontrol.Provider.qps.enabled
true true/false 否 是否启用Provider流控
-
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 13
配置项 默认值 取值范围 是否必选
含义 注意
cse.flowcontrol.Provider.qps.limit.[ServiceName].[Schema].[operation]
2147483647(maxint)
(0,2147483647],整形
否 每秒钟允许的请求数
支持microservice、schema、operation三个级别的配置
cse.flowcontrol.Provider.qps.global.limit
2147483647(maxint)
(0,2147483647],整形
否 provider接受请求流量的全局配置
没有具体到微服务的配置时,此配置生效
配置说明-Consumer
限流策略配置在microservice.yaml文件中,相关配置项见表1-3。要开启服务消费者端的限流策略,还需要在处理链中配置消费端限流handler,配置示例如下:
cse: handler: chain: Consumer: default: qps-flowcontrol-consumer
表 1-3 QPS 流控配置项说明
配置项 默认值 取值范围 是否必选
含义 注意
cse.flowcontrol.Consumer.qps.enabled
true true/false 否 是否启用Consumer流控
-
cse.flowcontrol.Consumer.qps.limit.[ServiceName].[Schema].[operation]
2147483647(maxint)
(0,2147483647],整形
否 每秒钟允许的请求数
支持microservice、schema、operation三个级别的配置
1.2.5 降级
概念阐述
降级策略是当服务请求异常时,微服务所采用的异常处理策略。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 14
降级策略有三个相关的技术概念:“隔离”、“熔断”、“容错”:
● “隔离”是一种异常检测机制,常用的检测方法是请求超时、流量过大等。一般的设置参数包括超时时间、同时并发请求个数等。
● “熔断”是一种异常反应机制,“熔断”依赖于“隔离”。熔断通常基于错误率来实现。一般的设置参数包括统计请求的个数、错误率等。
● “容错”是一种异常处理机制,“容错”依赖于“熔断”。熔断以后,会调用“容错”的方法。一般的设置参数包括调用容错方法的次数等。
把这些概念联系起来: 当“隔离”措施检测到N次请求中共有M次错误的时候,“熔断”不再发送后续请求,调用“容错”处理函数。这个技术上的定义,是和NetflixHystrix一致的,通过这个定义,非常容易理解它提供的配置项,参考:https://github.com/Netflix/Hystrix/wiki/Configuration。当前CSE提供两种容错方式,分别为返回null值和抛出异常。
场景描述
用户通过配置降级策略,可以设置微服务的异常处理策略。
配置说明
配置项支持对所有接口生效,或者对某个微服务的某个具体方法生效。
配置项生效范围
● 按照类型(type):配置项能够针对Provider,Consumer进行配置。
● 按照范围(scope):配置项能够针对MicroService进行配置,也可以针对【x-schema-id +operationId】进行配置。
本章节如果没有特殊说明,所有的配置项都支持按照下面的格式进行配置:
cse.[namespace].[type].[MicroServiceName].[接口名称].[property name]
type指Provider或者Consumser, 针对特定的微服务的配置,需要增加MicroServiceName,针对接口配置的,需要指定接口名称,接口名称由【x-schema-id + operationId】组成。
隔离 配置可选配置项格式示例如下:
cse.isolation.Consumer.timeout.enabledcse.isolation.Consumer.DemoService.timeout.enabledcse.isolation.Consumer.DemoService.hello.sayHello.timeout.enabledcse.isolation.Provider.timeout.enabledcse.isolation.Provider.DemoService.timeout.enabledcse.isolation.Provider.DemoService.hello.sayHello.timeout.enabled
须知
在下面的表格里面,全部省略type和MicroServiceName。未特殊说明,配置项都支持Provider和Consumer。例如:对于服务消费者,需要配置为:cse.isolation.Consumer.timeout.enabled。
例如:对于服务提供者,需要配置为:cse.isolation.Provider.timeout.enabled。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 15
表 1-4 降级策略相关配置项说明
配置项 默认值
取值范围
是否必选
含义 注意
cse.isolation.timeout.enabled
FALSE
- 否 是否启用超时检测
-
cse.isolation.timeoutInMilliseconds
30000
- 否 超时时间阈值 -
cse.isolation.maxConcurrentRequests
10 - 否 大并发数阈值 -
cse.circuitBreaker.enabled
TRUE
- 否 是否启用熔断措施
-
cse.circuitBreaker.forceOpen
FALSE
- 否 不管失败次数,都进行熔断
-
cse.circuitBreaker.forceClosed
FALSE
- 否 任何时候都不熔断
当与forceOpen同时配置时,forceOpen优先。
cse.circuitBreaker.sleepWindowInMilliseconds
15000
- 否 熔断后,多长时间恢复
恢复后,会重新计算失败情况。注意:如果恢复后的调用立即失败,那么会立即重新进入熔断。
cse.circuitBreaker.requestVolumeThreshold
20 - 否 10s内统计错误发生次数阈值,超过阈值则触发熔断
由于10秒还会被划分为10个1秒的统计周期,经过1s中后才会开始计算错误率,因此从调用开始至少经过1s,才会发生熔断。
cse.circuitBreaker.errorThresholdPercentage
50 - 否 错误率阈值,达到阈值则触发熔断
-
cse.fallback.enabled
TRUE
- 否 是否启用出错后的故障处理措施
-
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 16
配置项 默认值
取值范围
是否必选
含义 注意
cse.fallback.maxConcurrentRequests
10 - 否 并发调用容错处理措施(cse.fallbackpolicy.policy)的请求数,超过这个值则不再调用处理措施,直接返回异常
-
cse.fallbackpolicy.policy
throwexception
● returnnull
● throwexception
否 出错后的处理策略
-
注意
谨慎使用cse.isolation.timeout.enabled=true。因为系统处理链都是异步执行,中间处理链的返回,会导致后面处理链的逻辑处理效果丢失。尽可能将cse.isolation.timeout.enabled保持默认值false,并且正确设置网络层超时时间cse.request.timeout=30000。
示例代码cse: handler: chain: Consumer: default: bizkeeper-consumer isolation: Consumer: timeout: enabled: true timeoutInMilliseconds: 30000 circuitBreaker: sleepWindowInMilliseconds: 15000 requestVolumeThreshold: 20 fallback: enabled: true policy: throwexception
说明
降级策略需要启用服务治理能力,对应的服务提供者的handler是bizkeeper-provider,服务消费者的handler是bizkeeper-consumer。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 17
1.2.6 熔断
场景描述
熔断策略是对CSE熔断功能的设置,用户通过配置熔断策略可以指定在何种条件下CSEJava SDK框架将终止发送请求。
配置说明
熔断作为异常反应机制是降级策略的一部分,相关概念还有隔离和容错。三者的关系以及配置方式参见降级。
1.2.7 错误注入
场景描述
用户在Consumer端使用错误注入,可以设置发往指定微服务的请求时延、错误及其触发概率。
注意事项
注入请求的延迟时间统一为毫秒。
配置说明
故障注入配置在microservice.yaml文件中,相关配置项见下表。要开启服务消费者端的故障注入,还需要在处理链中配置消费端故障注入handler,配置示例如下:
cse: handler: chain: Consumer: default: loadbalance,fault-injection-consumer
错误注入配置项说明
[scope]代表故障注入的生效范围,可配置值包括全局配置_global,或指定微服务的服务名[ServiceName]。
[protocol]代表使用的通信协议,可配置值包括rest或highway。
配置项 默认值
取值范围
是否必选
含义 注意
cse.governance.Consumer.[scope].policy.fault.protocols.[protocol].delay.fixedDelay
无 (0,9223372036854775807],长整形
否 Consumer端发送延迟注入请求的延迟时间。
时间单位是毫秒
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 18
配置项 默认值
取值范围
是否必选
含义 注意
cse.governance.Consumer.[scope].policy.fault.protocols.[protocol].delay.percent
100
(0,100],整形
否 Consumer端发送延迟注入请求的触发概率。
-
cse.governance.Consumer.[ServiceName].schemas.[schema].policy.fault.protocols.[protocol].delay.fixedDelay
无 (0,9223372036854775807],长整形
否 Consumer端发送到对应schema延迟注入请求的延迟时间。
支持schema级别的配置
cse.governance.Consumer.[ServiceName].schemas.[schema].policy.fault.protocols.[protocol].delay.percent
100
(0,100],整形
否 Consumer端发送到对应schema延迟注入请求的触发概率。
支持schema级别的配置
cse.governance.Consumer.[ServiceName].schemas.[schema].operations.[operation].policy.fault.protocols.[protocol].delay.fixedDelay
无 (0,9223372036854775807],长整形
否 Consumer端发送到对应operation延迟注入请求的延迟时间。
支持operation级别的配置
cse.governance.Consumer.[ServiceName].schemas.[schema].operations.[operation].policy.fault.protocols.[protocol].delay.percent
100
(0,100],整形
否 Consumer端发送到对应operation延迟注入请求的触发概率。
支持operation级别的配置
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 19
配置项 默认值
取值范围
是否必选
含义 注意
cse.governance.Consumer.[scope].policy.fault.protocols.[protocol].abort.httpStatus
无 (100,999],整形
否 Consumer端发送错误注入请求的http错误码。
-
cse.governance.Consumer.[scope].policy.fault.protocols.[protocol].abort.percent
100
(0,100],整形
否 Consumer端发送错误注入请求的触发概率。
-
cse.governance.Consumer.[ServiceName].schemas.[schema].policy.fault.protocols.[protocol].abort.httpStatus
无 (100,999],整形
否 Consumer端发送到对应schema错误注入请求的http错误码。
支持schema级别的配置
cse.governance.Consumer.[ServiceName].schemas.[schema].policy.fault.protocols.[protocol].abort.percent
100
(0,100],整形
否 Consumer端发送到对应schema错误注入请求的触发概率。
支持schema级别的配置
cse.governance.Consumer.[ServiceName].schemas.[schema].operations.[operation].policy.fault.protocols.[protocol].abort.httpStatus
无 (100,999],整形
否 Consumer端发送到对应operation错误注入请求的http错误码。
支持operation级别的配置
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 20
配置项 默认值
取值范围
是否必选
含义 注意
cse.governance.Consumer.[ServiceName].schemas.[schema].operations.[operation].policy.fault.protocols.[protocol].abort.percent
100
(0,100],整形
否 Consumer端发送到对应operation错误注入请求的触发概率。
支持operation级别的配置
示例代码cse: governance: Consumer: _global: policy: fault: protocols: rest: delay: fixedDelay: 5000 percent: 10cse: governance: Consumer: ServerFaultTest: schemas: schema: operations: operation: policy: fault: protocols: rest: abort: httpStatus: 421 percent: 100
1.2.8 使用调用链公有云提供了业务无侵入的埋点功能APM。只需要通过公有云部署容器应用,并选择启用调用链监控功能,即可使用调用链服务。
1.2.9 使用仪表盘● 功能描述
微服务可以将自己的运行数据上报给Dashboard服务,在公有云上查看仪表盘数据、分布式事务数据等。该章节是描述如何启用微服务数据上报功能。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 21
● 配置参考
– 增加依赖关系(pom.xml)引入jar包。<dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>cse-handler-cloud-extension</artifactId></dependency>
– 配置handler仪表盘数据依赖于两个handler,一个bizkeeper-provider(客户端为bizkeeper-consumer),一个perf-stats,所以对应的pom依赖需要先引入。
cse: handler: chain: Provider: default: bizkeeper-provider,perf-stats,tracing-provider,sla-provider Consumer: default: bizkeeper-consumer,loadbalance,perf-stats,tracing-consumer,sla-consumer
– 配置上报monitor地址
TenantLB_ADDRESS为公有云接入地址。cse: monitor: client: serverUri: https://cse.cn-north-1.myhuaweicloud.com:443
该配置项配置了仪表盘上报地址。其中,serverUri可以在公有云“工具下载> 微服务框架”页面查到对应的仪表盘上报地址,修改协议(http/https)、主机名(可能使用域名)和端口号。一般不建议配置,SDK会做自动发现,如有特殊配置才需要配置,比如使用弹性IP接入。
1.2.10 文件上传
概述
文件上传,当前只在vertx rest通道中可用,servlet rest的支持后续会增加。
文件上传使用标准的http form格式,可与浏览器的上传直接对接。
Producer在jaxrs或springmvc开发模式下可用:
● 支持servlet定义的javax.servlet.http.Part类型。
● Springmvc模式下,也支持org.springframework.web.multipart.MultipartFile。
两种数据类型:
● 功能是一致的,MultipartFile的底层也是Part。● 可以混合使用,比如第一个参数是Part,第二个参数是MultipartFile。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 22
须知
● 先配置文件上传临时目录,默认为null不支持文件上传,文件上传请求Content-Type必须为multipart/form-data。
● 同名参数只支持一个文件。
● 支持一次传输多个不同参数名的文件。
● 通过MultipartFile或Part打开流后,记得关闭,否则上传的临时文件会无法删除,终导致上传临时目录被撑爆。
● 可以直接使用@RequestPart传递普通参数。
Springmvc模式下的代码样例:
@PostMapping(path = "/upload", consumes = MediaType.MULTIPART_FORM_DATA)public String fileUpload(@RequestPart(name = "file1") MultipartFile file1, @RequestPart(name = "file2") Part file2, @RequestPart String param1) { ……}
表 1-5 配置说明
配置项 默认值 含义
cse.uploads.directory null 上传的临时文件保存在哪个目录,默认值null表示不支持文件上传。
cse.uploads.maxSize -1 http body的 大允许大小,默认值-1表示无限制。
Consumer
支持以下数据类型:
● java.io.File
● javax.servlet.http.Part
● java.io.InputStream
● org.springframework.core.io.Resource
使用InputStream时,因为是流的方式,此时没有客户端文件名的概念,所以producer获取客户端文件名会得到null。
如果既要使用内存数据,又想让producer可以获取客户端文件名,可以使用resource类型,继承org.springframework.core.io.ByteArrayResource,且overridegetFilename即可。
● 透明RPC代码样例:interface UploadIntf { String upload(File file);}
获得接口引用后,直接调用即可:
String result = uploadIntf.upload(file);
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 23
● RestTemplate代码样例:Map<String, Object> map = new HashMap<>();map.put("file", new FileSystemResource("a file path!"));map.put("param1", "test");HttpHeaders headers = new HttpHeaders();headers.setContentType(org.springframework.http.MediaType.MULTIPART_FORM_DATA);HttpEntity<Map<String, Object>> entry = new HttpEntity<>(map, headers);
String reseult = template.postForObject( url, entry, String.class);
1.2.11 文件下载文件下载,当前在vertx rest通道和servlet rest中可用。
Producer● 下载普通文件
return new File(......);
● 下载临时文件
本场景下,需要根据请求参数动态创建临时文件,下载完成后,需要将临时文件删除
return new FilePart(file).setDeleteAfterFinished(true);
● 下载org.springframework.core.io.Resource因为resource不一定表示文件下载,所以需要通过swagger annotation(@ApiResponse)标识这是一个文件下载场景
以ByteArrayResource为例说明:
@GetMapping(path = "/resource")@ApiResponses({ @ApiResponse(code = 200, response = File.class, message = "")})public Resource resource() { …… return new ByteArrayResource(bytes) { @Override public String getFilename() { return "resource.txt"; } };}
上例中,因为ByteArrayResource没有文件名的概念,所以需要实现Resource的getFilename方法,也可以通过ResponseEntity进行包装:
@GetMapping(path = "/resource")@ApiResponses({ @ApiResponse(code = 200, response = File.class, message = "")})public ResponseEntity<Resource> resource() { …… return ResponseEntity .ok() .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=resource.txt") .body(resource);}
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 24
● 下载InputStream因为InputStream不一定表示文件下载,所以需要通过swagger annotation(@ApiResponse)标识这是一个文件下载场景
有的场景下,资源并不保存在本地。return ResponseEntity .ok() .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE) .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=resource.txt") .body(stream);
在下载完成后,ServiceComb会自动关闭stream,开发人员不必再关注。
● 文件类型判定
只要没有通过ResponseEntity直接设置HttpHeaders.CONTENT_TYPE,ServiceComb都会尝试通过File、Part、Resource中的文件名后缀进行自动判定。
ServiceComb使用java的mime type机制进行文件类型判定,如果业务场景中的文件后缀无法被识别,ServiceComb会默认处理为application/octet-stream如果这不满足要求,假设文件后缀为xyz,期望文件类型为application/file-xyz,以下方式任选一种均可解决:
a. 通过Java的mime type机制扩展
在META-INF目录下,创建mime.types文件,其内容为:application/file-xyz xyz
b. 在业务代码中通过Part指定return new FilePart(null, file).contentType("application/file-xyz");
c. 在业务代码中通过ResponseEntity指定return ResponseEntity .ok() .header(HttpHeaders.CONTENT_TYPE, "application/file-xyz") .body(……);
● 文件名
只要没有通过ResponseEntity直接设置HttpHeaders.CONTENT_DISPOSITION,ServiceComb都会尝试通过File、Part、Resource中的文件名生成HttpHeaders.CONTENT_DISPOSITION,假设文件名为file.txt,则生成的数据如下:Content-Disposition: attachment;filename=file.txt;filename*=utf-8’’file.txt
不仅仅生成filename,还生成了filename*,这是因为如果文件名中出现了中文、空格,并且filename正确地做了encode,ie、chrome都没有问题,但是firefox直接将encode后的串当作文件名直接使用了。firefox按照https://tools.ietf.org/html/rtf6266,只对filename*进行解码。
如果业务代码中直接设置Content-Disposition,需要自行处理多浏览器支持的问题。
Consumer消费端统一使用org.apache.servicecomb.foundation.vertx.http.ReadStreamPart处理文件下载。
● 透明RPCpublic interface ……{ ReadStreamPart download1(……); ReadStreamPart download2(……);}
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 25
● RestTemplate以get为例:ReadStreamPart part = restTemplate.getForObject(url, ReadStreamPart.class);
● 从ReadStreamPart读取数据
ReadStreamPart提供了一系列方法,将数据流保存为本地数据:org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveAsBytes()org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveAsString()org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveToFile(String)org.apache.servicecomb.foundation.vertx.http.ReadStreamPart.saveToFile(File, OpenOptions)
须知
● 在得到ReadStreamPart实例时,并没有完成文件内容的下载,调用save系列方法才开始真正从网络上读取文件数据。
● 如果使用saveAsBytes、saveAsString,数据是直接保存在内存中的,如果下载的文件很大,会内存撑爆的风险。
● save系列方法,返回的都是CompletableFuture对象:
● 如果要阻塞等待下载完成,通过future.get()即可
● 如果通过future.whenComplete进行异步回调处理,要注意回调是发生在网络线程中的,此时需要遵守reactive的线程规则。
1.2.12 Reactive
简单同步模式的 Producer示例代码:
@GetMapping(path = "/hello/{name}")public String hello(@PathVariable(name = "name") String name){ return "hello " + name;}
与此对应的处理流程如下:
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 26
这是传统典型的工作模型,核心思想是不阻塞网络线程,将业务放在独立的线程中处理(为了简化表达,executor中只画一个线程)。
一般情况下,此模式问题不大。
嵌套同步调用
不是所有的业务都是简单处理一下,就可以直接应答,可能还需要调用其他微服务.
示例代码:
public interface Intf{ String hello(String name);}
@GetMapping(path = "/hello/{name}")public String hello(@PathVariable(name = "name") String name){ return "from remote: hello " + intf.hello(name);}
与此对应的处理流程如下:
根据这个流程的特点,可以看到会产生以下结果:
● 因为是同步调用,在“Other microservices”未应答之前“Microservice A”的调用线程一直处于阻塞等待状态,不处理任何其他事务。
● 当Executor中所有线程都在等待远程应答时,所有新的请求都只能在Queue中排队,得不到处理,此时整个系统相当于停止工作了。
● 要增加处理能力,只能增加Executor中的线程数,而操作系统并不能无限地增加线程数,事实上增加线程数带来的收益是一个抛物线模型,超出一定的临界值后,系统的处理能力其实会下降,而这个临界值并不会太大。
● 当业务逻辑中,需要多次进行远程同步操作时,会更加恶化这个现象。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 27
嵌套同步调用的“错误”优化
针对前一场景,有人会认为将“Invoke producer method”丢进另一个线程池,可以解决问题,包括以下处理方式:
● 在producer method打标注@Async,由AOP负责将对该方法的调用丢进其他线程池。
● 在producer method内部通过业务代码转移线程。
形成以下流程:
根据这个流程的特点,可以看到会产生以下结果:
● “Invoke producer method”必须立即返回,否则Executor线程还是得不到释放。
● “Invoke producer method”必须提供一个新的机制告知调用流程自己的返回值,不是 终返回值(当前没有这个机制)。
● 虽然Executor线程释放了,但是Customer Executor,其实还是阻塞住,在等待远端应答,整个系统的阻塞状态并没有得到改变;而且还凭空多了一次线程切换。
● 该机制看上去,唯一的作用,是释放了executor线程,让executor线程有机会处理其他请求,这相当于隔离仓的概念,处理速度慢的业务不要影响其他业务;但是这个概念CSE Java SDK是可以直接支持的,可以配置指定的业务方法独占全新的executor,这样整个流程就跟“嵌套同步调用”完全一样,流程更简单,而不需要在“Invoke producer method”层次来做这个事情。
纯 Reactive 机制
示例代码:
public interface Intf{ CompletableFuture<String> hello(String name);
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 28
}
@GetMapping(path = "/hello/{name}")public CompletableFuture<String> hello(@PathVariable(name = "name") String name){ CompletableFuture<String> future = new CompletableFuture<>(); intf.hello(name).whenComplete((result, exception) -> { if (exception == null) { future.complete("from remote: " + result); return; }
future.completeExceptionally(exception); }); return future;}
与此对应的处理流程如下:
● 与传统流程不同的是,所有功能都在eventloop中执行,并不会进行线程切换。
● 橙色箭头走完后,对本线程的占用即完成了,不会阻塞等待应答,该线程可以处理其他任务。
● 当收到远端应答后,由网络数据驱动开始走红色箭头的应答流程。
● 只要有任务,线程就不会停止,会一直执行任务,可以充分利用cpu资源,也不会产生多余的线程切换,去无谓地消耗cpu。
因为同步模式下,需要大量的线程来提升并发度,而大量的线程又带来线程切换的额外消耗。
测试数据表明,reactive模式,只需要消耗同步模式不到一半的cpu,即可达到或超过同步模式的tps,并且时延更低。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 29
混合 Reactive 机制
Reactvie要求:所有在eventloop中执行的逻辑,不允许有任何的阻塞动作,包括不限于wait、sleep、巨大循环、同步查询DB等等。
CSE Java SDK底层是基于vertx的,vertx生态中有jdbc、mq、zooKeeper等等各种丰富组件的reactive驱动,一般情况下都可以满足要求。
但是有的场景下,确实有的同步操作无法避免,比如:
● 私有的安全加固的redis,只提供了同步驱动
● 较复杂的业务运算
此时,可以将这些同步的逻辑抽取出来放到线程池中去处理,而其他部分仍然使用reactive的流程。
关于 reactive 的一些说明● Producer
– producer是否使用reactive与consumer如何调用,没有任何联系。
– 当operation返回值为CompletableFuture类型时,默认此operation工作于reactive模式,此时如果需要强制此operation工作于线程池模式,需要在microservice.yaml中明确配置;假设某operation,其schemaId为sid,operationId为asyncQuery,则需要进行以下配置:cse: executors: Provider: sid.asyncQuery: cse.executor.groupThreadPool
这里的cse.executor.groupThreadPool是serviceComb内置的默认线程池,用户可以任意指定为自己的定制线程池。
● Consumer– consumer是否使用reactive与producer如何实现,没有任何联系。
– 当前只支持透明RPC模式,使用JDK原生的CompletableFuture来承载此功能。
completableFuture的when、then等等功能都可直接使用。
但是completableFuture的async系列功能,其实是另外启线程池来执行功能,不建议使用。
关于RxJava Observable的支持后续会加入。
关于AsyncRestTemplate的支持后续会加入。
1.2.13 AK/SK 加密存储
概念阐述
本节介绍的AK/SK加密存储是基于共享秘钥的AES256加解密存储方案,通过工具生成秘钥物料,然后使用工具利用秘钥文件对指定的明文进行加密。例如可以使用这种方法对数据库密码进行加密,使用的时候再使用CSE SDK接口进行解密。
注意事项● 若使用jre1.8.151之前的版本,请下载jce_policy-8.zip解压覆盖{JAVA_HOME}\jre
\lib\security下的文件。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 30
● 若使用jre1.8.151之后的版本(包括jre1.8.151),请将{JAVA_HOME}\jre\lib\security\java.security文件中crypto.policy=unlimited取消注释。
AK/SK 存储方案
AK/SK认证依赖用户配置的AK/SK,CSE默认支持自定义配置,用户可以自己实现解密接口,也可以使用CSE默认提供的机制。CSE内部默认提供明文和安全两种实现机制,下面分别来介绍下三种方式的配置方法,推荐使用密文的AK/SK存储方案。
1. 明文方法,在microservice.yaml文件中增加配置。 cse: credentials: accessKey: yourak secretKey: yoursk akskCustomCipher: default
2. 密文方式,在microservice.yaml文件中增加配置。cse: credentials: accessKey: yourak #明文 secretKey: yoursk #密文 akskCustomCipher: security
默认提供的安全存储中,ak是不进行加密的。读取cipher的时候,会优先读取CIPHER_ROOT下面的certificate.yaml配置,参考AK/SK安全存储详细操作步骤。
3. 自定义实现,首先自己实现接口com.huawei.paas.foundation.auth.credentials.AKSKCipher,里面有两个方法:
– String name();这个是cse.credentials.akskCustomCipher的名称定义,需要配置在配置文件中。
– char[] decode(TYPE type, char[] encrypted);解密接口,TYPE表示ak还是sk,因为两者可能实现不一样的加密方式。
然后在microservice.yaml文件中增加配置。
cse: credentials: accessKey: yourak #对应的加解密后的ak secretKey: yoursk #对应的加解密后的sk akskCustomCipher: youciphername #实现类里面的name()方法返回的名称
再添加接口的SPI声明,在src/main/resources/META-INF/services新建一个文件com.huawei.paas.foundation.auth.credentials.AKSKCipher,内容为自己的实现类类名,例如:com.huawei.paas.cse.demo.pojo.client.CustomAKSKDepl。
AK/SK 安全存储详细操作步骤
步骤1 下载加解密工具,支持windows x64和linux x64系统。
步骤2 使用加解密工具生成物料。
使用命令keytool gen -a yourak -s yoursk命令,会在当前目录下生成root.key、common_shared.key、certificate.yaml文件。
说明
详细说明可以查看工具的帮助keytool gen -h。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 31
步骤3 复制root.key、common_shared.key、certificate.yaml到环境中,建议放到/opt/CSE/etc/cipher,本地调试的时候可以放到任意目录,所有需要部署微服务的节点都需要。如果是容器化部署,还需要挂载卷到指定目录。
说明
certificate.yaml不一定要放在CIPHER_ROOT下面,如果certificate.yaml放在CIPHER_ROOT下面,ak和sk优先从certificate.yaml读取,project默认从服务中心地址域名解析出来。特别注意:CSE专享版场景下,是IP直连,解析不出来,所以需要手工加入project。
如果这文件不放在CIPHER_ROOT下面,则ak,sk和project信息从微服务的microservice.yaml文件获取。
步骤4 设置一个环境变量CIPHER_ROOT,环境变量的值设置为步骤3凭证文件所在的目录。然后启动应用。
步骤5 查看CSE控制台面板,服务是否注册成功,也可以查看应用启动日志,是否有服务注册成功日志。
----结束
1.3 Spring Cloud 开发
1.3.1 应用接入 ServiceComb 引擎
Spring Cloud应用无需修改代码,可以方便的接入ServiceComb引擎。
接入ServiceComb有如下好处:
1. 开发者可以专注于业务系统的开发,把精力从中间件的可靠性评估、集群部署、运维监控等复杂的事情中解放出来。
2. 实现业务快速交付和敏捷开发。利用ServiceStage平台,根据业务规模,动态的调整资源使用,降低业务风险。
3. 路由管理:可以根据配置将流量分摊到不同的微服务实例中,轻松的实现灰度发布功能
4. 服务网格:对于其他语言,如php, python, go, dotnet core可以使用服务网格接入与spring cloud应用统一治理
下图展现了CSE基础服务、PaaS平台服务和第三方服务的关系:
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 32
在本章节中,将简单介绍接入ServiceComb引擎的原理,并详细介绍Spring Cloud应用接入方法,通过一个Spring Cloud应用改造的案例,说明接入步骤
建议开发者先通过CSE提供的“快速体验微服务能力”
由于spring-cloud-huawei发布在华为的开源仓库,在开始之前需要设置maven仓库信息以及导入相关的dependency managment方便之后引入依赖。
1. 配置华为云仓库地址,修改maven的配置文件setting.xml,添加华为云repository和pluginRepository。 <mirrors> <mirror> <id>huaweicloud</id> <mirrorOf>*,!HuaweiCloudSDK</mirrorOf> <url>https://repo.huaweicloud.com/repository/maven/</url> </mirror> </mirrors>
<profiles> <profile> <id>MyProfile</id> <pluginRepositories> <pluginRepository> <id>HuaweiCloudSDK</id> <url>https://repo.huaweicloud.com/repository/maven/huaweicloudsdk/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories> <repositories> <repository> <id>HuaweiCloudSDK</id> <url>https://repo.huaweicloud.com/repository/maven/huaweicloudsdk/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> </profile> </profiles>
<activeProfiles> <activeProfile>MyProfile</activeProfile> </activeProfiles>
2. 项目中可以使用dependencyManagement引入依赖,引入spring-cloud-starter-huawei-servicecomb-discovery,用于注册发现服务,示例如下。<dependencyManagement> <dependencies> <dependency> <groupId>com.huaweicloud</groupId> <artifactId>spring-cloud-huawei-dependencies</artifactId> <version>${project.version}</version> <type>pom</type> <scope>import</scope>
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 33
</dependency> </dependencies></dependencyManagement>
1.3.2 使用注册中心
SpringCloud 扩展机制
SPI是Service Provider Interface的缩写,相当于一种规范,它是JDK内置的一种服务提供发现机制。只要在指定的目录定义好接口,引入符合规范的jar包就可以工作了,非常适用于第三方开发者进行扩展。
SPI本身也有一些问题如:JDK自带的SPI实现会一次性实例化所有扩展点,这会导致应用启动的时间变长,并且浪费不必要的资源。
Spring就是采用的SPI机制进行扩展,与其他很多框架不同,Spring更多强调的是开放性,或者说是扩展性。在Spring的全家桶中,很多组件都是从外部集成进来的,各种starter就是这些组件的集合。如注册发现,可以使用Consul、Eureka、ZooKeeper、Etcd等实现。
SpringCloud依赖于SpringBoot,SpringBoot又依赖于Spring,SpringCloud的扩展性来源于SpringBoot中的@EnableAutoConfiguration, 大致的加载步骤如下。
1. SpringBoot启动的时候,会扫描classpath下所有Jar中META-INF/spring.factories文件。
2. 读取指定的Configuration,根据Configuration上的Conditional条件自动创建bean。
3. 放入Spring Context中,这样就注入了容器,任何地方都可以直接注入使用了。
快速开始
spring-cloud-huawei可以使用springcloud的方式注册发现,只需要修改部分配置文件即可,步骤如下。
步骤1 参见3.1节设置仓库地址以及引入下面依赖。 <dependencies> <dependency> <groupId>com.huaweicloud</groupId> <artifactId>spring-cloud-starter-huawei-servicecomb-discovery</artifactId> </dependency> </dependencies>
步骤2 新建Project或module,定义配置文件。
通过配置文件application.yml定义配置。
server: port: 8080spring: application: name: price cloud: servicecomb: discovery: enabled: true address: https://cse.cn-east-2.myhuaweicloud.com serviceName: price
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 34
version: 0.0.1 healthCheckInterval: 30 credentials: enable: true accessKey: your ak secretKey: your sk akskCustomCipher: default project: cn-east-2
步骤3 启动类添加注解,示例如下。@SpringBootApplication@EnableDiscoveryClientpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}
----结束
运行 demo通过项目中的示例开始实现服务注册发现,spring-cloud-huawei-sample/discovery-demo下提供了三个工程,用来模拟springcloud工程迁移到ApacheServiceComb 的注册中心的场景:
● price-provider:价格服务,服务提供者,RESTful方式提供接口。
● order-consumer:订单服务,服务消费者,RESTful方式提供接口,以RestTemplate的方式调用price-provider获取价格信息。
● product-consumer-feign:产品服务,服务消费者,RESTful方式提供接口,以feign的方式调用price-provider获取价格信息。
运行demo步骤如下。
步骤1 下载 servicecomb-service-center, 参考servicecomb-service-center的quick start文档,运行 servicecomb-service-center。
步骤2 分别运行main函数,启动三个示例服务。
1. 在application.properties配置actuator。management.endpoints.web.exposure.include=*management.endpoint.health.show-details=alwaysmanagement.security.enabled=false
2. 通过actuator查看服务运行情况。
http://127.0.0.1:8080/actuator/service-registry正确情况会显示UP。
3. 如果要设置服务的状态,可以通过如下命令,将服务的状态修改为DOWN。curl -i -H "Content-Type: application/json" -X POST -d '{"status":"DOWN"}' http://localhost:8080/actuator/service-registry
步骤3 查看服务注册中心,查看实例运行状态,地址如下。
http://127.0.0.1:30103
步骤4 通过curl、浏览器或使用postman验证调用情况。
product-consumer-feign访问地址如下。
http://127.0.0.1:8089/product?id=11
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 35
order-consume访问地址如下。
http://127.0.0.1:8088/order?id=11
----结束
配置项说明
application.yaml文件配置项说明如下。
配置 key 默认值
启动ServiceComb服务发现
spring.cloud.servicecomb.discovery.enabled
true
注册中心地址 spring.cloud.servicecomb.discovery.address
-
服务名 spring.cloud.servicecomb.discovery.serviceName
如果没有,使用spring.application.name
应用名 spring.cloud.servicecomb.discovery.appName
default
版本号 spring.cloud.servicecomb.discovery.version
0.0.0+
启动健康检查 spring.cloud.servicecomb.discovery.healthCheck
true
健康检查间隔时间 spring.cloud.servicecomb.discovery.healthCheckInterval
10s
自动发现注册中心集群地址, 如果只配置一个,可以发现健康的注册中心
spring.cloud.servicecomb.discovery.autoDiscovery
false
1.3.3 使用分布式配置服务
前提条件
开始前需要在在ServiceStage上创建微服务引擎。
快速开始
步骤1 参见3.1节设置仓库地址以及引入下面依赖。 <dependencies> <dependency> <groupId>com.huaweicloud</groupId> <artifactId>spring-cloud-starter-huawei-config</artifactId> </dependency> </dependencies>
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 36
步骤2 新建Project或module,定义配置文件。
通过配置文件bootstrap.yml定义配置,在spring cloud中,bootstrap.yml的启动优先级高于application.yml,application.yml配置等同注册发现配置。
spring: application: name: price cloud: servicecomb: config: serverAddr: https://cse.cn-east-3.myhuaweicloud.com watch: delay: 10000 credentials: enable: true accessKey: your ak secretKey: your sk akskCustomCipher: default
步骤3 通过注解@Value取得配置中心的值。@Value("${server.port}")
----结束
运行 demo通过项目中的示例开始分布式配置,spring-cloud-huawei-sample/config-demo用来模拟springcloud工程使用华为云ServiceStage分布式配置的场景。
步骤1 在ServiceStage中新建相关配置,如demo中的dd,请参考全局配置。
步骤2 修改配置文件bootstrap.yml,并且启动服务spring: application: name: price cloud: servicecomb: config: serverAddr: https://cse.cn-east-3.myhuaweicloud.com watch: delay: 10000 credentials: enable: true accessKey: your ak secretKey: your sk akskCustomCipher: default
步骤3 验证
访问如下地址,显示dd在配置中心配置的值。
http://127.0.0.1:8080/price?id=11
----结束
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 37
1.3.4 接入分布式事务引擎 DTM
DTM 设计思想
在微服务架构下,一次请求调用多个服务,每个服务独享数据库,通过接口隔离,因此数据的一致性受到很大影响。 使用两阶段提交(2PC)将会导致性能大幅下降,增加数据库的压力,而且数据库相对于业务服务来说,难以伸缩。
DTM采用了TCC的分布式事务设计模式,相对于两阶段提交来说,性能更高,不会对数据库的数据加锁。开发人员只需要通过 注解标示分布式事务的参数,无需自己控制事务的逻辑,DTM以服务的形式提供给开发者,降低了开发难度。
步骤说明如下:
步骤1:进入到发起全局事务的方法内时,会先向DTM集群申请注册一个全局事务ID(Global Transaction ID),只有申请成功才可继续后续流程。
步骤2.1:事务发起者将申请到的全局事务ID透传到所调用的事务参与者中。
步骤2.2:事务参与者利用得到的全局事务ID,向DTM集群注册申请一个分支事务ID(Branch Transaction ID),只有申请成功才可继续此事务参与者的后续流程。
步骤2.3:事务参与者完成自身业务逻辑(即完成TCC中的Try阶段)。
步骤2.4:事务参与者将自身业务逻辑结果上传到DTM集群,并示意分支事务结束。
步骤3.1~3.4:与2.1~2.4类似,完成剩余事务参与者的业务逻辑。
步骤4:事务发起者发起TCC二阶段。
步骤5.1:DTM集群根据全局事务ID,找到事务参与者,发起TCC二阶段。
步骤5.2:与5.1类似,完成剩余事务参与者的TCC二阶段。
步骤6:DTM集群通告事务发起者全局事务结束。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 38
前提条件
开始前需要在ServiceStage上创建微服务引擎和分布式事务引擎
快速开始
步骤1 参见3.1节设置仓库地址以及引入下面依赖。<dependency> <groupId>com.huaweicloud</groupId> <artifactId>spring-cloud-starter-huawei-dtm</artifactId></dependency>
步骤2 新建Project或module,定义全局事务,支持通过RestTemplate和Feign两种模式调用分支事务。
1. 通过配置文件(application.yml)定义事务信息。dtm: appName: reserve #应用名称 rpc: sslEnabled: true #是否启用ssl proxy: endpoint: https://192.168.0.5:30125 #dtm服务地址,从dtm引擎中获取
2. 通过注解DTMTxBegin定义全局事务。 @DTMTxBegin(appName = "reserve") public String getOrder(@RequestParam("id") String id) { String discountCouponResult = restTemplate.getForObject("http://coupon/discountCoupon?id=" + id, String.class); LOGGER.info("bookRoomResult:" + discountCouponResult); String bookTicketResult = restTemplate.getForObject("http://ticket/bookTicket?id=" + id, String.class); LOGGER.info("bookTicketResult:" + bookTicketResult); return discountCouponResult + "-------" + bookTicketResult; }}
步骤3 新建Project或module,定义分支事务。
1. 通过配置文件(application.yml)定义事务信息。dtm: appName: coupon #应用名称 rpc: sslEnabled: true #是否启用ssl proxy: endpoint: https://192.168.0.5:30125 #dtm服务地址,从dtm引擎中获取
2. 通过注解DTMTccBranch定义分支事务,放到"try"方法上,通过confirmMethod和cancelMethod定义确认和回滚方法。 @GetMapping(value = "/discountCoupon") @DTMTccBranch(identifier = "coupon", confirmMethod = "confirm", cancelMethod = "cancel") public void discountCoupon() throws InterruptedException { //try,预留资源,判断是否可以执行。如库存服务,可以在数据库中增加字段,预减库存 }
public void confirm() { //confirm,可以理解为事务提交,如库存服务,真正的把预留的库存扣掉 }
public void cancel() { //cancel,回滚方法,当出现异常的时候调用此方法释放资源,如库存服务,释放预留库存 }
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 39
步骤4 在huaweicloud分布式事务控制面板上查看事务执行情况。
----结束
运行 Demo
通过项目中的示例开始分布式事务,spring-cloud-huawei-sample/dtm-demo下提供了四个工程,用来模拟spring cloud工程使用华为云ServiceStage分布式事务的场景:
● reserve:预订服务使用RestTemplate,事务发起方。
● reserve-feign:预订服务使用Feign,事务发起方。
● coupon:优惠券服务,分支事务。
● ticket:票务服务,分支事务。
运行demo步骤如下。
步骤1 修改配置文件。
路径为:/src/main/resources/application.yamldtm: appName: reserve ##应用名称 rpc: sslEnabled: true ##开启SSL验证,华为云目前必须开启 proxy: endpoint: https://192.168.X.XXX:30125 ##dtm服务的地址
步骤2 生成docker镜像,并推送到镜像仓库。
以reverse为例,示例命令如下。
cd spring-cloud-huawei/spring-cloud-huawei-sample/dtm-demo/reserve docker build -t reserve:0.1 .
打tag,这里需要跟云上的路径和组织相对应,示例命令如下。
docker tag reserve:0.1 swr.cn-north-4.myhuaweicloud.com/wang/reserve:0.1
推送到镜像仓库,示例命令如下。
docker push swr.cn-north-4.myhuaweicloud.com/wang/reserve:0.1
重复此步骤,完成reserve-feign、coupon、ticket构建归档。
步骤3 应用部署
进入应用列表创建应用,选择ServiceComb引擎,创建应用。应用配置说明如下。
1. 框架选择:Java chassis。2. 运行环境选择:docker。3. 部署系统选择:云容器引擎CCE。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 40
4. 设置集群。
5. 应用来源选择生成的镜像。
6. 开启外网访问。
7. 端口填写8080。
8. 设置访问方式。
9. 微服务引擎使用专业版微服务引擎。
10. 其他配置使用默认。
重复以上步骤,分别部署reserve-feign、coupon、ticket三个应用。
步骤4 验证事务
通过生成的域名地址访问应用,示例如下。
http://xxxx/reverse?id=1
正常页面会返回成功,日志中会有响应的日志记录。
查看dtm控制台,历史事务,会有相应的事务提交记录。
步骤5 回滚
如果要验证回滚,可以将ticket或者coupon停掉,活跃事务中会看到事务一直在等待重试, 当停掉的事务重新启动后,事务会再次提交,示例中可以在日志中看到。
如果要验证超时,示例如下。
http://xxxx/reverse?id=sleep
ticket会一直在Confirm方法中阻塞,同样可以通过日志和dtm控制台看到相应情况。
----结束
通过 RestTemplate 使用 DTM 分布式事务
如果使用RestTemplate实现DTM分布式事务,代码仅需要增加注解, 通过注解DTMTxBegin定义全局事务。
@DTMTxBegin(appName = "reserve") public String getOrder(@RequestParam("id") String id) { String discountCouponResult = restTemplate.getForObject("http://coupon/discountCoupon?id=" + id, String.class); LOGGER.info("bookRoomResult:" + discountCouponResult); String bookTicketResult = restTemplate.getForObject("http://ticket/bookTicket?id=" + id, String.class); LOGGER.info("bookTicketResult:" + bookTicketResult); return discountCouponResult + "-------" + bookTicketResult; }})
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 41
通过注解DTMTccBranch定义分支事务,放到"try"方法上。通过confirmMethod和cancelMethod定义确认和回滚方法。
@GetMapping(value = "/discountCoupon") @DTMTccBranch(identifier = "coupon", confirmMethod = "confirm", cancelMethod = "cancel") public void discountCoupon() throws InterruptedException { //try,预留资源,判断是否可以执行。如库存服务,可以在数据库中增加字段,预减库存 }
public void confirm() { //confirm,可以理解为事务提交,如库存服务,真正的把预留的库存扣掉 }
public void cancel() { //cancel,回滚方法,当出现异常的时候调用此方法释放资源,如库存服务,释放预留库存 }
通过 Feign 使用 DTM 分布式事务
DTM使用方法与RestTemplate用法相同。
1.3.5 使用路由管理
路由管理提供灵活的路由定义规则,可以利用路由规则轻松的实现灰度发布。
前提条件
需要在ServiceStage上创建微服务引擎。
快速开始
步骤1 参见3.1节设置仓库地址以及引入下面依赖,用于路由管理。<dependency> <groupId>com.huaweicloud</groupId> <artifactId>spring-cloud-starter-huawei-router</artifactId> </dependency>
步骤2 新建Project或module,定义配置文件。
通过配置文件application.yml来配置路由规则,具体配置参考3.6-路由规则管理。
servicecomb: routeRule: canary-provider: | - precedence: 1 #优先级 route: #路由规则 - weight: 80 tags: version: 0.0.1 - weight: 20 tags: version: 0.0.2
步骤3 启动服务,流量按照配置实现预期分配。
----结束
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 42
运行 demo
通过项目中的示例开始分布式配置,spring-cloud-huawei-sample/canary-demo用来模拟springcloud工程使用华为云ServiceStage设置灰度发布的场景。
步骤1 分别修改canary-consumer、canary-provider、canary-provider-beta三个工程的application.yml配置文件。其中canary-consumer工程需要额外配置bootstrap.yaml用来连接配置中心。
application.yaml配置说明如下。
server: port: 8091spring: application: name: consumer cloud: servicecomb: discovery: enabled: true # 开启服务发现 address: https://cse.cn-north-4.myhuaweicloud.com:443 # 注册中心地址 version: 0.0.2 # 服务版本 healthCheckInterval: 30 # 心跳间隔 autoDiscovery: true # 同一vpc下可避免域名解析 credentials: enable: true # 开启华为IAM认证 accessKey: yourak # ak secretKey: yoursk # sk project: cn-north-4 # 填写region akskCustomCipher: default
bootstrap.yaml配置文件是配置中心地址。
spring: application: name: consumer cloud: servicecomb: config: serverAddr: https://cse.cn-north-4.myhuaweicloud.com # 配置中心地址 watch: delay: 10000 credentials: enable: true # 开启华为IAM认证 accessKey: yourak # ak secretKey: yoursk # sk akskCustomCipher: default # 填写region project: cn-north-4
对于canary-consumer可以在application.yaml额外配置灰度发布规则,通过更改route来完成流量的预期分配。此外灰度发布提供对feign和hytrix的支持,且不需要额外引用/配置。示例如下。
servicecomb: routeRule: canary-provider: | - precedence: 2 #优先级 route: #路由规则 - weight: 100 tags: version: 0.0.1
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 43
步骤2 分别启动canary-consumer、canary-provider、canary-provider-beta三个服务。
步骤3 验证
访问如下地址。
http://127.0.0.1:8091/canary?id=11
可以发现流量已经按照预期分配。
----结束
1.3.6 路由管理规则说明
场景描述
用户可以通过使用路由管理,来进行灰度发布实现版本的平滑过渡升级。目前灰度发布已经采取了新的规则,如果要访问老的灰度发布访问,请参考灰度发布。
注意事项
1. 若要使用灰度发布功能,需要微服务对接配置中心。
2. 灰度规则可以自定义,在microservice.yaml中定义,提供示例规则如下。servicecomb: routeRule: provider: | #服务名 - precedence: 2 #优先级 match: #匹配策略 headers: #header匹配 region: regex: 'regoin[0-9]*' caseInsensitive: false # 是否区分大小写,默认为false,区分大小写 type: exact: gray route: #路由规则 - weight: 100 #权重值 tags: version: {version1} app: {appId} - precedence: 1 route: - weight: 20 tags: version: 0.01 taga: tag - weight: 80 tags: version: 0.02
规则说明● 匹配特定请求由match配置,匹配条件是:source tags和headers。
● Header中的字段的匹配支持正则,等于匹配。
● 如果未定义match,则可匹配任何请求。
● 转发权重定义在routeRule.{targetServiceName}.route下,由weight配置,weight数值表示百分数。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 44
● 服务分组定义在routeRule.{targetServiceName}.route下,由tags配置,配置内容有version和app。
● caseInsensitive 配置条件是否区分大小写,默认false区分大小写,true则不区分大小写。
● 优先级数量越大优先级越高。
匹配流程
对于上面的示例配置,所有访问provider服务的请求,首先尝试与优先级为2的第一个的match规则进行匹配header:header存在key为region的按照正则规则区分大小写匹配,存在key为type的进行字符串精准匹配。若匹配match成功则按照route的配置分配100%的流量到version和tags对应的实例。若匹配match失败则进入下个优先级为1的规则。不同规则优先级不能相等。
异常情况的处理
如果因为规则配置错误,或者没有match到任何一条规则,流量会直接跳过灰度规则,相当于没有灰度发布配置。
如果已经匹配了match,因为对应的version或者tags找不到实例,则剩余流量自动转发到目前的 新版本。
负载均衡算法
借鉴了nginx,使用平滑加权轮询算法,流量会均 的等比分配到对应的服务实例上。
实例 tags 的配置
微服务可以指定实例的属性tags,tags可以在microservice.yaml中指定,也可以通过服务中心的API进行修改。
instance-description: properties: tags: tag_key: tag_value
1.4 在 Spring Boot 中使用 CSE
1.4.1 背景介绍
概述
Spring Boot可以让开发者能够更加快速的构建Spring应用。主要提供了如下功能:
● 创建独立可执行的Spring应用。通过将应用程序打包为jar,就可以通过java -jar来执行应用程序。
● 内嵌Tomcat、Jetty等Web服务器,而不需要开发者打包war。● 提供starter简化maven依赖关系配置。
将Spring Boot用于微服务开发,可以极大的简化开发者配置和部署。CSE提供了完善的的服务治理能力、良好的跨语言特性和高效的异步通信能力,通过使用CSE,可以快速启用各种满足商业运维需要的功能。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 45
场景描述
本文将介绍如何在Spring Boot中集成和使用CSE。开发者通常会以如下几种方式使用Spring Boot:
1. Java应用方式:引入spring-boot-starter,开发普通Java应用。该应用不会启动Web服务器。
2. Web开发方式:引入spring-boot-starter-web,开发Web应用。该应用会包含一个内嵌的Tomcat或者Jetty服务器,并且使用The Spring Web MVC framework(简称Spring MVC)开发REST接口。
在两种情况下,都可以集成CSE,原理图如下:
● Java应用方式
这种集成方式相对简单,相当于直接将CSE通过Spring Boot应用拉起,不涉及任何改造和变化。
● Web开发方式
该集成方式的本质是将Spring MVC的DispatcherServlet替换为CSE的RestServlet。
1.4.2 CSE 提供的组件说明针对Spring Boot、Spring Cloud,提供了如下几个组件:
● spring-boot-starter-configuration用于接入配置中心。当需要在Spring Boot、Spring Cloud应用中,使用配置中心作为动态配置管理工具时,需要依赖该组件。
● spring-boot-starter-registry用于接入服务中心。当需要在Spring Boot、Spring Cloud应用中,使用服务中心作为服务注册、发现管理工具时,需要依赖该组件。
● spring-boot-starter-discovery用于适配Spring Cloud的DiscoveryClient接口。当在Spring Cloud中使用@EnableDiscoveryClient时,需要依赖该组件。
● spring-boot-starter-provider
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 46
用于在Spring Boot中通过@EnableServiceComb启用CSE的核心功能。这个功能可以用于“Java应用方式”和“Web开发方式”。在“Web开发方式”中,通过spring.main.web-environment=false禁用了Web环境。因此,这个模块主要是解决“Java应用方式”的问题。
● spring-boot-starter-transport用于在Spring Boot中通过@EnableServiceComb启用CSE的核心功能,并启用CSE的RestServlet。用于“Web开发方式”。
开发过程中会使用到的组件是spring-boot-starter-provider和spring-boot-starter-transport,详细使用场景会在后面的章节说明。
1.4.3 Java 应用方式开发步骤使用Java方式集成,为Spring Boot应用增加了一个高效的HTTP服务器和REST开发框架。这种方式集成非常简单。只需要在项目中引入相关依赖,并且使用@EnableServiceComb标签即可。项目代码请参考示例。
步骤1 引入依赖
依赖关系中增加spring-boot-starter-provider,即可引入CSE的核心功能。cse-solution-service-engine增加了接入公有云相关的认证模块和治理相关模块,并排除了log4j运行时包,防止和spring boot缺省携带的logback冲突。引入hibernate-validator的目的是spring boot会检测validation-api的实现类,检测不到会无法启动。
<dependencyManagement> <dependencies> <dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>cse-dependency</artifactId> <version>2.3.58</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>
<dependencies> <dependency> <groupId>org.apache.servicecomb</groupId> <artifactId>spring-boot-starter-provider</artifactId> </dependency> <dependency> <groupId>com.huawei.paas.cse</groupId> <artifactId>cse-solution-service-engine</artifactId> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> </dependency></dependencies>
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 47
步骤2 启用CSE的核心功能
在启动类前面增加@EnableServiceComb即可。
@SpringBootApplication@EnableServiceCombpublic class WebsiteMain { public static void main(final String[] args) { SpringApplication.run(WebsiteMain.class, args); }}
通过以上配置,就可以完整使用CSE提供的所有功能,使用CSE开发REST服务,并开启各种治理功能。
步骤3 配置微服务
通过microservice.yaml文件可以定制微服务的信息,包括应用名称、微服务名称、监听的地址和端口等。
cse-config-order: 100
APPLICATION_ID: spring-boot //应用名称service_description: name: spring-boot-simple //微服务名称 version: 0.0.1 //微服务版本号
cse:
# for local test service: registry: address: https://cse.cn-north-1.myhwclouds.com //服务中心信息,其中address为服务中心地址 instance: watch: false healthCheck: interval: 5
config: client: serverUri: https://cse.cn-north-1.myhwclouds.com //配置中心信息,其中address为配置中心地址 refreshMode: 1 refresh_interval: 15000# monitor:# client:# serverUri: https://cse.cn-north-1.myhwclouds.com //服务看板信息,其中address为服务看板地址# credentials:# accessKey: your access key# secretKey: your secret key# akskCustomCipher: default
rest: address: 0.0.0.0:9093 //微服务端口,请确保该端口号无冲突
credentials: accessKey: your ak //请填写AK secretKey: yours sk //请填写SK akskCustomCipher: default
servicecomb:
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 48
rest: servlet: urlPattern: /servicecomb/rest/*
步骤4 集成CSE后,可以通过CSE的方式开发REST接口:@RestSchema(schemaId = "hello") @RequestMapping(path = "/")public class HelloService { @RequestMapping(path = "hello", method = RequestMethod.GET) public String sayHello(@RequestParam(name="name") String name) { return "Hello " + name; }}
步骤5 通过访问http://localhost:9093/hello?name=world验证开发结果。
----结束
1.4.4 Web 开发方式开发步骤Web开发方式和Java应用方式的开发步骤基本类似。代码请参考示例。
主要有如下区别:
● Java应用方式基于spring-boot-starter,而Web开发方式基于spring-boot-starter-web。
● Java应用方式依赖spring-boot-starter-provider,而Web开发方式依赖spring-boot-starter-transport。spring-boot-starter-web已经携带了hibernate-validator,不需要额外依赖。
● 在启动函数中,Web开发方式可以通过以下声明关闭org.springframework.web.servlet.DispatcherServlet。@SpringBootApplication(exclude=DispatcherServletAutoConfiguration.class)
通过@EnableServiceComb会启用org.apache.servicecomb.transport.rest.servlet.RestServlet。虽然排除DispatcherServlet不是必须的,但是大多数场景一个微服务里面存在多个REST框架都不是很好的主意,会造成很多使用上的误解。
● 在microservice.yaml文件中通过配置项servicecomb.rest.servlet.urlPattern来指定RestServlet的URL根路径。并且配置项cse.rest.address里面的监听端口,必须与Tomcat监听的端口保持一致(默认是8080,可以通过application.yml中增加server.port修改)。
开发步骤
步骤1 集成CSE后,可以通过CSE的方式开发REST接口:@RestSchema(schemaId = "hello")@RequestMapping(path = "/")public class HelloService { @RequestMapping(path = "hello", method = RequestMethod.GET) public String sayHello(@RequestParam(name="name") String name) { return "Hello " + name; }}
步骤2 通过访问http://localhost:9093/servicecomb/rest/hello?name=world验证开发结果。其中/servicecomb/rest是配置文件中指定的URI,可以设置为/。
您可以看到使用的标签和Spring MVC大部分是一样的。但也有少量不一样的地方,比如:
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 49
1. 通过RestSchema替换RestController。2. 需要显示声明@RequestMapping。
如果业务代码不是新开发,而是基于Spring MVC做的开发,现在基于CSE做改造,还需要注意在禁用DispatcherServlet后,与其有关的功能特性将不再生效。
在下面的章节,还会详细介绍在Spring MVC模式下两者的区别。
----结束
1.4.5 Java 应用方式和 Web 开发方式的差异两种开发方式都会启用CSE的全量功能,Java应用方式运行于独立的HTTP服务器(基于vert.x构建)上,性能上存在很大的优势。Web开发方式运行于Tomcat或者其他内置的Web服务器之上,作为一个Servlet接收请求,因此在开发过程中,可以使用Web容器提供的一些功能,比如提供页面服务,使用Filter等。当应用只需要提供REST服务,并且对性能要求很高的场景,建议使用Java应用方式。
1.4.6 Spring MVC 模式的差异CSE支持使用Spring MVC提供的标签(org.springframework.web.bind.annotation)来声明REST接口,但是两者是独立的实现,而且有不一样的设计目标。CSE的目标是提供跨语言、支持多通信协议的框架,因此去掉了Spring MVC中一些对跨语言支持不是很好的特性,也不支持运行特定框架强相关的特性,比如直接访问Servlet协议定义的HttpServletRequest。下面是一些显著的差别。
● 服务声明方式
Spring MVC使用@RestController声明服务,而CSE使用@RestSchema声明服务,并且需要显式的使用@RequestMapping声明服务路径,以区分该服务是采用Spring MVC的标签还是使用JAX RS的标签。@RestSchema(schemaId = "hello") @RequestMapping(path = "/")
Schema是CSE的服务契约,是服务运行时的基础,服务治理、编解码等都基于契约进行。在跨语言的场景,契约也定义了不同语言能够同时理解的部分。
● 数据类型支持
采用Spring MVC,可以在服务定义中使用多种数据类型,只要这种数据类型能够被Json序列化和反序列化。比如:// 抽象类型public void postData(@RequestBody Object data)// 接口定义public void postData(@RequestBody IPerson interfaceData)// 没指定类型的泛型public void postData(@RequestBody Map rawData) // 具体协议相关的类型public void postData(HttpServletRequest rquest)
上面的类型在CSE都不提供支持。因为CSE会根据接口定义生成契约,从上面的接口定义,如果不结合实际的实现代码或者额外的开发文档说明,无法直接生成契约。也就是站在浏览器的REST视角,不知道如何在body里面构造消息内容。
为了支持快速开发,CSE的数据类型限制也在不停的扩充,比如支持HttpServletRequest,但是实际在使用的时候,他们与Web服务器的语义是不一样的,比如不能直接操作流。因此建议开发者在CSE的使用场景下,尽可能使用契约能够描述的类型,让代码阅读性更好。
● 常用标签支持
下面是CSE对于Spring MVC常用标签的支持情况。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 50
标签名称 是否支持
说明
RequestMapping 是 -
GetMapping 是 -
PutMapping 是 -
PostMapping 是 -
DeleteMapping 是 -
PatchMapping 是 -
RequestParam 是 -
CookieValue 是 -
PathVariable 是 -
RequestHeader 是 -
RequestBody 是 目前支持application/json,plain/text。
RequestPart 是 用于文件上传的场景,对应的标签还有Part、MultipartFile。
ResponseBody 否 返回值缺省都是在body返回。
ResponseStatus 否 可以通过ApiResponse指定返回的错误码。
RequestAttribute 否 Servlet协议相关的标签。
SessionAttribute 否 Servlet协议相关的标签。
MatrixVariable 否 -
ModelAttribute 否 -
ControllerAdvice 否 -
CrossOrigin 否 -
ExceptionHandler 否 -
InitBinder 否 -
● 其他
CSE不支持在GET方法中使用POJO对象进行参数映射。比如:public voidgetOperation(Person p)CSE不支持在GET方法中使用Map映射所有可能的参数。比如:public voidgetOperation(Map<String,String> p)
1.5 使用 CSE-Codegen 插件
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 51
1.5.1 CSE-Codegen 插件概述
插件简介
服务契约,指基于OpenAPI规范的微服务接口契约,是服务端与消费端对于接口的定义。服务契约用于服务端和消费端的解耦,服务端围绕契约进行服务的实现,消费端根据契约进行服务的调用。CSE Java SDK使用yaml文件格式定义服务契约,可支持多种风格开发微服务。
CSE-Codegen是基于Swagger Codegen实现的代码生成工具,用户只需在微服务工程的服务端和消费端的pom文件分别引入依赖并运行插件,就可以根据契约仓库中定义好的契约文件,生成服务端和消费端的框架代码,快速构建微服务应用。
插件特性● 新增契约同步功能
支持从远端的Git仓库同步一个或多个契约到微服务工程中,每次运行都可以根据新的契约生成框架代码。
● 服务提供者推荐使用SpringMVC风格,服务消费者推荐使用透明RPC风格
在不指明language的情况下,为服务提供者生成SpringMVC风格的框架代码,为服务消费者生成透明RPC风格的框架代码。
● 为服务提供者和服务消费者生成完备的框架性代码
通过在微服务工程的pom文件中配置插件依赖,运行插件后生成以下文件:服务提供者provider生成model + delegate + controller + impl,服务消费者consumer生成model + delegate + impl。
● 适应多服务多契约的场景
在配置中增加参数,可以适应多服务多契约的场景。
● 使用契约中的x-java-class参数,避免consumer和provider的model路径不一致导致调用失败
x-java-class作为契约中一个重要的参数,存在于definitions中的每一个model,标志着model的package路径,能够保证服务消费者consumer和服务提供者provider的model的package路径统一。要求契约的每个model都具备x-java-class,根据x-java-class > service.packageName > packageName的优先级生成model的pacakge路径,避免consumer和provider的model路径不一致导致调用失败。
● 大程度保证显式契约和隐式契约一致
契约必须按照标准的Swagger API Spec语法来描述,使用yaml来表示。
契约中建议model都使用x-java-class参数,保证package路径统一。否则,使用REST方式会调用失败,使用RPC方式会使性能下降。
契约中不建议使用default返回码,CSE Java SDK不支持default返回码,插件也默认屏蔽default返回码。
插件严格按照契约定义,针对契约的不同返回码,生成的框架代码有所体现,大程度保证显式契约和隐式契约一致。
1.5.2 使用 CSE-Codegen 插件开发微服务使用CSE-Codegen插件开发微服务步骤很简单,只需要准备一个Git仓库用于存放契约,在微服务工程里面引入插件依赖,运行插件就能同步远端契约到本地并根据契约
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 52
生成框架代码。可以参考项目示例代码,步骤如下。目前CSE-Codegen的版本已经更新到2.2.9并上传到华为镜像站的huaweicloudsdk仓库,后续版本也会发布到这里。
步骤1 Git仓库归档契约
创建远端Git仓库,用于契约管控,上传契约文件到Git仓库中。可以参考契约仓库示例。
步骤2 配置maven的settings文件
到华为镜像站里面找到HuaweiCloud SDK,下载settings.xml,替换掉原来的settings文件。
步骤3 配置pom文件,引入插件
使用eclipse的用户可能会发现pom文件出现“Plugin execution not covered bylifecycle configuration”的报错信息。出现这种情况不影响插件使用,可以不用理会,也可以按照eclipse的修复提示进行修复。
1. consumer模块引入huawei-swagger-codegen-maven-plugin,插件版本号是2.2.9,groupId不再是io.swagger,而是com.huawei.paas.cse。schemaType指定参数“consumer”,生成服务消费者框架代码,参数说明如表1-6所示。 <plugins> <plugin> <groupId>com.huawei.paas.cse</groupId> <artifactId>huawei-swagger-codegen-maven-plugin</artifactId> <version>2.2.9</version> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> <configuration> <skip>false</skip> <skipOverwrite>false</skipOverwrite> <repositories> <repository> <repoUrl> https://github.com/huaweicse/cse-codegen-schemas.git</repoUrl> <branch>master</branch> <services> <service> <!--<appId>lala</appId>--> <serviceName>myprovider</serviceName> <packageName>com.huawei.paas.consumer</packageName> <schemaType>consumer</schemaType> <schemas> <schema> <schemaPath>yaml/myservice.yaml</schemaPath> </schema> </schemas> </service> </services> </repository> </repositories> <packageName>com.huawei.paas.consumer</packageName> </configuration> </plugin> </plugins>
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 53
表 1-6 参数说明
参数 说明
skip 是否跳过执行该插件功能,默认是true,所以这里需要手动将skip设为false。
skipOverWrite 是否跳过文件覆盖,默认是false,即每次运行插件都可以更新框架代码。
repositories 定义多个契约仓库。
repository 定义单个契约仓库,即远端契约所在的git仓库。
repoUrl 契约仓库地址,http、https、ssh格式都适用。
branch 契约仓库分支名。
services 定义多个服务。
service 定义单个服务,每个服务可以有多个契约文件。
appId 应用Id(选填,只在服务消费者consumer这边指定,跨应用调用的时候可以填对应的服务提供者provider的appId)。
serviceName 服务名(服务消费者consumer和服务提供者provider都填provider的服务名)。
packageName(service层) 生成的框架代码(delegate、impl、controller)的包路径,当契约中的model里面没有x-java-class,也作为model的包路径。
schemaType 指定服务角色是服务消费者consumer还是服务提供者provider,根据契约生成对应的框架代码。
schemas 定义多个契约文件。
schema 定义单个契约文件。
schemaPath 契约文件在契约仓库的相对路径。
packageName 生成代码的包路径,优先级小于service里面的packageName,当两者都没有设置,插件运行会报错。
2. provider模块引入huawei-swagger-codegen-maven-plugin,插件版本号是
2.2.9,groupId不再是io.swagger,而是com.huawei.paas.cse。schemaType指定参数“provider”,生成服务提供者框架代码。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 54
<plugins> <plugin> <groupId>com.huawei.paas.cse</groupId> <artifactId>huawei-swagger-codegen-maven-plugin</artifactId> <version>2.2.9</version> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> <configuration> <skip>false</skip> <skipOverwrite>false</skipOverwrite> <repositories> <repository> <repoUrl> https://github.com/huaweicse/cse-codegen-schemas.git</repoUrl> <branch>master</branch> <services> <service> <serviceName>myprovider</serviceName> <packageName>com.huawei.paas.provider</packageName> <schemaType>provider</schemaType> <schemas> <schema> <schemaPath>yaml/myservice.yaml</schemaPath> </schema> </schemas> </service> </services> </repository> </repositories> <packageName>com.huawei.paas.provider</packageName> </configuration> </plugin> </plugins>
步骤4 运行插件,同步契约并生成框架代码
执行命令,运行CSE-Codegen插件:mvn generate-sources
或者直接编译整个微服务工程,插件运行。当然,不是说每次编译都要运行插件,所以插件配置提供了一个skip参数,默认skip为false,如果想要阻止插件运行导致重复生成框架代码,我们只需要将skip设置为true。
同步契约:
1. 首先会检查工程的gitRepo目录下是否存在同名的Git仓库,如果存在则进行删除。
2. 下载整个Git仓库到工程的gitRepo目录下。
3. 插件根据scchemaPath查找gitRepo里的契约文件,复制到契约文件到工程的microservices目录下,如目录中存在同名契约则替换掉。
生成框架代码:
1. 生成consumer端框架代码:model类、delegate接口、impl实现类(具备RPC调用接口)。
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 55
2. 生成provider端框架代码:model类、controller类、delegate接口、impl实现类。
步骤5 根据框架代码,用户实现自己的业务逻辑
如果impl目录不存在或者impl目录下不存在契约对应的impl实现类,则生成impl实现类;如果impl目录下已存在契约对应的实现类,则不生成(避免覆盖用户已有的业务逻辑)。用户可以在impl实现类中实现自己的业务逻辑。如果用户想要使用框架提供的impl实现类,那么就必须将现有的实现类删除,重新运行插件。
步骤6 测试consumer和provider
测试consumer和provider是否可以通信,可以下载本地服务中心,如图1-1所示。配置好工程里的microservice.yaml,启动服务中心,启动consumer和provider,测试consumer和provider是否正常通信。
图 1-1 本地轻量化服务中心
----结束
微服务云应用平台开发指南 1 Java SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 56
2 Go SDK
2.1 概述CSE(Cloud Service Engine) Go Chassis是华为推出的产品级微服务开发框架。使用CSE Go Chassis开发微服务,可以 大化的简化开发门槛,提升产品上线速度。同时可以获得微服务运行时高可靠性保证、运行时动态治理等一系列开箱即用的能力。
本文档会涵盖在开发过程中需要关心的细节及其使用指南。
如有疑问,可通过访问ServiceStage论坛发帖反馈。
Features● 注册发现:帮助微服务自注册并发现其他微服务。
● 插件化注册中心:默认对接ServiceCenter和文件系统,开发者可自己扩展Kubernetes,Consul,Eureka等服务。
● 限流:提供客户端与服务端限流。
● 负载均衡:提供Filter与Strategy2种方式对实例进行选择,并可定制。
● 熔断:可通过超时时间,错误率,并发量等条件进行熔断控制,保护系统,防止雪崩效应。
● 降级:熔断后可配置降级策略。
● 处理链:支持在一次请求调用中,插入自己的处理逻辑。
● 插件化协议:默认支持http、Highway RPC两种协议。
● 插件化Cipher:在证书,AK/SK等敏感数据加载时,支持使用自己的加解密算法。
● Metrics:支持导出Prometheus格式监控数据。
● Tracing:分布式调用链追踪,支持对接Zipkin。
● 日志:支持扩展自己的Writer实现,可上报给kafka,Elasticseach等组件,默认支持本地文件和标准输出。
● 动态配置框架:对接不同Source,当Source中的配置项出现变化,将触发事件,让微服务感知,用户可自定义事件触发的动作。
● 配置热加载:负载均衡,熔断,降级等配置支持运行时热加载。
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 57
概念解释
● Registry
注册中心负责微服务的注册和发现。
● Service Discovery
服务发现组件,负责服务发现并周期性轮询注册中心中的服务到本地缓存。
● Protocol server and client
支持开发者自己将协议逻辑插入到go chassis中,接入统一的治理和微服务管理当中。
2.2 工作原理
● 不同协议请求进入到各协议Server,Server将具体的协议请求转换为Invocation统一抽象模型,并传入Handler chain,在这里Chassis已经默认实现了很多的Handler,比如熔断,限流等, 终再进入Transport handler,使用具体的协议客户端传输到目标。
● 每次请求生成的监控数据,通过http API导出的方式由Prometheus收集处理,可通过扩展的方式输出到kafka等服务中,也可使用公有云APM服务收集处理日志。
● 注册中心默认对接ServiceCenter。
● Archaius为动态配置框架,可从各种不同的source中读取配置。
2.3 开发指导
2.3.1 定义微服务
概述
使用microservice.yaml文件来定义您的微服务,概念介绍如下。
● 微服务实例:一个进程就是微服务实例,实例属于一个微服务
● 微服务:微服务是存储中的静态信息实体,它有实例 。
您可以将项目视为微服务,在编译、构建和运行之后,它就变成了一个微服务实例。
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 58
配置
microservice.yaml文件配置项说明如下。
表 2-1 配置说明
配置项 是否必选 类型 说明
name 必选 string 微服务名称。
hostname 可选 string 主机名,可以是IP地址、$INTERNAL_IP占位符或主机名等。
默认主机名是os.hostname()的返回值。
如果定义主机名为$INTERNAL_IP,则go-chassis会将ip地址(而不是主机名)上报给服务中心,这在主机名没有实际意义的场景下(例如容器主机)是有用的。
APPLICATION_ID 可选 string 应用ID,默认值:default
version 可选 string 版本号,默认值:0.0.1。
properties 可选 map 微服务metadata,通常是在代码工程中定义的,随代码库改变。
instance_properties
可选 map 实例metadata,在运行时,可以因环境不同而不同。
paths 可选 map 微服务API path,将在servicecenter中注册。
示例
微服务定义示例如下。
service_description: name: Server hostname: 10.244.1.3 properties:
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 59
project: X1 instance_properties: nodeIP: 192.168.0.111 paths: - path: /rest/demoservice property: checksession: true
2.3.2 注册中心
概述
Registry是负责微服务注册与发现的模块,支持对接不同的注册中心服务,默认对接了Service center以及本地文件系统,但是开发者也可参考本章开发自己的Registry插件对接Eureka,Consul,Kubernetes等服务。
配置
无论注册中心采用何种数据模型,都需要对接到Go Chassis框架的数据模型上。具体请参考sc_convertor.go是如何对接模型的。
必须实现的接口如下,因为框架的自动运行机制依赖于这些方法:
表 2-2 方法说明
方法 说明
RegisterService 注册微服务信息。
RegisterServiceInstance 注册微服务实例信息。
Heartbeat 向注册中心发送实例心跳。
GetMicroServiceID 获取服务ID。
FindMicroServiceInstances 根据条件查询微服务实例。
GetProviders 获取本实例依赖的所有微服务。
GetMicroService 根据service ID获得微服务信息。
UnregisterMicroServiceInstance 程序退出,优雅注销时使用。
● 实现下面函数来返回您的注册中心插件。
f func(opts ...Option) Registry
● 调用registry.InstallPlugin来注册自己的注册中心插件。
● 修改配置文件。cse: service: registry: type: servicecenter #这里改为自己的插件名
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 60
2.3.3 配置中心
概述
系统通过配置中心来提供统一配置服务,配置中心用于配置的管理和下发,为微服务提供配置查询存储等服务。开发者可以在应用中配置ConfigCenter的访问路径和策略,实现与配置中心的交互,使用Archaius包获取配置。
配置
配置中心的配置分布在chassis.yaml及microservice.yaml两个文件。chassis.yaml中配置使用的配置中心地址等。microservice.yaml文件是微服务元数据配置文件,用于配置微服务的属性。
说明
当服务中心地址配置为公有云APIgateway时,autodiscovery功能不生效,需要将其设置为false,否则访问配置中心报错。
表 2-3 配置说明
配置项 默认值 说明
serverUri - 配置中心地址,支持多个,使用逗号分隔。
如果使用ip+端口的方式访问配置中心,端口号固定是30103。
refreshInterval 30 客户端主动从配置中心拉取配置的周期。
refreshPort 30104 配置中心动态下发配置的端口。
refreshMode 1 配置的更新方式 默认为定时拉取。
api.version v3 访问配置中心的api版本。
autodiscovery false 自动发现配置中心。
示例
客户端周期性拉取config center做配置更新,refreshInterval指定客户端拉取配置的周期,默认为30s。refreshMode更新方式仅支持1。
cse: config: client: serverUri: https://127.0.0.1:30103 #配置中心地址 refreshInterval: 10 #拉取周期10s autodiscovery: true refreshPort: 30104 api: version: v3
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 61
2.3.4 协议服务器
概述
您可以在 go chassis中扩展自己的协议,目前支持rest(http)和gRPC。
配置
microservice.yaml文件配置项说明如下。
表 2-4 配置说明
配置项 是否必选 类型 说明
protocols.{protocol_server_name}
必选 string 协议服务器的名称。
必须是协议名称或由协议名称和后缀组成。
后缀和协议用连字符“ - ”连接 ,如:rest-{suffix}。
protocols.{protocol_server_name}.advertiseAddress
可选 string 服务器广播地址。
如果您使用服务中心,该地址将在服务中心中注册,以便其他服务可以发现您的地址。
protocols.{protocol_server_name}.listenAddress
必选 string 服务器监听地址。例如:
192.168.0.1:8080,其中192.168.0.1表示具体网卡IP,8080表示服务监听端口
示例
此配置将启动2个http服务和1个grpc服务。
cse: protocols: rest: listenAddress: 192.168.0.1:5000 rest-admin: listenAddress: 192.168.0.1:5001 grpc: listenAddress: 192.168.0.1:6000
如果使用ipv6协议,因为[]是yaml格式的对象列表,需要双引号。
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 62
cse: protocols: rest: listenAddress: "[ipv6地址]:5000"
2.3.5 处理链
概述
处理链中包含一系列handler, 在一次调用中可以通过扩展调用链的方式来插入定制的处理逻辑,如何开发新的Handler,可参考Handler,本章节只讨论如何配置框架已经实现的handler。
配置cse: handler: Consumer: {name}:{handler_names} Provider: {name}:{handler_names}
Consumer表示,当你要调用别的服务时会通过的处理链。
Provider表示,当你被别人调用人会通过的处理链。
支持在Consumer和Provider中定义多个不同的chain name,如果handler配置为空,那么框架会自动为Consumer与Provider加载默认的handlers,chain的名称为default。
● Consumer的默认chain中的handler说明
表 2-5 Consumer 的默认 chain
名称 功能
ratelimiter-consumer 客户端限流
router 路由策略
loadbalance 负载均衡
tracing-consumer 客户端调用链追踪
transport 各协议客户端处理请求,如果你使用自定义处理链配置,那么结尾处必须加入这个handler
● Provider的默认chain中的handler说明
表 2-6 Provider 的默认 chain
名称 功能
ratelimiter-provider 服务端限流
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 63
名称 功能
tracing-provider 服务端调用链追踪
API用户也可自定义默认处理链内的handler都有哪些。
//SetDefaultConsumerChains your custom chain map for Consumer,if there is no config, this default chain will take affectfuncSetDefaultConsumerChains(cmap[string]string)//SetDefaultProviderChains set your custom chain map for Provider,if there is no config, this default chain will take affectfuncSetDefaultProviderChains(cmap[string]string)
你可以检查handler.go中的内置处理程序列表,const部分显示处理程序列表。
const ( //consumer chain Transport = "transport" Loadbalance = "loadbalance" BizkeeperConsumer = "bizkeeper-consumer" TracingConsumer = "tracing-consumer" RatelimiterConsumer = "ratelimiter-consumer" Router = "router" FaultInject = "fault-inject"
//provider chain RatelimiterProvider = "ratelimiter-provider" TracingProvider = "tracing-provider" BizkeeperProvider = "bizkeeper-provider")
示例handler: chain: Consumer: default: bizkeeper-consumer, router, loadbalance, ratelimiter-consumer,transport custom: some-handler
2.3.6 Invoker
概述
Invoker是开发人员调用远程服务的入口点。
API● Rest Invoker
使用NewRestInvoker创建一个invoker实例,可接受chain等自定义选项。
ContextDo可以接受一个http request作为参数,开发者可通过request的API对request进行操作,并作为参数传入该方法。funcNewRestInvoker(opt...Option)*RestInvokerfunc(ri*RestInvoker)ContextDo(ctxcontext.Context,req*http.Request,options...InvocationOption)(*rest.Response,error)
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 64
● RPC Invoker使用NewRPCInvoker创建invoker实例,可接受chain、filters等自定义选项。
指定远端的服务名、struct name、func name以及请求参数和返回接口即可调用provider端, 终结果会赋值到reply参数中。
funcNewRPCInvoker(opt...Option)*RPCInvokerfunc(ri*RPCInvoker)Invoke(ctxcontext.Context,microServiceName,schemaID,operationIDstring,arginterface{},replyinterface{},options...InvocationOption)error
无论Rest还是RPC调用方法都能够接受多种选项对一次调用进行控制,参考options.go查看更多选项。
示例● RPC
invoker.Invoke(ctx, "Server", "HelloServer", "SayHello", &helloworld.HelloRequest{Name: "Peter"}, reply,
)
● Rest在初始化invoker时还指定了这次请求要经过的处理链名称custom。
req, _ := rest.NewRequest("GET", "http://RESTServer/sayhello/world")defer req.Close()resp, err := core.NewRestInvoker(core.ChainName("custom")).ContextDo(context.TODO(), req)
● 多端口
如果为同一协议定义不同的端口,如下所示。
cse: protocols: rest: listenAddress: 192.168.0.1:5000 rest-admin: listenAddress: 192.168.0.1:5001
然后你可以使用后缀“admin”作为访问rest-admin服务器的端口。
req,_:=rest.NewRequest("GET","http://RESTServer:admin/sayhello/world")
使用服务名称来访问rest server。req,_:=rest.NewRequest("GET","http://RESTServer/sayhello/world")
2.3.7 负载均衡策略
概述
用户可以通过配置选择不同的负载均衡策略,当前支持轮询、随机、基于响应时间的权值、会话保持等多种负载均衡策略。
配置
负载均衡的配置项为cse.loadbalance.[MicroServiceName].[PropertyName],其中若省略MicroServiceName,则为全局配置;若指定MicroServiceName,则为针对特定微服务的配置。优先级:针对特定微服务的配置 > 全局配置。
关于重试backOff的配置详见容错。
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 65
配置项 默认值 配置说明
strategy.name RoundRobin 策略可选择[RoundRobin|Random|SessionStickiness|WeightedResponse]。SessionStickiness目前只支持Rest调用。
retryEnabled false 是否允许重试。
retryOnNext 0 请求失败后向其他实例重试的次数。
retryOnSame 0 请求失败后向同一个实例重试的次数。
backoff - 重试配置,详见容错。
须知
● 使用SessionStickiness策略,需要业务代码存储cookie,并在http请求中带入Cookie,http头中返回如下信息:
Set-Cookie: go-chassisLB=0406060d-0009-4e06-4803-080008060f0dhttp请求需带上cookie访问:
Cookie: go-chassisLB=0406060d-0009-4e06-4803-080008060f0d● 使用 WeightedResponse策略,启用后30s 策略会计算好数据并生效,80%左右的
请求会被发送到延迟 低的实例里。
API除了通过配置文件传入负载均衡策略,还支持用户客户端调用传入WithStrategy的方式。
invoker.Invoke(ctx, "Server", "HelloServer", "SayHello", &helloworld.HelloRequest{Name: "Peter"}, reply, core.WithContentType("application/json"), core.WithProtocol("highway"), core.WithStrategy(loadbalance.StrategyRoundRobin),)
示例
配置chassis.yaml的负载均衡部分,以及添加处理链。
cse: loadbalance: # 全局负载均衡配置 strategy: name: RoundRobin microserviceA: # 微服务级别的负载均衡配置 strategy: name: SessionStickiness
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 66
2.3.8 负载均衡过滤器
概述
负载均衡过滤器实现在负载均衡模块中,它允许开发者定制自己的过滤器,使得经过负载均衡策略选择实例前,预先对实例进行筛选。在一次请求调用过程中可以使用多个过滤策略,对从本地cache或服务中心获取的实例组进行过滤,将经过精简的实例组交给负载均衡策略做后续处理。
配置
目前可配的filter只有根据Availability Zone,可根据微服务实例的region以及AZ信息进行过滤,优先寻找同Region与AZ的实例。
cse: loadbalance: serverListFilters: zoneaware
需要配置实例的Datacenter信息。
region: name: us-east availableZone: us-east-1
APIGo-chassis支持多种实现Filter接口的过滤器。FilterEndpoint支持通过实例访问地址过滤,FilterMD支持通过元数据过滤,FilterProtocol支持通过协议过滤,FilterAvailableZoneAffinity支持根据Zone过滤。
type Filter func([]*registry.MicroServiceInstance) []*registry.MicroServiceInstance
示例
客户端实例过滤器Filter的使用支持用户通过API调用传入,并且可以一次传入多个Filter,对实例组进行层层条件筛选。客户端调用传入的方式是调用options的WithFilter方法。
invoker.Invoke(ctx, "Server", "HelloServer", "SayHello", &helloworld.HelloRequest{Name: "Peter"}, reply, core.WithProtocol("highway"), core.WithStrategy(loadbalance.StrategyRoundRobin), core.WithFilters( loadbalance.FilterEndpoint("highway://127.0.0.1:8080"), loadbalance.FilterProtocol("highway"), ),)
2.3.9 使用 Archaius 管理动态配置
概述
go-archaius本身是个功能强大的分布式系统配置管理框架,go-chassis集成go-archaius,调用archaius API来管理自身的本地配置文件和配置中心的配置。使用go-chassis的开发者也可以使用archaius API来开发自己的业务系统。
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 67
go-chassis提供动态配置管理能力,支持远程、本地文件、环境变量及命令行等多种配置管理,并由go-archaius提供统一的接口获取配置。
应用场景
go-archaius适用于CI/CD,服务运行时等。
举例:服务分布在各个服务器中,在需要更改配置时,不想登录到每个机器上进行文件编辑,并进行服务重启,也不可通过CI/CD系统重新部署一个程序。
解决方案:当遇到配置变更时,只需要在配置中心中进行更改,各个服务收到变更消息后,进行更改并在运行时生效,如图2-1和图2-2所示。
图 2-1 下发配置
图 2-2 更改服务配置
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 68
更多文档可参考开源项目go-archaius。
示例
1. 管理本地配置文件请参考示例。
2. 远程管理业务配置请参考示例。
2.3.10 路由策略
概述
路由策略可应用于AB测试场景和新版本的灰度升级,主要通过路由规则来根据请求的来源、目标服务、Http Header及权重将服务访问请求分发到不同版本的微服务实例中。
go chassis利用archaius的动态配置能力,从远程获取配置规则,并在运行时使配置生效,如图2-3所示。
图 2-3 go chassis
配置
路由规则当前只支持在配置文件配置,支持rest和highway协议。
Consumer配置如下:
灰度发布的路由规则只在服务的消费端配置使用,用于将特定的请求,按一定权重,分发至同一服务名的不同分组。
用户可在conf/router.yaml文件中设置:
routeRule: {targetServiceName}: # 服务名 - precedence: {number} #优先级 match: #匹配策略 source: {sourceServiceName} #匹配某个服务名 headers: #header匹配 {key0}: regex: {regex} {key1} exact: {=?} route: #路由规则 - weight: {percent} #权重值 tags:
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 69
version: {version1} app: {appId} - precedence: {number1} match: refer: {sourceTemplateName} #参考某个source模板ID route: - weight: {percent} tags: version: {version2} app: {appId} sourceTemplate: #定义source模板 {templateName}: # source 模板ID source: {sourceServiceName} sourceTags: {tag}:{value} headers: {key0}: regex: {regex} {key1} exact: {=?} {key2}: noEqu: {!=?} {key3} greater: {>?} {key4}: less: {<?} {key5} noLess: {>=?} {key6}: noGreater: {<=?}
路由规则说明:
● 匹配特定请求由routeRule.{targetServiceName}.match配置,匹配条件是:source(源服务名)、source tags及headers,另外也可以使用refer字段来使用source模板进行匹配。
● Match中的Source Tags用于和服务调用请求中的。sourceInfo中的tags进行逐一匹配。
● Header中的字段的匹配支持正则、=、!=、>、<、>=、<=七种匹配方式。
● 如果未定义match,则可匹配任何请求。
● 转发权重定义在routeRule.{targetServiceName}.route下,由weight配置。
● 服务分组定义在routeRule.{targetServiceName}.route下,由tags配置,配置内容有version和app。
API● 设置Router Rules
这个接口会彻底覆盖运行时的路由规则。
router.SetRouteRule(rr map[string][]*config.RouteRule)
● 获取Router Rulesrouter.GetRouteRule() 返回值 map[string][]*config.RouteRule
示例● 目标服务
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 70
每个路由规则的目标服务名称都由routeRule中的Key值指定。例如下表所示,所有以“Carts”服务为目标服务的路由规则均被包含在以“Carts”为Key值的列表中。
routeRule: Carts: - precedence: 1 route: - weight: 100 #percent tags: version: 0.0.1
Key值(目标服务名称)应该满足是一个合法的域名称。例如,一个在服务中心中注册的服务名称。
● 规则优先级
针对某个特定的目标服务可以定义多条路由规则,在路由规则匹配过程中的匹配顺序按照各个规则的“precedence”字段的值来确定。“precedence”字段是可选配置,默认为0,值越大则优先级越高。如果两个规则的“precedence”配置值相同,则它们的实际匹配顺序是不确定的。
一种常用的模式是为指定的目标服务提供一条或多条具有高优先级的匹配请求源/Header的路由规则,并同时提供一条低优先级的只依照版本权重分发请求的路由规则,且这条规则不设置任何匹配条件以处理剩余的其他请求。
以下面的路由规则为例,对所有访问“Carts”服务的请求,如果满足header中包含“Foo:bar”,则将请求分发到服务的“2.0”版本的实例中,剩余的其他请求全部分发到“1.0”版本的实例中。
routeRule: Carts: - precedence: 2 match: headers: Foo: exact: bar route: - weight: 100 tags: version: 2.0 - precedence: 1 route: - weight: 100 tags: version: 1.0
● 请求匹配规则match: refer: {templateName} source: {sourceServiceName} headers: {key}: regex: {regex} {key1}: exact: {exact}
请求的匹配规则属性配置如下:
属性 说明
引用(refer) 引用的匹配规则模板名称,用户可选择在sourceTemplate中定义匹配规则模板,并在此处引用。若引用了匹配规则模板,则其他配置项不用配置。
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 71
属性 说明
源服务(source)
表示发送请求的服务,与consumer是一个意义。
header(headers)
匹配headers。如果配置了多条Header 字段校验规则,则需要同时满足所有规则才可完成路由规则匹配。匹配方式有以下几种:
● 精确匹配(exact):header必须等于配置
● 正则(regex):按正则匹配header内容
● 不等于(noEqu):header不等于配置值
● 大于等于(noLess): header不小于配置值
● 小于等于(noGreater):header不大于配置值
● 大于(greater):header大于配置值
● 小于(less): header小于配置值
示例:
match: source: vmall headers: cookie: regex: "^(.*?;)?(user=jason)(;.*)?$"
仅适用于来自vmall,header中的“cookie”字段包含“user=jason"的服务访问请求。
● 分发规则
每个路由规则中都会定义一个或多个具有权重标识的后端服务,这些后端服务对应于用标签标识的不同版本的目标服务的实例。如果某个标签对应的注册服务实例有多个,则指向该标签版本的服务请求会按照用户配置的负责均衡策略进行分发,默认会采用round-robin策略。
分发规则的属性配置如下:
属性 说明
权重(weight) 本条规则的分发比重,配置为1-100的整数,表示百分比。
标签(tags) 用于区分相同服务名的不同服务分组,支持的key值为:版本(version),默认值为0.0.1。应用(app),默认值为default。
下面的例子表示75%的访问请求会被分流到具有“version:2.0”标签的服务实例中,其余25%的访问请求会被分发到1.0版本的实例中。
route: - weight: 75 tags: version: 2.0 - weight: 25
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 72
tags: version: 1.0
● 定义匹配模板
我们可以通过预定义源模板(模板中的结构为一个Match结构),并在match部分引用该模板来进行路由规则的匹配。在下面的例子中,“vmall-with-special-header”是一个预定义的源模板的Key值,并在Carts的请求匹配规则中被引用。routeRule: Carts: - precedence: 2 match: refer: vmall-with-special-header route: - weight: 100 tags: version: 2.0sourceTemplate: vmall-with-special-header: source: vmall headers: cookie: regex: "^(.*?;)?(user=jason)(;.*)?$"
2.3.11 限流
概述
用户可以通过配置限流策略限制Provider端或Consumer端的请求频率,使每秒请求数限制在 大请求量的大小。其中Provider端的配置可限制接收处理请求的频率,Consumer端的配置可限制发往指定微服务的请求的频率。
配置
限流配置在rate_limiting.yaml中,同时需要在chassis.yaml的handler chain中添加handler。其中qps.limit.[service] 是指限制从service 发来的请求的处理频率,若该项未配置则global.limit生效。Consumer端不支持global全局配置,其他配置项与Provider端一致。
配置项 默认值 配置说明
flowcontrol.qps.enabled
true 是否开启流控模块。
flowcontrol.qps.global.limit
2147483647(max int) 流控全局配置。
flowcontrol.qps.limit.[service]
2147483647(max int) 每秒允许的请求数。
APIqpslimiter提供获取流控实例的接口GetQpsTrafficLimiter和相关的处理接口。其中ProcessQpsTokenReq根据目标qpsRate在handler chain中sleep响应时间实现限流,UpdateRateLimit提供更新qpsRate限制的接口,DeleteRateLimiter提供了删除流控实例的接口。
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 73
● 对请求流控
qpslimiter.GetQpsTrafficLimiter().ProcessQpsTokenReq(key string, qpsRateint)
● 更新流控限制
qpslimiter.GetQpsTrafficLimiter().UpdateRateLimit(key string, valueinterface{})
● 删除流控实例
qpslimiter.GetQpsTrafficLimiter().DeleteRateLimiter(key string)
示例● Provider示例
Provider端需要在chassis.yaml添加ratelimiter-provider。同时在rate_limiting.yaml中配置具体的请求数。
cse: handler: chain: Provider: default: ratelimiter-providercse: flowcontrol Provider: qps: enabled: true # enable rate limiting or not global: limit: 100 # default limit of provider limit: Server: 100 # rate limit for request from a provider
● Consumer示例
在Consumer端需要添加ratelimiter-consumer这个handler。同时在rate_limiting.yaml中配置具体的请求数。
cse: handler: chain: Consumer: default: ratelimiter-consumercse: flowcontrol: Consumer: qps: enabled: true # enable rate limiting or not limit: Server: 100 # rate limit for request to a provider
2.3.12 容错
概述
go-chassis提供自动重试的容错能力,用户可配置retry及backOff策略自动启用重试功能。
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 74
配置
重试功能的相关配置与客户端负载均衡策略都在chassis.yaml的cse.loadbalance.配置下。当retryEnabled配置为true时,可通过配置retryOnSame和retryOnNext定制重试次数。另外可通过backOff定制重试策略,默认支持三种backOff策略。
● zero:固定重试时间为0的重试策略,即失败后立即重试不等待。
● constant:固定时间为backoff.minMs的重试策略,即失败后等待backoff.minMs再重试。
● jittered:按指数增加重试时间的重试策略,初始重试时间为backoff.minMs,大重试时间为backoff.MaxMs。
配置项 默认值 配置说明
retryEnabled false 是否开启重试功能。
retryOnSame 0 请求失败后向同一个实例重试的次数。
retryOnNext 0 请求失败后向其他实例重试的次数。
backoff.kind zero 重试策略:[jittered或constant或zero]。
backoff.minMs 0 重试 小时间间隔,单位ms。
backoff.MaxMs
0 重试 大时间间隔,单位ms。
示例
配置chassis.yaml负载均衡部分中的重试参数。
cse: loadbalance: retryEnabled: true retryOnNext: 2 retryOnSame: 3 backoff: kind: jittered MinMs: 200 MaxMs: 400
2.3.13 熔断降级请参考用户指南与开发指南。
2.3.14 传输层配置请参考Transport。
2.3.15 Metrics
Metrics 接口介绍
go chassis提供方便的API帮助用户记录自己的业务数据到Promethues Exporter中,以Rest API的方式对外暴露业务数据
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 75
请参考Metrics。
接入 CSE MonitoringMetrics用于度量服务性能指标。开发者可通过配置文件来将框架自动收集的metrics上传到CSE监控系统。
相关配置项如下:
配置项 默认值 说明
cse.monitor.client.serverUri - CSE monitoring地址
cse.monitor.client.userName default 用户名称
cse.monitor.client.domainName
default 域名称
服务要接入CSE monitoring需要独立import相应的包
import _ "github.com/ServiceComb/cse-collector"
示例如下:
cse: monitor: client: serverUri: https://cse.cn-north-1.myhuaweicloud.com:443
同时配置好auth.yaml的ak/sk信息,可以在CSE Dashboard看到上传的监控数据。
2.3.16 TLS参考TLS查看如何使用和完整的例子。
2.3.17 契约管理
概述
go-chassis读取服务契约并将其内容上传至注册中心。
配置
契约文件必须为yaml格式文件,契约文件应放置于go-chassis的schema目录。
schema目录位于:
1. conf/{serviceName}/schema,其中conf表示go-chassis的conf文件夹。
2. ${SCHEMA_ROOT}。
2的优先级高于1。
API包路径:
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 76
import "github.com/ServiceComb/go-chassis/core/config/schema"
契约字典,key值为契约文件名,value为契约文件内容:
var DefaultSchemaIDsMap map[string]string
示例conf`-- myservice `-- schema |-- myschema1.yaml `-- myschema2.yaml
2.3.18 Java 和 Go 互相调用
当在同一个项目中需要同时使用Java和Go语言时,Java可以基于servicecomb-java-chassis作为client,Go使用go-chassis作为client,使用servicecomb-service-center作为注册中心。
Go作为provider
java调用go时,go-chassis不会自动生成反序列化需要用到schema中x-java-interface标示的class,需要手动把此参数添加到schema中,所以,请在chassis.yaml中设定noRefreshSchema: true,表示不会自动生成schema,否则每次启动已经添加class的schema会被无添加class的schema覆盖。其他无需任何特殊设置。代码请参考java-call-go。
Java作为provider
由于go-chassis不支持highway协议,必须使用HTTP通信。其他无需任何特殊设置。
2.4 自定义功能
2.4.1 Log
概述
Go chassis以插件的形式提供日志组件功能。其中标准输出默认加载,文件输出可选,用户可定制写日志方式。
配置
用户可通过lager暴露的接口实现自己的日志输出,同时将注册的writer名字配置在lager.yaml中。
● 通过实现io.Writer自定义日志接口type Writer interface { Write(p []byte) (n int, err error)}
● 使用并注册新日志writerRegisterWriter(name string, writer io.Writer)writers: file,stdout,[your_writer]
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 77
示例● 实现并注册日志接口,其中syslog.New返回的writer实现了Write(b []byte) (int,
error)方法import ( "github.com/go-chassis/paas-lager" "github.com/go-chassis/paas-lager/syslog")
func init() { w, _ := syslog.New() stlager.RegisterWriter("syslog", w)}
● lager.yaml配置示例如下writers: syslog,file,stdoutlogger_level: DEBUGlogger_file: log/chassis.loglog_format_text: falserollingPolicy: sizelog_rotate_date: 1log_rotate_size: 10log_backup_count: 7
2.4.2 Handler
概述
Go chassis以插件的形式支持在一次请求调用中,插入自己的处理逻辑。
配置
实现handler需要如下三步骤。其中[service_type] 可配置为Provider或Consumer,[chain_name]默认为default。
● 注册Handler逻辑
RegisterHandler(name string, f func() Handler) error● 实现Handler接口
type Handler interface { Handle(*Chain, *invocation.Invocation, invocation.ResponseCallBack) Name() string}
● 在chassis.yaml中添加handler chain配置cse: handler: chain: [service_type]: [chain_name]: [your_handler_name]
示例
示例中注册的是名为fake-handler的处理链,其实现的Handler方法仅记录inv的endpoint信息。
package handlerimport ( "github.com/ServiceComb/go-chassis/core/handler" "github.com/ServiceComb/go-chassis/core/invocation"
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 78
"log")const Name = "fake-handler"type FakeHandler struct{}
func init() { handler.RegisterHandler(Name, New) }func New() handler.Handler { return &FakeHandler{} }func (h *FakeHandler) Name() string { return Name }
func (h *FakeHandler) Handle(chain *handler.Chain, inv *invocation.Invocation, cb invocation.ResponseCallBack) { log.Printf("fake handler running for %v", inv.Endpoint) chain.Next(inv, func(r *invocation.InvocationResponse) error { return cb(r) })}
chassis.yaml配置示例如下
cse: handler: chain: Provider: default: fake-handler
2.4.3 Go-Archaius
概述
go-archaius是go-chassis的动态配置框架,目前支持CSE 配置中心、本地文件、ENV、CMD等配置管理。如果用户希望接入自己的配置服务中,可以参考本章节实现。
配置
go-archaius支持同时配置多种源,包括命令行、环境变量、外部源及文件等。用户可通过ConfigurationFactory接口的AddSource方法添加自己的配置源,并通过RegisterListener方法注册EventListener。
AddSource(core.ConfigSource) errorRegisterListener(listenerObj core.EventListener, key ...string) error
其中配置源需要实现ConfigSource接口。GetPriority和GetSourceName必须实现且有有效返回,分别用于获取配置源优先级和配置源名称。GetConfigurations和GetConfigurationByKey方法用于获取全部配置和指定配置项,需要用户实现。其他方法可以返回空。
● GetPriority方法用于确定配置源的优先级,go-archaius内置的5个配置源优先级由高到底分别是配置中心、命令行、环境变量、文件、外部配置源,对应着0到4五个整数值。用户自己接入的配置源可自行配置优先级级别,数值越小则优先级越高。GetSourceName方法用于返回配置源名称。
● 若没有区域区分的集中式配置中心,DemensionInfo相关接口可返回nil不实现。
● Cleanup用于清空本地缓存的配置。
● DynamicConfigHandler接口可根据需要实现,用于实现动态配置动态更新的回调方法。
type ConfigSource interface { GetSourceName() string
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 79
GetConfigurations() (map[string]interface{}, error) GetConfigurationsByDI(dimensionInfo string) (map[string]interface{}, error) GetConfigurationByKey(string) (interface{}, error) GetConfigurationByKeyAndDimensionInfo(key, dimensionInfo string) (interface{}, error) AddDimensionInfo(dimensionInfo string) (map[string]string, error) DynamicConfigHandler(DynamicConfigCallback) error GetPriority() int Cleanup() error}
注册EventListener用于在配置源更新时处理由Dispatcher分发的事件。
type EventListener interface { Event(event *Event)}
示例● 实现configSource
type fakeSource struct { Configuration map[string]interface{} changeCallback core.DynamicConfigCallback sync.Mutex}
func (*fakeSource) GetSourceName() string { return "TestingSource" }func (*fakeSource) GetPriority() int { return 0 }
func (f *fakeSource) GetConfigurations() (map[string]interface{}, error) { config := make(map[string]interface{}) f.Lock() defer f.Unlock() for key, value := range f.Configuration { config[key] = value } return config, nil}
func (f *fakeSource) GetConfigurationByKey(key string) (interface{}, error) { f.Lock() defer f.Unlock() configValue, ok := f.Configuration[key] if !ok { return nil, errors.New("invalid key") } return configValue, nil}
func (f *fakeSource) DynamicConfigHandler(callback core.DynamicConfigCallback) error { f.Lock() defer f.Unlock() f.changeCallback = callback return nil}
func (f *fakeSource) Cleanup() error { f.Lock() defer f.Unlock() f.Configuration = make(map[string]interface{}) f.changeCallback = nil return nil}
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 80
func (*fakeSource) AddDimensionInfo(d string) (map[string]string, error) { return nil, nil }func (*fakeSource) GetConfigurationByKeyAndDimensionInfo(k, d string) (interface{}, error) { return nil, nil }func (*fakeSource) GetConfigurationsByDI(d string) (map[string]interface{}, error) { return nil, nil }
● 添加configSourcefunc NewConfigSource() core.ConfigSource { return &fakeSource{ Configuration: make(map[string]interface{}), }}factory, _ := goarchaius.NewConfigFactory()err := factory.AddSource(fakeSource.NewConfigSource())
● 注册evnetListenertype EventHandler struct{ Factory goarchaius.ConfigurationFactory}func (h EventHandler) Event(e *core.Event) { value := h.Factory.GetConfigurationByKey(e.Key) log.Printf("config value after change %s | %s", e.Key, value)}factory.RegisterListener(&EventHandler{Factory: factory}, "a*")
2.4.4 Protocol请参考Protocol。
2.5 运维
2.5.1 指标监控指标是服务运行的重要监控数据,go chassis使用Promethues exporter模式对指标进行收集,并将收集到的指标导出。除了QPS、延迟、请求量、cpu和内存等系统指标外,也支持对用户自定义的业务指标,如用户登录数,在线用户数,交易数等进行收集。
步骤1 配置metric功能为开启状态,详细相关配置请参考metric。
步骤2 在servicestage进行容器部署go-chassis应用时,在“自定义指标监控”进行配置,"上报路径"为在步骤一时所配置的路径,如未配置默认为/metrics,“上报端口”为应用监听的端口,示例如下图所。
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 81
步骤3 配置完成并部署完成后,指标数据可到AOM进行查看。进入AOM界面后,选择“视图管理 > 指标监控”。
步骤4 在“选择指标”区域选中需要查看的指标,查看该指标的数据。
除了可以查看服务的指标数据,我们亦可以选中需要查看的实例查看每一个实例的指标数据。
----结束
2.5.2 日志采集与查看在你使用ServiceStage部署go-chassis应用的时候,你可以在“应用运维管理”中查看相关运行日志。
步骤1 在部署应用时,在“高级设置”中"运维监控"下的"日志采集"单击"添加日志策略",如下图
步骤2 在日志策略弹框选择容器路径,然后在“挂载路径”输入你所配置的运行日志的路径,日志配置请参考log
如下图示例配置,应用运行在/home/chassis下,日志文件路径配置为log/chassis.log,
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 82
步骤3 部署完成后,在服务列表下选择“应用运维管理”,如下图所示
步骤4 在应用运维管理界面左侧,单击“日志管理”,进入日志管理界面,如下图所示。
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 83
步骤5 选择你部署的应用所在的集群,然后在下方输入你的应用名称进行搜索你部署的应用,然后单击chassis.log后面的查看按钮进行查看,如下图所示。
----结束
2.5.3 熔断定位服务端的某个API超时、客户端高并发或者服务端返回错误(网络错误或是用户自定义错误状态码而导致的错误),达到一定阈值就会引起熔断发生。
熔断发生后,将以网络隔离的方式将服务端的API和客户端隔离,客户端将不会再访问此API。开发者可通过分析客户端和服务端日志来定位错误,并找出根因。
定位方法:
步骤1 此时服务端的API已经被隔离,检查服务端日志,查看这个API在被调用时,发生了什么。
步骤2 检查客户端日志查看熔断原因
● 查看Call got Error相关日志,查看在调用过程中传输层的错误返回是什么,是网络错误、超时还是用户自定义的错误状态码。
● 看到max concurrency,说明客户端的并发量超过阈值。
----结束
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 84
辅助定位方法:根据指标监控的指标数据查看服务运行时发生了什么。
常见熔断原因:● 服务端死锁。
● 客户端并发量过大。
● 服务端超时响应。
● 根据传输层配置定义错误码,服务端返回状态码符合配置内容。
微服务云应用平台开发指南 2 Go SDK
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 85
3 Mesh 指南
3.1 简介
什么是 mesherMesher是Service Mesh的一个具体的实现,是一个轻量的代理服务以Sidecar的方式与微服务一起运行。
Service Mesh是由William Morgan定义:
Service Mesh是一个基础设施层,用于处理服务间通信。云原生应用有着复杂的服务拓扑,Service Mesh保证请求可以在这些拓扑中可靠地传输。在实际应用当中,Service Mesh通常是由一系列轻量级的网络代理组成的,它们与应用程序部署在一起,但应用程序不需要知道它们的存在。
随着云原生应用的崛起,Service Mesh逐渐成为一个独立的基础设施层。在云原生模型里,一个应用可以由数百个服务组成,每个服务可能有数千个实例,而每个实例可能会持续地发生变化。服务间通信不仅异常复杂,而且也是运行时行为的基础。管理好服务间通信对于保证端到端的性能和可靠性来说是非常重要的。
Service Mesh实际上就是处于TCP/IP之上的一个抽象层,它假设底层的L3/L4网络能够点对点地传输字节(当然,它也假设网络环境是不可靠的,所以Service Mesh必须具备处理网络故障的能力)。
从某种程度上说,Service Mesh有点类似TCP/IP。TCP对网络端点间传输字节的机制进行了抽象,而Service Mesh则是对服务节点间请求的路由机制进行了抽象。Service
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 86
Mesh不关心消息体是什么,也不关心它们是如何编码的。应用程序的目标是“将某些东西从A传送到B”,而Service Mesh所要做的就是实现这个目标,并处理传送过程中可能出现的任何故障。
与TCP不同的是,Service Mesh有着更高的目标:为应用运行时提供统一的、应用层面的可见性和可控性。Service Mesh将服务间通信从底层的基础设施中分离出来,让它成为整个生态系统的一等公民——它因此可以被监控、托管和控制。
为什么使用 mesher● 业务代码无须改造
● 支持老旧应用接入
● 普通应用快速成为云原生应用
● 业务代码零侵入
基本实现原理
Mesher是L7层协议代理,Mesher以Sidecar模式运行在应用所在的Pod内,与Pod共享网络与存储:
1. Pod中的应用使用Mesher作为http代理,可以自动发现其他服务。
2. Mesher会代替Pod中的应用向注册中心注册应用相关信息,以便让其他应用发现。
发起一次网络请求的过程中存在微服务消费者和提供者,场景如下:
● 场景一:仅消费者使用Mesher作为Sidecar。提供者需要自己实现服务注册发现,或者使用Java或GO chassis开发框架,否则无法发现AccountService。
应用间的网络请求如下:
Store web -> Mesher -> Account service
● 场景二:消费者提供者均使用Mesher作为Sidecar。此场景无需再使用微服务开发框架。
应用间的网络请求如下:
Store web -> Mesher -> Mesher -> Account service
● 场景三:仅提供者使用Mesher作为Sidecar消费者需要使用 Java或者Go chassis开发框架。
应用间的网络请求如下:
Store web -> Mesher -> Account service
注意事项
应用上云后需要作出一定的配置变更。例如在Mesher所处环境外,StoreWeb在访问AccountService时使用http://IP:port/进行访问。在使用Mesher后,使用http://AccountService:port/即可进行访问,文档中将详细讲解。
3.2 配置
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 87
3.2.1 简介
配置文件在不同基础设施部署有不同的方案
- 在VM部署,用户可以直接进行编辑
- 在kubernetes部署,利用configmap将配置应用到容器中
- 在ServiceStage部署参考创建Mesher应用。
3.2.2 ak/sk(公有云使用)
文件名
auth.yaml
${CIPHER_ROOT}/certificate.yaml(高优先级)
场景
当mesher连接公有云上的CSE服务中心、配置中心、仪表盘时,用户必须配置ak/sk信息,否则无法通过认证。
配置方式
文件内容如下:
cse: credentials: accessKey: secretKey: project: akskCustomCipher: default #used to decrypt sk when it is encrypted
● cse.credentials.project为服务所在project,若不涉及多project,请置空。
● cse.credentials.akskCustomCipher为加解密工具名,当以明文配置sk时,无需修改。当以密文配置sk时,需要提供加解密工具。加解密工具定制,请参见定制Cipher加解密工具。
3.2.3 定制 Cipher 加解密工具
场景
对于mesher可能使用到的敏感信息,例如证书密码、ak/sk,当用户以明文配置这些信息时,存在泄露风险。为了解决此问题,mesher支持自定义加解密工具,用户可使用密文配置敏感信息,由mesher调用加解密工具对密文进行解密。
开发工具
请用户准备go语言开发环境。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 88
须知
● 自定义加解密工具功能由go语言plugin机制实现,目前只支持linux系统。
● go语言版本:1.8。
● gcc版本:高于4.8.2(推荐编译系统:Ubuntu 14.04,SUSE 12.1)。
步骤1 编写插件代码。
1. 设置package名为main。
2. 编写结构体实现以下接口:type Cipher interface {Encrypt(src string) (string, error)
Decrypt(src string) (string, error)}
3. 定义该结构体对象,对象名为“Cipher”,用户负责对象的初始化。
步骤2 编译插件。
执行如下命令:
go build -buildmode=plugin -o {pluginFile}.so {gofile}.go
得到插件文件{pluginFile}.so。
步骤3 将插件文件放置于指定目录下。
将插件文件放置于{workDir}/lib或/usr/lib目录下,其中{workDir}为mesher可执行文件所在目录。
说明
插件文件名必须与配置的加解密工具名相同。
----结束
示例
加解密工具代码示例:
package main
import ( "strings")
const suffix = ".mycipher"
type MyCipher struct {}
func (m *MyCipher) Encrypt(src string) (string, error) { return src+suffix, nil}
func (m *MyCipher) Decrypt(src string) (string, error) { return strings.TrimSuffix(src, suffix), nil}
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 89
var Cipher MyCipher
该工具加解密方式分别为在尾部添加和删除字符串“.mycipher”。用户将代码编译为插件mycipher.so,放置到对应目录。若用户的ak/sk明文分别为myak/mysk,则用户可在auth.yaml文件中配置:
cse.credentials.accessKey: myak.myciphercse.credentials.secretKey: mysk.myciphercse.credentials.akskCustomCipher: mycipher
3.2.4 对接服务中心和配置中心
文件名
chassis.yaml
场景
可以定义注册发现、配置中心、处理链等配置,不推荐用户对里面已经调校好的配置进行更改。完整示例如下,用户可查看注释了解所有配置。
说明
service.registry.autodiscovery 配置项是否开启自动发现,开启后将从服务中心注册发现注册的其他服务中心。config.client.autodiscovery配置是否开启配置中心的自动发现。当服务中心地址设置为公有云APIgateway时,则不支持这两个自动发现功能,即不能设置autodiscovery为true。
cse: protocols: http: listenAddress: 127.0.0.1:30101 service: registry: #address: http://127.0.0.1:30100 # uri of service center address: https://cse.cn-north-1.myhuaweicloud.com:443 # uri of service center scope: full #set full to be able to discover other app's service watch: false # set if you want to watch instance change event autoIPIndex: true # set to true if u want to resolve source IP to microservice config: client: serverUri: https://cse.cn-north-1.myhuaweicloud.com:443 #uri of config center refreshMode: 1 # 1: only pull config. refreshInterval: 30 # unit is second monitor: #Send monitoring data to CSE monitor Server client: serverUri: https://cse.cn-north-1.myhuaweicloud.com:443 # monitor server url
3.2.5 微服务信息定义
文件名
microservice.yaml
场景
用于描述微服务信息。更多信息请参考http://go-chassis.readthedocs.io/en/latest/user-guides/microservice.html
示例:
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 90
APPLICATION_ID: mesherservice_description: name: hellomesher version: 0.0.1 environment: #microservice environment properties: allowCrossApp: false
配置说明
表 3-1 配置说明
配置项 说明
APPLICATION_ID 描述服务属于哪个应用。
name 微服务名称。
version 微服务版本,默认为0.0.1。
properties 可选配置。定义微服务的元数据信息。
allowCrossApp 可选配置。微服务是否允许其他应用的微服务发现,默认为false。在开启跨app访问时使用。
须知
当使用apache server时,服务名中不要带下划线。
apache server禁止hostname中包含下划线,而使用mesher时,服务名即为hostname,所以访问带下划线的服务名时,apache server将返回400错误:Yourbrowser sent a request that this server could not understand.如果必须使用带下划线的服务名,为保证正常访问,可以在conf/httpd.conf添加配置项:HttpProtocolOptions unsafe但该配置项会带来安全风险,用户应在配置前明确知晓:https://httpd.apache.org/docs/2.4/mod/core.html#httpprotocoloptions
3.2.6 负载均衡与重试
文件名
load_balancing.yaml
场景
Sidecar场景,即单consumer多provider时,参照以下方法编辑文件,对负载均衡治理指令进行设置:
● cse.loadbalance.strategy.name: Random
● cse.loadbalance.{provider}.strategy.name: Random
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 91
其中{provider}字段内容为服务名,如cse.loadbalance.ServiceB.strategy.name:Random。
须知
使用会话粘滞,需要业务代码存储cookie,并在http请求中带入Cookie,Mesher在头中返回如下信息:
Set-Cookie: SERVICECOMBLB=0406060d-0009-4e06-4803-080008060f0dhttp请求需带上cookie访问:
Cookie: SERVICECOMBLB=0406060d-0009-4e06-4803-080008060f0d
完整示例cse: loadbalance: strategy: name: RoundRobin # Strategy name, Support Random,RoundRobin, WeightedResponse and SessionStickiness retryEnabled: false # if there is resposne error, retry request or not retryOnNext: 2 # request to the same instance retryOnSame: 3 # request to another instance based on strategy backoff: # backoff policy kind: constant # jittered/constant/zero MinMs: 200 # millisecond, Minimum duration to backoff MaxMs: 400 # millisecond, Maximum duration to backoff
3.2.7 熔断降级
文件名
circuit_breaker.yaml
概念描述
熔断降级策略是当服务请求异常时,微服务所采用的异常处理策略。
降级策略有三个相关的技术概念:“隔离”、“熔断”和“容错”。
● “隔离”是一种异常检测机制,常用的检测方法是请求超时、流量过大等。一般的设置参数包括超时时间、同时并发请求个数等。
● “熔断”是一种异常反应机制,“熔断”依赖于“隔离”。熔断通常基于错误率来实现。一般的设置参数包括统计请求的个数、错误率等。
● “降级”是一种异常处理机制,“降级”依赖于“熔断”。熔断以后,会调用“降级”的方法。
把这些概念联系起来: 当“隔离”措施检测到N次请求中共有M次错误的时候,“熔断”不再发送后续请求,调用“降级”处理函数。
当前提供两种降级方式,分别为返回null值和抛出异常。
场景描述
用户通过配置熔断降级策略,可以设置微服务的异常处理策略。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 92
配置说明
配置项的格式为:
cse.[namespace].Consumer.[servicename].[property]: configuration
其中namespace取值为:isolation|circuitBreaker|fallback,分别表示隔离、熔断、降级策略。不同namespace对应不同的property,servicename为可选配置。
为了方便描述,下表中的配置项均省略了Consumer和servicename。
配置项如表3-2所示。
表 3-2 降级策略相关配置项说明
配置项 默认值
取值范围 是否必选
含义 注意
cse.isolation.timeoutInMilliseconds
30000
- 否 超时时间阈值 -
cse.isolation.maxConcurrentRequests
1000 - 否 大并发数阈值
-
cse.circuitBreaker.enabled
true - 否 是否启用熔断措施
-
cse.circuitBreaker.forceOpen
false - 否 无论失败次数为多少,都进行熔断
-
cse.circuitBreaker.forceClosed
false - 否 任何时候都不熔断
当与forceOpen同时配置时,forceOpen优先。
cse.circuitBreaker.sleepWindowInMilliseconds
15000
- 否 熔断后,多长时间恢复
恢复后,会重新计算失败情况。注意:如果恢复后的调用立即失败,那么会立即重新进入熔断。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 93
配置项 默认值
取值范围 是否必选
含义 注意
cse.circuitBreaker.requestVolumeThreshold
20 - 否 10s内统计错误发生次数阈值,超过阈值则触发熔断
由于10s还会被划分为10个1s的统计周期,经过1s中后才会开始计算错误率,因此从调用开始至少经过1s,才会发生熔断。
cse.circuitBreaker.errorThresholdPercentage
50 - 否 错误率阈值,达到阈值则触发熔断
-
cse.fallback.enabled
true - 否 是否启用出错后的降级处理措施
-
cse.fallbackpolicy.policy
throwexception
● returnnull● throwexce
ption
否 出错后的降级策略
-
完整样例---cse: isolation: Consumer: timeout: enabled: false timeoutInMilliseconds: 1 maxConcurrentRequests: 100 Server: timeout: enabled: true timeoutInMilliseconds: 1000 maxConcurrentRequests: 1000 circuitBreaker: Consumer: enabled: false forceOpen: false forceClosed: true sleepWindowInMilliseconds: 10000 requestVolumeThreshold: 20 errorThresholdPercentage: 10 Server: enabled: true forceOpen: false forceClosed: false sleepWindowInMilliseconds: 10000 requestVolumeThreshold: 20
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 94
errorThresholdPercentage: 5 fallback: Consumer: enabled: true maxConcurrentRequests: 20 fallbackpolicy: Consumer: policy: throwexception
3.2.8 限流
文件名
chassis.yaml
场景
限流是为了应对DOS攻击对QPS进行限制的服务治理策略。
配置说明
配置项 默认值 说明
cse.flowcontrol.Consumer.qps.enabled
true 开启服务消费端流控。
cse.flowcontrol.Provider.qps.enabled
true 开启服务提供端流控。
cse.flowcontrol.Consumer.qps.limit.[ServiceName]
2147483647 消费端 大QPS。可从服务、schema、operation三个粒度进行配置。
cse.flowcontrol.Provider.qps.limit.[ServiceName]
2147483647 提供端 大QPS。只能从服务级别进行配置。
Consumer 限流
用户在consumer端使用限流策略,可以限制发往指定微服务的请求的频率。
● 若不配置QPS上限,则默认为2147483647。
● 若配置cse.flowcontrol.Consumer.qps.limit.ms=10,000,则调用服务ms时的 大QPS为10000。
配置样例:
cse: flowcontrol: Consumer: qps: enabled: true limit: Server: 1000
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 95
Provider 限流
服务提供端的限流只从服务级别进行限制,如cse.flowcontrol.Provider.qps.limit.ms=1000,表明服务ms允许的 大QPS为1000。
配置样例:
cse: flowcontrol: Provider: qps: enabled: true limit: Server: 1000
3.2.9 监控
文件名
monitoring.yaml
场景
提供了接入CSE仪表盘,zipkin的能力,用于监控微服务状态以及分布式调用追踪
调用链追踪功能用于追踪请求的完整调用链路,搜集调用链路的性能数据,计算并对比性能指标。
mesher的调用链数据使用zipkin格式,用户可自己部署Zipkin server并使用
须知
1. 当你对自己的业务代码端口直接进行访问时,是得不到QPS,Latency等监控数据的。如果想获得监控数据需要使用业务所在IP与mesher端口进行访问。
2. 需要上报CSE 监控界面,需要确保处理链中包含以下粗体字标注handler。consumer: outgoing: ratelimiter-consumer,bizkeeper-consumer,loadbalance,transport incoming: bizkeeper-provider,ratelimiter-provider,local-selection,transport
3. 需要上报调用链追踪数据需确保处理链中包含以下粗体字标注handlerconsumer: outgoing: ratelimiter-consumer,loadbalance,tracing-consumer,transport: incoming: tracing-provider,ratelimiter-provider,local-selection,transport
完整样例cse: monitor: #Send monitoring data to CSE monitor Server client: serverUri: https://10.21.209.37:30109 # monitor server url enable: true #set it to true if you want to send the data to monitor server api: version: v1 #默认为v2,表示使用监控的哪个API版本tracing: enabled: true #enable distribution tracing collectorType: namedPipe #http: Send tracing info to zipkin server #file:Write tracing info to file
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 96
#namedPipe:Write tracing info to linux named pipe. collectorTarget: /home/chassis.trace #If the collectorType is "http", the target is a zipkin server url, if the collecterType is "file" or "namedPipe", the target is a file path.
3.2.10 TLS
文件名
tls.yaml
场景
通过在mesher而不是应用中处理TLS,TLS通信可以在不修改业务代码的情况下进行。透明的TLS通信使业务开发者能够专注于业务开发,而不关心编写TLS相关代码。
推荐使用者托管自己的TLS相关配置。
图 3-1 单 Mesher
图 3-2 多 Mesher
示例中,StoreWeb与Mesher之间的通信是未加密的,但主机间的通信是加密的。因此,StoreWeb不必担心通信安全,Mesher会处理。
配置
配置格式:
{tag}.{key}: 具体配置
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 97
tag表示标签,决定该配置型作用于哪个对象,key表示真正的配置项,tag可自定义,key固定。配置项说明如表3-3所示。
表 3-3 配置说明
配置项 默认值 允许值 说明
cipherPlugin default default,aes 若私钥的加密密码也是加密的,这里需要指定解密插件。
参考定制Cipher加解密工具定制插件。
verifyPeer true boolean 是否验证对端:
● Server:只验证对端证书,不检查CN。
● Client:同时验证证书和CN。
cipherSuits TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- 支持的TLS套件
protocol TLSv1.2 TLSv1.0 /TLSv1.1 / TLSv1.2
注意:TLSv1.0/TLSv1.1不是安全的协议,默认不采用这两种协议,如果用户自己确定选择这两种,则需要了解存在的风险。
caFile N/A - Trust certificate证书文件路径。
certFile N/A - 证书文件路径。
keyFile N/A - 私钥文件地址。
certPwdFile N/A - 若私钥被加密,则密码需存储在该文件中,注意文件内容不能有换行符,linux下可用命令echo "abc"|tr -d '\n\t'> {passFile}生成无换行符的文件。私钥未加密则置空。
● Sidecar Mode– 使用HTTPS协议
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 98
如果用户想为Mesher设置HTTPS代理,那么必须对SSL进行配置,标签为mesher.Provider,如下: mesher.Provider.cipherPlugin: default mesher.Provider.verifyPeer: false mesher.Provider.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 mesher.Provider.protocol: TLSv1.2 mesher.Provider.caFile: /etc/trust.cer mesher.Provider.certFile: /etc/cert.pem mesher.Provider.keyFile: /etc/key.pem mesher.Provider.certPwdFile:
– 透明TLS如果用户想使用透明TLS,那么必须对Consumer和Provider进行SSL配置。
ProviderProvider与Mesher部署在同一台主机中。当Provider为AccountService时,SSL标签为AccountService.rest.Provider,如下: AccountService.rest.Provider.cipherPlugin: default AccountService.rest.Provider.verifyPeer: false AccountService.rest.Provider.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 AccountService.rest.Provider.protocol: TLSv1.2 AccountService.rest.Provider.caFile: /etc/trust.cer AccountService.rest.Provider.certFile: /etc/cert.pem AccountService.rest.Provider.keyFile: /etc/key.pem AccountService.rest.Provider.certPwdFile:
Consumer如果服务使用透明的TLS来调用其他服务,那么它必须为这些服务提供Consumer的SSL配置。当StoreWeb为AccountService时,SSL标签为AccountService.rest.Consumer,如下: AccountService.rest.Consumer.cipherPlugin: default AccountService.rest.Consumer.verifyPeer: false AccountService.rest.Consumer.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 AccountService.rest.Consumer.protocol: TLSv1.2 AccountService.rest.Consumer.caFile: /etc/trust.cer AccountService.rest.Consumer.certFile: /etc/cert.pem AccountService.rest.Consumer.keyFile: /etc/key.pem AccountService.rest.Consumer.certPwdFile:
说明
Sidecar模式中,Mesher禁止监听在0.0.0.0上。
完整样例ssl: # The provider is the service which run in the same host/pod with mesher. for example the service name of provider is ServiceA, then the ssl tag is ServiceA.rest.provider # if u set this , no need to consider about expose your own service as https service, # your service shoule better only listen on 127.0.0.1, mesher wil expose https and use http to communicate with your service ServiceA.rest.Provider.cipherPlugin: default ServiceA.rest.Provider.verifyPeer: false ServiceA.rest.Provider.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ServiceA.rest.Provider.protocol: TLSv1.2 ServiceA.rest.Provider.caFile: # Should give the proper cerftificate path for provider.certFile and provider.keyFile if certificate files are not mounted then comment those option. ServiceA.rest.Provider.certFile: /etc/ssl/cert/ServiceA.crt
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 99
ServiceA.rest.Provider.keyFile: /etc/ssl/cert/ServiceA.key ServiceA.rest.Provider.certPwdFile:
# If a service want to use transparent tls to call other services, it must supplies consumer ssl config for these services. # for example ServiceA want to communicate with ServiceB the config is like below ServiceB.rest.Consumer.cipherPlugin: default ServiceB.rest.Consumer.verifyPeer: false ServiceB.rest.Consumer.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ServiceB.rest.Consumer.protocol: TLSv1.2 ServiceB.rest.Consumer.caFile: ServiceB.rest.Consumer.certFile: ServiceB.rest.Consumer.keyFile: ServiceB.rest.Consumer.certPwdFile:
3.2.11 路由规则
文件名
router.yaml
场景
用户灰度发布(AB test,canary release)
路由规则负责根据请求的来源、目标服务、Header及权重将服务访问请求分发到不同版本的服务实例中。
配置格式routeRule: {targetServiceName}: - precedence: {number} match: refer: {templateName} source: {sourceServiceName} headers: {key}: regex: {regex} exact: {header} route: - weight: {percent} tags: version: {version} app: {appId}sourceTemplate: {templateName}: source: {sourceServiceName} headers: {key}: regex: {regex} exact: {header}
ruleRule定义的是,将特定的请求,按一定权重,分发至同一服务名的不同分组。
匹配特定请求由routeRule.{targetServiceName}.match配置,匹配条件是:source(源服务名)、header,如果未定义match则匹配任何请求。
转发权重定义在routeRule.{targetServiceName}.route下,由weight配置。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 100
服务分组定义在routeRule.{targetServiceName}.route下,由tags配置,配置内容有version和app。
示例:
routeRule: Carts: - precedence: 1 match: source: vmall headers: Content-Type: exact: application/json route: - weight: 100 #percent tags: version: 0.0.1 app: default
该配置意义为,对源服务为vmall且header中带有Content-Type:application/json的请求,以100%的权重发送至Carts:0.0.1:default(name:version:app)。
routeRule下的key表示目标服务,value属性配置说明如下:
表 3-4 routeRule 属性配置
属性 说明
优先级
(precedence)
路由规则生效的优先级。整数,默认为0,数值越大优先级越高。
匹配规则
(match)
请求匹配规则,表示本路由规则对什么样的请求生效。
分发规则
(route)
将请求按配置的规则分发。
目标服务
每个路由规则的目标服务名称都由routeRule中的Key值指定。例如下表所示,所有以“Carts”服务为目标服务的路由规则均被包含在以“Carts”为Key值的列表中。
routeRule: Carts: - precedence: 1 route: - weight: 100 #percent tags: version: 0.0.1
Key值(目标服务名称)应该满足是一个合法的域名称。例如,一个在服务中心中注册的服务名称。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 101
规则优先级
针对某个特定的目标服务可以定义多条路由规则,在路由规则匹配过程中的匹配顺序按照各个规则的“precedence”字段的值来确定。“precedence”字段是可选配置,默认为0,值越大则优先级越高。如果两个规则的“precedence”配置值相同,则它们的实际匹配顺序是不确定的。
一种常用的模式是为指定的目标服务提供一条或多条具有高优先级的匹配请求源/Header的路由规则,并同时提供一条低优先级的只依照版本权重分发请求的路由规则,且这条规则不设置任何匹配条件以处理剩余的其他请求。
以下面的路由规则为例,对所有访问“Carts“服务的请求,如果满足header中包含”Foo:bar“,则将请求分发到服务的”2.0“版本的实例中,剩余的其他请求全部分发到”1.0“版本的实例中。
routeRule: Carts: - precedence: 2 match: headers: Foo: exact: bar route: - tags: version: 2.0 - precedence: 1 route: - tags: version: 1.0 weight: 100
请求匹配规则match: refer: {templateName} source: {sourceServiceName} headers: {key}: regex: {regex} exact: {header}
请求的匹配规则属性配置如下:
表 3-5 请求匹配规则属性配置
属性 说明
引用
(refer)引用的匹配规则模板名称,用户可选择在sourceTemplate中定义匹配规则模板,并在此处引用。若引用了匹配规则模板,则其他配置项不用配置。
源服务
(source)
表示发送请求的服务,和consumer是一个意义。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 102
属性 说明
header(headers)
匹配header。如果配置了多条Header 字段校验规则,则需要同时满足所有规则才可完成路由规则匹配。
匹配方式有以下几种:
精确匹配(exact):header必须等于配置。
正则(regex):按正则匹配header内容。
不等于(noEqu):header不等于配置值
大于等于(noLess): header不小于配置值
小于等于(noGreater):header不大于配置值
大于(greater):header大于配置值
小于(less): header小于配置值
示例:
match: source: vmall headers: cookie: regex: "^(.*?;)?(user=jason)(;.*)?$"
仅适用于来自vmall,header中的“cookie”字段包含“user=jason"的服务访问请求。
分发规则route: - weight: {percent} tags: version: {version} app: {appId}
分发规则的属性配置如下:
表 3-6 分发规则属性匹配
属性 说明
权重
(weight)
本条规则的分发比重,配置为1-100的整数,表示百分比。
标签
(tags)用于区分相同服务名的不同服务分组,支持的key值为:
版本(version),默认值为0.0.1。
应用(app),默认值为default。
每个路由规则中都会定义一个或多个具有权重标识的后端服务,这些后端服务对应于用标签标识的不同版本的目标服务的实例。如果某个标签对应的注册服务实例有多
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 103
个,则指向该标签版本的服务请求会按照用户配置的负责均衡策略进行分发,默认会采用round-robin策略。
下面的例子表示75%的访问请求会被分流到具有“version:2.0”标签的服务实例中,其余25%的访问请求会被分发到1.0版本的实例中。
route: - weight: 75 tags: version: 2.0 - weight: 25 tags: version: 1.0
定义匹配模板
我们可以通过预定义源模板(模板中的结构为一个Match结构),并在match部分引用该模板来进行路由规则的匹配。在下面的例子中,“vmall-with-special-header”是一个预定义的源模板的Key值,并在Carts的请求匹配规则中被引用。routeRule: Carts: - precedence: 1 match: refer: vmall-with-special-header route: - weight: 75 tags: version: 2.0 app: default - weight: 25 tags: version: 1.0 app: defaultsourceTemplate: vmall-with-special-header: source: vmall headers: cookie: regex: "^(.*?;)?(user=jason)(;.*)?$"
完整示例sourceTemplate: vmall-with-special-header: source: vmall sourceTags: version: 2.0 headers: cookie: regex: "^(.*?;)?(user=jason)(;.*)?$" X-Age: exact: "18"routeRule: Carts: #host in the invoke request(like service name in service center - precedence: 2 #the higher the more percedent route: - tags: version: 1.2 #by default is 0.1 when connected to sc app: HelloWorld #by default is "default" when connected to sc weight: 80 #route 80% invoke requests here - tags:
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 104
version: 2.0 weight: 20 # 20% match: refer: vmall-with-special-header - precedence: 1 route: - tags: version: 3.0 weight: 100
3.2.12 错误注入
文件目录
conf/router.yaml
场景
用于测试你的服务的容错能力,可以让你知道,当出现错误或者延时时,系统仍然能够运行。
配置
在router.yaml的处理链中添加错误注入功能,并添加错误注入配置。
cse: handler: chain: Consumer: outgoing: fault-inject,ratelimiter-consumer,bizkeeper-consumer,loadbalance,transport governance: Consumer: _global: #对所有请求注入错误,若对发送至特定服务的请求注入错误,将其改为对应服务名 policy: fault: protocols: rest: #协议,支持rest与highway abort: httpStatus: 400 #注入错误码 percent: 50 #注入概率 delay: fixedDelay: 2 #注入时延,单位为s percent: 100 #注入概率
3.2.13 契约配置
文件目录
conf/{servicename}/schema/{schemaID}.yaml
场景
当一个微服务作为服务提供者,并且消费者是Java SDK开发的微服务时,那么这个微服务就需要提供契约来描述自身的API接口。
在mesher conf目录下创建{servicename}/schema文件夹,将契约文件放到这个目录下即可。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 105
3.3 Admin API
3.3.1 简介Mesher Admin API 提供路由查询,健康检查,监控等API。
配置
编辑chassis.yaml启用admin API server监听
cse: protocols: grpc: listenAddress: 127.0.0.1:40101 http: listenAddress: 127.0.0.1:30101 rest-admin: listenAddress: 127.0.0.1:30102 # listen addr use to adminAPI
编辑mesher.yaml以启用Admin API
admin: enable: true #是否启用 goRuntimeMetrics : true #是否开启go运行时监控并导出metric数据
3.3.2 健康检查
功能业务
查看mesher健康状态
URI
GET /v1/mesher/health
请求消息
无
响应消息
响应参数
参数说明请参见表3-7。
表 3-7 参数说明
参数 类型 说明
Health health 健康状态。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 106
表 3-8 health 参数说明
参数 类型 说明
serviceName string 微服务名
version string 微服务版本
status string 状态有green(健康)和red(不健康) 当与注册中心失联后,状态将变为red
connectedConfigCenterClient
bool 是否和配置中心连接
connectedMonitoring
bool 是否和CSE仪表盘连接
响应示例
{ "serviceName": "cart", "version": "0.1", "status": "green", "connectedConfigCenterClient": false, "connectedMonitoring": false}
状态码
状态码如表3-9所示。
表 3-9 状态码
code Description
200 请求成功
500 内部错误
3.3.3 Mesher 版本信息
功能业务
查看mesher版本
URI
GET /v1/mesher/version
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 107
请求消息
无
响应消息
响应参数
参数说明请参见表3-10。
表 3-10 参数说明
参数 类型 说明
text text 版本号
响应示例
1.0
状态码
状态码如表3-11所示。
表 3-11 状态码
code Description
200 请求成功
500 内部错误
3.3.4 路由信息
功能业务
查询路由规则,接口可返回一个服务的相关的路由信息定义
URIGET /v1/mesher/routeRule/{serviceName}
参数说明请参见表3-12。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 108
表 3-12 参数说明
参数 位于
类型 必选 说明
serviceName path
String 否 微服务名,查询微服务消费者如何对目标微服务进行引流
请求消息
无
响应消息
响应参数
表 3-13 参数说明
参数 类型 说明
路由信息 text 路由完整信息
响应示例
- precedence: 2 route: - tags: app: HelloWorld version: "1.2" weight: 80 - tags: app: HelloWorld version: "1.3" weight: 20 match: refer: vmall-with-special-header source: vmall sourceTags: version: v2 httpHeaders: X-Age: exact: "18" cookie: regex: ^(.*?;)?(user=jason)(;.*)?$- precedence: 1 route: - tags: version: "1.0" weight: 100 match: refer: "" source: "" sourceTags: {} httpHeaders: {}
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 109
状态码
状态码如表3-14所示。
表 3-14 状态码
code Description
200 请求成功
400 错误的请求
500 内部错误
3.3.5 Metric 信息
功能业务
查看mesher metric数据,metrics信息符合开源的prometheus标准格式,可通过Promethues进行收集并对接进入Grafana进行监控
URIGET /v1/mesher/metrics
请求消息
无
响应消息
响应参数
参数说明请参见表3-15。
表 3-15 参数说明
参数 类型 说明
text text prometheus 格式的metric数据
响应示例
# HELP go_goroutines Number of goroutines that currently exist.# TYPE go_goroutines gaugego_goroutines 28# HELP go_info Information about the Go environment.# TYPE go_info gaugego_info{version="go1.9"} 1# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.# TYPE go_memstats_alloc_bytes gaugego_memstats_alloc_bytes 3.891488e+06
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 110
# HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed.# TYPE go_memstats_alloc_bytes_total countergo_memstats_alloc_bytes_total 1.63252264e+08# HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table.# TYPE go_memstats_buck_hash_sys_bytes gaugego_memstats_buck_hash_sys_bytes 1.454785e+06# HELP Server_request_latency_seconds request_latency_seconds# TYPE Server_request_latency_seconds summaryServer_request_latency_seconds{AppId="CSE",version="0.1",quantile="0.5"} 0.000658564Server_request_latency_seconds{AppId="CSE",version="0.1",quantile="0.9"} 0.001710824Server_request_latency_seconds{AppId="CSE",version="0.1",quantile="0.99"} 0.001710824Server_request_latency_seconds_sum{AppId="CSE",version="0.1"} 0.004386012Server_request_latency_seconds_count{AppId="CSE",version="0.1"} 5# HELP Server_requests_total requests_total# TYPE Server_requests_total counterServer_requests_total{AppId="CSE",version="0.1"} 5# HELP Server_succeses_total succeses_total# TYPE Server_succeses_total counterServer_succeses_total{AppId="CSE",version="0.1"} 5# HELP mesher_request_latency_seconds request_latency_seconds# TYPE mesher_request_latency_seconds summarymesher_request_latency_seconds{AppId="default",version="0.1",quantile="0.5"} 0.000658564mesher_request_latency_seconds{AppId="default",version="0.1",quantile="0.9"} 0.001710824mesher_request_latency_seconds{AppId="default",version="0.1",quantile="0.99"} 0.001710824mesher_request_latency_seconds_sum{AppId="default",version="0.1"} 0.004386012mesher_request_latency_seconds_count{AppId="default",version="0.1"} 5# HELP mesher_5xx_errors 5xx_errors# TYPE mesher_5xx_errors countermesher_5xx_errors{AppId="default",version="0.1"} 2# HELP mesher_failures_total failures_total# TYPE mesher_failures_total countermesher_failures_total{AppId="default",version="0.1"} 2# HELP mesher_requests_total requests_total# TYPE mesher_requests_total countermesher_requests_total{AppId="default",version="0.1"} 5# HELP mesher_services_monitored services_monitored# TYPE mesher_services_monitored gaugemesher_services_monitored{AppId="default",version="0.1"} 1# HELP mesher_start_time_seconds start_time_seconds# TYPE mesher_start_time_seconds gaugemesher_start_time_seconds{AppId="default",version="0.1"} 1.507637815e+09# HELP mesher_succeses_total succeses_total# TYPE mesher_succeses_total countermesher_succeses_total{AppId="default",version="0.1"} 5
状态码
状态码如表3-16所示。
表 3-16 状态码
code Description
200 请求成功
500 内部错误
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 111
3.4 多协议接入
3.4.1 gRPC
操作步骤
步骤1 编辑chassis.yaml,启用grpc代理,默认已打开。cse: protocols: grpc: listenAddress: 127.0.0.1:40101 http: listenAddress: 127.0.0.1:30101
步骤2 应用代码适配,需要加入一个定制的Dialer。
假设之前的代码是:
conn,err:=grpc.Dial("10.0.1.1:50051",grpc.WithInsecure(),)
需要改为 //target address is consist of the provider name(in that case "Server") and provider portconn, err := grpc.Dial("Server:50051", grpc.WithInsecure(), grpc.WithDialer(func(addr string, time time.Duration) (net.Conn, error) { //127.0.0.1:40101 is local grpc proxy address return net.DialTimeout("tcp", "127.0.0.1:40101", time) }))
步骤3 部署mesher及应用。
----结束
3.5 多语言接入
3.5.1 nodejs 接入 Mesher请参考nodejs基于Mesher接入已有应用。
3.5.2 PHP 接入 Mesher请参考PHP基于Mesher接入已有应用。
3.5.3 .NET 接入 Mesher通过ServiceStage部署,可以将dotnet应用变为云原生应用,需要符合以下条件:
● 使用docker进行打包
● 使用linux与dotnet core生态
● 支持标准http_proxy环境变量以进行代理设置
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 112
说明
当前支持的dotnet core的版本为:2.0.9版本及以上,3.0版本以下。
Demo 说明
用户可以使用dotnet demo示例,示例Demo包含如下两个服务。
● payment service此服务的API为 /v1/payments,访问该服务会返回一串json。
● order service此服务的API为 /v1/orders, 当你调用它时调用 /v1/payments接口,并把json透传回来。
ServiceStage 部署
1. 确保order配置文件中payment地址正确
给payment service起个名字“payment” 以代替本地127.0.0.1的寻址方式,端口需要保留,输入以下命令。vim order/src/appsettings.json
{ "ServiceEndpoints": { "PaymentServiceEndpoint": "http://payment:8080" }, ....}
2. 打包payment和order的镜像
首先选择上传到某个region的swr,比如swr.cn-north-1.myhuaweicloud.com,在该region的软件中心创建组织,比如demo,具体参考创建组织。
示例命令如下:cd order/src/ sudo docker build . -t swr.cn-north-1.myhuaweicloud.com/demo/ordernet:1.0cd payment/src/ sudo docker build . -t swr.cn-north-1.myhuaweicloud.com/demo/paymentnet:1.0
3. 上传镜像
登录ServiceStage,进入软件中心,通过界面上传,请参考上传镜像。
通过命令push,示例如下:docker push swr.cn-north-1.myhuaweicloud.com/demo/ordernet:1.0 docker push swr.cn-north-1.myhuaweicloud.com/demo/paymentnet:1.0
4. 部署应用
– 部署payment应用
i. 登录ServiceStage控制台,创建应用。应用类型选择:ServiceComb应用。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 113
ii. 填写基本信息,框架选择“Mesher”,运行环境选择“Docker”,,应用名称输入:payment,设置部署集群,实例数选择1即可,其他参数使用默认配置。
说明
应用名字要跟1中order配置文件中的地址保持完全一致,所以名字为payment。
iii. 设置应用配置信息,选择3中上传的payment应用镜像,设置ServiceComb微服务引擎,购买微服务引擎专享版请参考购买ServiceComb引擎。其他参数使用默认配置。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 114
iv. 规格确认,提交后开始创建应用,等待应用创建完成。
– 部署order应用
i. 登录ServiceStage控制台,创建应用。应用类型选择:ServiceComb应用。
ii. 填写基本信息,框架选择“Mesher”,运行环境选择“Docker”,,应用名称输入:order,设置部署集群,实例数选择1即可,其他参数使用默认配置。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 115
iii. 设置应用配置信息,选择3中上传的order应用镜像;开启外网访问,应用端口填写80;设置ServiceComb微服务引擎,购买微服务引擎专享版请参考购买ServiceComb引擎。其他参数使用默认配置。
iv. 规格确认,提交后开始创建应用,等待应用创建完成。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 116
结果验证
等待2个服务全部部署完成 点击外网访问地址,如下图所示。
调用对应接口,返回json串,如下图所示。
查看ServiceComb控制台(如果进入控制台,具体参考进入仪表盘),会看到已经存在的服务,并且可以监控和进行治理,具体参考微服务治理。
3.6 运维
3.6.1 日志查看在你使用ServiceStage部署应用的时候,同时勾选使用Mesher时,你可以在“应用运维管理”中查看Mesher的相关运行日志。
步骤1 点击服务列表,单击“应用运维管理”,如下图所示。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 117
步骤2 单击“日志管理”,进入日志管理界面,如下图所示。
步骤3 选择你部署的应用所在的集群,然后在下方输入你的应用名称进行搜索你部署的应用,然后单击mesher.log后面的查看按钮进行查看,如下图所示。
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 118
----结束
微服务云应用平台开发指南 3 Mesh 指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 119
4 远程调试
4.1 概述
简介
云上调试(CloudDebug)主要用于支撑租户调试人员对单个集群内微服务实例中的Java程序进行远程调试。
主要功能包括:
● 查询功能:可对集群内所有的微服务进行查询,查询结果展示在插件UI界面中的“Service List”中。针对某一微服务,查询属于该微服务的所有实例名和实例的集群内IP地址,并将查询结果展示在插件UI界面中的“Instance List”中,如下图所示。
● 远程调试功能:CloudDebug主要设计用于对ServiceStage租户集群内微服务实例中的Java程序进行远程调试,支持所有通用Java调试功能,如程序断点、变量查看、堆栈查看等;
CloudDebug由部署于租户集群内的CloudDebug微服务、用户本地PC上运行的Eclipse插件、LocalProxy本地代理三部分构成,Eclipse插件和LocalProxy本地代理包由调试者从“ServiceStage>应用开发>微服务开发>工具下载”,在“远程调试工具”页签下载。
调试时的部署示意图如下:
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 120
调试时CloudDebug plugin(CloudDebug 提供的Eclipse plugin)经过本地代理后,通过微服务集群内的CloudDebug服务与容器实例中的JVM通信,控制Java程序,进行调试。
CloudDebug支持同时对多个实例进行远程调试,在Eclipse上调试者可以配置多个调试配置用于连接不同的容器实例,即同一客户端支持同时对多个实例进行远程调试,如下图所示:
CloudDebug还支持同时为多个用户提供远程调试服务,如下图所示,多个客户端可以同时通过CloudDebug服务与集群内不同的容器实例中的JVM通信,控制Java程序的运行,进行调试,如下图所示:
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 121
使用流程
使用CloudDebug进行微服务Java远程调试的操作流程如下:
1. 调试者:下载并安装CloudDebug工具包内的Eclipse插件与本地代理;
2. 调试者:生成公私钥,将公钥交给租户管理员;
3. 租户管理员:配置调试者的公钥;
4. 租户管理员:在需要调试的微服务所在集群中,某一台拥有EIP(Elastic IP)的节点上预置服务端pkcs12证书及CA证书;
5. 租户管理员:开启需要调试微服务所在集群的CloudDebug服务;
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 122
6. 调试者:进行LocalProxy的配置,启动LocalProxy;
7. 调试者:在Eclipse插件中进行配置,查询微服务
8. 调试者:选中需要调试的微服务实例,开始Java远程调试;
9. 调试者:结束调试;
10. 租户管理员:关闭CloudDebug服务。
4.2 下载安装
环境&依赖
CloudDebug仅提供了Eclipse的插件,用户需要先自行下载和安装Eclipse。
CloudDebug支持的Eclipse如下:
● Eclipse IDE for Java EE Developers(Neon 4.6.3) Windows 64-bit
客户端支持的操作系统为:windows 7 64bits。
下载 CloudDebug 客户端
步骤1 下载CloudDebug Eclipse插件工具包。
进入“ServiceStage>应用开发>微服务开发>工具下载”,在“远程调试工具”页签下载CloudDebug远程调试工具的Eclipse插件工具包CloudDebug_ToolKits_for_Eclipse.rar。Eclipse插件工具包中共包括5个jar包和一个bundles.info文件(*代表版本号)以及一个LocalProxy本地代理。分别为:
org.eclipse.debug.core_3.11.0.clouddebug*.jar
org.eclipse.debug.ui_3.12.0.clouddebug*.jar
org.eclipse.jdt.debug.ui_3.8.0.clouddebug*.jar
org.eclipse.jdt.debug_3.11.0.clouddebug*.jar
org.eclipse.jdt.launching_3.9.0.clouddebug*.jar
bundles.info
LocalProxy.rar
----结束
安装 Eclipse 插件
前置条件
用户已经安装好Eclipse Neon 4.6.3。
操作步骤
步骤1 Eclipse插件包含在下载CloudDebug客户端中下载的工具包CloudDebug_ToolKits_for_Eclipse.rar中,解压该包,得到5个*jar文件和1个bundles.info文件。
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 123
步骤2 复制插件中的全部5个jar包到[Eclipse Neon 4.6.3安装目录]\plugins\目录下。
步骤3 复制bundles.info到[Eclipse Neon 4.6.3安装目录]\configuration\org.eclipse.equinox.simpleconfigurator目录下替换掉原bundles.info文件。
步骤4 验证安装是否成功。
启动eclipse,打开“Debug->Debug Configurations…”,如图4-1所示:
图 4-1 插件查看入口
可以在调试配置界面左侧调试类型列表中找到CloudDebug Java Application选项,说明插件安装成功,如图4-2所示:
图 4-2 Debug Configurations 界面
----结束
安装 LocalProxy
步骤1 LocalProxy本地代理包含在下载CloudDebug客户端中下载的工具包CloudDebug_ToolKits_for_Eclipse.rar中,解压后得到LocalProxy.rar文件。
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 124
步骤2 解压本地代理压缩包:LocalProxy.rar包含两个文件,解压后得到LocalProxy.exe可执行文件及etc配置文件目录。
----结束
4.3 操作指南
4.3.1 调试准备
生成公私钥
每一位调试者使用CloudDebug都需要一对RSA公私钥以便权限认证。公钥交由租户管理员,在“ServiceStage>应用开发>微服务开发>远程调试”界面进行配置,私钥由调试者自行保管。在进行云上调试时,调试者在LocalProxy配置文件中配置私钥文件路径,LocalProxy本地代理会使用该私钥进行数字签名,并在和CloudDebug的交互时附上数字签名进行操作权限认证,若认证通过则CloudDebug接受请求提供服务,否则Eclipse插件提示认证不通过,无法继续调试。
调试者在首次使用CloudDebug进行调试时都需要先生成RSA公私钥,并进行配置。
生成公私钥有以下两种方法,您可以选择其中一种用于公私钥生成:
● Linux环境下,使用如下命令生成公私钥:
ssh-keygen -t rsa -b 2048
● Windows环境下推荐使用PuTTYgen生成,PuTTYgen官方下载地址为: https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html,使用PuTTYgen生成RSA公私钥的过程如下:
a. 启动PuTTYgen。
b. 在界面Parameters区域框中选择密钥类型为RSA。
c. 在界面Parameters区域框中输入密钥长度为2048。
d. 单击Generate生成密钥。
e. 完成生成后,直接复制界面中Key区域框中的公钥至空白文档并保存。
f. 选中菜单栏Conversions-> Export OpenSSH Key 将私钥导出为OpenSSH格式。
配置公私钥
1. 将公钥文件交给租户管理员,由管理员进入“ServiceStage>应用开发>微服务开发>远程调试”界面中配置公钥。若配置界面中显示所配置的公钥,说明集群管理员已经配置成功。
2. 私钥文件由调试者保管在客户端,请用户记住私钥保存的路径,后续在本地代理配置文件中进行配置时需要配置客户端保存的私钥路径。
说明
若调试者丢失私钥,则需要重新生成并配置公钥,并及时通知管理员删除配置在云上调试中的原公钥。
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 125
配置 SSL 证书
CloudDebug默认开启SSL加密通信,且LocalProxy与CloudDebug之间实现双向认证,因此用户需要:
1. 为CloudDebug提供SSL所需的证书及CA证书。
2. 为本地LocalProxy提供客户端密钥和证书。
警告
若管理员在启动CloudDebug服务时不配置服务端证书目录,则视为主动关闭SSL通信,CloudDebug将使用未加密的通道提供服务,相应的,用户需要承担使用不加密通道进行调试所带来的安全风险。
普通用户或许未购买可信第三方签发的证书,因此建议按照以下方法配置SSL证书:
1. 使用openssl工具,自签发服务端证书及私钥和客户端证书及私钥。
2. 将证书(root.crt和server.p12)预置在私有集群的一台EIP节点上。
3. 在启动CloudDebug时将证书所在目录配置到CloudDebug启动参数中,并给CloudDebug配置这台EIP节点的标签(具体方法详见开启集群内CloudDebug服务),这样可以让CloudDebug部署在这台EIP节点上。
4. 将客户端密钥和证书提供给LocalProxy使用(LocalProxy如何使用密钥和证书,见LocalProxy配置与启动)。
下面介绍如何使用openssl工具生成自签发的服务端证书及私钥和客户端证书及私钥(openssl工具请用户自行进行安装)。
须知
1、建议在下述步骤中生成密钥时加入“-passout:<密钥加密口令>”选项,生成加密格式的密钥,防止敏感信息泄露。
2、下述步骤中标红的文件名请勿改动,目前CloudDebug只能识别固定的文件名:root.crt,server.p12
步骤1 生成根密钥及CA根证书。openssl genrsa -aes256 -passout pass:<用户根密钥口令> -out root.key 2048 openssl req -x509 -new -key root.key -passin pass:<用户根密钥口令> -days 365 -out root.crt
步骤2 查看私有集群中已绑定EIP的节点的IP地址,并依此来签发服务端证书:这样可支持CloudDebug与LocalProxy之间的双向认证。openssl genrsa -out server.key 2048openssl req -new -key server.key -config ./openssl.cnf -out server.csr openssl x509 -req -CA root.crt -CAkey root.key -passin pass:<用户根密钥口令> -CAcreateserial -in server.csr -out server.crt -extensions v3_req -extfile openssl.cnf
其中openssl.cnf为openssl在签发服务端证书时所采用的配置文件,下面是一份可用的openssl.cnf文件,用户也可根据具体需求自定义openssl配置,唯一要求用户在openssl.cnf中配置[alt_names]中的IP.1项为CloudDebug即将部署到的EIP节点的IP:
[req] distinguished_name = req_distinguished_name req_extensions = v3_req
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 126
[req_distinguished_name] countryName = Country Name (2 letter code) countryName_default = CN stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = BeiJing localityName = Locality Name (eg, city) localityName_default = YaYunCun organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = Domain Control Validated commonName = Internet Widgits Ltd commonName_max = 64
[ v3_req ] # Extensions to add to a certificate request basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names
[alt_names] # IP.1 must be the same with the IP that your server listening toIP.1 = EIP节点的IP
步骤3 生成pkcs12证书:上一步中生成了服务端证书和密钥,再使用下述命令将证书和密钥打包成pkcs12格式的标准SSL证书:openssl pkcs12 -export -out server.p12 -inkey server.key -in server.crt
步骤4 生成客户端密钥和证书(给LocalProxy使用)。openssl genrsa -aes256 -passout pass:<用户客户端密钥口令> -out client.key 2048openssl req -new -key client.key -passin pass:<用户客户端密钥口令> -out client.csropenssl x509 -req -in client.csr -CA root.crt -CAkey root.key -passin pass:<用户根密钥口令> -CAcreateserial -out client.crt -days 365
----结束
LocalProxy 配置与启动
在客户端中,进入LocalProxy/etc目录,修改config.json配置文件:
{ "localDebugPort": , "localQueryPort": , "cloudDebugServerAddress": "", "cloudQueryServerAddress": "", "keyFilePath": "", "logPath": "", "tlsMode": true, "clientCert": "", "clientKey": "", "caCert": ""}
须知
1. 配置文件为json格式,下述配置项中填写windows文件目录时需将"\"替换为"/"。
2. tlsMode项需要与CloudDebug是否开启SSL模式保持一致,CloudDebug是否开启SSL模式参考开启集群内CloudDebug服务。
3.在配置cloudDebugServerAddress和cloudQueryServerAddress是注意区分调试服务和查询服务两个地址,分别对应填入相应的配置项中。
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 127
表 4-1 配置项说明
配置项 说明
localDebugPort 本地代理监听调试端口号(1~65535)。
localQueryPort 本地代理监听微服务查询转发端口号(1~65535)。
cloudDebugServerAddress
CloudDebug调试服务访问地址(ip:port形式),通过“ServiceStage > 应用上线 > 应用管理”,选择相应的集群,单击clouddebug服务进入详情页,单击“查看访问方式”,查看外部访问地址值。
cloudQueryServerAddress
CloudDebug微服务查询服务访问地址(ip:port形式),通过ServiceStage > 应用上线 > 应用管理”,选择相应的集群,点击clouddebug服务进入详情页,选择“访问方式”查看外部访问地址值。
keyFilePath openssh私钥文件路径(支持明文形式或加密形式),公私钥生成方法参考生成公私钥。
logPath 本地代理日志保存目录。
tlsMode true/false,是否开启SSL加密通信;若填false,则无需配置之后的三项。
clientCert 客户端证书文件目录(参考配置SSL证书中生成的客户端证书client.crt)。
clientKey 客户端密钥文件目录(支持明文形式或加密形式)(参考配置SSL证书中的客户端私钥client.key)。
caCert CA证书目录(参考配置SSL证书中的CA证书root.crt)。
完成配置后双击LocalProxy.exe启动本地代理,或者在LocalProxy目录下,“shift+鼠标右键”选择“在此处打开命令窗口”,再在命令行中输入“localProxy.exe”后回车,启动本地代理。
在开启SSL双向认证的前提下,若客户端私钥为加密形式,则在启动LocalProxy时命令行界面将会提示输入密钥口令,然后LocalProxy再启动。
说明
1. 本地代理默认只侦听本地localhost地址的端口,外部不可访问。
2. 双击启动LocalProxy.exe后若程序初始化出错,将出现LocalProxy.exe闪退的情况,且用户无法感知出错的原因,因此建议用户按下述方式启动LocalProxy,按此方法启动localProxy可以避免程序初始化报错闪退时导致无法查看错误信息的问题。
1. 在LocalProxy.exe所在目录下,按住shift+鼠标右键,选择“在此打开命令窗口”;
2. 在弹出的windows命令行窗口中,输入LocalProxy.exe,点击回车,即可启动LocalProxy。
开启集群内 CloudDebug 服务
每个集群有一个CloudDebug服务,调试前,你需要在待调试的微服务实例所在集群中打开CloudDebug服务。
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 128
进入“ServiceStage>应用开发>微服务开发>远程调试”界面,可以看到用户每个集群都对应一个CloudDebug服务启动开关,按以下步骤启动CloudDebug服务。
警告
在下述步骤中,若管理员在启动CloudDebug服务时不开启SSL模式,则视为主动关闭SSL通信,CloudDebug将使用未加密的通道提供服务,相应的,用户需要承担使用不加密通道进行调试所带来的安全风险。
用户需开启SSL双向认证及加密通信的前提条件如下:
1. 已自签发服务端证书和根证书、客户端证书和密钥,方法见配置SSL证书。
2. 用户根据上述EIP来签发服务端证书(pkcs12格式),方法见配置SSL证书。
3. 服务端证书、根证书已预置在集群中某一个节点上,且该节点已绑定EIP。
4. LocalProxy配置文件中已配置客户端证书和密钥及根证书,方法见LocalProxy配置与启动。
步骤1 (用户需要开启SSL模式时,请执行)为CloudDebug配置EIP节点的标签。该节点为前提条件中已经预置了服务端证书、根证书的EIP节点。
须知
出于安全性考虑,CloudDebug服务启动之后会将节点中预置的server.p12证书删除,因此每次启动SSL模式前,都需要重新预置server.p12证书到该EIP节点。
步骤2 (用户需要开启SSL模式时,请执行)为CloudDebug配置EIP节点上服务端证书和根证书所在的目录。
步骤3 配置CloudDebug查询服务和调试服务的端口号。
步骤4 打开CloudDebug开关。
----结束
说明
基于安全性考虑,CloudDebug服务在开启48小时后将自动强制关闭,这时无论是否有用户正在使用,CloudDebug都会强制关闭,所以推荐用户即用即开,用完即关。
开启待调试实例中 JVM 调试端口
需要开启待调试实例中JVM调试端口,以便调试,具体操作方法是:在开发阶段,把微服务部署的Dockerfile里的jar包启动命令放在一个bash脚本中,Dockerfile内则简单执行该bash脚本。bash脚本中增加启动JVM远程调试的参数“-agentlib:jdwp=transport=dt_socket,address=0:8000,server=y,suspend=n”,例如原启动命令为“java -jar demo.jar”,则加入JVM启动参数后命令为“java -agentlib:jdwp=transport=dt_socket,address=0:8000,server=y,suspend=n -jardemo.jar”,再发布镜像即可通过CloudDebug进行远程连接并进行调试。JVM参数中“address=0:8000”的“8000”表示JVM侦听8000端口作为远程调试端口,该端口号可用户自定义,并对应插件界面上的“Instance Port”的值。
经上述方法在bash脚本中增加JVM启动参数后,将Java项目进行编译打包,再经过Dockerfile构建镜像,可以发布启动JVM侦听调试端口的微服务,若需要关闭JVM则需
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 129
要重新构建镜像再发布,通过下述方法,无需重新构建镜像只要简单的设置环境变量,再重新启动微服务应用即可实现开关JVM调试端口:
步骤1 修改jar包启动命令,例如原命令为“java -jar demo.jar”,则可以将JVM开启调试端口的命令放置到一个环境变量中,例如$CMDVAR,而将原启动命令修改为 “java$CMDVAR -jar demo.jar”,即从环境变量读取JVM调试模式的启动参数;
步骤2 再在启动微服务应用时在ServiceStage中的应用部署界面上配置应用的环境变量,设置“CMDVAR”为环境变量名,变量值设置为“-agentlib:jdwp=transport=dt_socket,address=0:8000,server=y,suspend=n”
步骤3 若需要关闭JVM调试服务,则将环境变量删除,再启动微服务应用即可。
----结束
上述方法从容器的环境变量读取JVM的启动参数,配置环境变量为“-agentlib:jdwp=transport=dt_socket,address=0:8000,server=y,suspend=n”则启动JVM 调试模式,不配置相应的环境变量则关闭JVM调试模式,这样就可以实现无需重新修改Dockerfile进行容器构建、镜像发布就能实现JVM调试模式的开启和关闭。
说明
每个实例只支持单个调试连接,即当该实例正在被调试时,其他调试者或调试者客户端无法再对其进行调试。
4.3.2 开始调试
Eclipse 插件配置
步骤1 打开Eclipse进入CloudDebug Java Application界面,如图4-3所示;
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 130
图 4-3 CloudDebug Eclipse 插件 UI 界面
步骤2 选择源码项目,单击Browse选择待调试程序的本地代码项目,用于调试时搜索源代码,如图4-4。
须知
进行远程调试需要本地代码和集群内容器中的Java程序保持一致,否则无法正常进行调试操作。
图 4-4 选择 Java 项目
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 131
步骤3 设置本地代理相关信息,如图4-5。
图 4-5 配置 LocalProxy 本地端口
配置项说明:
配置项 说明
Host 由于Eclipse插件必须通过本地代理方可查询和调试,因此该项不可编辑,默认为localhost。
Debug Port LocalProxy调试端口号,参考LocalProxy配置与启动中配置的调试转发端口号。
Query Port LocalProxy微服务查询端口号,参考LocalProxy配置与启动中配置的微服务查询转发端口号。
步骤4 设置被调试实例的JVM侦听端口号,即开启集群内CloudDebug服务中配置的侦听端口号。
该端口号为启动JVM时参数中server字段绑定的调试端口号,例如启动时参数为“-agentlib:jdwp=transport=dt_socket,address=0:8000,server=y,suspend=n”,那么该Instance Port应该设置为8000;
图 4-6 实例端口(容器内 JVM 侦听的调试端口)
步骤5 (可选)配置是否允许Eclipse插件终止远程Java程序。
若勾选“Allow termination of remote VM”,则允许在调试时从Eclipse插件端终止远程Java程序的运行,如图5 设置是否允许终止远程Java程序所示。
图 4-7 设置是否允许终止远程 Java 程序
在启动调试后,可以单击工具栏中的 按钮终止远程Java程序的运行。
终止远程Java程序会导致该实例停止运行,建议调试中途需要断开调试连接而并不想
停止实例运行,通过单击工具栏中的 按钮退出调试。
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 132
步骤6 单击“Query”从CloudDebug服务获取租户微服务信息,“Service List”中会显示微服务名列表,如图4-8。
图 4-8 微服务查询结果
步骤7 在Service List中选中一个微服务,右侧的Instance List中会显示该微服务下的实例列表。在Instance List选择需要调试的java应用所在的实例。
图 4-9 查询某个微服务的实例信息
步骤8 (可选)单击“Apply”可保存调试配置内容,以便下次调试无需重复配置LocalProxy地址和各个端口。
----结束
开始调试
上述配置完成后,单击“Debug”开始调试。
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 133
图 4-10 完成所有配置并指定调试目标
现在你可以开始像普通的Java远程调试一样调试微服务中的Java应用程序了。
说明
IDE可启动多个远程调试配置,配置过程与上述的一致,即使所调试的Java程序之间有交互,但原理上所进行的每个调试均为相互独立的远程调试过程。
结束调试
单击工具栏中“disconnect”按钮断开调试连接;若暂时无需再继续对微服务进行调试,请通知管理员关闭CloudDebug服务。
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 134
4.4 常见错误处理
4.4.1 Eclipse 插件错误提示及处理
“Error: Authorization Failed”
操作:单击“Query”。
错误原因:认证失败,选择的私钥所对应的公钥并没有由租户管理员配置到“ServiceStage>应用开发>微服务开发>远程调试”界面中,导致CloudDebug未能获取到该私钥所对应的公钥,认证失败。
处理方法:将公钥交由租户管理员配置到“ServiceStage>应用开发>微服务开发>远程调试”界面中,然后再选择正确的私钥文件进行操作。
“Error: Not Found Service and Instance Information”
操作:单击“Query”。
错误原因:租户集群内并未部署任何微服务应用,导致没有查询到微服务信息;
处理方法:请先部署微服务应用,再进行查询操作。
“Error: No Response From CloudDebug Server”1. 错误原因:CloudDebug查询端口(localQueryPort)配置不正确。
处理方法:在“ServiceStage>应用开发>微服务开发>远程调试”界面查看对应集群的CloudDebug服务的查询端口,并配置到本地代理配置文件中的localQueryPort参数中。
2. 错误原因:CloudDebug服务地址(cloudQueryServerAddress)配置不正确。
处理方法:从“ServiceStage > 应用上线 > 应用管理”中选择对应集群查看CloudDebug应用的访问地址,并将其中的查询访问地址配置到本地代理配置文件中的cloudQueryServerAddress参数中。
3. 错误原因:在SSL模式下,CloudDebug使用的证书与LocalProxy使用的客户端证书不配套。
处理方法:建议参考配置SSL证书生成配套的服务端证书与客户端证书。
“Error: Failed to connect to remote VM”
操作:单击“Debug”。
该类错误主要原因为CloudDebug无法为本地Eclipse插件创建远程调试的连接,具体情况如下所示:
1. 错误原因:调试目标实例中的JVM未启动。
处理方法:在调试前先启动调试目标JVM,侦听容器内本地调试端口。
2. 错误原因:当前该调试目标正在被其他调试者调试。
处理方法:等待该调试目标空闲时再进行调试。
3. 错误原因:DebugPort配置不正确。
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 135
处理方法:配置正确的DebugPort,可从ServiceStage查看。
4. 错误原因:查询微服务及微服务实例后,未选择具体的实例,就点击了Debug开始调试。
处理方法:微服务查询成功后,需在查询结果显示窗口右侧的实例列表中,选中需要调试的实例,方可进行调试。
4.4.2 CloudDebug 内部错误日志说明及处理方法CloudDebug微服务部署在租户集群中某个节点上,CloudDebug日志记录在CloudDebug容器内“/home/paas/clouddebug/log”目录下,租户管理员可以在ServiceStage中查看CloudDebug具体运行在哪一个节点上,然后通过ssh或webssh登录该节点,进入容器查看日志。租户管理员根据调试者使用情况反馈,若反应Eclipse无法进行远程调试,在排除调试配置错误的因素时,可以查看CloudDebug日志进行错误排查。
“Error[Init]”类型
场景:CloudDebug启动时的初始化过程。
1. 错误日志:Can't Listen on Debug Port。错误原因:CloudDebug容器内调试端口被占用,或解析容器内IP地址错误。
处理方法:CloudDebug在容器内默认侦听的查询端口为8000,调试端口为9000,一般情况下不会发生该错误,如查看到该错误提示,请联系运维人员。
2. 错误日志:Can't Listen on Query Port。错误原因:CloudDebug容器内查询端口被占用。
处理方法:CloudDebug在容器内默认侦听的查询端口为8000,调试端口为9000,一般情况下不会发生该错误,如查看到该错误提示,请联系运维人员。
3. 错误日志:Init TLS Config For TCP Server Error。错误原因:获取SSL证书失败或者证书错误。
处理防范:参照3.1.3节所属来生成SSL证书。
“Error[Query]”类型
场景:Eclipse插件端发起查询微服务和实例的请求。
1. 错误日志:Bad Request nil Header。错误原因:违法请求,http头中未包含必要的认证信息。
处理方法:CloudDebug只接受从正规渠道获取的Eclipse插件端发起的微服务和实例信息的查询请求。
2. 错误日志:Invalid Signature。
错误原因:http头中未包含数字签名字段。
3. 错误日志:Can't Fetch Instance Info。
错误原因:无法获取相应微服务的实例信息。
处理方法:有可能是由于微服务无实例,请先部署微服务实例后在进行查询和调试。
4. 错误日志:Can't Parse Instance Info。
错误原因:无法解析相应微服务的实例Json数据。
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 136
处理方法:检查该微服务是否已部署实例,该问题主要是由Json数据中不包含任何一条实例信息导致,因此若已获取Json数据,但是Json数据中没有Instance数据,则会在日志中记录该错误,不影响Eclipse插件端。
“Error[Debug]”类型
该类错误出现于Eclipse插件发起调试请求,即调试者在Eclipse插件上单击“Debug”后有可能发生的错误日志。
1. 错误日志:Resolve IP Failed。
错误原因:Eclipse插件提交的调试目标IP不合法,解析失败。
处理方法:联系运维人员。
2. 错误日志:Dial Failed。
错误原因:该调试目标不接受远程调试,可能原因有:该调试目标正在被其他调试者调试,或是目标实例容器内尚未启动JVM,或者调试者配置的Instance Port与实际实例中JVM侦听的容器内端口不一致,该错误通常还会引起Can’tConnect Remote JVM的错误日志。
处理方法:等待其他调试者释放该调试目标;启动微服务实例时,需配上环境变量“$CMDVAR”,如开启待调试实例中JVM调试端口中所述,开启JVM调试端口,并在Eclipse插件上侦听JVM侦听的端口号(Instance Port)。
3. 错误日志:Can't Connect to Remote JVM。
错误原因:调试目标实例中尚未启动JVM。
处理方法:调试者开始调试前,需事先启动调试目标实例中的JVM,具体操作方式见开启待调试实例中JVM调试端口开启调试端口。
4.5 缩略语文章中用到的缩写解释
缩略语 英文全名 中文解释
k8s kubernetes PaaS基于的容器集群管理框架
JVM Java VirtualMachine
Java虚拟机
VM Virtual Machine 本文中指的是JVM
EIP Elastic IP 弹性IP
微服务云应用平台开发指南 4 远程调试
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 137
5 Eclipse ServiceStage 插件使用指南
5.1 快速开始
简介
Eclipse ServiceStage插件使应用开发者能轻易实现与华为云ServiceStage应用管理与运维平台的集成,具有以下特性。
● 应用配置
● 应用部署
● 应用状态查询
● 应用模型和契约管理
安装
下载servicestage-eclipse,可以获取预置的应用管理与运维平台插件jar包。
当你获得ServiceStage插件jar包后,只能手动安装插件,请将它放在${ECLIPSE_INSTALLATION}/dropins路径下。
例如,如果您的Eclipse安装在/eclipse路径下,请将插件包放在/eclipse/dropins路径下。然后重启Eclipse以使更新生效。
配置
配置Huawei Preferences(“Window > Preferences> Huawei”),如图5-1所示。
1. 选择区域。
2. 输入用户名和密码。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 138
图 5-1 配置 Huawei Preferences
在此页,您可以看到Reset Token键。如果您在后续安装中遇到问题,您可使用此功能。
5.2 应用管理
应用配置
您可以创建自己的应用项目。在您的工作区,每一个项目都有各自的一套ServiceStage设置。这些设置存于项目根目录下的servicestage.xml文件中。
右键单击“项目”,选择“ServiceStage> Configure”,如图5-2、图5-3所示。
1. 填写应用信息。
2. 填写用于存储待上传部署文件的SWR仓库信息。
3. 选择集群ID、ELB ID、VPC ID等平台信息。
4. 选择应用所需的服务信息。
5. 单击“Finish”创建或更新项目的servicestage.xml文件。
说明
本插件目前仅支持Tomcat和Node.js应用。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 139
图 5-2 应用信息
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 140
图 5-3 服务信息
应用部署
Preferences和应用信息都配置完成后,您可以开始部署war文件,如图5-4所示。
1. 如有必要,构建项目,生成war文件。
2. 在项目窗口,右键单击war文件或Node.js项目,选择“ServiceStage >Deploy”。
3. 开启部署进程并显示进程信息。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 141
图 5-4 部署
部署过程如下:
1. 上传选择的war文件或Node.js项目到SWR仓库。
2. 部署或更新应用到ServiceStage。
3. 监控部署过程至部署完成。部署完成时,显示应用URL地址。
如果在任一阶段出现部署问题,会有对话框信息提示。或者,您也可以通过错误日志查看详情。
应用状态查询
您可随时查看应用状态。右键单击“项目”,选择“ServiceStage> Status”。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 142
5.3 应用模型和契约管理ServiceStage View可用于管理应用模型和契约,您可以通过选择“Tools >ServiceStage > Manage Application Group”打开ServiceStage View。
ServiceStage View支持离线和在线两种模式。
● 离线模式
是指ServiceStage Eclipse插件无需连接到华为ServiceStage。该模式适用于无网络连接的环境。
● 在线模式
是指Eclipse插件连接到华为ServiceStage
在离线模式下,您只能修改本地应用模型和契约。通过点击右上角的“Sync”按钮,您可以同步本地应用模型和契约变更到华为ServiceStage上。
创建应用模型
1. 由于应用模型需要使用Git仓库储存契约,您首先需要在Eclipse工作区指定Git仓库。
2. 在华为ServiceStage上创建一个应用组。点击“Sync”按钮,该应用组即会出现在ServiceStage View上。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 143
3. 右击该用户组,点击弹出的“New Application Model”选项以创建一个应用模型。
4. 填写应用模型信息,然后点击“Next”。
5. (可选)选择需要添加到该应用模型的契约。您可在应用模型创建完毕后再添加契约。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 144
6. 如果出现系统提示,询问您是否要登录您的应用模型Git仓库及授权华为ServiceStage登录您的仓库,请进行授权。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 145
7. 通过上述步骤,您在ServiceStage View上成功创建应用模型。
说明
● 当您在Local Models下创建应用模型时,应用模型只在本地创建,而不会在华为ServiceStage创建。
● 通过拖拽Local Models组下的应用模型到ServiceStage组下,该模型即能在华为ServiceStage创建。
创建应用契约
在应用模型下创建应用契约。同一个应用模型下可创建多个应用契约。
1. 右击应用模型,选择“New Contract”创建应用契约。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 146
2. 填写应用契约信息。
点击右侧“…”按钮打开文件浏览器,选择契约文件。
如果是一个新契约,请输入契约文件名称。
3. 点击“Finish”完成契约创建。
您可通过文本编辑器打开契约文件。
升级应用模型和契约
当应用模型处于“DRAFT”状态时,您可在ServiceStage View更新模型及契约信息。
当应用模型处于“PENDING_PUBLISH”、“PUBLISH”、“NOT_DEPLOY”等状态时,模型及契约信息无法更新。
发布应用模型
右击应用模型,然后选择“Publish”进行模型发布。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 147
模型的状态变为“PENDING_PUBLISH”。在华为ServiceStage界面,管理员将收到一个发布审核的请求。管理员后续需要审视和处理该请求。
删除应用模型
右击应用模型,然后选择“Delete”删除模型。模型的状态变为“PENDING_DELETE”。
当应用模型处于“DRAFT”状态时,当您点击“Sync”按钮,该模型会被立即删除。当应用模型处于非“DRAFT”状态时,管理员将收到一个删除审核的请求。管理员后续需要审视和处理该请求。
该模型删除后,其下的契约也会相应删除。但是,对应的契约文件不会从文件系统中删除。
删除应用契约
右击应用契约,然后选择“Delete”删除契约。
您可以选择删除“Contract Only”或“Contract and File”。当选择“Contract andFile”时,契约文件会同时从文件系统中删除。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 148
通过契约生成代码
您可通过契约生成项目桩代码。
1. 右击一个应用模型,然后选择“Generate Code”生成项目桩代码。
2. 选择项目类型,输入项目名称。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 149
3. 点击“Finish”生成系统代码,然后将生成的系统代码导入到Package Explorer。
通过代码生成契约
您可通过项目代码生成契约。
1. 右击项目,选择“ServiceStage > Generate Contract”。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 150
2. 选择契约文件所在的文件夹,点击“Finish”生成契约文件。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 151
验证契约
在进行验证契约前,您需要确保Maven仓库下存在contract-validator Maven包。
1. 右击项目,选择“ServiceStage > Add Application Group”。
2. 选择应用组和模型,然后选择“Enable Contract Validation”, 后点击“Finish”。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 152
3. 检查contract-validator Maven插件是否已经安装。
在下面的例子中,该插件安装在项目的pom.xml文档下。<plugin> <groupId>com.huawei.servicestage</groupId> <artifactId>contract-validator</artifactId> <configuration> <contractSource> <param>{PATH-TO-CONTRACT}</param> </contractSource> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>validate</goal> </goals> </execution> </executions></plugin>
4. contract-validator Maven插件会伴随着Maven构建同步运行。
执行以下命令启动契约验证(Maven构建的一部分)mvn clean package
比对契约和合并代码
在比对契约和合并代码前,您需要添加应用组和模型到指定应用。
可参考“验证契约”环节的步骤添加应用模型到指定应用。
1. 右击项目,选择“ServiceStage > Merge with Contract”进入“Merge Dialog”页面。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 153
2. Merge Dialog”的首页是关于端点的代码合并。
当您需要保存一个新方法到一个新文件下,您可点击“Class Selector”按钮,然后选择方法所在的目标文件。
当您不指定任何文件,新方法将保存到默认的文件下。如果您不需要合并特定端点的代码,可以取消勾选该端点。
另外,您可点击“…”按钮查看代码合并前后的方法。您可直接编辑合并后的方法,然后进行保存。
3. Merge Dialog”的第二个页面是关于契约代码的合并。
您可参考端点的代码合并步骤进行操作。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 154
4. 点击“Merge”完成合并。该项目下的代码将会连同合并的代码一起更新。
微服务云应用平台开发指南 5 Eclipse ServiceStage 插件使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 155
6 应用绑定的中间件配置信息说明
在创建应用过程中(如Web类应用、移动应用),可以绑定中间件(如DCS、RDS)。应用绑定的中间件配置信息可以通过以下环境变量获取。
分布式会话环境变量
分布式会话:基于DCS实现的稳定可靠的会话存储,支持主流Web容器的自动注入,如tomcat context,node.js express-session,php的session handler等。
分布式会话相关环境变量说明如表6-1所示。
表 6-1 DCS 分布式会话相关环境变量
环境变量 说明
DISTRIBUTED_SESSION_CLUSTER 实例是否是集群模式,取值true/false
DISTRIBUTED_SESSION_TYPE 分布式会话实例的存储类型,当前只支持Redis
DISTRIBUTED_SESSION_VERSION 分布式会话实例的版本号
DISTRIBUTED_SESSION_NAME 分布式会话实例的名称
DISTRIBUTED_SESSION_HOST 分布式会话实例的连接IP地址
DISTRIBUTED_SESSION_PORT 分布式会话实例的连接IP端口
DISTRIBUTED_SESSION_PASSWORD 分布式会话实例的连接密码
分布式缓存环境变量
分布式缓存服务(Distributed Cache Service,简称DCS)是华为云提供的一款内存数据库服务,兼容了Redis和Memcached两种内存数据库引擎,为您提供即开即用、安全可靠、弹性扩容、便捷管理的在线分布式缓存能力,满足用户高并发及数据快速访问的业务诉求。
分布式缓存相关环境变量如表6-2所示。
微服务云应用平台开发指南 6 应用绑定的中间件配置信息说明
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 156
表 6-2 DCS 分布式缓存相关环境变量
环境变量 说明
DISTRIBUTED_CACHE_CLUSTER 实例是否是集群模式,取值true/false
DISTRIBUTED_CACHE_TYPE 分布式缓存实例的存储类型,当前只支持Redis
DISTRIBUTED_CACHE_VERSION 分布式缓存实例的版本号
DISTRIBUTED_CACHE_NAME 分布式缓存实例的名称
DISTRIBUTED_CACHE_HOST 分布式缓存实例的连接IP地址
DISTRIBUTED_CACHE_PORT 分布式缓存实例的连接IP端口
DISTRIBUTED_CACHE_PASSWORD 分布式缓存实例的连接密码
关系型数据库环境变量
华为云关系型数据库(Relational Database Service,简称RDS)是一种基于云计算平台的即开即用、稳定可靠、弹性伸缩、便捷管理的在线关系型数据库服务。
关系型数据库相关环境变量如表6-3所示。
表 6-3 RDS 关系型数据库相关环境变量
环境变量 说明
RELATIONAL_DATABASE_NAME 关系型数据库实例名称
RELATIONAL_DATABASE_CONNECTION_TYPE
关系型数据库实例的连接类型,取值为JNDI/SPRING_CLOUD_CONNECTOR
RELATIONAL_DATABASE_JNDI_NAME 关系型数据库实例的JNDI名称,如果连接类型为JNDI
RELATIONAL_DATABASE_DB_NAME 关系型数据库实例的数据库名
RELATIONAL_DATABASE_DB_USER 关系型数据库实例的数据库用户
RELATIONAL_DATABASE_DB_TYPE 关系型数据库实例的数据库类型,当前只支持MySQL
RELATIONAL_DATABASE_VERSION 关系型数据库实例的数据库版本
RELATIONAL_DATABASE_HOST 关系型数据库实例的数据库IP地址
RELATIONAL_DATABASE_PORT 关系型数据库实例的数据库端口
RELATIONAL_DATABASE_PASSWORD 关系型数据库实例的数据库密码
微服务云应用平台开发指南 6 应用绑定的中间件配置信息说明
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 157
7 DTM Client SDK 开发指南
7.1 概述
产品介绍
分布式事务管理中间件(Distributed Transaction Management,DTM)是一款用于解决分布式环境下事务一致性问题的产品。在复杂环境下,事务可能会出现的各种异常,DTM能够将开发者从处理这种异常中解放出来,聚焦于业务逻辑本身。
DTM支持TCC(Try-Confirm-Cancel)事务模型,支持以注解的方式定义事务信息,实现事务高效便捷的接入。此外,DTM具有处理高并发事务请求的能力,支持自动部署、弹性伸缩等全生命周期运维管控能力。
当前版本提供基于java的DTM Client SDK,适配华为云ServiceStage的ServiceComb微服务引擎。引入DTM Client SDK同时必须引入CSE Java SDK(请参考开发环境搭建),二者绑定使用,可以将微服务注册到微服务引擎控制台,在分布式事务引擎控制台查看事务的详细信息。
DTM 实现原理
一个业务接入DTM后,从发起到结束一次事务,大致经历如图7-1所示步骤。
微服务云应用平台开发指南 7 DTM Client SDK 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 158
图 7-1 事务处理步骤
步骤说明如下:
步骤1:进入到发起全局事务的方法内时,会先向DTM集群申请注册一个全局事务ID(Global Transaction ID),只有申请成功才可继续后续流程。
步骤2.1:事务发起者将申请到的全局事务ID透传到所调用的事务参与者中。
步骤2.2:事务参与者利用得到的全局事务ID,向DTM集群注册申请一个分支事务ID(Branch Transaction ID),只有申请成功才可继续此事务参与者的后续流程。
步骤2.3:事务参与者完成自身业务逻辑(即完成TCC中的Try阶段)。
步骤2.4:事务参与者将自身业务逻辑结果上传到DTM集群,并示意分支事务结束。
步骤3.1~3.4:与2.1~2.4类似,完成剩余事务参与者的业务逻辑。
步骤4:事务发起者发起TCC二阶段。
步骤5.1:DTM集群根据全局事务ID,找到事务参与者,发起TCC二阶段。
步骤5.2:与5.1类似,完成剩余事务参与者的TCC二阶段。
步骤6:DTM集群通告事务发起者全局事务结束。
使用限制及要求
在TCC(Try-Confirm-Cancel)事务模型下,提供了Try、Confirm以及Cancel等3种逻辑方法。开发者需要对应用程序进行改造,才能接入DTM。接入DTM的应用程序TCC方法应该遵循以下规则。
● 接入DTM的应用程序TCC方法应保证幂等性
幂等性:在此指某个应用程序的执行方法被多次调用后,其结果应是保持一致的。
在复杂的分布式环境中,各种异常如网络抖动、部署服务器故障等均有可能发生,对于某个方法可能会由于出现上述故障而被多次请求,所以需要保证方法的幂等性。
微服务云应用平台开发指南 7 DTM Client SDK 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 159
● 接入DTM的应用程序TCC方法应保证原子性
原子性:在此指某个应用程序的执行方法被多次调用后,其结果应该是要么全部成功,要么全部失败的。
由于DTM 分布式事务中间件通过对方法执行结果的异常捕获来确认事务提交状态,如果存在一半成功一半失败的场景,将影响事务执行的 终结果。所以要保证方法的原子性。
7.2 接口说明下载DTM Client SDK包(通过maven仓库获取,具体请参见开发环境搭建),其中DTM-Server为独立运行的事务协调中心,DTM-Client内嵌事务代理。业务应用通过DTM-Client与DTM-Server进行交互,通过切面拦截的方式,在业务执行前和执行后分别将执行事件结果告知DTM-Server。
DTM-Client对外提供api接口,包含全局发起(@DTMTxBegin)、分支参与(@DTMTccBranch)以及事务上下文操作(DTMContext)等3类接口。
全局发起接口(@DTMTxBegin)● 接口描述
全局发起接口(@DTMTxBegin)的定义及说明如下。public @interface DTMTxBegin { int timeout() default 180000; String appName(); boolean enableGlobalSyncType() default false; boolean callbackAsync() default false;}
表 7-1 DTMTxBegin 接口方法说明
方法名 方法说明
timeout() 设置全局事务的超时时间,当执行时间超过设置值后,将停止全局事务,发起回滚操作。
单位为ms,缺省值为180000ms。
appName() 设置全局事务的唯一标识。
enableGlobalSyncType() 与 callbackAsync 配合使用,说明如下:
若enableGlobalSyncType设置为true,按照 @DTMTxBegin的callbackAsync设置为准。
若enableGlobalSyncType设置为false,按照@DTMTccBranch的callbackAsync设置为准。
缺省值为 false。
微服务云应用平台开发指南 7 DTM Client SDK 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 160
方法名 方法说明
callbackAsync() 仅当enableGlobalSyncType设置为true时生效,设置二阶段推进方式。
true:表示全部分支二阶段异步执行。
false:表示全部分支二阶段同步执行。
缺省值为 false。
● 使用方式
在全局事务发起的方法头中加入@DTMTxBegin注解,并声明全局标识即可,示例如下所示。@DTMTxBegin(appName = "booking") @Path(value = "/book") public void book() throws InterruptedException { System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + "-" + DTMContext.getDTMContext().getGlobalTxId() + "-" + "start booking..."); planeService.bookTicket(); TimeUnit.SECONDS.sleep(10); hotelService.bookRoom(); System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + "-" + DTMContext.getDTMContext().getGlobalTxId() + "-" + "booking succeeded!"); }
分支参与接口(@DTMTccBranch)● 接口描述
分支参与接口(@DTMTccBranch)的定义及说明如下。public @interface DTMTccBranch { String confirmMethod(); String cancelMethod(); String identifier(); boolean callbackAsync() default false;}
表 7-2 DTMTccBranch 接口方法说明
方法名 方法说明
confirmMethod() 二阶段提交将会执行。
cancelMethod() 二阶段回滚将会执行。
identifier() 分支事务唯一标识。
微服务云应用平台开发指南 7 DTM Client SDK 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 161
方法名 方法说明
callbackAsync() 仅当enableGlobalSyncType设置为false时生效,设置二阶段推进方式。
true:表示当前分支事务二阶段异步执行,不受其余分支事务二阶段执行结果影响。
false:表示当前分支二阶段同步执行。
缺省值为false。
● 使用方式
在分支事务执行的方法头中加入@DTMTccBranch注解,并声明分支标识以及相应的二阶段提交和回滚方法即可,示例如下所示。@RestSchema(schemaId = "plane")@RequestMapping(value = "plane")public class PlaneService { @RequestMapping(value = "/bookTicket", method = RequestMethod.GET) @DTMTccBranch(identifier = "plane", confirmMethod = "confirm", cancelMethod = "cancel") public void bookTicket() throws InterruptedException { TimeUnit.SECONDS.sleep(5); System.out.println("book plane ticket"); } public void confirm() { System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + "-" + DTMContext.getDTMContext().getGlobalTxId() + "-" + DTMContext.getDTMContext().getBranchTxId() + "confirm plane ticket"); } public void cancel() { System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + "-" + DTMContext.getDTMContext().getGlobalTxId() + "-" + DTMContext.getDTMContext().getBranchTxId() + "cancel plane ticket"); }}
事务上下文操作接口(DTMContext)
事务上下文操作接口(DTMContext)说明如下。
● 自定义事务信息(一阶段执行)
自定义strData长度不允许超过100字节,且不能带有逗号。DTMContext context = DTMContext.getDTMContext();context.setCustomizedData(strData);
● 读取自定义事务信息(二阶段执行)DTMContext context = DTMContext.getDTMContext();String result = context.getCustomizedData();
● 查询全局事务IDDTMContext context = DTMContext.getDTMContext();long result = context.getGlobalTxId();
● 查询分支事务ID
微服务云应用平台开发指南 7 DTM Client SDK 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 162
DTMContext context = DTMContext.getDTMContext();long result = context.getBranchTxId();
● 传递事务上下文
事务执行过程中,需要异步执行某些分支时候使用。DTMContext context = DTMContext.getDTMContext();context.setGlobalTxId(globalTxId);context.setBranchTxId (branchTxId);
● 事务挂起
事务执行过程中,某些分支不希望加入该全局分支中。DTMContext.suspendTransaction()
● 事务恢复
当执行事务挂起之后,回到原来流程时需要执行事务恢复动作。DTMContext.resumeTransaction()
● 当前是否有可用DTM Serverboolean result = DTMContext.hasAvailableServer();
● 查询所有可用DTM ServerString result = DTMContext.showAvailableServer ();
7.3 开发环境搭建
前提条件
已经安装Maven。
操作步骤
步骤1 设置好maven环境。
步骤2 在项目pom.xml文件中添加如下依赖。<dependencies> <dependency> <groupId>com.huawei.paas.dtm</groupId> <artifactId>dtm-client-servicecomb</artifactId> <version>1.0.0</version> </dependency>
</dependencies>
步骤3 配置microservice.yaml
需要配置服务中心、配置中心地址、dtm相关的handler,具体配置如下。
● 服务消费端(consumer)配置APPLICATION_ID: ${应用名}service_description: name: ${服务名} version: ${服务版本号}cse: service: registry: address: https://${服务中心地址} instance: watch: false config: client:
微服务云应用平台开发指南 7 DTM Client SDK 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 163
serverUri: https://${配置中心地址} refreshMode: 1 refresh_interval: 5000 handler: chain: Consumer: default: dtm-consumer-handler, loadbalance rest: address: 0.0.0.0:9999 dtm: appName: ${配置的dtmappname} rpc: sslEnabled: true proxy: endpoint: ${dtm服务监听地址}
● 服务提供端(provider)配置APPLICATION_ID: ${应用名}service_description: name: ${服务名} version: ${服务版本号}cse: service: registry: address: https://${服务中心地址} instance: watch: false config: client: serverUri: https://${配置中心地址} refreshMode: 1 refresh_interval: 5000 handler: chain: Consumer: default: dtm-provider-handler rest: address: 0.0.0.0:9999 dtm: appName: ${配置的dtmappname} rpc: sslEnabled: true proxy: endpoint: ${dtm服务监听地址}
----结束
7.4 Demo 样例参考
Demo 说明
示例Demo以旅游机票和酒店预订为例,booking是旅游预订业务的总入口,plane是机票预订服务,hotel是酒店预订服务。booking服务作为一个全局事务,包括plane跟hotel两个分支事务,如图7-2所示。
微服务云应用平台开发指南 7 DTM Client SDK 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 164
图 7-2 Demo 说明
全局发起者(booking)
全局发起者(booking服务)示例代码如下,@DTMTxBegin 定义了全局事务的边界,表示某个全局事务的开始。其中可设置appName(便于用户标识某一类事务)、timeout(超时参数)等。
此处通过分支执行是否抛出异常,来判断 终进行全局提交或者全局回滚。
package com.huawei.paas.dtm.sample.booking;
import com.huawei.middleware.dtm.client.annotations.DTMTxBegin;import com.huawei.middleware.dtm.client.context.DTMContext;import com.huawei.paas.dtm.sample.booking.api.HotelService;import com.huawei.paas.dtm.sample.booking.api.PlaneService;import org.apache.servicecomb.provider.pojo.RpcReference;import org.apache.servicecomb.provider.rest.common.RestSchema;
import javax.ws.rs.Path;import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.TimeUnit;
@RestSchema(schemaId = "booking")@Path(value = "booking")public class BookingConsumer {
@RpcReference(microserviceName = "plane", schemaId = "plane") private PlaneService planeService;
微服务云应用平台开发指南 7 DTM Client SDK 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 165
@RpcReference(microserviceName = "hotel", schemaId = "hotel") private HotelService hotelService;
@DTMTxBegin(appName = "booking") @Path(value = "/book") public void book() throws InterruptedException { System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + "-" + DTMContext.getDTMContext().getGlobalTxId() + "-" + "start booking..."); planeService.bookTicket(); TimeUnit.SECONDS.sleep(10); hotelService.bookRoom(); System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + "-" + DTMContext.getDTMContext().getGlobalTxId() + "-" + "booking succeeded!"); }
}
分支参与者(plane)
分支参与者(plane服务)示例代码如下,@DTMTccBranch 定义了分支事务的边界,其中需要配置用于分支标识的identifier及二阶段推进所要执行的confirm和cancel方法。
每个分支都有自己唯一的分支id及全局id(同个全局事务的每个分支的全局id相同),可通过调用DTMContext的接口进行获取。
package com.huawei.paas.dtm.sample.plane;
import com.huawei.middleware.dtm.client.context.DTMContext;import com.huawei.middleware.dtm.client.tcc.annotations.DTMTccBranch;import org.apache.servicecomb.provider.rest.common.RestSchema;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;
import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.TimeUnit;
@RestSchema(schemaId = "plane")@RequestMapping(value = "plane")public class PlaneService {
@RequestMapping(value = "/bookTicket", method = RequestMethod.GET) @DTMTccBranch(identifier = "plane", confirmMethod = "confirm", cancelMethod = "cancel") public void bookTicket() throws InterruptedException { TimeUnit.SECONDS.sleep(5); System.out.println("book plane ticket"); }
}
● 二阶段推进(plane提交)示例代码public void confirm() { System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + "-" + DTMContext.getDTMContext().getGlobalTxId() + "-" + DTMContext.getDTMContext().getBranchTxId() + "confirm hotel");
微服务云应用平台开发指南 7 DTM Client SDK 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 166
}
● 二阶段推进(plane回滚)示例代码public void cancel() { System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + "-" + DTMContext.getDTMContext().getGlobalTxId() + "-" + DTMContext.getDTMContext().getBranchTxId() + "cancel hotel");
}
分支参与者(hotel)分支参与者(hotel服务)示例代码如下,@DTMTccBranch 定义了分支事务的边界,其中需要配置用于分支标识的identifier及二阶段推进所要执行的confirm和cancel方法。
每个分支都有自己唯一的分支id及全局id(同个全局事务的每个分支的全局id相同),可通过调用DTMContext的接口进行获取。
package com.huawei.paas.dtm.sample.hotel;
import com.huawei.middleware.dtm.client.context.DTMContext;import com.huawei.middleware.dtm.client.tcc.annotations.DTMTccBranch;import org.apache.servicecomb.provider.rest.common.RestSchema;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;
import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.TimeUnit;
@RestSchema(schemaId = "hotel")@RequestMapping(value = "/hotel")public class HotelService {
@RequestMapping(value = "/bookRoom", method = RequestMethod.GET) @DTMTccBranch(identifier = "hotel", confirmMethod = "confirm", cancelMethod = "cancel") public void bookRoom() throws InterruptedException { TimeUnit.SECONDS.sleep(5); System.out.println("book hotel room"); }
}
● 二阶段推进(hotel提交)示例代码public void confirm() { System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + "-" + DTMContext.getDTMContext().getGlobalTxId() + "-" + DTMContext.getDTMContext().getBranchTxId() + "confirm hotel");
}
● 二阶段推进(hotel回滚)示例代码public void cancel() { System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()) + "-" + DTMContext.getDTMContext().getGlobalTxId() + "-" + DTMContext.getDTMContext().getBranchTxId()
微服务云应用平台开发指南 7 DTM Client SDK 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 167
+ "cancel hotel");}
微服务云应用平台开发指南 7 DTM Client SDK 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 168
8 servicestage-maven-plugin 使用指南
8.1 工具介绍
功能说明● 支持将软件包上传到华为云软件仓库。
● 使用软件包关联应用(tomcat或者java的运行环境)进行升级。
使用场景● 在ServiceStage创建Java应用或Tomcat应用后,可以使用maven插件升级应用,
将本地项目编译后的jar包(或者War包)覆盖应用原有程序包完成应用升级。
● 目前maven插件支持CCE和CCI的部署系统。
前提条件
创建一个tomcat或者java类型的的应用,详情请参考创建Web应用。
工具配置1. 下载ServiceStage-Maven-Plugin压缩包,将其拷贝到自己的本地maven仓库
中,然后解压即可。
maven仓库解压后,目录结构如下。├──com.huawei.servicestage ├──servicestage-client ├──servicestage-maven-plugin
2. 在项目的根目录下创建一个servicestage_maven.properties文件,在文件中配置如下相关参数。servicestage.iam.domain = xxxservicestage.iam.username = xxxservicestage.iam.password = xxxservicestage.iam.region = xxxservicestage.app.name = xxxservicestage.app.version = x.xservicestage.app.swr.namespace = xxxservicestage.app.swr.version = xxxservicestage.app.swr.repo = xxxservicestage.app.binaryname = xxx.jarservicestage.maven.plugin.skip = false
微服务云应用平台开发指南 8 servicestage-maven-plugin 使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 169
参数说明如下。
参数名称 是否必填
参数说明 备注
servicestage.iam.domain
是 IAM的登录租户 登录华为云的账户名。
注意:不能是邮箱,必须是账户名
servicestage.iam.username
是 IAM的登录用户名 登录华为云的用户名,当没有用户名时,则用户名即为账户名。
注意:不能是邮箱,也不能是手机号。
servicestage.iam.password
是 IAM的登录密码 登录华为云的密码。
servicestage.iam.region
是 当前所在的区域 登录华为云后,地址栏可以看到region=xxx,例如:北京一就是cn-north-1
servicestage.app.name
是 ServiceStage的应用名称
登录ServiceStage控制台,进入“应用管理->应用列表”可以查看应用的名称。
servicestage.app.binaryname
是 要发布的二进制文件名称(带后缀)
一般在项目target目录下,例如:test.jar,test.war
servicestage.app.version
否 应用的版本 版本格式:x.x,默认值是1.0。
servicestage.app.swr.namespace
否 软件包归档的组织名称
登录ServiceStage控制台,进入“软件中心>软件仓库”,可以查看组织名称。
默认会有一个组织。
servicestage.app.swr.repo
否 软件包归档的仓库名称
登录ServiceStage控制台,进入“软件中心>软件仓库”,可以查看仓库名称,系统默认值是截取于应用名称。
servicestage.app.swr.version
否 软件包归档的仓库的版本
登录ServiceStage控制台,进入“软件中心>软件仓库”,可以查看仓库版本,默认值是1.0。
微服务云应用平台开发指南 8 servicestage-maven-plugin 使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 170
参数名称 是否必填
参数说明 备注
servicestage.maven.plugin.skip
否 编译过程中是否跳过servicestage的插件的使用
默认值是false。
3. 在pom文件中加上插件依赖,示例如下。<build> <plugins> <plugin> <groupId>com.huawei.servicestage</groupId> <artifactId>servicestage-maven-plugin</artifactId> <version>1.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>deploy</goal> </goals> </execution> </executions> </plugin> </plugins></build>
8.2 使用指南
使用说明
maven插件的使用非常简单,创建应用后,如果要想发布项目模块的jar包或者war包,只需要在该模块执行2和3即可。
关于配置文件的位置修改和存放处说明:要发布某个模块,就修改该模块的配置。
● 场景1:一个项目只有一个模块。├──Myproject ├──src... ├──pom.xml 在pom.xml加上servicestage的插件配置 └──servicestage_maven.properties 配置servicestage插件所需参数
● 场景2:一个项目有多个模块,想发布其中某个模块,例如module-B,想升级多个就配置多个,以此类推。├──Myproject│ ├──module-A│ │ ├──src...│ │ └──pom.xml│ ││ ├──module-B│ │ ├──src...│ │ ├──pom.xml 在pom.xml加上servicestage的插件配置│ │ └──servicestage_maven.properties 配置servicestage插件所需参数│ ││ └──module-C│ ├──src...│ └──pom.xml└──pom.xml
微服务云应用平台开发指南 8 servicestage-maven-plugin 使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 171
maven 的编译命令使用说明
servicestage-maven-plugin是支持mvn编译命令通过环境变量传参的,使用过程中会优先使用mvn编译命令的环境变量,其次再使用servicestage_maven.properties的变量值,执行命令示例如下。
mvn clean package -Dservicestage.iam.domain=xxx -Dservicestage.iam.username=xxx -Dservicestage.maven.plugin.skip=false
使用示例
步骤1 创建web应用。
运行环境Tomcat8或者Java8。
应用来源根据需要选择,可以随便选一个,后面升级的时候会覆盖该应用已有的来源。
步骤2 应用创建以后,应用访问结果如下。
步骤3 下载maven插件的依赖的压缩包,并解压到自己本地maven仓库中去。
微服务云应用平台开发指南 8 servicestage-maven-plugin 使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 172
步骤4 配置本地项目的参数,请参考工具介绍中的工具配置说明。
步骤5 编译打包。
mvn package的时候,工具会将该项目编译的软件包升级指定的应用。
步骤6 查看升级应用的结果,等升级完成之后访问该应用,对比升级后和升级前的结果。
应用升级中,如下图所示。
微服务云应用平台开发指南 8 servicestage-maven-plugin 使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 173
应用完成升级后,访问应用,如下图所示。
----结束
微服务云应用平台开发指南 8 servicestage-maven-plugin 使用指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 174
9 移动应用 QuickAPP 开发指南
9.1 概述MBaaS是ServiceStage提供的一项移动后端服务,用户可以使用ServiceStage创建此类服务。ServiceStage MBaaS提供各种移动后端功能,如数据存储、用户管理、访问控制、会话管理等,同时还配备了基于浏览器的仪表板,帮助开发人员轻松配置和管理移动后端。
ServiceStage MBaaS的使用过程如图1 MBaaS的使用所示。
1. 在ServiceStage上创建MBaaS应用
2. 开发移动应用程序
3. 配置移动后端
4. 发布移动应用程序
5. 在移动设备上使用应用程序
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 175
图 9-1 MBaaS 的使用流程
9.2 阅读须知在使用本指南之前,做好以下准备:
1. 已经注册ServiceStage账号,并且可以访问ServiceStage服务。
2. 本指南基于64位Microsoft Windows 10版本进行测试,请尽量使用较新的Windows版本。
9.3 创建移动后端步骤1 登录ServiceStage,选择“应用管理 > 应用列表”,单击“创建应用”
步骤2 选择“移动应用”,设置应用基本信息,其中带“*”标志的参数为必填参数。
1. 应用名称:输入mbaas。2. 应用显示名称:自动生成mbaas。3. 应用号:不能为空,访问移动后端时需要使用,根据需要设置。
4. 主密钥:不能为空,访问移动后端时需要使用,根据需要设置。
5. 部署系统:支持“云容器引擎CCE”和“云容器示例CCI”,下面以“云容器引擎CCE”为例。
6. 选择已有集群,需要绑定弹性IP,如果没有集群,需要创建。
7. 其他使用默认配置。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 176
图 9-2 应用基本信息
步骤3 单击“下一步”,进行应用配置。
1. 访问方式:选择已有负载均衡,如果没有,需要创建。
2. 数据库:系统已经勾选关系型数据库,单击“去配置>>”,配置PostgreSQL数据库信息,如果没有PostgreSQL数据库,需要新创建。
3. 其他使用默认配置。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 177
步骤4 单击“下一步”,确认规格,单击“提交”。
应用创建完成后,在应用列表可查看应用状态。
----结束
9.4 开发工具设置
设置 Node.js本指南使用Node.js(版本是v10.13.0)作为编程语言,请按照以下步骤安装Node.js。
1. 下载Node.js安装程序。
本例使用的是 Windows 10 64位安装包(.msi文件)
2. 安装Node.js双击下载的msi文件,使用系统默认设置安装即可,如图9-3所示。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 178
图 9-3 安装 Node.js
3. 验证
安装完成后,通过打开命令提示符验证安装。
运行'node -v'和'npm -v'以验证安装和版本,如图9-4所示。
图 9-4 验证安装版本
4. (可选)设置网络代理
对于使用代理访问公网的用户,需要设置代理信息。
示例命令如下,将代理主机和端口更改为公司代理。npm config set proxy http://proxy.mycompany.com:8080 npm config set https-proxy http://proxy.mycompany.com:8080
如果代理需要id和密码,请使用以下命令。npm config set proxy http://<user>:<password>@proxy.mycompany.com:8080 npm config set https-proxy http:// <user>:<password>@proxy.mycompany.com:8080
如果您的密码包含特殊字符,则需要对其进行编码,例如#将成为%23。
设置 Git
本指南使用Git作为源代码管理工具,按照以下步骤安装Git客户端。
1. 下载Git客户端安装程序。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 179
本例使用的是 Windows 10 64位安装包。
2. 安装Git客户端
双击下载的exe文件,使用系统默认设置安装即可,如图9-5所示。
图 9-5 开始安装 Git 客户端
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 180
图 9-6 Git 客户端安装成功
3. (可选)代理设置
对于使用代理访问公网的用户,需要设置代理信息。
示例命令如下,将代理主机和端口更改为公司代理。git config --global http.http://github.com.proxy http://<user>:<password>@proxy.mycompany.com:8080 git config --global http.http://github.com.sslverify falsegit config --global http.https://github.com.proxy http://<user>:<password>@proxy.mycompany.com:8080 git config --global http.https://github.com.sslverify false
9.5 加载 Quick App 样例以下步骤介绍从Github加载Quick App移动应用的样例。
操作步骤
1. 运行Git客户端,进入到workspace,运行以下命令:git clone https://github.com/CPE-OAuth/servicestage-mobileapp-quickapp-example.git
说明
如果在clone项目时遇到问题,可以直接到对应的GitHub代码库下载项目Zip包。
2. 切换到servicestage-mobileapp-quickapp-example目录,示例命令如下:
cd {{path to}}/servicestage-quickapp-example3. 安装依赖项,命令如下:
npm install安装所有依赖项可能需要一些时间。完成后回显示例如下。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 181
4. 下载快应用IDE,本例将使用快速应用IDE构建应用程序开发环境。
下载DevecoFastAppIDE-V1.1.8-Win64.exe文件,然后安装。
5. 安装完成后,启动IDE,导入样例工程。
单击“File>Open project”。选择项目根目录以将项目导入快应用IDE。
要了解快应用IDE的更多详细信息和功能,请参阅官方文档。
6. 在快应用IDE的顶层菜单中,使用“Buid> Run Build”来编译和构建项目。
7. 编译和打包成功后,将在项目根目录下生成“build”文件夹和“dist”文件夹。
– Build文件夹
包含临时输出,包括已编译的页面js、图像等。
– Dist文件夹
包含 终版本,包括rpk文件。构建目录中的资源被打包并压缩到一个名为rpk的后缀文件中。此rpk文件是编译后项目的 终输出。
9.6 导入示例数据本指南中的移动应用需要示例数据,使用ServiceStage移动后端仪表盘导入数据。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 182
操作步骤
1. 访问移动应用外部访问地址,地址如下图所示。
使用创建移动后端中指定的应用号和主密钥登录。
2. 登录移动后台后,进入数据管理页面,导入示例数据。
3. 单击“导入”,打开“ 导入Schema”对话框。选择"多个类对象"。
4. 示例数据位于加载Quick App样例加载的servicestage-mobileapp-quickapp-example项目中。
首先,上传示例Schema文件,文件路径如下。
{{path to}}/servicestage-mobileapp-quickapp-example/data/All_Models_with_photo.json然后选择示例照片文件的文件夹,路径如下。
{{path to}}/servicestage-mobileapp-quickapp-example/data/minpics
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 183
单击“上传”确认并允许将文件上载到移动后端。
单击“确定”,上传文件。
导入进度,如下所示。
5. 导入成功后,将返回数据管理界面。可以看到导入的数据模型和数据,浏览数据并查看导入的内容。
9.7 连接移动后端获取移动应用程序以后,可以连接到ServiceStage的移动后端了。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 184
操作步骤
1. 打开PareUtil.js文件。
示例路径如下
<path to>/servicestage-mobileapp-quickapp-example/src/common/pareutil.js
2. 修改配置参数。
修改appID,使用创建移动后端中设定的移动后端的应用号替换。
替换移动后端的hostName。示例:<app name>.cn-north-1.huaweicse.com,如下图所示。
修改后保存文件。
var hostName="mbaas.cn-north-1.huaweicse.com";var server_URL="http://"+hostName+"/mbaas";var appID = "app01";
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 185
须知
在Service Stage Console中找到创建移动后端中创建的移动后端的应用程序URL,示例如下
https://console.huaweicloud.com/servicestage/?region=cn-north-1#/apps/list。
在该地址可以获得移动后端的主机名,例如http://johnsmbaas.cn-north-1.huaweicse.com。
3. 在快应用IDE,使用“Build> Run Build”重建项目。
9.8 在移动设备上运行 APP要在手机中运行移动应用程序,需要在手机中安装快速应用程序调试器和快速应用程序预览。按照以下说明在手机中运行移动应用程序。
1. 安装工具。
将apk文件复制到手机后,单击apk文件安装应用程序。
– 快应用调试器是一款Android应用程序,下载并安装调试器APK。
– 快应用预览版是一个在移动设备上运行快速应用程序的平台,下载并安装平台APK。
2. 安装平台和调试器后,打开手机上的调试器。
3. 如果在打开调试器时无法单击该按钮,请将您的手机系统升级到 新版本。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 186
4. 将加载Quick App样例中生成的rpk文件复制到手机。
须知
有些公司可能阻止了USB文件传输,请按照符合公司规定的方式将文件传输到手机。
5. 打开调试器并选择INSTALL WITH FILE选项,然后单击复制的rpk文件以安装应用程序。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 187
安装成功后,启动应用程序显示如下。如果没有,您可以从快应用预览版启动应用程序。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 188
6. 单击“Login”创建新帐户并登录。
9.9 (可选)设置 Android 模拟器我们还可以使用Android Studio中的模拟器(Android虚拟设备)来运行移动应用程序。
在 BIOS 中启用虚拟化
在BIOS中启用虚拟化 Android Studio模拟器需要硬件加速。它是通过从机器的BIOS启用虚拟化来完成的。
如何进入笔记本电脑或台式机的BIOS菜单,通常是重新启动机器并按下某些功能键,例如, F2。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 189
进入BIOS菜单后,查找“Virtualization Support”项,然后启用。
设置 Android StudioAndroid Studio是一款用于移动应用程序开发的IDE。它配备了用于开发和测试的手机模拟器,在本指南中将使用Android Studio作为开发工具。
本例是在Windows 10上安装Android Studio。如果您运行的是其他操作系统或需要更多信息,请访问Android Studio官方网站。
1. 下载 新的Android Studio安装程序。
android-studio-ide-181.5056338-windows.exe文件下载如图1 下载AndroidStudio所示。
图 9-7 下载 Android Studio
2. 安装Android Studio,使用默认设置安装即可。
图 9-8 开始安装 Android Studio
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 190
图 9-9 Android Studio 安装完成
3. (可选)设置网络代理信息。
对于使用代理访问公网的用户,首次启动Android Studio时,需要设置代理信息,如图9-10、图9-11所示。
图 9-10 不能联网
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 191
图 9-11 设置代理
4. 安装SDK。
如果未安装Android SDK,则会提示安装Android SDK。
使用默认设置安装即可,如图9-12所示。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 192
图 9-12 安装 Android SDK
5. 启动Android Studio,如图9-13所示。
图 9-13 Android Studio
6. IDE检查更新。
单击右下角的“Configure>Check for Updates”开始更新,如图9-14所示,更新完成时提示如图9-15所示。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 193
图 9-14 更新 IDE
图 9-15 完成更新
说明
了解更多,请参考以下内容。
● https://developer.android.com/studio/run/emulator-acceleration
● https://developer.android.com/studio/run/emulator
7. 设置环境变量。
– 将adb.exe(Android Debug Bridge)添加到PATH Windows环境变量
adb.exe位于Windows 10中的C:\ Users {{Your Username}} \ AppData \Local \ Android \ Sdk \ platform-tools中。 在Windows开始菜单中,搜索“高级系统设置”,然后单击右侧的“环境变量”。在那里找到PATH环境变量
– 在同一个环境变量窗口中,如果未设置JAVA_HOME,则将JAVA_HOME添加到环境变量。
设置模拟器
我们将使用模拟器(Android虚拟设备)来运行本指南中描述的移动应用程序。请按照以下说明添加模拟器。
1. 在Windows开始菜单中,搜索“高级系统设置”,然后单击右下角的“环境变量”。在“用户变量”中,添加一个新条目。
ANDROID_ADB_SERVER_PORT = 6037
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 194
说明
Windows 10后台进程与Android调试器桥之间存在端口冲突,两者都使用了端口5037。为避免此问题,需更改ADB端口。
2. 重启Android Studio。
3. 从菜单栏中,单击“Tools -> AVD Manager”。
4. 单击“Create Virtual Device…”按钮
5. 选择“Pixel 2”,然后单击Next。
图 9-16 选择 Pixel 2
6. 选择“KitKat, API Level 19, armabi-v7a, Android 4.4”,单击“Next”。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 195
7. 单击“Finish”,将出现新的模拟器。
8. 单击“ Actions”下的 按钮首次启动模拟器。这可能需要一些时间。
9. 以下是模拟器的外观。
10. 网络代理服务器设置
如果使用了网络代理服务器,则需要在计算机中设置本地HTTP代理服务器。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 196
11. 设置模拟器代理来访问Internet。单击 打开扩展控件,选择“Settings ->Proxy”设置代理。
9.10 (可选)在模拟器中运行移动应用在Android studio中成功设置模拟器后,按照以下步骤运行QuickEats移动后端示例应用程序。
操作步骤
1. 下载快速应用程序调试器(quickapp_debugger.apk)和QuickApp预览版(quickapp_platform_preview_release_v1030.apk),详见在移动设备上运行APP章节内容。
2. 从 Tool -> SDK Manager中查找Android SDK文件夹位置。
3. 在命令提示符下,切换到{{path from previous step}}\platform-tools路径,使用以下命令安装APK。.\adb.exe install {{path to}}\quickapp_debugger.apk.\adb.exe install {{path to}}\quickapp_platform_preview_release_v1030.apk
安装模拟器后,如下图所示。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 197
4. 复制QuickEats Sample Application rpk文件。
在连接移动后端中构建的QuickEats Sample Application rpk文件位于dist文件夹下,要将文件复制到模拟器,只需将其拖到模拟器,它将被复制到/sdcard/Download目录下。
5. 在模拟器中启动QuickApp Debugger。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 198
6. 单击“ INSTALL WITH FILE”,单击右上角的 ,选择“Display advanceddevice”。
然后可以在调试器中看到SDCARD,单击“Download”并选择com.application.quickeats.debug.rpk,开始安装rpk。
7. 安装成功后,启动QuickEats显示如下,如果没有启动,您可以从Quick AppPreview启动应用程序。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 199
8. 单击“Signup ”,创建新帐户,然后按照说明进行登录。
9.11 (可选)使用 Quick App 构建移动应用程序本节介绍如何使用Quick App构建Mobile应用程序示例。
在加载Quick App样例中如何加载源代码,加载之后源代码目录如下。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 200
关键文件说明如下:
● / src文件夹包含示例应用程序源。
● app.ux文件
包含项目公共资源脚本以及描述页面/自定义组件的多个UX文件,典型的例子如下。
● 公共目录
包含了公共资源文件和组件文件。每个页面目录都存储相应页面的资源文件和组件文件,例如图像,CSS,JS等。
● /src/manifest.jsonmanifest.json清单文件描述了有关应用程序的基本信息,如应用程序描述、界面声明、页面路由(在“router”中)以及与UI显示相关的配置(在“display”中)。
您可以在清单文件中配置应用程序的主页(在移动应用程序启动时作为主屏幕打开)
在示例中,/ src / Login中是主页,可以在清单中配置, json如下。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 201
页面和自定义组件是用ux文件编写的。 ux文件由三部分组成: template 、style 和script.。
● template
类似HTML的标记语言,包含基本组件、自定义组件、事件,构建起页面结构。
● style
用于描述模板的组件样式,用于确定组件的显示方式。
● script
用于定义页面数据和实现生命周期接口。
页面文件的典型示例如下。
示例应用程序包含以下页面:Login、Signup、About、Restaurants、TopRated。
每个页面在相应的文件夹中都有自己的UX文件,如下所示。
每个文件夹都包含index.ux文件,其中包含相应的页面设计模板,脚本和样式。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 202
通过解析rest apis可以实现从示例应用程序连接到移动后端。
配置所需的主机和应用程序ID以连接和查询来自Mobile后端的数据,示例餐馆查询代码如下所示。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 203
9.12 (可选)开始开发自己的移动应用本节介绍更多从头创建移动应用程序的信息,供开发人员参考。
要创建快速应用程序项目,需要Node.js和hap工具包。Node.js的安装在开发工具设置中已经说明。
运行快速应用程序需要Android设备,例如物理安卓机。在(可选)设置Android模拟器中描述了设置模拟器的步骤。
以下是使用Quick App创建移动应用程序的说明。
1. 要创建新的快速应用程序项目,需要安装 toolkit工具和调试器。
在命令行运行以下命令npm install -g hap-toolkit
执行命令行hap -V将输出指示hap-toolkit安装成功的版本信息,如以下命令所示 hap –V
2. 安装toolkit工具后,可以使用全局命令创建项目模板,如下所示 hap init <project name> e.g: hap init QuickEats
3. 执行该命令后,将在当前目录中创建一个文件夹作为项目根目录。
该项目已包含项目配置和示例页面的初始代码。
项目根目录的主要结构如下├── sign rpk包签名模块 │ └── debug 调试环境
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 204
│ ├── certificate.pem 证书文件│ └── private.pem 私钥文件├── src│ ├── Common 公用的资源和组件文件│ │ └── logo.png 应用图标│ ├── Demo 页面目录│ | └── index.ux 页面文件,可自定义页面名称│ ├── app.ux APP文件,可引入公共脚本,暴露公共数据和方法等│ └── manifest.json 项目配置文件,配置应用图标、页面路由等└── package.json 定义项目需要的各种模块及配置信息
目录的简要说明如下
– src项目源文件夹
– sign签名模块。
微服务云应用平台开发指南 9 移动应用 QuickAPP 开发指南
文档版本 01 (2019-06-19) 版权所有 © 华为技术有限公司 205