Spring Cloud(Dalston.SR5)--Hystrix 断路器-合并请求

在 Spring Cloud 中可以使用注解的方式来支持 Hystrix 的合并请求,缓存与合并请求功能需要先初始化请求上下文才能实现,因此,必须实现 javax.servlet.Filter 用于创建和销毁 Hystrix 的请求上下文,合并请求的注解需要用到 @HystrixCollapser 和 @HystrixCommand ,示例如下:

  • 创建 Filter

    和缓存一样,在 Filter 初始化时就创建 HystrixRequestContext,然后在每个请求调用 doFilter 方法时,将初始化的上下文赋值到当前线程存储,这样就能在全局使用 Hystrix 的缓存和合并请求

    package org.lixue;

       

    import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;

       

    import javax.servlet.*;

    import javax.servlet.annotation.WebFilter;

    importj ava.io.IOException;

       

    @WebFilter(urlPatterns="/*",filterName="HystrixRequestContextFilter")

    public class HystrixRequestContextFilter implements Filter{

    HystrixRequestContext context=null;

       

    @Override

    public void init(FilterConfig filterConfig) throws ServletException{

    context=HystrixRequestContext.initializeContext();

    }

       

    @Override

    publicvoid doFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain) throws IOException,ServletException{

    HystrixRequestContext.setContextOnCurrentThread(context);

    try{

    chain.doFilter(request,response);

    }catch(Exceptionex){

    ex.printStackTrace();

    }

    }

       

    @Override

    publicvoiddestroy(){

    if(context!=null){

    context.shutdown();

    }

    }

    }

   

  • 创建服务调用

    注解 @HystrixCollapser 标注合并请求的方法,需要设置该注解的 batchMethod 属性,该属性设置用于处理批量请求的方法,可以设置 collapserProperties 属性,表示合并请求相关参数配置,这里配置了 timerDelayInMilliseconds 属性,表示合并 5 秒的请求;使用 @HystrixCommand 标注了实际批量请求的方法。

    package org.lixue;

       

    import com.alibaba.fastjson.JSON;

    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 org.apache.commons.lang.StringUtils;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.stereotype.Component;

    import org.springframework.web.client.RestTemplate;

       

    import java.util.LinkedList;

    import java.util.List;

    import java.util.Map;

    import java.util.concurrent.Future;

       

    @Component

    public class HelloWorldCollapseClient{

       

    @Autowired

    private RestTemplate restTemplate;

       

    @HystrixCollapser(batchMethod="speakCollapse",collapserProperties={

    @HystrixProperty(name="timerDelayInMilliseconds",value="5000")

    })

    public Future<String> speak(String name){

    return null;

    }

       

    @HystrixCommand

    private List<String> speakCollapse(List<String> names){

    System.out.println("speakNamesiscall,namesis"+names);

    String jsonResponse=

    restTemplate.getForObject("http://HELLOWORLD-PROVIDER/speaks?names="+ StringUtils.join(names,',') ,String.class);

    Map<String,String> mapResponse=(Map<String,String>)JSON.parse(jsonResponse);

    List<String> list=new LinkedList<>();

    for(int i=0;i<names.size();i++){

    list.add(mapResponse.get(names.get(i)));

    }

    return list;

    }

    }

  • 测试验证

    由于我们使用了 Ribbon 因此首先启动 eureka-server 和 service-provider 服务,然后启动该项目,访问 http://localhost:8077/speak?name=abc 可以看到能正常返回信息,如下:

    Hello World abc Port=8080

    服务输出日志:

    speaks names=abc

    使用多个浏览器选项页面,访问 http://localhost:8077/speak?name=abc 多次,可以看到服务都是等待了 5秒后返回,并且都是同时返回,而服务端只被请求了一次。

       

原文地址:https://www.cnblogs.com/li3807/p/8916822.html