0。环境nacos版本:1。4。1SpringCloud:Hoxton。SR9SpringBoot:2。4。4SpringCloudalibaba:2。2。5。RELEASESpringCloudopenFeign2。2。2。RELEASE 测试代码:github。comhsfxuebaos1。Ribbon的工作流程 我们知道,微服务在启动成功之后,默认30s次会从注册中心拉取服务注册表到本地缓存起来,而我们使用Ribbon时是通过RestTemplate发起请求,URL以:http:userserveruser。。。服务名方式去调用服务,其实Ribbon干的事情就是根据URL中的服务名去本地的服务注册表中查找服务名对应的服务实例(一个或多个),然后通过负载均衡算法选择其中一个服务后,发起Http请求,那接下来我们就来看一下Ribbon的底层到底是怎么工作的2。Ribbon配合RestTemplate使用 首选需要定义RestTemplateSpringBootApplicationEnableEurekaClientpublicclassOrderServerApplication1030{配置一个RestTemplate,http客户端,支持Rest风格LoadBalanced:负载均衡注册,让RestTmplate可以实现负载均衡请求这个标签标记RestTemplate可以使用LoadBalancerClient进行负载均衡BeanLoadBalancedpublicRestTemplaterestTemplate(){returnnewRestTemplate();}省略。。。}复制代码 调用服务的是否使用服务名调用:RestControllerpublicclassOrderController{需要配置成BeanAutowiredprivateRestTemplaterestT浏览器调用该方法RequestMapping(valueorder{id},methodRequestMethod。GET)publicUsergetById(PathVariable(id)Longid){发送http请求调用user的服务,获取user对象:RestTemplateuser的ip,user的端口,user的Controller路径Stringurlhttp:localhost:1020Stringurlhttp:发送http请求returnrestTemplate。getForObject(url,User。class);}}复制代码 被LoadBalanced标记的RestTemplate可以使用LoadBalancerClient负载均衡客户端实现负载均衡,我们在使用RestTemplate发起请求的时候需要跟上服务名的方式http:userserveruser3。LoadBalancerClient负载均衡客户端 我们从LoadBalanced入手,先看一下LoadBalancerClient它的源码。注解标记RestTemplate可以使用LoadBalancerClient负载均衡客户端AnnotationtomarkaRestTemplatebeantobeconfiguredtouseaLoadBalancerClientauthorSpencerGibbTarget({ElementType。FIELD,ElementType。PARAMETER,ElementType。METHOD})Retention(RetentionPolicy。RUNTIME)DocumentedInheritedQualifierpublicinterfaceLoadBalanced{}复制代码 这个注解LoadBalanced的作用在注释上说得非常清楚,就是标记RestTemplate可以使用使用LoadBalancerClient来实现负载均衡,LoadBalancerClient就是Ribbon实现负载均衡的一个客户端,它在springcloudcommons包下,我们可以直接看LoadBalancerClient的源码:客户端负载均衡RepresentsaclientsideloadbalancerauthorSpencerGibbpublicinterfaceLoadBalancerClientextendsServiceInstanceChooser{执行请求,会根据serviceId使用负载均衡查找服务使用负载均衡器执行指定服务executerequestusingaServiceInstancefromtheLoadBalancerforthespecifiedservice服务Id服务ID来查找负载平衡器paramserviceIdtheserviceidtolookuptheLoadBalancerparamrequestallowsimplementationstoexecutepreandpostactionssuchasincrementingmetrics返回选择的服务returntheresultoftheLoadBalancerRequestcallbackontheselectedServiceInstanceTTexecute(StringserviceId,LoadBalancerRequestTrequest)throwsIOE执行请求,这个方法多了一个参数ServiceInstance,即请求指定的服务executerequestusingaServiceInstancefromtheLoadBalancerforthespecifiedserviceparamserviceIdtheserviceidtolookuptheLoadBalancerparamserviceInstancetheservicetoexecutetherequesttoparamrequestallowsimplementationstoexecutepreandpostactionssuchasincrementingmetricsreturntheresultoftheLoadBalancerRequestcallbackontheselectedServiceInstanceTTexecute(StringserviceId,ServiceInstanceserviceInstance,LoadBalancerRequestTrequest)throwsIOE重构URL,把http:myservicepathtoservice重构成http:ip:端口pathtoserviceCreateaproperURIwitharealhostandportforsystemstoutilize。SomesystemsuseaURIwiththelogicalserivcenameasthehost,suchashttp:myservicepathtoservice。Thiswillreplacetheservicenamewiththehost:portfromtheServiceInstance。paraminstanceparamoriginalaURIwiththehostasalogicalservicenamereturnareconstructedURIURIreconstructURI(ServiceInstanceinstance,URIoriginal);}复制代码 LoadBalancerClient接口三个方法,excute()为执行请求,reconstructURI()用来重构url,它实现了ServiceInstanceChooser接口,这个接口的作用是用来选择服务的,看下源码通过使用负载平衡器,选择一个服务器发送请求。Implementedbyclasseswhichusealoadbalancertochooseaservertosendarequestto。authorRyanBaxterpublicinterfaceServiceInstanceChooser{从LoadBalancer中为指定服务选择一个ServiceInstanceChooseaServiceInstancefromtheLoadBalancerforthespecifiedservice根据服务id去LoadBalancer查找服务paramserviceIdtheserviceidtolookuptheLoadBalancer返回查找到的服务实例ServiceInstancereturnaServiceInstancethatmatchestheserviceIdServiceInstancechoose(StringserviceId);}复制代码 提供了一个choose方法,根据服务IDserviceId查找一个ServiceInstance服务实例,这里的serviceId其实就是http:userserverurl中带的服务名。 LoadBalancerClient还有一个默认实现类RibbonLoadBalancerClient,这个实现是针对Ribbon的客户端负载均衡,继承关系如下: RibbonLoadBalancerClient是一个非常核心的类,最终的负载均衡的请求处理由它来执行,源码如下:publicclassRibbonLoadBalancerClientimplementsLoadBalancerClient{privateSpringClientFactoryclientFpublicRibbonLoadBalancerClient(SpringClientFactoryclientFactory){this。clientFactoryclientF}重构URL,找到服务之后,把http:服务名格式重构成http:ip:port格式OverridepublicURIreconstructURI(ServiceInstanceinstance,URIoriginal){Assert。notNull(instance,instancecannotbenull);StringserviceIdinstance。getServiceId();RibbonLoadBalancerContextcontextthis。clientFactory。getLoadBalancerContext(serviceId);URISif(instanceinstanceofRibbonServer){RibbonServerribbonServer(RibbonServer)serverribbonServer。getServer();uriupdateToSecureConnectionIfNeeded(original,ribbonServer);}else{servernewServer(instance。getScheme(),instance。getHost(),instance。getPort());IClientConfigclientConfigclientFactory。getClientConfig(serviceId);ServerIntrospectorserverIntrospectorserverIntrospector(serviceId);uriupdateToSecureConnectionIfNeeded(original,clientConfig,serverIntrospector,server);}returncontext。reconstructURIWithServer(server,uri);}根据服务名,查找服务实例,选择一个返回ServiceInstanceOverridepublicServiceInstancechoose(StringserviceId){查找服务ServerservergetServer(serviceId);if(servernull){}returnnewRibbonServer(serviceId,server,isSecure(server,serviceId),serverIntrospector(serviceId)。getMetadata(server));}执行请求OverridepublicTTexecute(StringserviceId,LoadBalancerRequestTrequest)throwsIOException{获取负载均衡器〔重要〕ILoadBalancerloadBalancergetLoadBalancer(serviceId);选择服务,使用负载均衡器,根据服务的ID,选择一个服务ServerservergetServer(loadBalancer);if(servernull){thrownewIllegalStateException(NoinstancesavailableforserviceId);}选择的服务封装成一个RibbonServer:RibbonServerimplementsServiceInstanceRibbonServerribbonServernewRibbonServer(serviceId,server,isSecure(server,serviceId),serverIntrospector(serviceId)。getMetadata(server));执行请求调用服务returnexecute(serviceId,ribbonServer,request);}执行请求调用服务OverridepublicTTexecute(StringserviceId,ServiceInstanceserviceInstance,LoadBalancerRequestTrequest)throwsIOException{Sif(serviceInstanceinstanceofRibbonServer){server((RibbonServer)serviceInstance)。getServer();}if(servernull){thrownewIllegalStateException(NoinstancesavailableforserviceId);}RibbonLoadBalancerContextcontextthis。clientFactory。getLoadBalancerContext(serviceId);RibbonStatsRecorderstatsRecordernewRibbonStatsRecorder(context,server);try{使用LoadBalancerRequest向服务发请求TreturnValrequest。apply(serviceInstance);statsRecorder。recordStats(returnVal);returnreturnV}catchIOExceptionandrethrowsoRestTemplatebehavescorrectlycatch(IOExceptionex){statsRecorder。recordStats(ex);}catch(Exceptionex){statsRecorder。recordStats(ex);ReflectionUtils。rethrowRuntimeException(ex);}}privateServerIntrospectorserverIntrospector(StringserviceId){ServerIntrospectorserverIntrospectorthis。clientFactory。getInstance(serviceId,ServerIntrospector。class);if(serverIntrospectornull){serverIntrospectornewDefaultServerIntrospector();}returnserverI}是否是https请求privatebooleanisSecure(Serverserver,StringserviceId){IClientConfigconfigthis。clientFactory。getClientConfig(serviceId);ServerIntrospectorserverIntrospectorserverIntrospector(serviceId);returnRibbonUtils。isSecure(config,serverIntrospector,server);}根据服务ID选择服务protectedServergetServer(StringserviceId){returngetServer(getLoadBalancer(serviceId));}负载均衡器选择服务protectedServergetServer(ILoadBalancerloadBalancer){if(loadBalancernull){}returnloadBalancer。chooseServer(default);TODO:betterhandlingofkey}根据服务id得到负载均衡器protectedILoadBalancergetLoadBalancer(StringserviceId){returnthis。clientFactory。getLoadBalancer(serviceId);}。。。省略。。。复制代码 解释一下: 这里的ServiceInstancechoose(StringserviceId)方法的作用是根据ServideId选择一个服务,底层实现是通过LoadBalancer。chooseServer负载均衡器LoadBalancer来完成的服务的选择的 选择到服务之后调用execute向选择到的服务发起请求,通过LoadBalancerRequest来完成其请求。4。RestTemplate的执行流程 RestTmplate发请求时地址http:userserveruserid中userserver是当前服务需要调用的目标服务的服务名,那么Ribbon到底是如何实现负载均衡调用的呢?我们可以从这里跟踪一下RestTemplate的执行流程:publicclassRestTemplateextendsInterceptingHttpAccessorimplementsRestOperations{。。。省略。。。NullableprotectedTTdoExecute(URIurl,NullableHttpMethodmethod,NullableRequestCallbackrequestCallback,NullableResponseExtractorTresponseExtractor)throwsRestClientException{Assert。notNull(url,URIisrequired);Assert。notNull(method,HttpMethodisrequired);ClientHttpRObjectvar14;try{创建请求对象,使用SimpleClientHttpRequestFactory创建ClientHttpRequestClientHttpRequestrequestthis。createRequest(url,method);if(requestCallback!null){设置header和bodyrequestCallback。doWithRequest(request);}responserequest。execute();this。handleResponse(url,method,response);var14responseExtractor!null?responseExtractor。extractData(response):}catch(IOExceptionvar12){Stringresourceurl。toString();Stringqueryurl。getRawQuery();resourcequery!null?resource。substring(0,resource。indexOf(63)):thrownewResourceAccessException(IOerroronmethod。name()requestforresource:var12。getMessage(),var12);}finally{if(response!null){response。close();}}returnvar14;}复制代码 请求来到RestTemplatedoExecute方法,首选是通过使用SimpleClientHttpRequestFactory根据url和method创建ClientHttpRequest请求对象,使用的实现是InterceptingClientHttpRequestFactory,然后使用responserequest。execute();去执行请求,一路跟踪,请求来到InterceptingClientHttpRequestexecuteInternal:classInterceptingClientHttpRequestextendsAbstractBufferingClientHttpRequest{headers请求头,bufferedOutput输出内容protectedfinalClientHttpResponseexecuteInternal(HttpHeadersheaders,byte〔〕bufferedOutput)throwsIOException{创建拦截器执行器InterceptingClientHttpRequest。InterceptingRequestExecutionrequestExecutionnewInterceptingClientHttpRequest。InterceptingRequestExecution();returnrequestExecution。execute(this,bufferedOutput);}复制代码 这里通过InterceptingClientHttpRequest。InterceptingRequestExecution()拦截器执行器去执行请求,请求来到InterceptingClientHttpRequest。InterceptingRequestExecutionexecute:privateclassInterceptingRequestExecutionimplementsClientHttpRequestExecution{privatefinalIteratorClientHttpRequestIpublicInterceptingRequestExecution(){this。iteratorInterceptingClientHttpRequest。this。interceptors。iterator();}publicClientHttpResponseexecute(HttpRequestrequest,byte〔〕body)throwsIOException{if(this。iterator。hasNext()){〔重要〕这里取到的正是LoadBalancerInterceptorClientHttpRequestInterceptornextInterceptor(ClientHttpRequestInterceptor)this。iterator。next();returnnextInterceptor。intercept(request,body,this);}else{HttpMethodmethodrequest。getMethod();Assert。state(method!null,NostandardHTTPmethod);如果iterator中没有拦截器了,就创建一个ClientHttpRequest去执行请求ClientHttpRequestdelegateInterceptingClientHttpRequest。this。requestFactory。createRequest(request。getURI(),method);request。getHeaders()。forEach((key,value){delegate。getHeaders()。addAll(key,value);});if(body。length0){if(delegateinstanceofStreamingHttpOutputMessage){StreamingHttpOutputMessagestreamingOutputMessage(StreamingHttpOutputMessage)streamingOutputMessage。setBody((outputStream){StreamUtils。copy(body,outputStream);});}else{StreamUtils。copy(body,delegate。getBody());}}执行请求returndelegate。execute();}}}复制代码 InterceptingRequestExecution中维护了一个I其中LoadBalancerInterceptor就在该集合中,所以请求来到LoadBalancerInterceptorintercept(request,body,this);方法负载均衡拦截器publicclassLoadBalancerInterceptorimplementsClientHttpRequestInterceptor{负载均衡客户端〔重要〕privateLoadBalancerClientloadB负载均衡请求创建工厂privateLoadBalancerRequestFactoryrequestF初始化publicLoadBalancerInterceptor(LoadBalancerClientloadBalancer,LoadBalancerRequestFactoryrequestFactory){this。loadBalancerloadBthis。requestFactoryrequestF}初始化publicLoadBalancerInterceptor(LoadBalancerClientloadBalancer){forbackwardscompatibilitythis(loadBalancer,newLoadBalancerRequestFactory(loadBalancer));}拦截器核心方法【重要】request请求对象body内容OverridepublicClientHttpResponseintercept(finalHttpRequestrequest,finalbyte〔〕body,finalClientHttpRequestExecutionexecution)throwsIOException{请求的URL,格式如:http:userserveruser1,userserver是服务名finalURIoriginalUrirequest。getURI();URL中的服务名StringserviceNameoriginalUri。getHost();Assert。state(serviceName!null,RequestURIdoesnotcontainavalidhostname:originalUri);通过requestFactory。createRequest(request,body,execution)创建LoadBalancerRequest然后调用负载均衡器执行请求,参数:服务名,LoadBalancerRequestreturnthis。loadBalancer。execute(serviceName,requestFactory。createRequest(request,body,execution));}}复制代码 这里蛮重要的,请求调用了LoadBalancerInterceptorintercept负载均衡拦截器的拦截方法,获取到URL,从中获取到主机名即调用的服务名(Ribbon客户端服务名),然后使用LoadBalancerRequestFactory创建了LoadBalancerRequest请求对象,调用loadBalancerexecute负载均衡器执行请求5。ILoadBalancer选择服务(负载均衡) 请求来到RibbonLoadBalancerClientexecute:OverridepublicTTexecute(StringserviceId,LoadBalancerRequestTrequest)throwsIOException{获取负载均衡器ILoadBalancerloadBalancergetLoadBalancer(serviceId);loadBalancer选择服务ServerservergetServer(loadBalancer);if(servernull){thrownewIllegalStateException(NoinstancesavailableforserviceId);}选择的服务封装成RibbonServerRibbonServerribbonServernewRibbonServer(serviceId,server,isSecure(server,serviceId),serverIntrospector(serviceId)。getMetadata(server));LoadBalancerRequest对服务执行请求returnexecute(serviceId,ribbonServer,request);}复制代码 这里就蛮关键了:首选是通过服务名调用getLoadBalancer方法得到负载均衡器然后getServer(loadBalancer)是通过负载均衡器选择一个服务,底层会使用IRule的算法然后将服务封装成RibbonServer对象,交给LoadBalancerRequest去执行请求 这里的负载均衡器默认会走ZoneAwareLoadBalancer,它是通过SpringClientFactory从Ribbon上下文对象中获取到的负载均衡器对象,关于这个我们在上一章讨论过publicclassRibbonLoadBalancerClientimplementsLoadBalancerClient{。。。省略。。。privateSpringClientFactoryclientFprotectedILoadBalancergetLoadBalancer(StringserviceId){returnthis。clientFactory。getLoadBalancer(serviceId);}复制代码 而得到ILoadBalancer之后,调用getServer(loadBalancer)方法选择服务,我们跟踪一下publicclassRibbonLoadBalancerClientimplementsLoadBalancerClient{。。。省略。。。protectedServergetServer(ILoadBalancerloadBalancer){if(loadBalancernull){}ZoneAwareLoadBalancerchooseServerreturnloadBalancer。chooseServer(default);TODO:betterhandlingofkey}复制代码 这里loadBalancer。chooseServer(default);请求来到ZoneAwareLoadBalancerchooseServer,源码如下:publicclassZoneAwareLoadBalancerTextendsServerextendsDynamicServerListLoadBalancerT{。。。省略。。。OverridepublicServerchooseServer(Objectkey){if(!ENABLED。get()getLoadBalancerStats()。getAvailableZones()。size()1){如果禁用了zone,或者自由一个zone会走这里logger。debug(Zoneawarelogicdisabledorthereisonlyonezone);returnsuper。chooseServer(key);}下面就是根据zone选择服务了,默认情况下不会走下面Stry{LoadBalancerStatslbStatsgetLoadBalancerStats();得到zone快照MapString,ZoneSnapshotzoneSnapshotZoneAvoidanceRule。createSnapshot(lbStats);logger。debug(Zonesnapshots:{},zoneSnapshot);if(triggeringLoadnull){triggeringLoadDynamicPropertyFactory。getInstance()。getDoubleProperty(ZoneAwareNIWSDiscoveryLoadBalancer。this。getName()。triggeringLoadPerServerThreshold,0。2d);}if(triggeringBlackoutPercentagenull){triggeringBlackoutPercentageDynamicPropertyFactory。getInstance()。getDoubleProperty(ZoneAwareNIWSDiscoveryLoadBalancer。this。getName()。avoidZoneWithBlackoutPercetage,0。99999d);}得到可用的zoneSetStringavailableZonesZoneAvoidanceRule。getAvailableZones(zoneSnapshot,triggeringLoad。get(),triggeringBlackoutPercentage。get());logger。debug(Availablezones:{},availableZones);if(availableZones!nullavailableZones。size()zoneSnapshot。keySet()。size()){随机选择区域StringzoneZoneAvoidanceRule。randomChooseZone(zoneSnapshot,availableZones);logger。debug(Zonechosen:{},zone);if(zone!null){BaseLoadBalancerzoneLoadBalancergetLoadBalancer(zone);选择服务serverzoneLoadBalancer。chooseServer(key);}}}catch(Exceptione){logger。error(Errorchoosingserverusingzoneawarelogicforloadbalancer{},name,e);}if(server!null){}else{logger。debug(Zoneavoidancelogicisnotinvoked。);returnsuper。chooseServer(key);}}复制代码 这里做了一个判断,如果没有设置zone或者只有一个zone(默认),这里会调用returnsuper。chooseServer(key);通过父类的BaseLoadBalancerchooseServer方法选择服务,这也是默认的执行流程,代码走到了BaseLoadBalancerchooseServer方法中,源码如下publicclassBaseLoadBalancerextendsAbstractLoadBalancerimplementsPrimeConnections。PrimeConnectionListener,IClientConfigAware{publicServerchooseServer(Objectkey){if(counternull){创建一个计数器countercreateCounter();}计数器增加counter。increment();如果负载均衡规则为空,返回空if(rulenull){}else{try{〔重要〕调用了负载均衡器算法类的choose方法returnrule。choose(key);}catch(Exceptione){logger。warn(LoadBalancer〔{}〕:Errorchoosingserverforkey{},name,key,e);}}}复制代码 在BaseLoadBalancerchooseServer方法中调用了IRulechoose方法进行服务的选择服务,IRule有很多是算法策略实现类,默认会走轮询算法,如果有定义负载均衡算法,这里rule。choose调用的就是定义的算法类。 这里我打了个端点,跟踪了一下源码发现默认情况下会从BaseLoadBalancerchooseServer方法中调用PredicateBasedRulechoose,PredicateBasedRule本身是继承ClientConfigEnabledRoundRobinRule,也就是说PredicateBasedRule是使用的是轮询算法,同时它扩展了Predicate功能,即:提供了服务器过滤逻辑一个规则,提供了服务器过滤逻辑,具体使用的是AbstractServerPredicate实现过滤功能。过滤后,服务器从过滤列表中的循环方式返回。Arulewhichdelegatestheserverfilteringlogictoaninstanceof{linkAbstractServerPredicate}。Afterfiltering,aserverisreturnedfromfilteredlistinaroundrobinfashion。authorawangpublicabstractclassPredicateBasedRuleextendsClientConfigEnabledRoundRobinRule{抽象函数,返回AbstractServerPredicate,用来对服务做过滤的Methodthatprovidesaninstanceof{linkAbstractServerPredicate}tobeusedbythisclass。publicabstractAbstractServerPredicategetPredicate();Getaserverbycalling{linkAbstractServerPredicatechooseRandomlyAfterFiltering(java。util。List,Object)}。TheperformanceforthismethodisO(n)wherenisnumberofserverstobefiltered。OverridepublicServerchoose(Objectkey){得到负载均衡器ILoadBalancerlbgetLoadBalancer();通过AbstractServerPredicate的chooseRoundRobinAfterFiltering选出具体的服务实例AbstractServerPredicate的子类实现的Predicate逻辑来过滤一部分服务实例然后在以线性轮询的方式从过滤后的实例中选出一个OptionalServerservergetPredicate()。chooseRoundRobinAfterFiltering(lb。getAllServers(),key);if(server。isPresent()){returnserver。get();}else{}}}复制代码 这里使用了AbstractServerPredicatechooseRoundRobinAfterFiltering来选择服务从lb。getAllServers()得到所有的服务作为参数,继续跟踪下去Chooseaserverinaroundrobinfashionafterthepredicatefiltersagivenlistofserversandloadbalancerkey。publicOptionalServerchooseRoundRobinAfterFiltering(ListServerservers,ObjectloadBalancerKey){得到合格的服务列表,主要根据zone做一个过滤ListServereligiblegetEligibleServers(servers,loadBalancerKey);if(eligible。size()0){没找到合格的服务returnOptional。absent();}以线性轮询的方式合格的服务列表获取一个实例incrementAndGetModulo方法会以轮询的方式计算一个下标值returnOptional。of(eligible。get(incrementAndGetModulo(eligible。size())));}。。。省略。。。引用于RoundRobinRule算法策略,轮询ReferencedfromRoundRobinRuleInspiredbytheimplementationof{linkAtomicIntegerincrementAndGet()}。parammoduloThemodulotoboundthevalueofthecounter。returnThenextvalue。增量和取模实现轮询privateintincrementAndGetModulo(intmodulo){for(;;){intcurrentnextIndex。get();intnext(current1)if(nextIndex。compareAndSet(current,next)currentmodulo)}}复制代码 这里首先会通过zone过滤出可用的服务列表,然后使用轮询算法选择一个服务返回,到这里选择服务的流程调用6。LoadBalancerRequest执行服务 代码继续回到RibbonLoadBalancerClientexecute,选择完服务之后,服务被封装成RibbonServer:OverridepublicTTexecute(StringserviceId,LoadBalancerRequestTrequest)throwsIOException{得到负载均衡器ILoadBalancerloadBalancergetLoadBalancer(serviceId);选择服务ServerservergetServer(loadBalancer);if(servernull){thrownewIllegalStateException(NoinstancesavailableforserviceId);}把server封装成RibbonServerRibbonServerribbonServernewRibbonServer(serviceId,server,isSecure(server,serviceId),serverIntrospector(serviceId)。getMetadata(server));执行服务调用returnexecute(serviceId,ribbonServer,request);}复制代码 找到服务后,调用了execute方法执行后续请求OverridepublicTTexecute(StringserviceId,ServiceInstanceserviceInstance,LoadBalancerRequestTrequest)throwsIOException{Sif(serviceInstanceinstanceofRibbonServer){server((RibbonServer)serviceInstance)。getServer();}if(servernull){thrownewIllegalStateException(NoinstancesavailableforserviceId);}加载Ribbon负载均衡器上下文对象RibbonLoadBalancerContextcontextthis。clientFactory。getLoadBalancerContext(serviceId);RibbonStatsRecorderstatsRecordernewRibbonStatsRecorder(context,server);try{LoadBalancerRequest。apply执行请求TreturnValrequest。apply(serviceInstance);statsRecorder。recordStats(returnVal);returnreturnV}catchIOExceptionandrethrowsoRestTemplatebehavescorrectlycatch(IOExceptionex){statsRecorder。recordStats(ex);}catch(Exceptionex){statsRecorder。recordStats(ex);ReflectionUtils。rethrowRuntimeException(ex);}}复制代码 这里调用LoadBalancerRequest。apply执行请求,后面还会调用LoadBalancerRequestFactorycreateRequest方法创建请求,调用ClientHttpRequestExecutionexecute执行,然后又会将请求委派给ClientHttpRequestexecute去执行,再往后面走就是创建HttpURLConnection链接对象发送请求了,我们就不继续跟下去了。7。总结 纵观Ribbon的工作流程大致如下:初始化的时候创建好Ribbon的上下文,以及相关的组件,如ILoadBalancer,IConfig,IRule等等初始化过程中会通过ServerList从EurekaClient加载负载均衡候选的服务列表,并定时更新服务列表,使用ServerListFilter过滤之后,使用IPing检查是否更新服务列表被注解了LoadBalance标签的RestTemplate可以使用LoadBalancerClient作负载均衡,并添加好拦截器LoadBalancerInterceptor当请求发起RestTemplate会把请求交给LoadBalancerInterceptor拦截器,LoadBalancerInterceptor拦截器调用LoadBalancerClient接收到请求使用ILoadBalancer负载均衡器选择服务,底层用到IRule算法选择好服务之后,LoadBalancerClient把请求交给LoadBalancerRequest去执行 参考文章 springcloudopenfeign2。2。2源码分析 springcloudsourcestudy学习github地址 微服务入门到入土 SpringCloud之史上最详细Ribbon源码解读 SpringCloudRibbon源码解析SpringCloudAlibaba源码解析