使用Hystrix实现请求合并,降低服务器并发压力

1.引入Hystrix 

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

2.在启动类上开启Hystrix功能

@EnableHystrix

3.请求合并实现代码

import com.bzcst.bop.oms.orm.model.po.Product;
import com.bzcst.bop.oms.orm.service.ProductService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.Future;/*** @author 向振华* @date 2023/10/26 14:37*/
@Slf4j
@Service
public class BatchService {@Resourceprivate ProductService productService;@HystrixCollapser(batchMethod = "getByIds",scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,collapserProperties = {@HystrixProperty(name = HystrixPropertiesManager.MAX_REQUESTS_IN_BATCH, value = "10"),@HystrixProperty(name = HystrixPropertiesManager.TIMER_DELAY_IN_MILLISECONDS, value = "20")})public Future<Product> getById(Long id) {return null;}@HystrixCommandpublic List<Product> getByIds(List<Long> ids) {log.info("批查询 ---> " + ids);return productService.listByIds(ids);}
}

其中getById(Long id)方法并不会进入。 

其中ProductService 是基于mybatisplus的查询接口。

import com.bzcst.bop.oms.orm.model.po.Product;
import com.baomidou.mybatisplus.extension.service.IService;public interface ProductService extends IService<Product> {}

 4.调用

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.bzcst.bop.oms.orm.model.po.Product;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;/*** @author 向振华* @date 2023/10/26 14:32*/
@RestController
public class TestController {@Resourceprivate BatchService batchService;@GetMapping("/product/{id}")public Object product(@PathVariable Long id) throws Exception {Future<Product> productFuture = batchService.getById(id);return productFuture.get();}public static void main(String[] args) {// 创建线程池ExecutorService executorService = Executors.newFixedThreadPool(20);// 模拟20个并发请求CountDownLatch countDownLatch = new CountDownLatch(20);for (int i = 1; i <= 20; i++) {int fi = i;executorService.execute(() -> {try {countDownLatch.await();HttpRequest httpRequest = HttpRequest.get("http://localhost:8080/bop-oms/product/" + fi);String body = httpRequest.execute().body();System.out.println(fi + " ---> " + body);} catch (Exception e) {}});countDownLatch.countDown();}}
}

日志记录可以看出是批量处理

2023-10-26 17:54:31.708  INFO 10524 --- [-BatchService-9] c.bzcst.bop.oms.controller.BatchService  : 批查询 ---> [10, 5, 9, 15, 4, 12, 11, 16, 8, 14]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@58dfec5b] was not registered for synchronization because synchronization is not active
parser sql: SELECT id, xxx FROM oms_product WHERE id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2023-10-26 17:54:31.712  INFO 10524 --- [-BatchService-8] c.bzcst.bop.oms.controller.BatchService  : 批查询 ---> [3, 18, 1, 13, 7, 19, 20, 2, 6, 17]
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4235ea19] was not registered for synchronization because synchronization is not active
parser sql: SELECT id, xxx FROM oms_product WHERE id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
JDBC Connection [HikariProxyConnection@935862209 wrapping com.mysql.cj.jdbc.ConnectionImpl@130542a5] will not be managed by Spring
==>  Preparing: SELECT id, xxx FROM oms_product WHERE id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
==> Parameters: 10(Long), 5(Long), 9(Long), 15(Long), 4(Long), 12(Long), 11(Long), 16(Long), 8(Long), 14(Long)
JDBC Connection [HikariProxyConnection@205926351 wrapping com.mysql.cj.jdbc.ConnectionImpl@67b600cc] will not be managed by Spring
==>  Preparing: SELECT id, xxx FROM oms_product WHERE id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
==> Parameters: 3(Long), 18(Long), 1(Long), 13(Long), 7(Long), 19(Long), 20(Long), 2(Long), 6(Long), 17(Long)
<==    Columns: id, tenant_id, category_id, name, code, price, ladder_price, is_ladder_price, unit, is_enabled, description, version, create_by, create_time, update_by, update_time, delete_flag
<==        Row: 4, 1, 0, 转供电, 4, 4.00, , 0, , 1, , 1,  , 2022-12-29 17:01:09,  , 2022-12-29 17:01:09, 0
<==        Row: 5, 1, 0, 通下水道, XSD, 5.00, , 0, , 1, , 1,  , 2023-05-23 18:24:30,  , 2023-05-23 18:24:30, 0
<==        Row: 8, 1, 0, 门卡押金, 0302, 8.00, , 0, , 1, , 1,  , 2023-03-04 10:57:50,  , 2023-04-14 09:53:17, 0
<==        Row: 9, 1, 0, 阶梯单价, 12321, 9.00, , 1, , 1, , 1,  , 2023-10-13 16:39:09,  , 2023-10-13 16:39:09, 0
<==        Row: 10, 1, 0, 阿萨德, 123333, 10.00, , 0, , 1, , 1,  , 2023-09-14 10:43:01,  , 2023-09-14 10:43:01, 0
<==        Row: 11, 1, 0, 补贴空置费, 444, 11.00, , 0, , 1, , 1,  , 2023-03-02 17:05:10,  , 2023-03-02 17:05:10, 0
<==        Row: 12, 1, 0, 路灯费, B<N, 12.00, , 0, , 1, , 1,  , 2023-03-03 10:55:23,  , 2023-03-03 10:55:23, 0
<==        Row: 14, 1, 0, 零星物业, 3, 14.00, , 0, , 1, , 1,  , 2023-03-02 16:50:05,  , 2023-03-02 16:50:05, 0
<==        Row: 15, 1, 0, 零星电费, 2, 15.00, , 0, , 1, , 1,  , 2023-03-02 16:49:46,  , 2023-03-02 16:49:46, 0
<==        Row: 16, 1, 0, 非生活垃圾清运费, 16, 16.00, , 0, , 1, , 1,  , 2022-12-29 17:01:09,  , 2022-12-29 17:01:09, 0
<==      Total: 10
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@58dfec5b]
<==    Columns: id, tenant_id, category_id, name, code, price, ladder_price, is_ladder_price, unit, is_enabled, description, version, create_by, create_time, update_by, update_time, delete_flag
<==        Row: 1, 1, 0, 专项维修金, 1, 1.00, , 0, , 1, , 1,  , 2022-12-29 17:01:09,  , 2022-12-29 17:01:09, 0
<==        Row: 2, 1, 0, 车位空置费, 2, 2.00, , 0, , 1, , 1,  , 2022-12-29 17:01:09,  , 2022-12-29 17:01:09, 0
<==        Row: 3, 1, 0, 车位费, CWF01, 3.00, , 0, , 1, , 1,  , 2023-10-10 09:57:07,  , 2023-10-10 09:57:07, 0
<==        Row: 6, 1, 0, 服务费, 6, 6.00, , 0, , 1, , 1,  , 2022-12-29 17:01:09,  , 2022-12-29 17:01:09, 0
<==        Row: 7, 1, 0, 销售配合费, s, 7.00, , 0, , 1, , 1,  , 2022-12-29 17:01:09,  , 2022-12-29 17:01:09, 0
<==        Row: 13, 1, 0, 零星水费, 1, 13.00, , 0, , 1, , 1,  , 2023-03-02 16:49:18,  , 2023-03-02 16:49:18, 0
<==        Row: 17, 1, 0, 顾问费, 17, 17.00, , 0, , 1, , 1,  , 2022-12-29 17:01:09,  , 2022-12-29 17:01:09, 0
<==        Row: 18, 1, 0, 餐饮垃圾费, 18, 18.00, , 0, , 1, , 1,  , 2022-12-29 17:01:09,  , 2022-12-29 17:01:09, 0
<==        Row: 19, 1, 0, 租赁广告费用, 1000123, 19.00, [], 0, , 1, , 1,  , 2023-06-08 10:51:16,  , 2023-06-08 10:51:16, 0
<==        Row: 20, 1, 0, 租金, ZJ002, 20.00, [], 0, , 1, , 1,  , 2023-03-15 17:40:12,  , 2023-03-15 17:40:12, 0
<==      Total: 10
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4235ea19]

