一. ServiceComb对接 Spring Cloud Ribbon思路

在Ribbon的wiki介绍页(https://github.com/Netflix/ribbon/wiki/Working-with-load-balancers)可以发现这样的描述:

ServerList - this can be static or dynamic. If it is dynamic (as used by DynamicServerListLoadBalancer), a background thread will refresh and filter the list at certain interval

这段介绍了ServerList接口,该接口既可以是静态获取服务实例列表也可以是动态获取的。

如果是动态获取服务列表(被DynamicServerListLoadBalancer使用),会有一个后台线程在特定得时间间隔负责刷新和过滤服务列表。

 

也就是说,我们只要实现了ServerList接口,加上相应的配置让Ribbon获取到,就能向Ribbon提供ServiceComb自己的服务发现逻辑。

 

如下图↓↓↓

springcloud 一件启动 springcloud service_springcloud 一件启动

ServiceComb 在如下的org.apache.servicecomb:spring-boot-starter-discovery项目中实现了ServerList接口和相应的配置。

<dependency>
   <groupId>org.apache.servicecomb</groupId>
   <artifactId>spring-boot-starter-discovery</artifactId>
   <version>1.1.0</version></dependency>

 

二. 源码分析

项目结构

如下图,红色方框内为接入SpringCloud Ribbon组件的相关类。

springcloud 一件启动 springcloud service_java_02

 

下面我们分别来看看这几个类

↓↓↓



ScbRibbonConfiguration

Configuration 表示这是一个spring的配置类

EnableConfigurationProperties 使@ConfigurationProperties注解生效

ConditionalOnBean 只有特定名称或者类型的Bean存在于BeanFactory时才创建某个Bean

AutoConfigureAfter 只有在指定类的配置类配置完后才会生效

RibbonClients 允许在一个类中声明多个RibbonClient注解

注意Ribbon是懒加载的,而该类在RibbonAutoConfiguration初始化配置之后才会执行配置,所以该类也是懒加载

springcloud 一件启动 springcloud service_python_03

 



ScbRibbonClientConfiguration

在ScbRibbonConfiguration类中的RibbonClients注解指定了ScbRibbonClientConfiguration来实例化RibbonClient。 如下,该类实例化了一个ServerList对象,实际类型为ServiceCombServerList,该对象会替换DynamicServerListLoadBalancer类里的ServerList对象。

springcloud 一件启动 springcloud service_微服务_04



ServiceCombServerList

在Ribbon体系中,ServerList接口负责获取服务实例列表。ServiceComb使用ServiceCombServerList实现了该接口。该类使用了ServiceComb内置的服务发现能力。

ServiceCombServerList构造器里使用discoveryTree添加了一个过滤器ScbRibbonEndpointDiscoveryFilter。

•DiscoveryTree是ServiceComb Registry包的类。ServiceComb Registry包提供了服务注册,服务发现与过滤器等能力。

•ScbRibbonEndpointDiscoveryFilter继承了AbstractEndpointDiscoveryFilter,而AbstractEndpointDiscoveryFilter实现了DiscoveryFilter。DiscoveryFilter接口主要管理实例进行分组、缓存

getInitialListOfServers方法获取初始的servers;getUpdatedListOfServers方法获取更新的servers

springcloud 一件启动 springcloud service_springcloud 一件启动_05

 



ScbRibbonEndpointDiscoveryFilter

ScbRibbonEndpointDiscoveryFilter继承于AbstractEndpointDiscoveryFilter类,观察AbstractEndpointDiscoveryFilter代码可发现有一个discovery方法,这个方法会被DiscoveryTree使用以获取服务列表。此时已进入ServiceComb Registry包内部,具体的细节不展开分析。

springcloud 一件启动 springcloud service_springcloud 一件启动_06

关于filter类,实际上查看DiscoveryTree的源码可发现一些信息,如下是DiscoveryTree的doDiscovery方法,该方法属于ServiceCombServerList获取服务实例列表的调用链上,而该方法会将这个获取信息的任务交给DiscoveryFilter类去处理。

springcloud 一件启动 springcloud service_python_07

 

本文向社区读者从源码角度阐述了ServiceComb是如何与SpringCloud Ribbon协同工作的。