剑客
关注科技互联网

服务化体系之-兼容性与版本号

准备挽起袖子写个服务化的大系列,不想错过的同学,先把公众号关注了,jnby1978。

服务化体系之-兼容性与版本号

家大业大之后,服务的版本和兼容性就是个让人不得不正视的问题。

最近,路上有个说法,既然都是微服务了,那不同的版本可以认为是两个完全不一样的微服务,没必要再保留版本号了。

这篇文章按着唯品会的实战经历来探讨一下。

1. 兼容性原则

先搞些铺垫,我们一般认为下面的情况是兼容的:

  1. 增加新方法
  2. 增加可选的参数
  3. 修改参数为可选
  4. 删除参数
  5. 框架支持的话,参数的名称也可以改一下(如Thrift)

参数是对象的话,其属性的修改参见2-5条。

然后一般认为下面的情况是不兼容的:

  1. 修改方法的名称
  2. 删除方法
  3. 增加必填的参数
  4. 修改参数为必填
  5. 修改参数和返回值的类型

参数是对象的话,属性的修改参照3-5条。

2. 不兼容时服务如何升级?

服务要进行不兼容的升级时,家大业大的体系是永远不可能同时(比如同一个深夜,同一个小时甚至同一分钟)将所有的调用者客户端也升级的,那怎么办?

一种是不修改原来的接口,直接在同一个服务里增加新的方法来解决。这种应该是最简单的做法,不过日积月累下会有点dirty。

一种是同时运行新旧两个服务。这种方式干净,但要注意:

  • 要保证旧版的客户端SDK,调用不能被路由到新服务上。
  • 随着客户端不断割接过来,控制好新旧两个的集群容量。

3. 版本号原则

服务的版本号,和软件的版本号一样,一般整成三位:

第一位:不兼容的大版本, 如1.0 vs 2.0

第二位:兼容的新功能版本,如1.1 vs 1.2

第三位:兼容的BugFix版本,如1.1.0 vs 1.1.1

如果拿着低版本的SDK(如1.0.0) 发起请求,是不会被服务化框架路由到不兼容的版本的服务上的(如2.0.1),但会被路由到所有兼容版本的服务上(如1.1.1,1.2.0)。

4. 问题来了,到底要不要版本号?

4.1 版本号用于标示SDK版本是有益的

即使是兼容的小版本号。

版本号能让服务端与客户端两头的开发人员更好的对话,毕竟所谓兼容,有时候也有着某种代价与折衷,互相明确当前的版本会更好。

如果服务治理中心,能让所有服务提供者一目了然各个调用者的版本会更好,方便催人升级呀。

同时,在中央API文档中心,最好也是为每一个小版本保留一份文档,毕竟家大业大,有时全部客户端的升级可能是很长一段时间的事情。

4.2 不兼容的版本,是独立两个服务,还是用第一位版本来区分?

像我们这种命名渣,好不容易为服务里搞了个贴切的名字了,再想第二个其实很不容易,一般只能在函数名,服务名里直接带上数字,如GoodsService2,或者直接加个’New’,如GoodsServiceNew。

既然这样,还不如继续使用版本号。当然,前提是你家的服务化框架有这个路由能力,刚好我们家有。

4.3 基于版本的配置?

我们家框架之前的设计,将配置的粒度支持到每个小版本上,比如1.0版本的超时时间是10ms,1.2版本是20ms。而最后根据客户端的版本来就近选择,回头来看,白白增加复杂度,很多假设的场景其实没鸟用。

兼容的小版本只有一份配置就好,明年改改改。

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址