或者这样请求也可以

    @GetMapping("/product")public void product() throws Exception {List<Future> list = new ArrayList<>();for (long i = 1; i <= 20; i++) {Future<Product> productFuture = batchService.getById(i);list.add(productFuture);}for (Future future : list) {Object o = future.get();System.out.println(o);}}

如果scope是REQUEST方式,则需要使用HystrixRequestContext

    @GetMapping("/product")public void product() throws Exception {HystrixRequestContext context = HystrixRequestContext.initializeContext();try {List<Future> list = new ArrayList<>();for (long i = 1; i <= 20; i++) {Future<Product> productFuture = batchService.getById(i);list.add(productFuture);}for (Future future : list) {Object o = future.get();System.out.println(o);}} finally {context.shutdown();}}

5.@HystrixCollapser参数介绍

batchMethod,请求合并方法

scope,请求合并方式,REQUEST:请求范围,GLOBAL:全局范围,默认com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL

collapserProperties
HystrixPropertiesManager.MAX_REQUESTS_IN_BATCH 最大请求合并数量,默认Integer.MAX_VALUE
HystrixPropertiesManager.TIMER_DELAY_IN_MILLISECONDS 请求合并间隔毫秒值,默认10ms

注意,达到请求合并间隔毫秒值,没达到最大请求合并数量时,也会进行请求合并

