SpringCloud(11):Hystrix请求合并

news/2023/6/7 23:22:37

1 简介

 

如图,多个客户端发送请求调用(消费者)项目中的findOne方法,这时候在这个项目中的线程池中会发申请与请求数量相同的线程数,对EurekaServiceProvider(服务提供者)的getUserById方法发起调用,每个线程都要调用一次,在高并发的场景下,这样势必会对服务提供者项目产生巨大的压力。

请求合并就是将单个请求合并成一个请求,去调用服务提供者,从而降低服务提供者负载的,一种应对高并发的解决办法

2 请求合并的原理

NetFlix在Hystrix为我们提供了应对高并发的解决方案----请求合并,如下图

 

通过请求合并器设置延迟时间,将时间内的,多个请求单个的对象的方法中的参数(id)取出来,拼成符合服务提供者的多个对象返回接口(getUsersByIds方法)的参数,指定调用这个接口(getUsersByIds方法),返回的对象List再通过一个方法(mapResponseToRequests方法),按照请求的次序将结果对象对应的装到Request对应的Response中返回结果。

3 请求合并适用的场景

在服务提供者提供了返回单个对象和多个对象的查询接口,并且单个对象的查询并发数很高,服务提供者负载较高的时候,我们就可以使用请求合并来降低服务提供者的负载

4 请求合并带来的问题

问题:即然请求合并这么好,我们是否就可以将所有返回单个结果的方法都用上请求合并呢?答案自然是否定的!

原因:

1. 我们为这个请求人为的设置了延迟时间,这样在并发不高的接口上使用请求缓存,会降低响应速度

2. 实现请求合并比较复杂

5 实现方式

修改OrderService,添加下面方法

    @HystrixCollapser(batchMethod = "findAll", collapserProperties = {@HystrixProperty(name = "timerDelayInMilliseconds", value = "300")})public Future<String> findOne(Integer id) {System.out.println("被合并的请求");return null;}@HystrixCommandpublic List<String> findAll(List<Integer> ids) {System.out.println("合并的请求");String url = "http://study-user/getUserAll?ids={1}";return restTemplate.getForObject(url, List.class, StringUtils.join(ids, ","));}

在OrderController进行测试

    @RequestMapping("/findTest")public String findTest() throws ExecutionException, InterruptedException {HystrixRequestContext context = HystrixRequestContext.initializeContext();Future<String> f1 = orderService.findOne(1);Future<String> f2 = orderService.findOne(2);Thread.sleep(150);Future<String> f3 = orderService.findOne(3);String res = f1.get() + " , " + f2.get() + " , " + f3.get();context.close();return res;}

测试接口

 

查看日志输出

 

注解讲解:

以下面代码为例

@HystrixCommand(groupKey = "productStockOpLog", commandKey = "addProductStockOpLog",
fallbackMethod = "addProductStockOpLogFallback",
commandProperties = {
@HystrixProperty(name =
"execution.isolation.thread.timeoutInMilliseconds", value = "400"),//指定多久超时,单位毫秒。超
时进fallback
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value
= "10"),//判断熔断的最少请求数,默认是10;只有在一个统计窗口内处理的请求数量达到这个阈值,才会进行熔断与否
的判断
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",
value = "10"),//判断熔断的阈值,默认值50,表示在一个统计窗口内有50%的请求处理失败,会触发熔断
}
)
public void addProductStockOpLog(Long sku_id, Object old_value, Object new_value) throws
Exception {
if (new_value != null && !new_value.equals(old_value)) {
doAddOpLog(null, null, sku_id, null, ProductOpType.PRODUCT_STOCK, old_value != null
? String.valueOf(old_value) : null, String.valueOf(new_value), 0, "C端", null);
}
}
public void addProductStockOpLogFallback(Long sku_id, Object old_value, Object new_value)
throws Exception {
LOGGER.warn("发送商品库存变更消息失败,进入Fallback,skuId:{},oldValue:{},newValue:{}",
sku_id, old_value, new_value);
}

@HystrixCommand(groupKey="UserGroup", commandKey = "GetUserByIdCommand",
commandProperties = {
@HystrixProperty(name =
"execution.isolation.thread.timeoutInMilliseconds", value = "100"),//指定多久超时,单位毫秒。超
时进fallback
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value
= "10"),//判断熔断的最少请求数,默认是10;只有在一个统计窗口内处理的请求数量达到这个阈值,才会进行熔断与否
的判断
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",
value = "10"),//判断熔断的阈值,默认值50,表示在一个统计窗口内有50%的请求处理失败,会触发熔断
},
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "30"),
@HystrixProperty(name = "maxQueueSize", value = "101"),
@HystrixProperty(name = "keepAliveTimeMinutes", value = "2"),
@HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"),
@HystrixProperty(name = "metrics.rollingStats.numBuckets", value =
"12"),
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds",
value = "1440")
})

超时时间(默认1000ms,单位:ms)

(1)hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds

在调用方配置,被该调用方的所有方法的超时时间都是该值,优先级低于下边的指定配置

