写点什么

Hystrix- 服务容错处理:什么是 Hystrix,鲁班学院二期

用户头像
Geek_f90455
关注
发布于: 31 分钟前
private final String name;public MyHystrixCommand(String name) {  super (Hystr ixCommandGroupKey .Factory .asKey( "MyGroup"));  this.name = name;}
@Overrideprotected String run() {return this.name + ":" + Thread. currentThread() .getName();}
复制代码


}


首先需要继承`HystrixCommand`,通过构造函数设置一个`Groupkey`。具体的逻辑在`run方法`中,我们返回了一个当前线程名称的值。写一个`main方法`来调用上面编写的`MyHystrixCommand`程序,如以下代码所示:```javapublic static void main(String[] args)throws InterruptedException, ExecutionException {  String result = new MyHystrixCommand("yinjihuan").execute();  System.out.println(result);}
复制代码


输出结果是: yinjihuan:hystrix-MyGroup。由此可以看出,构造函数中设置的组名变成了线程的名字。


上面是同步调用,如果需要异步调用可以使用一下代码所示方法:


public static void main(String[] args)throws InterruptedException, ExecutionException {  Future<String>future = new MyHystrixCommand("yinjihuan").queue();  System.out.println( future.get());}
复制代码

二、 回退支持

下面我们通过增加执行时间模拟调用失败的情况,首先改造MyHystrixCommand,增加getFallback方法返回回退内容,如以下代码所示:


public class MyHystrixCommand extends HystrixCommand<String> {  private final String name ;  pub1ic MyHystrixCommand( String name) {    super (HystrixCommandGroupKey.Factory.asKey("MyGroup"));    this.name = name;  }  @Override  protected String run() {    try {      Thread. sleep(1000 * 10);    } catch (InterruptedExceptione) {      e.printStackTrace();    }    return this.name + ":" + Thread.currentThread() . getName();    @Override    protected String getFallback() {    return"失败了";  }}
复制代码


重新执行调用代码,可以发现返回的内容是“失败了”,证明已经触发了回退。

三、 信号量策略配置

信号量策略配置方法如以下代码所示:


public MyHystrixCommand(String name) {  super ( HystrixCommand . Setter    .Wi thGroupKey(Hystr ixCommandGroupKey .Factory .asKey( "MyGroup"))    . andCommandPropertiesDefaults (      Hystr ixCommandProperties . Setter( )      . withExecut ionIsolationStrategy(        Hystr ixCommandProperties        . ExecutionIsolat ionStrategy . SEMAPHORE      )    )  );  this.name = name;}
复制代码


之前在 run 方法中特意输出了线程名称,通过这个名称就可以确定当前是线程隔离还是信号量隔离。

四、 线程隔离策略配置

系统默认采用线程隔离策略,我们可以通过andThreadPoolPropertiesDefaults配置线程池的一些参数,如以下代码所示:


public MyHystrixCommand(String name) {  super(HystrixCommand.Setter.withGroupKey (    HystrixCommandGroupKey.Factory .asKey( "MyGroup"))    .andCommandPropertiesDefaults (      HystrixCommandProperties.Setter()        .withExecutionIsolationStrategy (          HystrixCommandProperties.ExecutionIsolationStrategy.THREAD        )    ) . andThreadPoolPropertiesDefaults (    HystrixThreadPoolProperties. Setter()      . withCoreSize(10 )      . withMaxQueueSize(100)      .withMax. imumSize(100)    )  );  this.name = name ;}
复制代码

五、 结果缓存

缓存在开发中经常用到,我们常用 Redis 这种第三方的缓存数据库来对数据进行缓存处理。Hystrix 中也为我们提供了方法级别的缓存。通过重写getCacheKey来判断是否返回缓存的数据,getCacheKey 可以根据参数来生成,这样同样的参数就可以都用到缓存了。


改造之前的 MyHystrixCommand ,在其中增加 getCacheKey 的重写实现,如以下代码所示:


@verrideprotected String getCacheKey() {  return String.valueOf(this.name);}
复制代码


在上面的代码中,我们创建对象时传进来的 name 参数作为缓存的 key。


为了证明能够用到缓存,在 run 方法中加一行输出,在调用多次的情况下,如果控制台只输出了一次,那么可以知道后面的都是走的缓存逻辑,如以下代码所示:


@overrideprotected String run() {  System.err.print1n("get data");  return this.name + ":" + Thread. currentThread().getName();}
复制代码


执行 main 方法,发现报错了:



根据错误提示可以知道,缓存的处理取决于请求的上下文,我们必须初始化Hystrix-RequestContext


改造 main 方法中的调用代码,初始化HystrixRequestContext,如以下代码所示:


public static void main(String[] args)throws InterruptedException, ExecutionException {  HystrixRequestContext context = HystrixRequestContext. initializeContext();  String result = new MyHystrixCommand("yinjihuan").execute();  System.out.println(result);  Future<string>future = new MyHystrixCommand("yinjihuan") .queue();  System.out.println(future.get());  context . shutdown() ;}
复制代码


改造完之后重写执行 main 方法,可以做正常运行了,输出结果如下



可以看到只输出一次 get data ,缓存生效。

六、 缓存清除

在上一节中我们学习了如何使用 Hystrix 来实现数据缓存功能。有缓存必然就有清除缓存的动作,当数据发生变动时,必须将缓存中的数据也更新掉,不然就会产生脏数据的问题。同样,Hystrix 也有清除缓存的功能。


增加一个支持缓存清除的类,如以下代码所示:


public class ClearCacheHystrixCommand extends HystrixCommand<String> {  private final String name ;  private static final HystrixCommandKey GETTER_ KEY =  HystrixCommandKey.Factory . asKey("MyKey");  public ClearCacheHystrixCommand (String name) {    super ( HystrixCommand . Setter .withGroupKey ( HystrixCommandGroupKey .      Factory .asKey( "MyGroup" )) . andCommandKey (GETTER_ KEY )    );    this.name = name;  }  public static void fushCache(String name) {    HystrixRequestCache.getInstance ( GETTER_ KEY ,HystrixConcurrencyStrategyDefault. getInstance()). clear (name);  }    @Override  protected String getCacheKey() {    return String.valueOf(this.name);  }    @Override  protected String run() {    System.err.println("get data");

**最后,附一张自己面试前准备的脑图:**
![image](https://static001.geekbang.org/infoq/4d/4d88e56bab4afe10290ff979f3768769.jpeg)
**面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典**

* Java核心知识整理
![image](https://static001.geekbang.org/infoq/89/896aee9dd91f40229a7468c254283089.png)

* Spring全家桶(实战系列)
![image.png](https://static001.geekbang.org/infoq/aa/aad3f82516edb5025a6de10f6863469f.png)

**Step3:刷题**
既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。
**以下是我私藏的面试题库:**
![image](https://static001.geekbang.org/infoq/ca/cab7391076a6aad49aa2070f2437cbdc.png)
很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。
**资料领取方式:[Java全套学习手册](https://gitee.com/vip204888/java-p7)**
以上学习资料均免费分享,最后祝愿各位身体健康,顺利拿到心仪的offer!
复制代码


用户头像

Geek_f90455

关注

还未添加个人签名 2021.07.06 加入

还未添加个人简介

评论

发布
暂无评论
Hystrix-服务容错处理:什么是Hystrix,鲁班学院二期