@HystrixCollapser是基于Spring的AOP实现的

com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect

6.请求合并工作流程图

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决Linux Debian12系统中安装VirtualBox虚拟机无法使用USB设备的问题

Debian12系统中安装VirtualBox&#xff0c;再VirtualBox虚拟机中无法使用 USB设备。如下图所示&#xff1a; 解决方法如下&#xff1a; 1.安装 Virtualbox增强功能。如下图所示&#xff1a; 2.添加相关用户、用户组&#xff08; Virtualbox 装完成后会有 vboxusers 和 vboxs…

Linux 网络驱动实验(PHY芯片LAN8720)

目录 嵌入式网络简介嵌入式下的网络硬件接口MII/RMII 接口MDIO 接口RJ45 接口I.MX6ULL ENET 接口简介 PHY 芯片详解PHY 基础知识简介LAN8720A 详解SR8201F 详解 Linux 内核网络驱动框架net_device 结构体net_device_ops 结构体sk_buff 结构体网络NAPI 处理机制 I.MX6ULL 网络驱…

SQL SERVER 表分区

1. 概要说明 SQL SERVER的表分区功能是为了将一个大表&#xff08;表中含有非常多条数据&#xff09;的数据根据某条件&#xff08;仅限该表的主键&#xff09;拆分成多个文件存放&#xff0c;以提高查询数据时的效率。创建表分区的主要步骤是 1、确定需要以哪一个字段作为分…

vite vue3 ts 使用sass 设置样式变量 和重置默认样式

1.安装scss 样式支持依赖 yarn add -D sass 2.使用sass <div><!-- 测试使用sass --><h1>测试使用sass</h1> </div><style scope lang"scss"> div {h1 {color: red;} } </style> 效果&#xff1a; 3.通过npm下载并复制…

Spring Cloud之Gateway网关学习【详细】

目录 统一网关Gateway 网关的实现 搭建网关 编写配置文件 路由断言工程 路由的过滤器 全局过滤器 网关过滤器执行顺序 网关的cors跨域配置 问题及解决 统一网关Gateway 网关的实现 SpringCloud中存在两种网关 gateway&#xff1a;基于Spring5中提供的WebFlux实现&a…

Unity 粒子特效-第三集-星星闪烁特效

一、特效预览 二、制作原理 星星素材资源 链接&#xff1a;https://pan.baidu.com/s/17D-9sC-ErtqmUxl81Ln1Mw?pwdndm9 提取码&#xff1a;ndm9 1.素材介绍 仔细看&#xff0c;我们的粒子贴图是&#xff08;如下&#xff09;&#xff0c;一颗星星 2.步骤介绍 1.星星动画的…

【如何写论文】硕博学位论文的结构框架、过程与大纲分析

硕士论文可以说是毕业前最重要的一部分&#xff0c;也可以说是展示和检验你3年研究生学习的成果的一个考试。硕士论文答辩和检验合格&#xff0c;才能够顺利拿到毕业生和学位证&#xff0c;可见其重要性。 目录 一、基础框架1.1、摘要&#xff08;Abstract&#xff09;1.2、绪论…

【多线程面试题十五】、synchronized可以修饰静态方法和静态代码块吗?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;synchronized可以修饰静…

灯串上亚马逊加拿大合规标准CSA认证如何办理?

