【SpringCloud NetFlix】SpringCloud整合Hystrix (二)请求合并与缓存

SpringCloud整合Hystrix (二)请求合并与缓存

引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
缓存
  • 新建过滤器
  • 使用缓存注解
  • 删除缓存
    • 配置命令key
    • 使用注解删除缓存

新建过滤器

@WebFilter(urlPatterns = "/*", filterName = "hystrixFilter")
public class MyFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {

    }
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HystrixRequestContext ctx = HystrixRequestContext.initializeContext();
        try {
            chain.doFilter(request, response);
        } catch (Exception e) {

        } finally {
            ctx.shutdown();
        }
    }
    public void destroy() {

    }
}

主启动类开启过滤器

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
//在 SpringBootApplication 上使用@ServletComponentScan 注解后,Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册
@ServletComponentScan
public class SaleApp {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
        public static void main(String[] args) {
        new SpringApplicationBuilder(SaleApp.class).web(true).run(args);
    }
}

使用缓存注解

@Service
public class CacheService {

    @Autowired
    private RestTemplate restTpl;

    //@CacheResult配合@HystrixCommand一起使用才有效果
    //该注解用来标记请求命令返回的结果应该被缓存,它必须与@HystrixCommand注解结合使用
    @CacheResult
    @HystrixCommand
    public Member cacheMember(Integer id) {
        System.out.println("调用 cacheMember 方法");
//      Member member = restTpl.getForObject(
//              "http://spring-hy-member/member/{id}", Member.class, id);
        return null;
    }

    @CacheResult
    //设置缓存的key值,便于删除指定key值结果
    //该注解用来在请求命令的参数上标记,使其作为缓存的Key值,如果没有标注则会使用所有参数。如果同事还是使用了@CacheResult和@CacheRemove注解的cacheKeyMethod方法指定缓存Key的生成,那么该注解将不会起作用
    @HystrixCommand(commandKey = "cacheKey")
    public String getCache(Integer id) {
        System.out.println("执行查询方法");
        return null;
    }

    //该注解用来让请求命令的缓存失效,失效的缓存根据定义Key决定
    @CacheRemove(commandKey = "cacheKey")
    @HystrixCommand
    public void removeCache(Integer id) {
        System.out.println("删除缓存方法");
    }
}

调用测试

@RestController
public class CacheController {

    @Autowired
    private CacheService cacheService;

    @RequestMapping(value = "/cache", method = RequestMethod.GET, 
            produces = MediaType.APPLICATION_JSON_VALUE)
    public String cache() {
        for(int i = 0; i < 3; i++) {
             //调用同样的接口,调用接口才会走缓存
            cacheService.cacheMember(1);
        }
        return "";
    }
    @RequestMapping(value = "/rc", method = RequestMethod.GET, 
            produces = MediaType.APPLICATION_JSON_VALUE)
    public String testRemoveCache() {
        cacheService.getCache(1);
        cacheService.getCache(1);

        cacheService.removeCache(1);
        System.out.println("#########  分隔线   ###########");
        cacheService.getCache(1);
        return "";
    }
}
请求合并

请求收集器

场景:对同一个请求多次调用,仅仅是请求参数不一致,可以考虑采用请求合并。

意义:一次传输比多次传输占用的带宽少,但是收集请求的过程中会占用服务器的资源,一次返回的结果数据量太大也会影响传输性能,用的时候需要权衡一下。

服务调用方

service

@Service
public class CollService {

    @HystrixCollapser(batchMethod = "getMembers", collapserProperties = {
            //1秒内发送的相同URL不同参数的请求都被收集
            @HystrixProperty(name = "timerDelayInMilliseconds", value = "1000")
    })
    //通过此处的单个请求方法来收集请求,然后实际执行getMembers,可以减少服务之间的调用
    public Future<Member> getMember(Integer id) {
        System.out.println("执行单个查询的方法");
        return null;
    }

    @HystrixCommand
    public List<Member> getMembers(List<Integer> ids) {
        List<Member> mems = new ArrayList<Member>();
        for(Integer id : ids) {
            System.out.println(id);
            Member m = new Member();
            m.setId(id);
            m.setName("angus");
            mems.add(m);
        }
        return mems;
    }
}

测试调用

@RestController
public class CollController {

    @Autowired
    private CollService collService;

    @RequestMapping(value = "/coll", method = RequestMethod.GET, 
            produces = MediaType.APPLICATION_JSON_VALUE)
    public String testCollapse() throws Exception {
        // 连续执行3次请求
        Future<Member> f1 = collService.getMember(1);
        Future<Member> f2 = collService.getMember(2);
        Future<Member> f3 = collService.getMember(3);
        Member p1 = f1.get();
        Member p2 = f2.get();
        Member p3 = f3.get();   
        return "";
    }
}

以上为疯狂SpringCloud微服务架构实战学习笔记
感谢杨恩雄老师:https://my.oschina.net/JavaLaw

猜你喜欢

转载自blog.csdn.net/zlt995768025/article/details/81663500