服务多版本,这感觉跟灰度发布有点类似。
===
服务上线后,随着业务的发展需要对功能进行变更,或者修复线上的BUG;服务升级之后,往往需要对服务采用多版本管理。
服务多版本管理是对分布式服务框架的重要特性,它涉及服务的开发、部署、在线升级和服务治理。
===
13.1 服务多版本管理设计
服务多版本管理对象包括服务提供者和消费者
1)服务提供者: 发布服务的时候,支持指定服务的版本号
2)服务消费者:消费服务的时候,支持指定引用的服务版本号或者版本范围
13.1.1服务版本号管理
服务的版本号信息并不是仅仅供人工阅读的,版本在分布式框架中是一个受系统管理的信息
维护一个服务的不同版本也是分布式服务框架支持服务在线升级的重要特性
当1个消费者依赖某个服务提供者时,通常需要指明它依赖服务的版本号信息。
服务的版本号是有序的,在服务名相同的情况下,2个相同服务名的不同服务版本的版本号可以比较大小。
完整的版本号由"主版本号“+副版本号+微版本号” 构成。
经验:
略
服务版本比较的原则,从前往后逐项比较,当且仅当服务名,主版本号,服务版本号和微版本号全部相同时,2个服务才是同1个服务,否则以第1个出现差异的版本号的大小决定服务版本的大小。
13.1.2 服务提供者
服务提供者的XML的service需要包含版本信息,用于服务提供者在发布服务的时候指定服务的版本号。
服务开发完成之后,需要将1个或者多个服务打包成1个jar包或者war包,为了便于对服务进行物理管理,打包后的名称中会包含服务的版本信息,例如service_1.0.1.jar
在微服务框架中,微服务独立开发,打包,部署和升级,因为微服务的版本和软件包的版本可以一一映射。
但是在实际开发中,特别是大企业应用开发,单独为每个服务打包和部署目前尚未成为主流,会增加成本,因此目前主流模式仍然是多个服务提供者打成1个大的jar/war包。
这就会存在1个问题:项目开发初期,各个服务的版本号保持一致,但是运行一段时间之后,有些服务进行了版本升级,有些服务没有,打包时,就造成版本号不一致。
===
另外,如果为每个服务都指定1个版本号,对开发而言也比较麻烦。有没有更好的服务版本管理方式呢?
略
13.1.3 服务消费者
与服务提供者不同的是,服务消费者往往不需要指定具体依赖的服务版本,而是一个版本范围
在服务框架中引入版本范围的原因有如下:
1)消费者关心的是某个新特性从哪个服务版本中开始提供,它并不关心服务提供者的版本演进以及具体的版本号。
2)消费者想使用当前环境中服务的最新版本,但是并不清楚具体的版本号,希望自动适配最新的服务版本
如果消费者不指定导入的服务版本,默认将查找0.0.0的服务提供者,找不到则抛出异常
这样做的核心目的就是要在开发阶段将服务版本号的设计和管理纳入到研发流程中进行统一管理。
13.1.4 基于版本号的服务路由
服务提供者将服务注册到服务注册中心时,将服务名+服务版本号+服务分组 作为路由关键信息存放到注册中心,服务消费者在发起服务调用时,除了携带服务名,方法名和参数列表之外,还需要携带消费的服务版本信息,由路由接口负责服务版本过滤,原理如图:
略
13.1.5 服务热升级
服务热升级的目标就是在业务不中断的情况下,实现系统的平滑升级,考虑到版本升级的风险,往往需要做多次滚动升级,最终根据升级之后新版本服务的运行状况决定是继续升级还是回退。
这就意味着在同一时刻,整个集群环境中会同时存在服务的多个版本在线运行,这就是热升级与传统AB测试的差异。
1)升级的节点需要重启,但是由于分布式服务框架具备服务的健康监测和自动发现,停机并不会中断业务
2)服务路由规则的定制:如果是滚动式的灰度发布,在相当长的一段时间内,线上都会存在多个版本
哪些用户或者业务需要路由到新版本上,需要通过路由策略和规则进行指定,服务框架应该支持用户配置自定义的路由规则来支持灵活的路由策略。
3)滚动升级和回退机制:无论在预发布环境中测试多么充分,有新的问题,此时,回退。
13.2 与OSGI的对比
略