灯串 灯串和配件都是插头连接的便携式、临时性商品&#xff0c;最大额定输入电压为 120 伏。 本政策适用于季节性照明、装饰性灯具以及灯串。 亚马逊灯串政策 根据亚马逊的要求&#xff0c;所有季节性和装饰性灯串均应经过检测&#xff0c;并且遵守下列法规、标准和要求&…

AUTOSAR CAN协议栈架构总览介绍

Classic AUTOSAR层级架构简介 如下图是Classic AUTOSAR层级架构图,每个层主要功能如下 微控制器抽象层:使上层软件和微处理器型号无关,包含MCU中内部外设的驱动以及MCU内存映射的外部设备的驱动ECU抽象层:使上层软件和ECU硬件设计无关,包含ECU板上外部设备的驱动以及内部…

Hi3516DV500部署paddle版型分析模型记录

原版模型测试并导出onnx paddle 版面分析-> https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.7/ppstructure/layout/README_ch.md 测试 python3 deploy/python/infer.py \ --model_dirmodel/picodet_lcnet_x1_0_fgd_layout_cdla_infer/ \ --image_fil…

Apache Dolphinscheduler如何不重启解决Master服务死循环

个人建议 Apache Dolphinscheduler作为一个开源的调度平台&#xff0c;目前已经更新到了3.X版本&#xff0c;4.0版本也已经呼之欲出。3.0版本作为尝鲜版本&#xff0c;新添加了许多的功能&#xff0c;同时也存在非常多的隐患&#xff0c;本人使用3.0版本作为生产调度也踩了很多…

Android开发知识学习——TCP / IP 协议族

文章目录 学习资源来自&#xff1a;扔物线TCP / IP 协议族TCP连接TCP 连接的建立与关闭TCP 连接的建立为什么要三次握手&#xff1f; TCP 连接的关闭为什么要四次挥手&#xff1f; 为什么要⻓连接&#xff1f; 常见面试题课后题 学习资源来自&#xff1a;扔物线 TCP / IP 协议…

OpenCV学习(一)——图像读取

1. 图像入门 读取图像显示图像写入图像 import cv2# 读取图像 img cv2.imread(lena.jpg) print(img.shape)# 显示图像 cv2.imshow(image, img) cv2.waitKey(0) cv2.destroyAllWindows()# 写入图像 cv2.imwrite(image.jpg, img)1.1 读取图像 读取图像cv.imread(filename, fl…

人工智能-softmax回归

回归可以用于预测多少的问题。 比如预测房屋被售出价格&#xff0c;或者棒球队可能获得的胜场数&#xff0c;又或者患者住院的天数。 事实上&#xff0c;我们也对分类问题感兴趣&#xff1a;不是问“多少”&#xff0c;而是问“哪一个”&#xff1a; 某个电子邮件是否属于垃圾…

最新版本QGIS 开始支持cesium 3D TILE 数据源了

最新版本QGIS 也开始支持3D TILE 数据源了!加载和运行速度也是慢&#xff0c;不过都这样&#xff0c;也不是qgis的问题!这东西对网络和性能要求比较高!据说这是cesium社区提供基金让qgis团队开发的&#xff0c;cesium社区真是很有钱啊&#x1f601;&#xff0c;不过也不奇怪&am…

分享8个分布式Kafka的使用场景

Kafka 最初是为海量日志处理而构建的。它保留消息直到过期&#xff0c;并让消费者按照自己的节奏提取消息。与它的前辈不同&#xff0c;Kafka 不仅仅是一个消息队列&#xff0c;它还是一个适用于各种情况的开源事件流平台。 1. 日志处理与分析 下图显示了典型的 ELK&#xff0…

Matlab中的app设计

1.窗口焦点问题&#xff1a; 窗口焦点问题&#xff1a;确保你的应用程序窗口正常处于焦点状态。有时&#xff0c;其他窗口的弹出或焦点切换可能导致应用程序最小化。点击应用程序窗口以确保它处于焦点状态。 窗口管理&#xff1a;确保你的 MATLAB 或操作系统没有未处理的错误或…

​测绘人注意,你可能会改变历史!

你也许想不到&#xff0c;曾经有一个测绘人员在进行实地测量作业时&#xff0c;在地图上就这么随手一标注&#xff0c;却让这个地方成为了如今的网红打卡地。 这个地方就是外地游客慕名而来的“宽窄巷子”&#xff0c;如果连这个地方都不知道的成都人&#xff0c;就应该不能算…