本文主要是介绍Hystrix-FailBack,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Hystrix降级技术解析-Fallback
一、降级
所谓降级,就是指在在Hystrix执行非核心链路功能失败的情况下,我们如何处理,比如我们返回默认值等。
如果我们要回退或者降级处理,代码上需要实现HystrixCommand.getFallback()方法或者是HystrixObservableCommand.resumeWithFallback()。
二、Hystrix的降级回退方式
1、Fail Fast 快速失败 直接抛异常
2、Fail Silent 无声失败|返回null,空Map,空List
3、Fallback: Static 返回默认值
4、Fallback: Stubbed 自己组装一个值返回
5、Fallback: Cache via Network 利用远程缓存
通过远程缓存的方式。在失败的情况下再发起一次remote请求,不过这次请求的是一个缓存比如redis。
由于是又发起一起远程调用,所以会重新封装一次Command,这个时候要注意,执行fallback的线程一定要跟主线程区分 开,也就是重新命名一个ThreadPoolKey。
通过远程缓存的方式。在失败的情况下再发起一次remote请求,不过这次请求的是一个缓存比如redis。由于是又发起一起远程调用,所以会重新封装一次Command,这个时候要注意,执行fallback的线程一定要跟主线程区分开,也就是重新命名一个ThreadPoolKey。
6、Primary + Secondary with Fallback 主次方式回退(主要和次要)
这个有点类似我们日常开发中需要上线一个新功能,但为了防止新功能上线失败可以回退到老的代码,我们会做一个开关比如使用zookeeper做一个配置开关,可以动态切换到老代码功能。那么Hystrix它是使用通过一个配置来在两个command中进行切换。
public class CommandFacadeWithPrimarySecondary extends HystrixCommand<String> {private final static DynamicBooleanProperty usePrimary = DynamicPropertyFactory.getInstance().getBooleanProperty("primarySecondary.usePrimary", true);private final int id;public CommandFacadeWithPrimarySecondary(int id) {super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("SystemX")).andCommandKey(HystrixCommandKey.Factory.asKey("PrimarySecondaryCommand")).andCommandPropertiesDefaults(// we want to default to semaphore-isolation since this wraps// 2 others commands that are already thread isolated// 采用信号量的隔离方式HystrixCommandProperties.Setter().withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE)));this.id = id;}//通过DynamicPropertyFactory来路由到不同的command@Overrideprotected String run() {if (usePrimary.get()) {return new PrimaryCommand(id).execute();} else {return new SecondaryCommand(id).execute();}}@Overrideprotected String getFallback() {return "static-fallback-" + id;}@Overrideprotected String getCacheKey() {return String.valueOf(id);}private static class PrimaryCommand extends HystrixCommand<String> {private final int id;private PrimaryCommand(int id) {super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("SystemX")).andCommandKey(HystrixCommandKey.Factory.asKey("PrimaryCommand")).andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("PrimaryCommand")).andCommandPropertiesDefaults(// we default to a 600ms timeout for primaryHystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(600)));this.id = id;}@Overrideprotected String run() {// perform expensive 'primary' service callreturn "responseFromPrimary-" + id;}}private static class SecondaryCommand extends HystrixCommand<String> {private final int id;private SecondaryCommand(int id) {super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("SystemX")).andCommandKey(HystrixCommandKey.Factory.asKey("SecondaryCommand")).andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("SecondaryCommand")).andCommandPropertiesDefaults(// we default to a 100ms timeout for secondaryHystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(100)));this.id = id;}@Overrideprotected String run() {// perform fast 'secondary' service callreturn "responseFromSecondary-" + id;}}public static class UnitTest {@Testpublic void testPrimary() {HystrixRequestContext context = HystrixRequestContext.initializeContext();try {//将属性"primarySecondary.usePrimary"设置为true,则走PrimaryCommand;设置为false,则走SecondaryCommandConfigurationManager.getConfigInstance().setProperty("primarySecondary.usePrimary", true);assertEquals("responseFromPrimary-20", new CommandFacadeWithPrimarySecondary(20).execute());} finally {context.shutdown();ConfigurationManager.getConfigInstance().clear();}}@Testpublic void testSecondary() {HystrixRequestContext context = HystrixRequestContext.initializeContext();try {//将属性"primarySecondary.usePrimary"设置为true,则走PrimaryCommand;设置为false,则走SecondaryCommandConfigurationManager.getConfigInstance().setProperty("primarySecondary.usePrimary", false);assertEquals("responseFromSecondary-20", new CommandFacadeWithPrimarySecondary(20).execute());} finally {context.shutdown();ConfigurationManager.getConfigInstance().clear();}}} }
三、总结
降级的处理方式,返回默认值,返回缓存里面的值(包括远程缓存比如redis和本地缓存比如jvmcache)。
但回退的处理方式也有不适合的场景:
1、写操作
2、批处理
3、计算
以上几种情况如果失败,则程序就要将错误返回给调用者。
这篇关于Hystrix-FailBack的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!