疯狂Spring Cloud连载(16)Hystrix属性配置与回退


声明:本文转载自https://my.oschina.net/JavaLaw/blog/1560867,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

本文节选自《疯狂Spring Cloud微服务架构实战》

Spring Cloud教学视频:https://my.oschina.net/JavaLaw/blog/1552993

Hystrix属性配置与回退

属性配置

        使用Hystrix时,可以为命令设置属性,以下的代码片断,为一个命令设置了执行的超时时间:

		public MyCommand(boolean isTimeout) { 		    super( 		    		Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")) 		            .andCommandPropertiesDefaults(HystrixCommandProperties.Setter() 		            		.withExecutionTimeoutInMilliseconds(500)) 		    	 ); 		} 

        以上的配置仅对该命令生效,设置了命令的超时时间为500毫秒,该配置项的默认值为1秒,如果想对全局生效,可以使用以下的代码片断:

		ConfigurationManager 				.getConfigInstance() 				.setProperty( 				"hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds",  				500); 

        以上的代码片断,同样设置了命令超时时间为500毫秒,但对全局有效。除了超时的配置外,还需要了解一下命令的相关名称,可以为命令设置以下名称:

  • 命令组名称(GroupKey):必须提供命令组名称,默认情况下,全局维护的线程池Map以该值作为key,该Map的value为执行命令的线程池。
  • 命令名称(CommandKey):可选参数。
  • 线程池名称(ThreadPoolKey):指定了线程的key后,全局维护的线程池Map将以该值作为key。

        以下的代码片断,分别设置以上的3个Key:

		public RunCommand(String msg) { 			super( 					Setter.withGroupKey( 							HystrixCommandGroupKey.Factory.asKey("group-key")) 							.andCommandKey(HystrixCommandKey.Factory.asKey("command-key")) 							.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("pool-key")) 					 					); 		} 

        Hystrix的配置众多,后面章节的案例会涉及部分的配置,读者如果想了解更多的配置,可到以下的地址查看:https://github.com/Netflix/Hystrix/wiki/Configuration

回退

        根据前面章节的流程图可知,至少会有3种情况触发回退(fallback):

  • 断路器被打开。
  •  线程池、队列、信号量满载。
  • 实际执行命令失败。

        在命令中,实现父类(HystrixCommand)的getFallback()方法,即可实现回退,当以上的情况发生时,将会执行回退方法。前面的例子中,已经展示了“执行命令失败”的回退,下面测试一下断路器被打开时的回退,详细请见代码清单6-7。

        代码清单6-7:

        06\6.2\first-hnystrix-client\src\main\java\org\crazyit\cloud\fallback\FallbackTest.java

public class FallbackTest {  	public static void main(String[] args) { 		// 断路器被强制打开 		ConfigurationManager.getConfigInstance().setProperty( 				"hystrix.command.default.circuitBreaker.forceOpen", "true"); 		FallbackCommand c = new FallbackCommand(); 		c.execute(); 		// 创建第二个命令,断路器关闭 		ConfigurationManager.getConfigInstance().setProperty( 				"hystrix.command.default.circuitBreaker.forceOpen", "false"); 		FallbackCommand c2 = new FallbackCommand(); 		c2.execute(); 	}  	static class FallbackCommand extends HystrixCommand<String> { 		public FallbackCommand() { 			super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); 		}  		/** 		 * 断路器被强制打开,该方法不会执行 		 */ 		protected String run() throws Exception { 			System.out.println("命令执行"); 			return ""; 		}  		/** 		 * 回退方法,断路器打开后会执行回退 		 */ 		protected String getFallback() { 			System.out.println("执行回退方法"); 			return "fallback"; 		} 	} } 

        如果让断路器打开,需要符合一定的条件,本例为了简单起见,在代码清单中,使用了配置管理类(ConfigurationManager)将断路器强制打开与关闭,在打开断路器后,FallbackCommand总会执行回退(getFallback)方法,将断路器关闭,命令执行正常。如果断路器被打开,而命令中没有提供回退方法,将抛出以下异常:

com.netflix.hystrix.exception.HystrixRuntimeException:  FallbackCommand short-circuited and no fallback available.

        另外,需要注意的是,命令执行后,不管是否会触发回退,都会去计算整个链路的健康状况,根据健康状况来判断是否要打开断路器,如果命令仅仅失败了一次,是不足以打开断路器的,关于断路器的逻辑将在后面章节讲述。

回退的模式

        Hystrix的回退机制比较灵活,你可以在A命令的回退方法中执行B命令,如果B命令也执行失败,同样也会触发B命令的回退,这样就形成一种链式的命令执行,例如以下代码片断:

	static class CommandA extends HystrixCommand<String> { 		…省略其他代码 		protected String run() throws Exception { 			throw new RuntimeException(); 		}  		protected String getFallback() { 			return new CommandB().execute(); 		}	 	} 

        还有其他较为复杂的例子,例如银行转账,假设一个转账命令包含调用A银行扣款、B银行加款两个命令,其中一个命令失败后,再执行转账命令的回退,如图6-4所示。

图6-4 多命令回退

        要做到图6-4的多命令只执行一次回退的效果,CommandA与CommandB,不能有回退方法,如果CommandA命令执行失败,并且该命令有回退方法,此时将不会执行“MainCommand”的回退方法。除了上面所提到的链式的回退以及多命令回退,读者还可以根据实际情况来设计回退。

本文节选自《疯狂Spring Cloud微服务架构实战》

Spring Cloud教学视频:https://my.oschina.net/JavaLaw/blog/1552993

本书代码共享地址:https://gitee.com/yangenxiong/SpringCloud

本文发表于2017年11月05日 10:34
(c)注:本文转载自https://my.oschina.net/JavaLaw/blog/1560867,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 3110 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

万稳万当,不如一默。任何一句话,你不说出来便是那句话的主人,你说了出来,便是那句话的奴隶。

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1