0
点赞
收藏
分享

微信扫一扫

Hystrix服务容错之请求合并

在觉 2023-02-21 阅读 100


当多个请求同时去请求一个方法时,可以等待一定数量的请求都过来以后,一并处理,这样相当于只调用了一次接口,比较节省服务器资源

增加依赖

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

服务实现类方法

注意里面的单个参数的方法就是原来多次调用的,增加了@HystrixCollapser注解修饰,batchMethod 对应的就是另一个ids参数的方法,相当于就是把id给集中起来用ids去访问另一个方法

我使用的时候,如果参数不是List就会报错,batch method is absent,找不到批处理方法

getOrderByIds这个方法如果​​List<Order> list = new ArrayList<>();​​这个集合的个数和请求合并的请求数量不同的话,会报错如下,当然这是我在学习中遇到的,实际生产中应该不会这样

Caused by: rx.exceptions.OnErrorNotImplementedException: Failed to map all collapsed requests to response. The expected contract has not been respected. 
Collapser key: ‘getOrderByIds’, requests size: ‘5’, response size: ‘1’

主要代码

com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL

我看了下源码中另一个参数REQUEST,是什么将请求折叠,不懂

GLOBAL这个意思合并作用域,就是不会跨越多个请求会话的,只在当前用户请求中合并多次请求为批处理请求。这里改成GLOBAL,就是可以跨越request context,合并不同用户的请求为一次批处理请求。

@HystrixCollapser(batchMethod = "getOrderByIds",
scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,
collapserProperties = {
//间隔多久的请求会进行合并,默认10ms
@HystrixProperty(name = "timerDelayInMilliseconds", value = "20"),
//批处理之前,批处理中允许的最大请求数
@HystrixProperty(name = "maxRequestsInBatch", value = "200"),
})
@Override
public Future<Order> getOrder(Integer id) {
System.out.println("单独的方法被单独调用了");
// Order order = new Order(1, "用户订单", 2, productService.getProductById(id));
return null;
}

//声明需要服务容错的方法
@HystrixCommand
@Override
public List<Order> getOrderByIds(List<Integer> ids) {
System.out.println("批量的请求方法被调用了");
Order order1 = new Order(1, "用户订单", 2, productService.getProduct());
Order order2 = new Order(1, "用户订单", 2, productService.getProduct());
Order order3 = new Order(1, "用户订单", 2, productService.getProduct());
Order order4 = new Order(1, "用户订单", 2, productService.getProduct());
Order order5 = new Order(1, "用户订单", 2, productService.getProduct());
List<Order> list = new ArrayList<>();
list.add(order1);
list.add(order2);
list.add(order3);
list.add(order4);
list.add(order5);
return list;
}

这里用Future来模拟并发请求

@RequestMapping("/orderById")
public Order getOrder(Integer id) {

Future<Order> order1 = orderService.getOrder(id);
Future<Order> order2 = orderService.getOrder(id);
Future<Order> order3 = orderService.getOrder(id);
Future<Order> order4 = orderService.getOrder(id);
Future<Order> order5 = orderService.getOrder(id);

try {
System.out.println(order1.get());
System.out.println(order2.get());
System.out.println(order3.get());
System.out.println(order4.get());
System.out.println(order5.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}

return new Order(1, "用户订单", 2, null);
}

主启动类增加注解
@EnableHystrix
@EnableCircuitBreaker
这两个都能用,选择一个就行,效果一样,在仅仅实现请求合并的情况下一模一样

package com.qiangqiang;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
//熔断器注解,下面的二选一
//@EnableHystrix
@EnableCircuitBreaker
@EnableFeignClients
public class SpringCloudOrderServerRemergeApplication {

public static void main(String[] args) {
SpringApplication.run(SpringCloudOrderServerRemergeApplication.class, args);
}

}


举报

相关推荐

0 条评论