【ci框架源码阅读】【社区卡密源码】【基于 angularjs 项目源码】ribbon执行源码

时间:2024-12-28 22:23:35 来源:技术源码指标 分类:探索

1.【SpringCloud原理】OpenFeign原来是执行这么基于Ribbon来实现负载均衡的
2.ribbon负载均衡详解
3.netflix已经有了feign这个httpclient,为什么还要开发ribb
4.SpringCloud(3):使用Ribbon进行负载均衡配置,以及遇坑指南
5.Ribbon负载均衡分析
6.springcloud中使用nacos做服务发现,源码其中“lb://”是什么连

ribbon执行源码

【SpringCloud原理】OpenFeign原来是这么基于Ribbon来实现负载均衡的

       欢迎来到本篇文章,之前我们已经深入探讨了OpenFeign的执行动态代理生成原理和Ribbon的运行机制。若要对OpenFeign的源码动态代理生成原理和Ribbon的运行原理有更深入的了解,可关注微信公众号“三友的执行java日记”,通过菜单栏查看整理的源码ci框架源码阅读相关内容。接下来,执行我们将继续深入SpringCloud组件原理,源码探讨OpenFeign是执行如何利用Ribbon实现负载均衡的,以及两组件如何协同工作的源码。

       一、执行Feign动态代理调用实现rpc流程解析

       我们从Feign客户端接口的源码动态代理生成原理出发,了解到动态代理基于JDK实现,执行所有方法调用最终都会调用到InvocationHandler接口的源码实现,即ReflectiveFeign.FeignInvocationHandler。执行接下来,我们将深入探讨FeignInvocationHandler如何实现rpc调用。

       FeignInvocationHandler通过invoke方法实现动态代理功能,其主要逻辑如下:

       1. 对于调用的方法是否为equals、hashCode、toString等特殊方法进行判断,社区卡密源码若为则无需走rpc调用。

       2. 从dispatch获取调用方法对应的MethodHandler,然后调用MethodHandler的invoke方法。

       3. MethodHandler在构建动态代理时生成,作用是最终实现rpc调用,每个方法有对应的MethodHandler。

       4. SynchronousMethodHandler是实现rpc调用的关键类,通过构造RequestTemplate、Options和重试组件,发起.netflix.client.conf.CommonClientConfigKey。

        <clientName>.<nameSpace>.NFLoadBalancerClassName=xx

        <clientName>.<nameSpace>.NFLoadBalancerRuleClassName=xx

        <clientName>.<nameSpace>.NFLoadBalancerPingClassName=xx

        <clientName>.<nameSpace>.NIWSServerListClassName=xx

        <clientName>.<nameSpace>.NIWSServerListFilterClassName=xx

        com.netflix.client.config.IClientConfig:Ribbon的客户端配置,默认采用com.netflix.client.config.DefaultClientConfigImpl实现。

        com.netflix.loadbalancer.IRule:Ribbon的负载均衡策略,默认采用com.netflix.loadbalancer.ZoneAvoidanceRule实现,该策略能够在多区域环境下选出最佳区域的实例进行访问。

        com.netflix.loadbalancer.IPing:Ribbon的实例检查策略,默认采用com.netflix.loadbalancer.NoOpPing实现,该检查策略是一个特殊的实现,实际上它并不会检查实例是否可用,而是始终返回true,默认认为所有服务实例都是可用的。

        com.netflix.loadbalancer.ServerList:服务实例清单的维护机制,默认采用com.netflix.loadbalancer.ConfigurationBasedServerList实现。

        com.netflix.loadbalancer.ServerListFilter:服务实例清单过滤机制,默认采org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter,该策略能够优先过滤出与请求方处于同区域的服务实例。

        com.netflix.loadbalancer.ILoadBalancer:负载均衡器,默认采用com.netflix.loadbalancer.ZoneAwareLoadBalancer实现,它具备了区域感知的能力。

        上面的配置是在项目中没有引入spring Cloud Eureka,如果引入了Eureka和Ribbon依赖时,自动化配置会有一些不同。

        通过自动化配置的实现,可以轻松的实现客户端的负载均衡。同时,针对一些个性化需求,我们可以方便的替换上面的这些默认实现,只需要在springboot应用中创建对应的实现实例就能覆盖这些默认的配置实现。

        @Configuration

        public class MyRibbonConfiguration {

            @Bean

            public IRule ribbonRule(){

                return new RandomRule();

            }

        }

        这样就会使用P使用了RandomRule实例替代了默认的com.netflix.loadbalancer.ZoneAvoidanceRule。

        也可以使用@RibbonClient注解实现更细粒度的客户端配置

       å¯¹äºŽRibbon的参数通常有二种方式:全局配置以及指定客户端配置

        全局配置的方式很简单

        只需要使用ribbon.<key>=<value>格式进行配置即可。其中,<key>代表了Ribbon客户端配置的参数名,<value>则代表了对应参数的值。比如,我们可以想下面这样配置Ribbon的超时时间

        ribbon.ConnectTimeout=

        ribbon.ServerListRefreshInterval=   ribbon获取服务定时时间

        全局配置可以作为默认值进行设置,当指定客户端配置了相应的key的值时,将覆盖全局配置的内容

        指定客户端的配置方式

        <client>.ribbon.<key>=<value>的格式进行配置.<client>表示服务名,比如没有服务治理框架的时候(如Eureka),我们需要指定实例清单,可以指定服务名来做详细的配置,

        user-service.ribbon.listOfServers=localhost:,localhost:,localhost:

        对于Ribbon参数的key以及value类型的定义,可以通过查看com.netflix.client.config.CommonClientConfigKey类。

        当在spring Cloud的应用同时引入Spring cloud Ribbon和Spring Cloud Eureka依赖时,会触发Eureka中实现的对Ribbon的自动化配置。这时的serverList的维护机制实现将被com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList的实例所覆盖,该实现会讲服务清单列表交给Eureka的服务治理机制来进行维护。IPing的实现将被com.netflix.niws.loadbalancer.NIWSDiscoveryPing的实例所覆盖,该实例也将实例接口的任务交给了服务治理框架来进行维护。默认情况下,用于获取实例请求的ServerList接口实现将采用Spring Cloud Eureka中封装的org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList,其目的是为了让实例维护策略更加通用,所以将使用物理元数据来进行负载均衡,而不是使用原生的AWS AMI元数据。在与Spring cloud Eureka结合使用的时候,不需要再去指定类似的user-service.ribbon.listOfServers的参数来指定具体的服务实例清单,因为Eureka将会为我们维护所有服务的实例清单,而对于Ribbon的参数配置,我们依然可以采用之前的两种配置方式来实现。

        此外,由于spring Cloud Ribbon默认实现了区域亲和策略,所以,可以通过Eureka实例的元数据配置来实现区域化的实例配置方案。比如可以将不同机房的实例配置成不同的区域值,作为跨区域的容器机制实现。而实现也非常简单,只需要服务实例的元数据中增加zone参数来指定自己所在的区域,比如:

        eureka.instance.metadataMap.zone=shanghai

        在Spring Cloud Ribbon与Spring Cloud Eureka结合的工程中,我们可以通过参数禁用Eureka对Ribbon服务实例的维护实现。这时又需要自己去维护服务实例列表了。

        ribbon.eureka.enabled=false.

        由于Spring Cloud Eureka实现的服务治理机制强调了cap原理的ap机制(即可用性和可靠性),与zookeeper这类强调cp(一致性,可靠性)服务质量框架最大的区别就是,Eureka为了实现更高的服务可用性,牺牲了一定的一致性,在极端情况下宁愿接受故障实例也不要丢弃"健康"实例。

        比如说,当服务注册中心的网络发生故障断开时候,由于所有的服务实例无法维护续约心跳,在强调ap的服务治理中将会把所有服务实例剔除掉,而Eureka则会因为超过%的实例丢失心跳而触发保护机制,注册中心将会保留此时的所有节点,以实现服务间依然可以进行互相调用的场景,即使其中有部分故障节点,但这样做可以继续保障大多数服务的正常消费。

        在Camden版本,整合了spring retry来增强RestTemplate的重试能力,对于我们开发者来说,只需要简单配置,即可完成重试策略。

        spring.cloud.loadbalancer.retry.enabled=true

        hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=

        user-service.ribbon.ConnectTimeout=

        user-service.ribbon.ReadTimeout=

        user-service.ribbon.OkToRetryOnAllOperations=true

        user-service.ribbon.MaxAutoRetriesNextServer=2

        user-service.ribbon.maxAutoRetries=1

        spring.cloud.loadbalancer.retry.enabled:该参数用来开启重试机制,它默认是关闭的。

        hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds:断路器的超时时间需要大于Ribbon的超时时间,不然不会触发重试。

        user-service.ribbon.ConnectTimeout:请求连接超时时间。

        user-service.ribbon.ReadTimeout:请求处理的超时时间

        user-service.ribbon.OkToRetryOnAllOperations:对所有操作请求都进行重试。

        user-service.ribbon.MaxAutoRetriesNextServer:切换实例的重试次数。

        user-service.ribbon.maxAutoRetries:对当前实例的重试次数。

        根据以上配置,当访问到故障请求的时候,它会再尝试访问一次当前实例(次数由maxAutoRetries配置),如果不行,就换一个实例进行访问,如果还是不行,再换一个实例访问(更换次数由MaxAutoRetriesNextServer配置),如果依然不行,返回失败

       é¡¹ç›®å¯åŠ¨çš„时候会自动的为我们加载LoadBalancerAutoConfiguration自动配置类,该自动配置类初始化条件是要求classpath必须要有RestTemplate这个类,必须要有LoadBalancerClient实现类。

        LoadBalancerAutoConfiguration为我们干了二件事,第一件是创建了LoadBalancerInterceptor拦截器bean,用于实现对客户端发起请求时进行拦截,以实现客户端负载均衡。创建了一个

        RestTemplateCustomizer的bean,用于给RestTemplate增加LoadBalancerInterceptor拦截器。

        每次请求的时候都会执行org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor的intercept方法,而LoadBalancerInterceptor具有LoadBalancerClient(客户端负载客户端)实例的一个引用,

        在拦截器中通过方法获取服务名的请求url(比如/p/1bddb5dc

        Spring cloud系列六 Ribbon的功能概述、主要组件和属性文件配置  

       /p/faffa

        本人有道云笔记中记录的参考文章

        文档:_ribbon 负载均衡.note

        链接:/noteshare?id=efc3efbbefd8ed0b9&sub=B0E6DFEEBDAF

netflix已经有了feign这个httpclient,为什么还要开发ribb

       Feign与Ribbon在设计上定位不同,Feign主打远程过程调用(RPC),虽然基于HTTP,但能屏蔽请求细节,用户只需声明接口,即可实现远程服务调用,无需关心HTTP请求细节或参数封装。而Ribbon则专注于负载均衡,RPC功能不是其强项,其主要优势在于从注册中心获取服务实例。二者互补,基于 angularjs 项目源码Feign无需Ribbon也能实现调用,只需指定服务IP和端口;Ribbon也无需Feign,但需实现HTTP请求参数封装。选择两者结合,源于解耦和单一职责原则。

       整合原理可参考相关文章。本文继续解析SpringCloud组件原理,重点剖析OpenFeign如何基于Ribbon实现负载均衡,以及二者如何协同工作。

       一、Feign动态代理调用实现RPC流程分析

       Feign客户端接口的动态代理生成基于JDK动态代理,通过FeignInvocationHandler实现方法调用。FeignInvocationHandler对invoke方法的实现避免了不需要RPC调用的方法(如equals、hashCode、toString)。通过dispatch获取要调用方法对应的MethodHandler,执行MethodHandler的invoke方法。MethodHandler在构建动态代理时生成,负责实现RPC调用。SynchronousMethodHandler处理RPC调用,免费主播源码其invoke方法构建RequestTemplate,封装HTTP请求参数。执行findOptions(argv)获取配置参数,使用重试组件,最后调用Client接口实现请求发送。

       二、LoadBalancerFeignClient

       Feign动态代理调用的关键在于Client,用于发送HTTP请求。通过分析可知,Feign客户端构建动态代理时,填充组件包括LoadBalancerFeignClient,实现Ribbon整合。FeignRibbonClientAutoConfiguration配置类导入相关组件并声明LoadBalancerFeignClient,注入Client实现、CachingSpringLoadBalancerFactory和SpringClientFactory,构建Feign.Builder的实现。

       LoadBalancerFeignClient实现整合过程,获取服务名,调用CachingSpringLoadBalancerFactory创建FeignLoadBalancer,实现负载均衡与请求发送。snake vs block源码

       三、FeignLoadBalancer

       FeignLoadBalancer为核心组件,负责选择负载均衡并发送HTTP请求。执行executeWithLoadBalancer重构请求路径,调用execute方法,基于特定Client实现发送请求,最终返回RibbonResponse。

       四、总结

       本文全面解析了OpenFeign、Ribbon以及Nacos组件在微服务架构中的协同工作原理。OpenFeign实现RPC调用时,Ribbon从注册中心获取服务实例列表,实现负载均衡。Ribbon与Nacos(或其它注册中心)协同工作,确保服务发现和负载均衡的高效执行。通过本文,读者应能理解这三个组件在微服务架构中的作用,并对它们的源码有基本认识。

SpringCloud(3):使用Ribbon进行负载均衡配置,以及遇坑指南

       使用Ribbon进行负载均衡配置是Spring Cloud体系中的一种关键实践。由于Eureka中已经集成了Ribbon,因此无需额外引入依赖。启动多个服务提供方时,在服务消费方的启动类中启用@LoadBalanced注解来激活负载均衡机制。将@LoadBalanced注解添加到消费方的RestTemplate方法上,即可实现通过服务名调用提供方的服务。

       在配置过程中,服务消费方通常使用DiscoveryClient来获取提供方的服务列表,并通过该列表指定具体的服务实例及其主机和端口。然而,开启负载均衡后,系统会自动选择合适的服务实例,无需人工指定,以提升服务调用的效率和可用性。

       值得注意的是,一旦使用了@LoadBalanced注解,直接访问提供方的特定主机名和端口号会引发异常(如java.lang.IllegalStateException: No instances available for localhost)。同时,服务名中应避免使用下划线,否则可能会遇到请求URI格式错误(如Request URI does not contain a valid hostname: service_provider/user/4...)的问题。

       在消费方控制器中,实现远程服务调用时,负载均衡效果通过LoadBalancerInterceptor和RibbonLoadBalancerClient类的源码展现。RibbonLoadBalancerClient通过默认的轮询策略分配服务实例,而其他策略如随机策略则可以在消费方配置文件中进行指定。重新运行测试用例后,负载均衡策略的切换效果明显。

       深入RibbonLoadBalancerClient源码,可以观察到通过BaseLoadBalancer类的chooseServer方法调用rule接口以执行负载均衡策略,其中轮询策略(RoundRobinRule)是默认设置。除了轮询策略之外,随机策略等其他负载均衡策略也可通过配置文件进行选择,以适应不同场景的需求。在实践过程中,通过测试和调整配置,可以有效提升服务调用的负载均衡效果。

Ribbon负载均衡分析

       Ribbon使用介绍

       Ribbon的使用非常简单,只需要在配置类中添加相应的配置即可。调用时,通过服务名在Eureka中注册的服务进行调用,Ribbon则自动进行负载均衡。以zhao-service-resume项目为例,开启多个服务实例并打印请求信息,即能观察到负载均衡的效果。Ribbon默认采用随机负载均衡策略(RandomRule),该策略全局生效,但可根据需求为不同服务设置不同的负载均衡策略。

       Ribbon源码解析

       自动装配类是配置加载的入口,例如LoadBalancerAutoConfiguration类。通过配置,LoadBalancerAutoConfiguration会自动注入带有@LoadBalanced注解的RestTemplate对象,并注入定制器RestTemplateCustomizer。在定制器代码中,添加了ClientHttpRequestInterceptor拦截器,该拦截器根据请求路径和地址执行负载均衡逻辑。最终,执行负载均衡策略选择服务端进行请求,实现负载均衡。服务列表的获取与更新在RibbonAutoConfigration中的SpringClientFactory和RibbonClientConfiguration类中实现,通过定时任务在ZoneAwareLoadBalancer的父类DynamicServerListLoadBalancer中重新赋值与更新服务列表。

springcloud中使用nacos做服务发现,其中“lb://”是什么连

       在Spring Cloud中,当使用Nacos作为服务发现机制时,你可能会遇到"lb://"这样的标记。这个标记代表了负载均衡。当配置文件中出现这样的标记时,Spring Cloud Gateway理解为需要执行负载均衡策略,并将请求转发到服务名对应的某个服务器。其实,负载均衡的实现依赖于负载均衡组件,如Ribbon或Spring Cloud LoadBalancer,它们通过获取服务列表来完成负载均衡操作。

       请注意,"lb://"这一标识与服务注册中心并无直接关联。无论是使用Nacos、Eureka还是其他注册中心,"lb://"的用法都是一样的。这个标记告诉Spring Cloud Gateway执行负载均衡,并将请求转发至对应的服务实例。

       至于Ribbon能够获取到服务注册列表的原因,是因为服务注册中心需要与之进行适配。Nacos、Eureka等注册中心通常都与Ribbon进行了良好的适配,因此,你无需关心具体实现细节。如果你对这部分内容感兴趣,可以查看我在微信公众号“三友的Java日记”中发布的文章《一文带你看懂Nacos是如何整合Spring Cloud——注册中心篇》。这篇文章详细阐述了Nacos如何适配Ribbon,帮助你了解整个流程。

       为了更深入理解Ribbon的负载均衡原理,你可以参考下面的资源:

       Spring Cloud原理Ribbon核心组件以及运行原理源码剖析