ServiceComb优雅上下线开源开发总结

举报
纷纷扰扰 发表于 2025/01/06 13:15:03 2025/01/06
348 0 0
【摘要】 背景微服务优雅上下线是一个非常重要的商业级特性,优雅上下线机制可以实现扩容、升级、缩容等场景下的业务零中断。 由于微服务存在海量的实例,每个实例都通过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

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。