微服务化后注意事项

随着业务发展,很多系统需要经历服务拆分的过程。微服务化过程踩坑也是很正常的事。如果在服务拆分之前做好充分准备,能帮我们少走很多弯路。本文主要从服务依赖,接口版本,隔离,数据一致等方面说说微服务化过程应该注意的点。

循环依赖问题

微服务化之后服务之间会存在各种依赖关系,不过依赖需要遵循一定的规则,不能太随意。否则,就会出现循环依赖的问题,而且会让调用关系变得错综复杂难于维护。下面是服务依赖的几条规则:

1,上层服务可以调用下层服务。

2,同级服务之间不能产生依赖关系,及不能产生调用关系。

3,下层服务不能调用上层服务。

4,服务之间的调用关系只能是单向的。

例如,在电商系统里包括支付服务(Pay),库存服务(Inventory),订单服务(Order)。支付服务和库存服务属于基础服务,订单服务属于上层服务。支付服务和库存服务是同级的服务,他们之间不能存在调用关系。订单服务属于上层服务,订单服务可以调用支付服务和库存服务,但是支付服务和库存服务不能调用上层的订单服务。

假设我们不管这些规则,让Order和Pay可以互相调用。这样就会产生循环依赖,Order调用Pay,Pay也调用Order,这样彼此都会依赖对方。

循环依赖导致哪些问题?

1,无限递归调用

假如,Order调用Pay的A方法,Pay调用Order的B方法。然后,A方法里又调用了Order的B方法,B方法里又调用了Pay的A方法。这样就会产生无限的递归调用,后果自然不言而喻了。


  1. Order { 
  2.    void B(){ 
  3.      Pay.A(); 
  4.    } 

  1. Pay{ 
  2.    void A(){ 
  3.      Order.B(); 
  4.    } 

2,部署依赖问题

假设Order,Pay,Inventory彼此之间都可以通过API互相调用。当API接口发生变更时,为了让其他服务能够正常调用,API需要重新编译。如果Order和Pay的API都有变化,上线发布时就需要特别小心。为了保证发布成功,就需要根据服务间API的依赖关系,详细考虑先打包部署哪个服务,后打包部署哪个服务,才不至于发布失败。如果有更多的服务呢?比如10几个,梳理依赖关系都会把人搞疯的。

3,另外,循环依赖会让服务间的调用关系变得错综复杂,系统难于维护。

接口版本兼容

一些初中级程序员往往会忽略接口变更的问题,经常会因为接口变更导致线上问题。比如某个小型电商平台的订单服务调用支付服务的某个接口,产品突然提了一个需求,这个需求需要在这个支付接口上加一个参数。开发这个需求的是个新手,他直接在原来的接口方法上实现了需求并加上了参数,联调测试通过后就发布上线了。结果刚上线订单服务就开始报错,因为方法变了,加了参数,订单服务找不到老的方法了。所以就会一直报错,直到订单服务上线为止。

所以我们一定要注意接口版本问题。我们可以新加一个方法去重载老的方法,在新方法里实现新的功能,新方法的定义除了多一个参数外,其他的和老方法一样。也就是给老方法加了一个新版本。

这样在支付服务上线后,订单服务上线之前就不会报错了,因为老方法仍然可用。订单服务上线后就直接切到了新版本的方法。

如果我们服务框架选用的是Dubbo,当一个接口的实现,出现不兼容升级时,可以用Dubbo的版本号过渡,版本号不同的服务相互间不引用。

可以按照以下的步骤进行版本迁移:

1. 在低压力时间段,先升级一半提供者为新版本

2. 再将所有消费者升级为新版本

3. 然后将剩下的一半提供者升级为新版本

老版本服务提供者配置:


  1. <dubbo:service interface="com.foo.BarService" version="1.0.0" /> 

新版本服务提供者配置:


  1. <dubbo:service interface="com.foo.BarService" version="2.0.0" 

老版本服务消费者配置:


  1. <dubbo:reference id="barService" interface="com.foo.BarService" version="1.0.0" /> 

新版本服务消费者配置:


  1. <dubbo:reference id="barService" interface="com.foo.BarService" version="2.0.0" /> 
【声明】:芜湖站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

相关文章