大厂是如何做微服务架构的服务路由的?

举报
JavaEdge 发表于 2021/06/03 22:55:58 2021/06/03
【摘要】 负载均衡算法是为了解决服务消费者如何从众多可用服务节点中选取一个最合适的节点发起调用。 但在业务中经常还会遇到这样的场景,比如服务A部署在北京、上海、广州三个数据中心,所有的服务节点按照所在的数据中心被分成了三组,那么服务A的消费者在发起调用时,该如何选择呢? 这就是服务路由。 什么是服务路由 服务消费者在发起服务调用时,必须根据特定规则选择服务节点,从而满足某...

负载均衡算法是为了解决服务消费者如何从众多可用服务节点中选取一个最合适的节点发起调用。

但在业务中经常还会遇到这样的场景,比如服务A部署在北京、上海、广州三个数据中心,所有的服务节点按照所在的数据中心被分成了三组,那么服务A的消费者在发起调用时,该如何选择呢?

这就是服务路由。

什么是服务路由

服务消费者在发起服务调用时,必须根据特定规则选择服务节点,从而满足某些特定需求。

应用场景

分组调用

为了保证服务高可用,实现异地多活,一个服务往往不止部署在一个数据中心,而且出于节省成本等考虑,有些业务可能不仅在私有机房部署,还会采用公有云部署,甚至采用多家公有云部署。服务节点也会按照不同的数据中心分成不同的分组,这时对于服务消费者来说,选择哪一个分组调用,就必须有相应的路由规则。

灰度发布

在服务上线发布的过程中,一般需要先在一小部分规模的服务节点上先发布服务,然后验证功能是否正常。如果正常的话就继续扩大发布范围;如果不正常的话,就需要排查问题,解决问题后继续发布。

流量切换

在业务线上运行过程中,经常会遇到一些不可抗因素导致业务故障,比如

  • 某机房光缆被挖断
  • 着火等事故

导致整个机房的服务都不可用。这时就需要按照某个指令,能够把原来调用这个机房服务的流量切换到其他正常的机房。

读写分离

大多业务来说都是读多写少,服务部署时,可以把读写分开部署,所有写接口可以部署在一起,而读接口部署在另外节点。

服务路由规则

条件路由

基于条件表达式的路由规则,以下面的条件路由为例,我来给你详细讲解下它的用法。

condition://0.0.0.0/dubbo.test.interfaces.TestService?
	category=routers&dynamic=true&priority=2&enabled=true&rule=
	" + URL.encode(" host = 10.20.153.10=> host = 10.20.153.11")

  
 
  • 1
  • 2
  • 3

condition:// 代表这是一段用条件表达式编写的路由规则,具体的规则是

host = 10.20.153.10 => host = 10.20.153.11

  
 
  • 1

=>前是服务消费者的匹配条件,后面是服务提供者的过滤条件
服务消费者节点满足匹配条件,就对该服务消费者执行后面的过滤规则。
这段表达式表达的意义就是IP为“10.20.153.10”的服务消费者都调用IP为“10.20.153.11”的服务提供者节点。

若服务消费者的匹配条件为空,就表示对所有的服务消费者应用,就像下面的表达式一样。

=> host != 10.20.153.11

  
 
  • 1

若服务提供者的过滤条件为空,就表示禁止服务消费者访问:

host = 10.20.153.10=>

  
 
  • 1

具体应用场景

排除某服务节点
=> host != 172.22.3.91

  
 
  • 1

一旦这条路由规则被应用到线上,所有的服务消费者都不会访问IP为172.22.3.91的服务节点,这种路由规则一般应用在线上流量排除预发布机以及摘除某个故障节点。

白名单
host != 10.20.153.10,10.20.153.11 =>

  
 
  • 1

除了IP为10.20.153.10和10.20.153.11的服务消费者可以发起服务调用以外,其他服务消费者都不可以。
比如某个后台服务只允许特定的几台机器才可以访问,这样的话可以机器控制访问权限。

黑名单
host = 10.20.153.10,10.20.153.11 =>

  
 
  • 1

除了IP为10.20.153.1010.20.153.11的服务消费者不能发起服务调用以外,其他服务消费者都可以。
比如线上经常会遇到某些调用方不管是出于有意还是无意的不合理调用,影响了服务的稳定性,这时候可以通过黑名单功能暂时予以封杀。

机房隔离
host = 172.22.3.* => host = 172.22.3.*

  
 
  • 1

