六、 request cache的请求缓存

 

查找是否开启了request cache,是否有请求缓存,如果有缓存,直接取用缓存,返回结果

6.1 reqeust context请求上下文概念

首先,有一个概念,叫做reqeust context,请求上下文。一般来说,在一个web应用中reqeust context(请求上下文),在一个web应用中,Hystrix会在一个filter里面,对每一个请求都施加一个请求上下文,例如 tomcat容器内,每一次请求,就是一次请求上下文,然后在这一次请求上下文中,我们会去执行N多代码,调用N多依赖服务,有的依赖服务可能还会调用好几次,在一次请求上下文中,如果有多个command,参数都是一样的,调用的接口也是一样的,其实结果可以认为也是一样的;那么这个时候,我们就可以让第一次command执行,返回的结果,被缓存在内存中,然后这个请求上下文中,后续的其他对这个依赖的调用全部从内存中取用缓存结果就可以了

不用在一次请求上下文中反复多次的执行一样的command,提升整个请求的性能。

 

6.2 初始化一个request context

一般来说,在java web来的应用中,都是通过filter过滤器来实现的

HystrixCommand和HystrixObservableCommand都可以指定一个缓存key,然后hystrix会自动进行缓存,接着在同一个request context内,再次访问的时候,就会直接取用缓存

用请求缓存,可以避免重复执行网络请求

多次调用一个command,那么只会执行一次,后面都是直接取缓存

对于请求缓存(request caching),请求合并(request collapsing),请求日志(request log),等等技术,都必须自己管理HystrixReuqestContext的声明周期

在一个请求执行之前,都必须先初始化一个request context

HystrixRequestContext context = HystrixRequestContext.initializeContext();

然后在请求结束之后,需要关闭request context

context.shutdown();

/**

 * hystrix请求上下文过滤器,请求缓存

 * @author Administrator

 *

 */

public class HystrixRequestContextFilter implements Filter {

    public void init(FilterConfig config) throws ServletException {

      

    }

    public void doFilter(ServletRequest request, ServletResponse response,

           FilterChain chain) throws IOException, ServletException {

       HystrixRequestContext context = HystrixRequestContext.initializeContext();

       try {

           chain.doFilter(request, response);

       } catch (Exception e) {

           e.printStackTrace();

       } finally {

           context.shutdown();

       }

    }

    public void destroy() {

      

    }

}

 

 

6.3 注册HystrixRequestContextFilter过滤器

   @Bean

    public FilterRegistrationBean filterRegistrationBean() {

        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new HystrixRequestContextFilter());

        filterRegistrationBean.addUrlPatterns("/*");

        return filterRegistrationBean;

    }

 

6.4 request cache的在Command中的实现

一次请求,就是一次request context,对相同的查询只能执行一次,其余的都走request cache。

在一次请求上下文中,如果有多个command,参数都是一样的,调用的接口也是一样的.那么这个时候,我们就可以让第一次command执行,返回的结果,被缓存在内存中,然后这个请求上下文中,,后续的其他对这个依赖的调用全部从内存中取用缓存结果

  /**

     * HystrixCommandHystrixObservableCommand都可以指定一个缓存key

     * 然后hystrix会自动进行缓存,接着在同一个request context内,再次访问的时候,就会直接取用缓存用请求缓存,

     * 可以避免重复执行网络请求

     */

    @Override

    protected String getCacheKey() {

        return "joint_examWholeAnalysis_" + associatedId;

    }

一个批量查询数据的接口

    /**

     * 总分分析:request cache

     * 在一次请求上下文中,如果有多个command,参数都是一样的,调用的接口也是一样的

     * 那么这个时候,我们就可以让第一次command执行,返回的结果,被缓存在内存中,然后这个请求上下文中,

     * 后续的其他对这个依赖的调用全部从内存中取用缓存结果

     * @param associatedId

     * @return

     * @throws ExecutionException

     * @throws InterruptedException

     */

    @RequestMapping(value="/jointExamWholeAnalysis/associatedIds/{associatedIds}")

    public String jointExamWholeAnalysisByIds(@PathVariable String associatedIds,HttpServletRequest request) throws InterruptedException, ExecutionException{

        String url = SERVICE_IP_PORT + MDJ_API_ASSOCIATED_JOINT_EXAM_WHOLE_ANALYSIS;

        for (String associatedId:associatedIds.split(",")) {

            HystrixCommand<String> jointExamWholeAnalysisCommand = new JointExamWholeAnalysisCommand(associatedId, url);

            String jointExamWholeAnalysis = jointExamWholeAnalysisCommand.execute();

            System.out.println(jointExamWholeAnalysis);

            System.out.println(jointExamWholeAnalysisCommand.isResponseFromCache());

 

        }

        return "success";

    }

 

6.5 Hystrix缓存的手动清理

    /**

     * 缓存的手动清理

     * @param associatedId

     */

    public static void flushCache(String associatedId) {

        HystrixRequestCache.getInstance(COMMAND_KEY, HystrixConcurrencyStrategyDefault.getInstance()).clear(associatedId);

    }

 

/**

 * request cache 手动清除Command

 * @author mawenbo

 *

 */

public class JoinExamWholeAnalysisFlushCacheCommand  extends HystrixCommand<Boolean>{

   

   

    private String associatedId;

    private static final HystrixCommandKey COMMAND_KEY = HystrixCommandKey.Factory.asKey("jointExamWholeAnalysis");

 

    public JoinExamWholeAnalysisFlushCacheCommand(String associatedId) {

        super(Setter

              //CommondGroup:默认情况下,因为就是通过command group来定义一个线程池的,统计信息,成功次数,[timeout(thread)]超时次数,失败次数,可以看到某一个服务整体的一些访问情况

                .withGroupKey(HystrixCommandGroupKey.Factory.asKey("AssociatedExamAllCourses"))

                .andCommandKey(COMMAND_KEY)

        );

    }

 

    @Override

    protected Boolean run() throws Exception {

        //执行缓存信息更新,清除缓存

        JointExamWholeAnalysisCommand.flushCache(associatedId);

        return true;

    }

 

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值