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