ServiceComb优雅上下线开源开发总结
【摘要】 背景微服务优雅上下线是一个非常重要的商业级特性,优雅上下线机制可以实现扩容、升级、缩容等场景下的业务零中断。 由于微服务存在海量的实例,每个实例都通过RPC请求相互访问,因此有非常多的场景可能导致上下线过程出现中断。比如:1. 微服务实例刚刚启动的时候,由于涉及资源初始化、连接池初始化、线程池初始化、数据库初始化等过程,第一次访问会比较慢。那么第一次访问该实例的并发不能太大,否则会由于竞争导...
背景
微服务优雅上下线是一个非常重要的商业级特性,优雅上下线机制可以实现扩容、升级、缩容等场景下的业务零中断。 由于微服务存在海量的实例,每个实例都通过RPC请求相互访问,因此有非常多的场景可能导致上下线过程出现中断。比如:
1. 微服务实例刚刚启动的时候,由于涉及资源初始化、连接池初始化、线程池初始化、数据库初始化等过程,第一次访问会比较慢。那么第一次访问该实例的并发不能太大,否则会由于竞争导致请求超时。
2. 作为微服务消费者,会缓存微服务提供者的实例列表,实例下线的时候,可能存在缓存未及时刷新,使用了已经下线的实例,导致请求失败。
需求分析
根据《ServiceComb优雅上下线开源开发计划书》中方案描述,主要目的是基于ServiceComb的微服务能够容器部署时候能够优雅上线,容器在停止时候优雅的下线,为此需要设计如下功能:
1.设计parpared接口作为启动探针,接口功能表示服务注册成功,同时服务注册的状态为“STARTING”,此时其它服务可以发现此服务,但是不能发起远程调用。
2.设计warmup作为就绪探针,接口逻辑是实现自定义功能初始化,比如加载缓存,自定义功能预热初始化之后,修改服务的注册状态为“UP”,服务消费者可调用。
3.设计prestop接口作为容器停止前处理容器生命周期处理,比如去除缓存,提交事务,停止定时任务,拒绝后续请求等,修改服务注册状态为down,服务不可调用。
4.设计一个预热验证的接口,进行并发测试,对接口服务进行扩容和缩容,此过程中持续不断的请求接口,要求请求不能有错误。
4.为上述三个接口设计权限验证,因为涉及到容器启停,需要保证安全性。预热验证接口走原本的业务权限验证。
此需求需要在华为开源实例servicecomb-fence中验证,使用servicecomb-service-center和zookeeper作为注册中心分别进行测试验证。
需求开发
servicecomb开发
核心思想:根据servicecomb.instance.initialStatus=STARTING/UP来设置服务注册示例的初始状态,并且把状态设置到Instace中注册保存到注册中心,然后Discovery服务从注册中心获取实例Instance中获取状态通过InstanceStatusDiscoveryFilter类控制是否访问这Provider服务示例。例如zookeeper:
servicecomb-fence示例开发
需要在上下文中设置全局的应用注册状态和预热状态,接口中使用这两个状态来处理请求的逻辑处理。注册状态通过SCBEngine中的注册后事件来设置注册状态。预热状态则由预热接口请求之后设置,初始值都是false.
parpared接口:
注册后事件状态触发,注册之后更新应用注册状态。
接口检测注册的状态,不为true报错返回
warmup接口:
1.第一步是进行token验证
2.第二步是检测状态,防止重复预热。
3.预热状态为false的话进行预热处理,防止并发需要加锁。
4.进行预热,更新预热状态为true
5.更新实例的状态,需要判断实例状态为STARTING才更新
prestop接口:
此接口作为容器生命周期-停止前的处理操作
1.更新示例状态为down,让消费者服务不再调用
2.关闭定时任务
3.请求线程阻塞3秒,让正常业务请求结束。
后续SCBengine会执行销毁操作。
预热验证接口:
简单预热Demo逻辑:请求warmup接口之后,会从数据库查询用户guest的信息缓存到map中。预热验证接口则从map中获取用户的ID返回。
验证流程:
JMeter发送请求 -> 网关 -> admin-service服务发现远程调用resource -> resource-sesrver扩缩容触发上下线接口功能
权限处理:
原本的业务权限验证过滤parpared,warmup,prestop三个接口,基于前缀匹配过滤
使用自定义的Token验证,使用时候通过工具类或者第三方Token在线解析生成token,token的秘钥配置在配置文件中,使用HS256算法。
Token直接在接口中验证,token作为请求头或参数传递
上下线功能开关:
因为servicecomb-fence中注册中心maven依赖是全局依赖管理的,有些项目需要上下线功能,有些不需要,所以需要配置服务状态来控制是否开启这个功能。
服务默认状态是UP,服务注册状态为UP;设置配置后服务注册的状态为STARTING。
部署验证
本次任务修改涉及servicecomb开源代码,fork代码分支为https://github.com/chenshouye168/servicecomb-java-chassis ,演示示例代码分支为https://gitcode.com/jupiterkiss/opensource-demo-servicecomb-241223 。修改代码本地测试后install到本地,实例项目直接打成jar包,制作镜像上传SWR,然后只用华为云CCE进行部署。部署如下:
注册中心:
购买华为云CSE-ServiceComb引擎
Nacos在CSE微服务引擎购买nacos实例。
Consul,etcd,zookeeper注册中心:直接在CCE集群中部署工作负载即可使用。
预热验证接口:
接口逻辑:接口请求返回用户guest的ID,实例启动之后初始化为null,预热接口查询数据库缓存,接口请求返回用户的ID。
验证标准: 40并发请求,一直不停,接口请求返回参数不能为空,接口不能报错
验证逻辑:对rersource-server服务进行手动扩容1->2->4实例,扩容过程中不断请求,查看过程中的错误率;扩容到4实例都是up的状态之后手动缩容到2->1实例,缩容过程中不停请求,查看缩容过程中的错误率.
JMeter配置:
初始状态:1个实例
扩容到2个实例:
扩容到4个实例:
缩容:4-2
缩容到2-1个实例:
使用指南
集成需要使用注册中心jar包依赖:
# zk
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>registry-zookeeper</artifactId>
</dependency>
# nacos
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>registry-nacos</artifactId>
</dependency>
# service-center
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>registry-service-center</artifactId>
</dependency>
# service-consul
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>registry-consul</artifactId>
</dependency>
# etcd
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>registry-etcd</artifactId>
</dependency>
开启优雅上线功能:
在需要优雅上下线功能的服务中设置服务启动初始状态,配置使用的注册中心地址信息
servicecomb:
instance:
initialStatus: STARTING
registry:
zk:
enabled: true
connectString: ${ZK_ADDRESS:127.0.0.1:2181}
# nacos:
# enabled: true
# serverAddr: ${NACOS_ADDRESS:http://127.0.0.1:8848}
# sc:
# enabled: true
# address: ${SERVICE_ADDRESS:http://127.0.0.1:30100}
# etcd:
# enabled: true
# connectString: ${ETCD_ADDRESS:http://127.0.0.1:2379}
# consul:
# enabled: true
# host: ${CONSUL_ADDRESS:localhost}
# post: 85001.0
开发优雅上下线接口:
具体可参照上面开发的示例。具体的类使用说明如下:
@Autowired
RegistrationManager registrationManager;
# 更新注册示例状态的方法
registrationManager.updateMicroserviceInstanceStatus(MicroserviceInstanceStatus.UP/DOWN);
权限:
上面示例中使用的是HS256生成的token做验证,只是简单的实现。可自定义进行验证实现。简易代码参考如下:
@Component
public class JwtTokenHandle {
@Value("${servicecomb.service.elegant.token_secret}")
private String tokenSecret;
public boolean verify(String authToken){
if (StringUtils.isBlank(authToken)){
return false;
}
try {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(tokenSecret)).build();
DecodedJWT jwt = verifier.verify(authToken);
if (jwt == null) {
return false;
}
}catch (Exception ex){
return false;
}
return true;
}
}
配置:
在负载中配置启动,就绪探针,容器生命周期-停止前处理,需要注意延迟时间设置,根据具体应用启动时间作为参考。
总结
通过源代码的修改和在servicecomb-fence示例中开发示例功能验证官方service-center,zookeeper,nacos,etcd,consul这几个注册中心,可以等官方发布新版本之后进行验证和使用。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)