(2)hystrix.command.HystrixCommandKey.execution.isolation.thread.timeoutInMilliseconds

在调用方配置,被该调用方的指定方法(HystrixCommandKey方法名)的超时时间是该值

线程池核心线程数 hystrix.threadpool.default.coreSize(默认为10)

Queue

(1)hystrix.threadpool.default.maxQueueSize(最大排队长度。默认-1,使用SynchronousQueue。其他值则使用 LinkedBlockingQueue。如果要从-1换成其他值则需重启,即该值不能动态调整,若要动态调整,需要使用到下边 这个配置)

(2)hystrix.threadpool.default.queueSizeRejectionThreshold(排队线程数量阈值,默认为5,达到时拒 绝,如果配置了该选项,队列的大小是该队列)

注意:如果maxQueueSize=-1的话,则该选项不起作用

断路器

(1)hystrix.command.default.circuitBreaker.requestVolumeThreshold(当在配置时间窗口内达到此数量 的失败后,进行短路。默认20个)

For example, if the value is 20, then if only 19 requests are received in the rolling

window (say a window of 10 seconds) the circuit will not trip open even if all 19 failed.

简言之,10s内请求失败数量达到20个,断路器开。

(2)hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds(短路多久以后开始尝试是否恢复,默认5s)

(3)hystrix.command.default.circuitBreaker.errorThresholdPercentage(出错百分比阈值,当达到此阈值后,开始短路。默认50%)

fallback

hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests(调用线程允许请求HystrixCommand.GetFallback()的最大数量,默认10。超出时将会有异常抛出,注意:该项配置对于THREAD隔离模式也起作用)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-4555153.html

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

关于SPI的隔离

SPI&#xff08;Serial Peripheral interface&#xff09;&#xff0c;即串行外围设备接口&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;由于其在芯片的管脚上只占用四根线&#xff0c;节约了芯片的管脚&#xff0c;同时为PCB的布局上节省…

CAN中继、CAN隔离器、智能三路CAN总线路由器集线器助力灵活组网

CANbridge-300智能CAN总线集线器具有3路独立隔离的can通道&#xff0c;每路CAN接口采用金升阳CAN隔离收发模块实现3000VDC电气隔离&#xff0c;电源输入防反设计&#xff0c;支持DC6.5~36V输入;具有优秀的EMC性能&#xff0c;可靠性测试项目: ESD接触放电6KV、浪涌1KV、脉冲群2…

PCB设计1 模块间的隔离

想要给板子的各个部分进行电气隔离&#xff0c;比如电源转压之后的各个电压12V | 5V | 3.3V 和用电的设备之间进行隔离&#xff0c;本来的想法是用2pin的跳线帽&#xff0c;但是在参考了一些资料之后&#xff0c;对2pin跳线帽有了一个新的认识&#xff0c;对2pin的跳线帽&#…

电子电气设备的电路隔离技术

电子电气设备的电路隔离技术 摘要&#xff1a;对电子电气电路的各种隔离进行了详尽的分析讨论&#xff0c;提出了抑制干扰而采取的电气隔离的技术措施&#xff0c;从而保证电气设备的正常工作。 关键词&#xff1a;电子&#xff1b;电路&#xff1b;电气隔离&#xff1b;干扰…

【Web技术】1048- 手把手教你实现web文本划线的功能

来源 | https://www.cnblogs.com/wanglinmantan/p/15106871.html开篇文本划线是目前逐渐流行的一个功能&#xff0c;不管你是小说阅读网站&#xff0c;还是卖教程的的网站&#xff0c;一般都会有记笔记或者评论的功能&#xff0c;传统的做法都是在文章底部加一个评论区&#xf…

photoshop菜鸟实用入门----选区

在Photoshop中处理图像时&#xff0c;精确地进行范围选取是一项非常重要的工作&#xff0c;这一操作的准胡与否将直接关系到最终图像处理效果的成败。不论是使用滤镜特效、使用色彩或色调等高级功能&#xff0c;还是进行简单的复制、粘贴或删除等操作&#xff0c;都与当前的选取…

html边缘取消白边,Photoshop巧用边缘蒙版去除锐化后的白边

学习PS微信公众号&#xff1a;xxps1979在摄影后期中&#xff1a;锐化的时候&#xff0c;经常会出现一些难看、尴尬的白边儿&#xff0c;非常的影响效果&#xff0c;相信每个人都有这样的经历;这个是和锐化的原理有关——锐化就是在细节边缘建立黑边儿、白边儿&#xff0c;增加局…

vim 全局替换_有一说一,Intellij IDEA 自带的 Vim 插件真心不错!

作者&#xff1a;kidneyball链接&#xff1a;iteye.com/blog/kidneyball-1828427在 IDEA Intellij小技巧和插件 一文中简单介绍了一下IdeaVim插件。在这里详细总结一下这个插件在日常编程中的一些常用小技巧。供有兴趣使用这个插件&#xff0c;但对Vim还不十分熟悉的朋友参考。…