当前位置: 移动技术网 > IT编程>开发语言>Java > SpringCloud断路器Hystrix原理及用法解析

SpringCloud断路器Hystrix原理及用法解析

2020年03月09日  | 移动技术网IT编程  | 我要评论

平乡自行车,幻想好莱坞,大良步行街

这篇文章主要介绍了springcloud断路器hystrix原理及用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

在分布式环境中,许多服务依赖项中的一些必然会失败。hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互。hystrix通过隔离服务之间的访问点、停止级联失败和提供回退选项来实现这一点,所有这些都可以提高系统的整体弹性

两个比较重要的类

  • hystrixcommand
  • hystrixobservablecommand

注解@hystrixcommand(fallbackmethods="methods")methods中可以添加降级策略

除了提供服务降级

还提供了请求缓存

  • @cacheresult
  • @cacheremve

不过添加cacheresult的时候,说

hystrixrequestcontext未初始化。

2020-01-13 16:12:10.273 error 15348 --- [nio-8083-exec-1] o.a.c.c.c.[.[.[/].[dispatcherservlet]  : servlet.service() for servlet [dispatcherservlet] in context with path [] threw exception [request processing failed; nested exception is java.lang.reflect.undeclaredthrowableexception] with root cause

java.lang.illegalstateexception: request caching is not available. maybe you need to initialize the hystrixrequestcontext?
  at com.netflix.hystrix.hystrixrequestcache.get(hystrixrequestcache.java:104) ~[hystrix-core-1.5.18.jar:1.5.18]
  at com.netflix.hystrix.abstractcommand$7.call(abstractcommand.java:478) ~[hystrix-core-1.5.18.jar:1.5.18]
  at com.netflix.hystrix.abstractcommand$7.call(abstractcommand.java:454) ~[hystrix-core-1.5.18.jar:1.5.18]
  at rx.internal.operators.onsubscribedefer.call(onsubscribedefer.java:46) ~[rxjava-1.3.8.jar:1.3.8]
  at rx.internal.operators.onsubscribedefer.call(onsubscribedefer.java:35) ~[rxjava-1.3.8.jar:1.3.8]

查看官方文档https://github.com/netflix/hystrix/wiki/how-to-use

typically this context will be initialized and shut down via a servletfilter that wraps a user request or some other lifecycle hook.

在同一用户请求的上下文中,相同依赖服务的返回数据始终保持一致。在当次请求内对同一个依赖进行重复调用,只会真实调用一次。在当次请求内数据可以保证一致性。

初始化是在filter中进行(官方建议),但是每一次请求都会进行初始化 。所以说和一般的缓存还是有去别的,可以解决高并发,保证的资源的线程安全。在某些场景很有用。

请求合并

/**
   * 建议: 服务提供方有较高的延迟。可以考虑使用请求合并
   * hystrixcollapser 合并请求的时候会创建一个请求处理器。如果每次合并的请求量不大,只有很少的请求还要合并,会造成合并时间窗
   * 并发量增大,时间窗的创建和消耗增大。所以只有在时间窗内有很大的并发量,推荐请求合并。
   *
   * batchmethod 请求合并后的替换方法com.gitee.munan56.cloud.hystrixconsumer.aservice#findall(java.util.list) 注意客户端要有这个方法
   *hystrixproperty 一个属性合并时间窗100s 这个时间结束后会发起请求,也就是指这个时间是合并处理的时间
   * @param id
   * @return
   */
  @hystrixcollapser(batchmethod = "findall",collapserproperties = @hystrixproperty(name = "timerdelayinmilliseconds",value = "100"))
  public string dobfindone(string id){

    system.out.println("begin do provider service");
    return resttemplate.getforentity("http://service-provider:8081/api/v1/provider/do",string.class).getbody();
  }

全部代码

package com.gitee.munan56.cloud.hystrixconsumer;

import com.netflix.hystrix.contrib.javanica.annotation.hystrixcollapser;
import com.netflix.hystrix.contrib.javanica.annotation.hystrixcommand;
import com.netflix.hystrix.contrib.javanica.annotation.hystrixproperty;
import com.netflix.hystrix.contrib.javanica.cache.annotation.cacheresult;
import com.netflix.hystrix.strategy.concurrency.hystrixrequestcontext;
import com.netflix.ribbon.proxy.annotation.hystrix;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.service;
import org.springframework.web.client.resttemplate;

import java.util.list;

/**
 * @author munan
 * @version 1.0
 * @date 2020/1/13 10:41
 */
@service
public class aservice {

  @autowired
  private resttemplate resttemplate;

  public string doaservice(){
    return "a service is run";
  }

//  @hystrix(fallbackhandler = )
  @hystrixcommand(fallbackmethod = "error")
  public string dobserviceone(){
    system.out.println("begin do provider service");
    return resttemplate.getforentity("http://service-provider:8081/api/v1/provider/do",string.class).getbody();
  }

  /**
   * cacheresult 请求缓存(针对request的缓存),官方建议在serverlet filter 中初始化hystrixrequestcontext
   * 在同一用户请求的上下文中缓存在统一请求的上下文环境中有效。
   * @param id
   * @return
   */
  @cacheresult(cachekeymethod = "getkey")
  @hystrixcommand(fallbackmethod = "error")
  public string dobservicetwo(string id){

    system.out.println("begin do provider service");
    return resttemplate.getforentity("http://service-provider:8081/api/v1/provider/do",string.class).getbody();
  }

  /**
   * 建议: 服务提供方有较高的延迟。可以考虑使用请求合并
   * hystrixcollapser 合并请求的时候会创建一个请求处理器。如果每次合并的请求量不大,只有很少的请求还要合并,会造成合并时间窗
   * 并发量增大,时间窗的创建和消耗增大。所以只有在时间窗内有很大的并发量,推荐请求合并。
   *
   * batchmethod 请求合并后的替换方法com.gitee.munan56.cloud.hystrixconsumer.aservice#findall(java.util.list) 注意客户端要有这个方法
   *hystrixproperty 一个属性合并时间窗100s 这个时间结束后会发起请求,也就是指这个时间是合并处理的时间
   * @param id
   * @return
   */
  @hystrixcollapser(batchmethod = "findall",collapserproperties = @hystrixproperty(name = "timerdelayinmilliseconds",value = "100"))
  public string dobfindone(string id){

    system.out.println("begin do provider service");
    return resttemplate.getforentity("http://service-provider:8081/api/v1/provider/do",string.class).getbody();
  }

  @hystrixcommand()
  public string findall(list<string> ids){
    system.out.println("begin do provider service");
    return resttemplate.getforentity("http://service-provider:8081/api/v1/provider/do",string.class).getbody();
  }

  /**
   * 服务降级
   * 指定调用服务出错的回调方法
   * @return
   */
  public string error(throwable e){
    return "do provider error this is default result" + "the error is " + e.getmessage();
  }
  /**
   *  服务降级
   * 指定调用服务出错的回调方法
   * @return
   */
  public string error(string id ,throwable e){
    return "do provider error this is default result" + "the error is " + e.getmessage();
  }


  public string getkey(string id){
    return id;
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网