六、 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;

    }

 

}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章