服务降级
Hystrix 提供了服务降级功能。
有些场景下当调用服务失败时,不应该产生一个Exception 异常给用户。而是采用执行备用策略。
比如:假如一个购物网站,它可以监控用户的行为,并尝试向用户推荐其它可以购买的商品。通常来说,可以调用微服务来对用户过去的行为进行分析,并返回针对特定用户的推荐列表。但是如果调用这个服务失败。则启动后备策略来检索一个更通用的偏好列表,该列表可以是热门商品的列表或基于全部用户购买记录分析的结果。
Hystrix 服务降级示例
package com.jijs.fallback.test;
import java.util.concurrent.TimeUnit;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandProperties;
public class HystrixFallbackDemo extends HystrixCommand<String> {
protected HystrixFallbackDemo() {
super(Setter.withGroupKey(
HystrixCommandGroupKey.Factory.asKey("HystrixFallback"))
.andCommandPropertiesDefaults(
HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds(1000)));
}
@Override
protected String run() throws Exception {
//执行超时
TimeUnit.MILLISECONDS.sleep(2000);
//执行异常
//int i = 5 / 0;
//主动抛出异常
//throw new HystrixTimeoutException();
return "ok";
}
@Override
protected String getFallback() {
return "fallback";
}
public static void main(String[] args) {
HystrixFallbackDemo t = new HystrixFallbackDemo();
String result = t.execute();
System.out.println(result);
}
}
使用 Hystrix 实现一个后备策略,开发人员必须以下做几点。
1、继承 HystrixCommand 类。
2、在构造中定义 Hystrix 相关策略
3、重写 HystrixCommand 类的 run() 方法,写自己的核心业务。
4、重写 HystrixCommand 类的 getFallback() 方法,来实现后备策略。
使用 HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(1000) 设置调用执行 run() 方法的超时时间为1秒。
当执行 run() 方法时间超过1秒、执行run报错 或 抛出异常都会执行 getFallback () 方法。
自己动手实现 Hystrix 的后备策略
package com.jijs.fallback.test;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class FallbackDemo {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Task task = new Task();
Future<String> f = executor.submit(task);
String result;
try {
result = f.get(1000, TimeUnit.MILLISECONDS); //执行超时时间1000
} catch (Exception e) {
//捕获所有的 Exception 异常,都执行 fallback方法。
result = task.fallback();
}
System.out.println(result);
executor.shutdown();
}
}
class Task implements Callable<String> {
public String call() throws Exception {
//执行超时
TimeUnit.MILLISECONDS.sleep(2000);
//执行异常
//int i = 5 / 0;
//主动抛出异常
//throw new HystrixTimeoutException();
return "ok";
}
//后备方法
public String fallback() {
return "fallback";
}
}
1、Hystrix 底层默认也是使用线程池来隔离不同的资源的。这里我们也模拟创建一个线程池。
2、然后将任务提交给线程池执行,因为任务实现了Callable 接口,所有我们可以使用 Future 来异步获取执行结果。
3、通过 Future.get(2000, TimeUnit.MILLISECONDS) 来指定 任务 执行的超时时间。
4、捕获异常,如果出现Exception的异常都执行 Task 的后备方法 fallback()。
从功能上来看,我们已经简单的实现了 Hystrix 的后备模式(超时、异常 等都可以执行后备方法)。
网友评论