疯狂Spring Cloud连载(20)Hystrix缓存与合并请求


声明:本文转载自https://my.oschina.net/JavaLaw/blog/1574823,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

本文节选自《疯狂Spring Cloud微服务架构实战》

Spring Cloud教学视频:https://my.oschina.net/JavaLaw/blog/1552993

Spring Cloud电子书:https://my.oschina.net/JavaLaw/blog/1570383

缓存与合并请求

缓存注解

        在6.3章节中,讲述了Hystrix的缓存功能,在Spring Cloud中,同样支持使用缓存,并且可以通过注解来实现。根据前面章节可知,缓存与合并请求功能,需要先初始化请求上下文才能实现。新建一个javax.servlet.Filter,用于创建与销毁Hystrix的请求上下文,请见代码清单6-9。

        代码清单6-19:

        codes\06\6.4\spring-hystrix-invoker\src\main\java\org\crazyit\cloud\HystrixFilter.java

@WebFilter(urlPatterns = "/*", filterName = "hystrixFilter") public class HystrixFilter implements Filter {      public void init(FilterConfig filterConfig) throws ServletException {     }     public void doFilter(ServletRequest request, ServletResponse response,             FilterChain chain) throws IOException, ServletException {         HystrixRequestContext context = HystrixRequestContext                 .initializeContext();         try {             chain.doFilter(request, response);         } finally {             context.shutdown();         }     }     public void destroy() {     } } 

        编写服务方法,使用@CacheResult注解进行修饰,请见代码清单6-20。

        代码清单6-20:CacheService.java

@Component public class CacheService {      @CacheResult     @HystrixCommand     public Person getPerson(Integer id) {         System.out.println("执行 getPerson 方法");         Person p = new Person();         p.setId(id);         p.setName("angus");         return p;     } } 

        注意服务方法中,被调用一次就会进行一次控制台输出。在控制器的方法中,调用多次getPerson方法,控制器代码请见代码清单6-21。

        代码清单6-21:

        codes\06\6.4\spring-hystrix-invoker\src\main\java\org\crazyit\cloud\InvokerController.java

    @RequestMapping(value = "/cache1/{personId}", method = RequestMethod.GET,              produces = MediaType.APPLICATION_JSON_VALUE)     public Person testCacheResult(@PathVariable Integer personId) {         // 调用多次服务         for(int i = 0; i < 3; i++) {             Person p = cacheService.getPerson(personId);             System.out.println("控制器调用服务 " + i);         }         return new Person();     } 

        控制器中调用了多次服务方法,也就是用户发送请求后,会执行多次服务方法,启动“服务调用者”,访问以下地址:http://localhost:9000/cache1/1,控制台输出如下:

执行 getPerson 方法 控制器调用服务 0 控制器调用服务 1 控制器调用服务 2 

        根据输出结果可知,在一次用户请求的过程中,服务方法只执行了一次,缓存生效。缓存的注解主要有以下3个:

  • @CacheResult:该注解修饰方法,表示被修饰的方法返回结果将会被缓存,需要与@HystrixCommand一起使用。
  • @CacheRemove:用于修饰方法让缓存失效,需要与@CacheResult的缓存key关联。
  • @CacheKey:用于修饰方法参数,表示该参数作为缓存的key。

        前面的例子使用了@CacheResult注解,下面的代码片断,结合@CacheResult与@CacheRemove一起使用:

    @CacheResult()     @HystrixCommand(commandKey = "removeKey")     public String cacheMethod(String name) {         return "hello";     }      @CacheRemove(commandKey = "removeKey")     @HystrixCommand     public String updateMethod(String name) {         return "update";     } 

        以上代码片断中的cacheMethod方法,使用的缓存key为“removeKey”,方法updateMethod被调用后,将会删除key为“updateMethod”的缓存。关于3个缓存注解更深入的使用,本小节不再赘述,读者可以自行测试。

合并请求注解

        在Spring Cloud中,同样支持合并请求,在一次HTTP请求的过程中,收集一段时间内的相同请求,放到一个批处理命令中执行。实现合并请求,同样需要先初始化请求上下文,具体请参见6.4.4中的Filter。接下来,编写服务类,请见代码清单6-22。

        代码清单6-22:CollapseService.java

public class CollapseService {      // 配置收集1秒内的请求     @HystrixCollapser(batchMethod = "getPersons", collapserProperties =          {              @HystrixProperty(name = "timerDelayInMilliseconds", value = "1000")          }     )     public Future<Person> getSinglePerson(Integer id) {         System.out.println("执行单个获取的方法");         return null;     }      @HystrixCommand     public List<Person> getPersons(List<Integer> ids) {         System.out.println("收集请求,参数数量:" + ids.size());         List<Person> ps = new ArrayList<Person>();         for (Integer id : ids) {             Person p = new Person();             p.setId(id);             p.setName("crazyit");             ps.add(p);         }         return ps;     } } 

        代码清单中,最后真实执行的方法为“getPersons”,getSinglePerson方法使用了@HystrixCollapser注解来修饰,会收集1秒内调用getSinglePerson的请求,放到getPersons方法中进行批处理。控制器中调用多次getSinglePerson方法,如代码清单6-23所示。

        代码清单6-23:

        codes\06\6.4\spring-hystrix-invoker\src\main\java\org\crazyit\cloud\InvokerController.java

    @RequestMapping(value = "/collapse", method = RequestMethod.GET,              produces = MediaType.APPLICATION_JSON_VALUE)     public String testCollapse() throws Exception {         // 连续执行3次请求         Future<Person> f1 = collapseService.getSinglePerson(1);         Future<Person> f2 = collapseService.getSinglePerson(2);         Future<Person> f3 = collapseService.getSinglePerson(3);         Person p1 = f1.get();         Person p2 = f2.get();         Person p3 = f3.get();         System.out.println(p1.getId() + "---" + p1.getName());         System.out.println(p2.getId() + "---" + p2.getName());         System.out.println(p3.getId() + "---" + p3.getName());                 return "";     } 

        异步执行了3次getSinglePerson方法,启动“服务调用者”,访问以下地址:http://localhost:9000/collapse,控制台输出如下:

收集请求,参数数量:3 1---crazyit 2---crazyit 3---crazyit 

        根据输出结果可知,最终只执行了getPersons方法。相对于直接使用Hystrix,Spring Cloud中合并请求较为简单,合并处理器已经由@HystrixCollapser注解帮我们实现,我们仅关心真正命令的执行即可。

本文节选自《疯狂Spring Cloud微服务架构实战》

Spring Cloud教学视频:https://my.oschina.net/JavaLaw/blog/1552993

Spring Cloud电子书:https://my.oschina.net/JavaLaw/blog/1570383

本书代码共享地址:https://gitee.com/yangenxiong/SpringCloud

本文发表于2017年11月17日 10:33
(c)注:本文转载自https://my.oschina.net/JavaLaw/blog/1574823,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2156 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1