Spring Cloud Bamboo源码分析

一、项目简介
Spring cloud bamboo是spring cloud中国社区推出的一个多版本控制插件,它通过扩展spring-cloud-ribbon实现了多版本调用,地址为 https://github.com/SpringCloud/spring-cloud-gray/tree/master/spring-cloud-bamboo
二、思路分析
在spring cloud微服务体系中,服务的请求主要为通过网关和内部服务之间调用,通过向项目开发者了解到目前spring-cloud-bamboo主要支持的是spring cloud Dalston.SR5版本以及spring boot1.5.4-1.5.7,也就是说网关是zuul,而内部调用在spring cloud下则为spring cloud-feign以及Ribbon+RestTemplate的方式,其中发现核心都是通过spring cloud ribbon去负载均衡的,所以说要实现多版本控制必须先要修改默认的Ribbon负载均衡规则,其次在zuul、feign、restTemplate做衔接。
三、核心实现Ribbon源码分析
首先通过思路分析,我们去找到项目的配置类BambooAutoConfiguration.java发现有@RibbonClients(defaultConfiguration = BambooRibbonClientsConfiguration.class),这个指明了Ribbon的配置类,打开配置来发现在这里配置了Bamboo的负载均衡规则
        
这里分析一下此配置的作用,通过@ConditionalOnMissingBean(value = {BambooAutoConfiguration.UnUseBambooIRule.class})配置了多版本负载均衡失效策略,这是为了其他扩展要修改负载均衡而做出的配置,其中BambooZoneAvoidanceRule类是负载均衡的规则。代码如下。
             
其中重写了Ribbon默认的ZoneAvoidanceRule的getPredicate(),返回了封装了原先默认的规则和先有的版本验证的Predicate,版本验证规则实现在BambooApiVersionPredicate类实现的,其中BambooZoneAvoidanceRule会被ILoadBalancer执行时调用choose方法,代码如下
          choose方法调用了gerPredicate()中的带过滤的负载均衡算法,最终在getEligibleServers()方法里调用了在BambooApiVersionPredicate类重写的apply()方法进行了版本过滤,代码如下

四、zuul、feign、restTemplate与ribbon的衔接
zuul和feign都是默认启用了Ribbon,restTemplate则是通过拦截器的方式注入了ribbon的逻辑,而通过上面分析bamboo已经做了新的负载均衡规则,而bamboo只需在这zuul、feign、restTemplate拦截器中做参数处理即可。
1.zuul
首先在zuul里通过增加filter的方式注入了bamboo的逻辑,路由前filter代码如下:

首先是封装了Bamboo所需的request已经需要的一些参数处理,而这些最终都是交给DefaultRibbonConnectionPoint类去处理,DefaultRibbonConnectionPoint类实现了BambooRibbonConnectionPoint接口,实现了executeConnectPoint()方法和shutdownconnectPoint()方法,其中executeConnectPoint()主要为ribbon做参数处理,DefaultRibbonConnectionPoint()则是做一些清理,其中executeConnectPoint()实现如下
            
其中在executeConnectPoint()方法中可以看到一个List<LoadBalanceRequestTrigger>,spring-cloud-bamboo提供一个LoadBalanceRequestTrigger接口,用户可以实现这个接口,这个接口的实现将会在ribbon请求发起时被执行。
BambooPostZuulFilter主要是在zuul在路由完请求执行的,bamboo主要在这个类中调用了DefaultRibbonConnectionPoint的shutdownconnectPoint()方法去清理了Threadlocal里的参数清理,此处不再赘述。
2.Feign
在bamboo.feign.config目录可以找到bamboo关于feign做的衔接配置,代码如下

首先用@EnableFeignClients指明了Feign的配置类来代替默认的配置,在BambooFeignClientsConfiguration中bamboo注入了默认的FeignClient,通过注入的FeignClient去构造了BambooFeignClient,启用了BambooFeignClient去执行请求,源码如下

通过源码我们可以发现,bamboo未对原来的feign做任何的修改,只是加入了ribbon版本过滤所需的参数构造逻辑,最终还是delegate.execute(request, options)去执行,有关参数构造的问题此处不再赘述,有兴趣的话可以去阅读源码。
3.restTemplate
默认ribbon的对restTemplate的处理为,构造了一个LoadBalancerInterceptor类去执行了ribbon逻辑,而bamboo已经对ribbon的负载均衡规则做了扩展实现了多版本控制,所以此处只需要构造一个ClientHttpRequestInterceptor的实现去构造ribbon多版本过滤的参数就行,bamboo实现的代码如下
四、关于version的设置和获取
bamboo对version的设置为通过eureka的eureka.instance.metadata-map设置,多版本用逗号分割,这是利用了eureka的元数据特性,服务消费者可以从eureka上获取到version来进行过滤。
bamboo对获取用户请求的version提供了一个接口,源码如下图

bamboo默认是通过queryString获取的,用户可根据需求来实现这个接口去做扩展或者修改默认内部类的实现。

个人博客地址:http://xuyangyang.club(点击打开)

微信订阅号:

                

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Gateway 是一个基于 Spring Framework 5、Spring Boot 2 和 Project Reactor 的 API 网关服务。它提供了一种简单而强大的方法来路由和过滤请求,并将它们转发到底层的微服务。对于理解 Spring Cloud Gateway 的工作原理和深入研究其源代码是非常有用的。 首先,通过源码可以发现 Spring Cloud Gateway 主要由三个核心模块组成:路由模块、过滤器模块和事件模块。路由模块负责根据定义的路由规则将请求转发到特定的目标地址。过滤器模块负责在请求的不同阶段执行一系列的过滤器来处理请求。事件模块则用于处理与路由和过滤器相关的异步事件。 源码中的路由模块使用了 Reactive Streams API 中的 Flux 和 Mono 类来处理异步操作。它利用 RouterFunction 和 HandlerFunction 来定义路由和处理请求的方法,并通过 RoutePredicateFactory 来解析和匹配路由规则。在路由模块中,使用了 Netty 库来实现底层的网络通信和请求转发。 通过源码分析过滤器模块,可以发现 Spring Cloud Gateway 的过滤器分为全局过滤器和自定义过滤器两种类型。全局过滤器在请求的全局范围内应用,并且可以用于添加一些全局的处理逻辑。自定义过滤器则允许开发者根据需要添加自定义的过滤逻辑。过滤器的执行顺序可以通过 Order 注解来控制,以满足不同过滤器的执行顺序需求。 事件模块在源码中使用了 Reactor 提供的 EventProcessor 来处理与路由和过滤器相关的事件。它使用了 Reactor 的 FluxSink 和 MonoSink 来创建异步事件源,并通过事件处理器将事件发送给注册的监听器。通过查看事件模块的源码,可以更加深入地了解 Spring Cloud Gateway 是如何处理与路由和过滤器相关的事件的。 总结而言,通过源码分析 Spring Cloud Gateway,我们可以更好地了解其内部的工作原理和实现细节。这对于开发者来说是非常有用的,因为它可以帮助我们更好地使用和扩展 Spring Cloud Gateway 来满足不同的场景需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值