1.【Hystrix技术指南】(7)故障切换的注注解运作流程原理分析(含源码)
2.Spring Boot 项目配合Hystrix 实现全局RestController超时熔断(api超过30秒返回timeout)
3.Hystrixä»ç»
4.Springboot之分布式事务框架Seata实现原理源码分析
5.ribbonè´è½½å衡详解
【Hystrix技术指南】(7)故障切换的运作流程原理分析(含源码)
目前对于一些非核心操作,如增减库存后保存操作日志发送异步消息时(具体业务流程),解源解析一旦出现MQ服务异常时,源码会导致接口响应超时,注注解因此可以考虑对非核心操作引入服务降级、解源解析服务隔离。源码源码提取解析接口
Hystrix说明
Hystrix是注注解Netflix开源的一个容灾框架,解决当外部依赖故障时拖垮业务系统、解源解析甚至引起雪崩的源码问题。
为什么需要Hystrix?注注解Hystrix设计理念
想要知道如何使用,必须先明白其核心设计理念,解源解析Hystrix基于命令模式,源码通过UML图先直观的注注解认识一下这一设计模式。
Hystrix如何解决依赖隔离Hystrix流程结构解析
流程说明:
以下四种情况将触发getFallback调用:
熔断器:Circuit Breaker
每个熔断器默认维护个bucket,解源解析容器id生成源码每秒一个bucket,源码每个bucket记录成功,失败,超时,拒绝的状态,默认错误超过%且秒内超过个请求进行中断短路。
Hystrix隔离分析
Hystrix隔离方式采用线程/信号的方式,通过隔离限制依赖的并发量和阻塞扩散.
线程隔离实际案例:
Netflix公司内部认为线程隔离开销足够小,不会造成重大的成本或性能的影响。Netflix 内部API 每天亿的HystrixCommand依赖请求使用线程隔,每个应用大约多个线程池,每个线程池大约5-个线程。
信号隔离
信号隔离也可以用于限制并发访问,防止阻塞扩散, 与线程隔离最大不同在于执行依赖代码的线程依然是请求线程(该线程需要通过信号申请),如果客户端是可信的且可以快速返回,可以使用信号隔离替换线程隔离,降低开销。 信号量的redis电脑配置源码大小可以动态调整, 线程池大小不可以。
线程隔离与信号隔离区别如下图:
fallback故障切换降级机制
有兴趣的小伙伴可以看看: 官方参考文档
源码分析
hystrix-core-1.5.-sources.jar!/com/netflix/hystrix/AbstractCommand.java
executeCommandAndObserve
使用Observable的onErrorResumeNext,里头调用了handleFallback,handleFallback中区分不同的异常来调用不同的fallback。
applyHystrixSemanticsViaFallback方法
hystrix-core-1.5.-sources.jar!/com/netflix/hystrix/AbstractCommand.java
hystrix-core-1.5.-sources.jar!/com/netflix/hystrix/AbstractCommand.java
针对每个commandKey获取或创建TryableSemaphoreActual
fallback源码分析小结
hystrix的fallback主要分为5种类型:
获取以上资源请访问开源项目 点击跳转
Spring Boot 项目配合Hystrix 实现全局RestController超时熔断(api超过秒返回timeout)
为了在Spring Boot项目中实现全局RestController的超时熔断,当API调用超过秒时返回timeout,我们需要寻找一种更高效的方法,避免手动为上百个控制器添加@HystrixCommand注解,这将是一项繁重的任务。起初,我尝试使用切面编程(AspectJ)包裹RestController,配置@HystrixCommand,但这似乎与HystrixCommand的特性产生了冲突。通过深入Hystrix源码分析和实例化HystrixCommand,越狱屏蔽插件源码我成功实现了全局的超时熔断策略,无需每个API都单独标注。
实现的关键在于在pom文件中添加适当的Hystrix依赖,并确保返回值使用ResponseEntity以控制响应码。对于非ResponseEntity类型的返回值,通过优化处理,可以避免超时后返回的意外情况。这个过程虽然注解方式简洁,但控制不当可能引发问题。在遇到注解失效或效果不佳时,通过创建私有实例进行管理通常更易于调试和问题定位。
Spring Boot的starter虽然提供了快速搭建项目的便利,但在精细化控制上可能面临挑战。答题吧项目源码因此,对于这类场景,注解的便利性和实例化管理的灵活性是需要权衡的。
Hystrixä»ç»
对Hystrixè³é»å·²ä¹ ï¼æè¿å好æ³å¨é¡¹ç®ä¸ä½¿ç¨è¿ä¸ªç¥å¨å°±é¡ºå¸¦ç 究äºä¸æï¼å¾å¤ç»èæ¥ä¸åæ·±å ¥ç 究åªè½æå®è§ä¸çå个æ¦å¿µè®²è§£ä¸ä¸ï¼è¿ä¸ªä»ç»çç´ æ大é½æ¥èªgithubä¸çHystrixå®ç½ã
æè°ä¸å¾èåè¨ï¼ä½å¡è½å¤ç¨å¾çæ¥è¡¨ç¤ºèä¸è½å¤è¡¨ç¤ºæ¸ æ¥çï¼å°±ä¸å¤ç¨æåæè¿°äºï¼çå¾è¯å®æ¯çæåè¦è®©äººæ¥çæ´ç½ä¸äºãå½ç¶æè¿æ¯é常建议å»githubä¸çHystrixå®æ¹wikiå»çåæ±åå³çææ¡£ï¼å¨åèæç®é¨åå·²ç»ç»åºäºé¾æ¥ã
æåæä¸ç¹ï¼å°±æ¯å¨Hystrixçå®ç°å½ä¸å¤§é使ç¨äºRxJavaçå¼æºå çææ¯ï¼è¿ä¸ªææ¯ä¹å没æä¹ç 究è¿ï¼æ以åé¢çå¾å¤æºç çåææ´å¤ä¾§éè¿ç¨åæèä¸ä¼æ·±å ¥ç»èï¼æå ´è¶£çå¯ä»¥èªå·±æ·±å ¥ç 究ä¸ï¼æå°±åå¤åªå¤©å¾ç©ºå¥½å¥½å»ç 究ä¸ä¸ï¼æ¯ç«RxJavaè¿ä¸ªä¸è¥¿å·ç§°æ¯ä¸ä¸ªéè¿ä½¿ç¨å¯è§å¯åºåæ¥ç¼åå¼æ¥ååºäºäºä»¶çç¨åºçåºã
hystrixçåºç°å³ä¸ºè§£å³éªå´©æåºï¼å®éè¿å个æ¹é¢çæºå¶æ¥è§£å³è¿ä¸ªé®é¢
Hystrixçé离主è¦æ¯ä¸ºæ¯ä¸ªä¾èµç»ä»¶æä¾ä¸ä¸ªé离ç线ç¨ç¯å¢ï¼æä¾ä¸¤ç§æ¨¡å¼çé离ï¼
Hystrixççæå¨å ¶å®å¯ä»¥ç解为就æ¯ä¸ä¸ªç»è®¡ä¸å¿ï¼ç»è®¡ä¸å®æ¶é´çªå£å 访é®æ¬¡æ°ï¼æå次æ°ï¼å¤±è´¥æ¬¡æ°çæ°å¼å¤å®æ¯å¦åççæãåççµè·¯çæçè¿ç¨å¦ä¸ï¼
hystrixå·¥ä½åç-è±æç
hystrixå·¥ä½åç-ä¸æç
å ³äºRxJavaç详解
Springboot之分布式事务框架Seata实现原理源码分析
在SpringBoot环境下的分布式事务框架Seata实现原理涉及到了代理数据源、注册代理Bean以及全局事务拦截器等关键环节。下面我们将逐步解析其核心逻辑。
首先,Seata通过GlobalTransactionScanner来注册项目中所有带有@GlobalTransactional注解的方法类。该扫描器是一个实现了BeanPostProcessor接口的类,它能够在Spring容器初始化时进行后置处理,从而实现全局事务的管理。
GlobalTransactionScanner实际上是一个InstantiationAwareBeanPostProcessor,它在实例化Bean前执行postProcessBeforeInstantiation方法,在实例化后执行postProcessAfterInstantiation方法,并在属性填充时执行postProcessProperties方法。尽管GlobalTransactionScanner类本身并未覆盖这3个方法,但在父类的实现中,这些方法用于处理Bean的实例化和属性设置过程。
关键在于postProcessAfterInitialization方法中实现的wrapIfNecessary方法,该方法在GlobalTransactionScanner类中被重写。当方法执行到existsAnnotation方法判断类方法是否带有@GlobalTransactional注解时,如果存在则创建一个GlobalTransactionalInterceptor作为拦截器处理全局事务。
在创建代理数据源时,Seata通过DataSourceProxy对系统默认数据源进行代理处理。通过shouldSkip方法判断当前bean是否需要被代理,如果bean是SeataProxy的子类且不是DataSource的子类且不在excludes集合中,则进行代理,从而代理当前系统的默认数据源对象。
全局事务拦截器主要负责全局事务的发起、执行和回滚。在执行全局事务的方法被代理时,具体的执行拦截器是GlobalTransactionalInterceptor。该拦截器处理全局事务的逻辑,包括获取全局事务、开始全局事务、执行本地业务、提交本地事务、记录undo log、提交数据更新等步骤。其中,提交本地事务时会向TC(Transaction Coordinator)注册分支并提交本地事务,整个过程确保了分布式事务的一致性。
当全局事务中任何一个分支发生异常时,事务将被回滚。参与全局事务的组件在异常发生时执行特定的回滚逻辑,确保事务一致性。在Seata的实现中,异常处理机制确保了事务的回滚能够正确执行。
Seata还提供了XID(Transaction Identifier)的传递机制,通过RestTemplate和Feign客户端进行服务间的调用,确保分布式系统中各个服务能够共享和处理全局事务。RestTemplate在请求头中放置TX_XID头信息,而Feign客户端通过从调用链中获取Feign.Builder,最终通过SeataHystrixFeignBuilder.builder方法实现XID的传递。
在被调用端(通过Feign调用服务),Seata自动配置会创建数据源代理,使得事务方法执行时能够获取到连接对象,而这些连接对象已经被代理成DataSourceProxy。SeataHandlerInterceptor拦截器对所有请求进行拦截,从Header中获取TX_XID,参与者的XID绑定到上下文中,通过ConnectionProxy获取代理连接对象。在数据库操作中,XID绑定到ConnectionContext,执行SQL语句时通过StatementProxy或PreparedStatementProxy代理连接,从而完成全局事务的处理。
综上所述,Seata通过一系列复杂的逻辑和机制,实现了SpringBoot环境下的分布式事务管理,确保了分布式系统中数据的一致性和可靠性。
ribbonè´è½½å衡详解
æå¡ç«¯è´è½½åè¡¡ï¼å¨å®¢æ·ç«¯åæå¡ç«¯ä¸é´ä½¿ç¨ä»£çï¼lvs å nginxã
硬件è´è½½åè¡¡ç设å¤ææ¯è½¯ä»¶è´è½½åè¡¡ç软件模åé½ä¼ç»´æ¤ä¸ä¸ªä¸æå¯ç¨çæå¡ç«¯æ¸ åï¼éè¿å¿è·³æ£æµæ¥åé¤æ éçæå¡ç«¯èç¹ä»¥ä¿è¯æ¸ åä¸é½æ¯å¯ä»¥æ£å¸¸è®¿é®çæå¡ç«¯èç¹ãå½å®¢æ·ç«¯åé请æ±å°è´è½½å衡设å¤çæ¶åï¼è¯¥è®¾å¤ææç§ç®æ³ï¼æ¯å¦çº¿æ§è½®è¯¢ãææéè´è½½ãææµéè´è½½çï¼ä»ç»´æ¤çå¯ç¨æå¡ç«¯æ¸ åä¸ååºä¸å°æå¡ç«¯ç«¯å°åï¼ç¶åè¿è¡è½¬åã
客æ·ç«¯è´è½½åè¡¡ï¼æ ¹æ®èªå·±çæ åµåè´è½½ãRibbonã
客æ·ç«¯è´è½½åè¡¡åæå¡ç«¯è´è½½åè¡¡æ大çåºå«å¨äº æå¡ç«¯å°åå表çåå¨ä½ç½®ï¼ä»¥åè´è½½ç®æ³å¨åªéã
2ãSpring Cloudçè´è½½åè¡¡æºå¶çå®ç°
Spring Cloud Ribbonæ¯ä¸ä¸ªåºäºHTTPåTCPç客æ·ç«¯è´è½½åè¡¡å·¥å ·ï¼å®åºäºNetflix Ribbonå®ç°ãéè¿Spring Cloudçå°è£ ï¼å¯ä»¥è®©æ们轻æ¾å°å°é¢åæå¡çREST模ç请æ±èªå¨è½¬æ¢æ客æ·ç«¯è´è½½åè¡¡çæå¡è°ç¨ãRibbonå®ç°å®¢æ·ç«¯çè´è½½åè¡¡ï¼è´è½½åè¡¡å¨æä¾å¾å¤å¯¹.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