IP网段为172.22.3.*的服务消费者,才可以访问同网段的服务节点。
一般应用于服务部署在多个IDC,理论上同一个IDC内的调用性能要比跨IDC调用性能要好,应用这个规则是为了实现同IDC就近访问。

读写分离
method = find*,list*,get*,is* => host =172.22.3.94,172.22.3.95
method != find*,list*,get*,is* => host = 172.22.3.97,172.22.3.98

  
 
  • 1
  • 2

find*、get*、is*等读方法调用IP为172.22.3.94和172.22.3.95的节点,除此以外的写方法调用IP为172.22.3.97和172.22.3.98的节点。
大部分业务读请求远大于写请求,而写请求的重要性往往要远远高于读请求,所以需要把读写请求进行分离,以避免读请求异常影响到写请求。

脚本路由

基于脚本语言的路由规则,常用的脚本语言比如JavaScript、Groovy、JRuby等。
比如:

"script://0.0.0.0/com.foo.BarService?
	category=routers&dynamic=false&rule=" + 
	URL.encode("(function route(invokers) { ... } (invokers))")

  
 
  • 1
  • 2
  • 3

script:// 代表了这是一段脚本语言编写的路由规则,具体规则定义在脚本语言的route方法实现。
比如下面这段用JavaScript编写的route()方法:
只有IP为10.20.153.10的服务消费者可以发起服务调用。

function route(invokers){
  var result = new java.util.ArrayList(invokers.size());
  for(i =0; i < invokers.size(); i ++){ if("10.20.153.10".equals(invokers.get(i).getUrl().getHost())){ result.add(invokers.get(i)); } }
  return result; 
 } (invokers);

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

服务消费者该如何获取路由规则呢?

获取服务路由

本地配置

路由规则存储在服务消费者本地上。服务消费者发起调用时,从本地固定位置读取路由规则,然后按照路由规则选取一个服务节点发起调用。

不排除某些服务消费者有特定的需求,需要定制自己的路由规则,这个时候就适合通过本地配置来定制。

配置中心管理

所有的服务消费者都从配置中心获取路由规则,由配置中心来统一管理。

服务路由最好是存储在配置中心中,由配置中心来统一管理。这样所有服务消费者就不需要在本地管理服务路由,因为大部分的服务消费者并不关心服务路由的问题,或者说也不需要去了解其中的细节。通过配置中心,统一给各个服务消费者下发统一的服务路由,节省了沟通和管理成本。

动态下发

一般是运维人员或者开发人员,通过服务治理平台修改路由规则,服务治理平台调用配置中心接口,把修改后的路由规则持久化到配置中心。因为服务消费者订阅了路由规则的变更,于是就会从配置中心获取最新的路由规则,按照最新的路由规则来执行。

动态下发可以理解为一种高级功能,它能够动态地修改路由规则,在某些业务场景下十分有用。比如某个数据中心存在问题,需要把调用这个数据中心的服务消费者都切换到其他数据中心,这时就可以通过动态下发的方式,向配置中心下发一条路由规则,将所有调用这个数据中心的请求都迁移到别的地方。

当然,这三种方式也可以一起使用,这个时候服务消费者的判断优先级是本地配置>动态下发>配置中心管理。

总结

服务路由简单说就是为了实现某些调用的特殊需求,比如分组调用、灰度发布、流量切换、读写分离等。在业务规模比较小的时候,可能所有的服务节点都部署在一起,也就不需要服务路由。但随着业务规模的扩大、服务节点增多,尤其是涉及多数据中心部署的情况,把服务节点按照数据中心进行分组,或者按照业务的核心程度进行分组,对提高服务的可用性是十分有用的。以微博业务为例,有的服务不仅进行了核心服务和非核心服务分组,还针对私有云和公有云所处的不同数据中心也进行了分组,这样的话就可以将服务之间的调用尽量都限定在同一个数据中心内部,最大限度避免跨数据中心的网络延迟、抖动等影响。

而服务路由具体是在本地配置,还是在配置中心统一管理,也是视具体业务需求而定的。如果没有定制化的需求,建议把路由规则都放到配置中心中统一存储管理。而动态下发路由规则对于服务治理十分有帮助,当数据中心出现故障的时候,可以实现动态切换流量,还可以摘除一些有故障的服务节点。

文章来源: javaedge.blog.csdn.net,作者:JavaEdge.,版权归原作者所有,如需转载,请联系作者。

原文链接:javaedge.blog.csdn.net/article/details/115055088

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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