高并发之请求合并

Java高并发下请求合并 1、 LinkedBlockingQueue队列将请求存放起来 2、ScheduledExecutorService定时任务调度,每隔一段时间执行任务处理队列里的请求 3、 CompletableFuture完成线程任务,返回结果 @Service public class QueryService { //定义一个内部类,用来封装请求的数据 class RequestData { String code; CompletableFuture<Map&l 阅读详情
应用场景

Redis官方介绍,Redis单机读写性能12万/s,批量处理能达到70w/秒。不管是缓存还是数据库,都有批量处理能力。当系统达到瓶颈时,才充分考虑压榨性能。适用于电商双十一,特定高并发场景。

思路

1、一个用户请求到来时,将请求放在一个队列中,单线程定时任务10ms从队列中取数据进行处理。
2、定时任务,把队列中的请求,批量的方式向后端和Redis缓存或数据库发起批量请求。
3、请求合并,请求阻塞等待请求处理完毕,需要用到Future

代码实现:
/**
* @author MrCai
* @date 2020/05/30
*/
public class MergeRequestTest {

	//阻塞队列
    static BlockingDeque<Request> blockingDeque = new LinkedBlockingDeque<>();
    
    //定时任务单线程
    static ScheduledExecutorService scheduled = Executors.newScheduledThreadPool(1);

    public static void main(String[] args) {

	//定时任务
    scheduled.scheduleAtFixedRate(() -> {
        int size = blockingDeque.size();
        if (size == 0){
            return;
        }

        Map<Integer, Request> map = Maps.newHashMap();
        List<Integer> codes = Lists.newArrayList();
        for (int i = 0; i < size; i++) {
            Request request = blockingDeque.poll();
            codes.add(request.code);
            map.put(request.code, request);
        }

        System.out.println("--------------------------- " + codes.size());
        Map<Integer, String> results = getResults(codes);

        for (Integer code : results.keySet()) {
            String value = results.get(code);
            Request request = map.get(code);
            request.future.complete(value);
        }
    },0,1, TimeUnit.MILLISECONDS);

    AtomicInteger count = new AtomicInteger(0);
    for (int i = 0; i < 1000; i++) {
        new Thread(() -> {
            int code = count.addAndGet(1);
            try {
                TimeUnit.MILLISECONDS.sleep(code % 10);
                String result = getResult(code);
                // System.out.println("Thread " + code + " : " + result);
            }catch (Exception e){
        }
   }).start();
  }
}


//获取单个结果 
public static String getResult(Integer code) throws Exception{
    Request request = new Request();
    request.code = code;
    CompletableFuture<String> future = new CompletableFuture<>();
    request.future = future;
    blockingDeque.add(request);
    return future.get();
}

//多结果查询(批量接口)
public static Map<Integer,String> getResults(List<Integer> codes){
    System.out.println(JSON.toJSONString(codes));
    Map<Integer, String> map = Maps.newHashMap();
    for (Integer code : codes) {
        map.put(code, code.toString());
    }
    return map;
}

    static class Request{
        Integer code;
        CompletableFuture<String> future;
    }
}
总结:

1、特定特大高并发场景使用,平时可通过参数配置,对请求合并进行动态配置
2、依旧存在阻塞队列中数据无限大的问题(10ms中请求合并过于庞大)
个人解决方案:

  • 多队列,请求hash存到队列中,每个队列都有定时任务进行处理请求
  • 定时任务请采用 scheduleatfixedrate(时间超过10ms,处理完后直接继续处理)
  • 定时任务间隔时间,可进行量的预估,设置合理的值
  • 按照各中间件refresh思想,设置定时时间、队列大小,两个参数任意一点满足则任务执行
Wazuh部署记录 Wazuh是一个免费的开源安全平台,统一了XDR和SIEM功能。它可以保护内部部署、虚拟化、容器化和基于云的环境中的工作负载。Wazuh帮助组织和个人保护其数据资产免受安全威胁。它被全球数千个组织广泛使用,从小型企业到大型企业。443:仪表盘界面访问端口1515:探针连接服务器端口1514:探针回传信息端口以上3个端口必须打开防火墙。 阅读详情

相关推荐

【python】epub的电子书繁体字与简体字转换

中文繁体与简体转换

xiexianyou666的博客 3088

Redis命令之HyperLogLog

文章目录1. 简介2. pfadd3. pfcount4. pmerge5. 总结 1. 简介 HyperLogLog是一个专门为了计算集合的基数而创建的概率算法,对于一个给定的集合,HyperLogLog可以计算出这个集合的近似基数:近似基数并非集合的实际基数,它可能会比实际的基数小一点或者大一点,但是估算基数和实际基数之间的误差会处于一个合理的范围之内 2. pfadd pfadd hyperloglog ele1 [ele2...]对给定的一个或多个集合元素进行计数 3. pfcount pfc

CodePanda@GPF的博客 817

python课程教学大纲-《Python语言基础》课程教学大纲

《Python语言基础》课程教学大纲课程名称:Python语言基础课程类别:专业选修课适用专业:电子信息工程考核方式:考查总学时、学分:32学时1.5学分其中讲授16学时,实验10学时,其他6学时一、课程性质、教学目标使学生在全面了解Python技术历史、现状与发展趋势的基础上,系统掌握Python基本概念、编程思想以及程序设计技术,具备熟练的Python编程技能和面向对象软件设计技术思想,完成本...

weixin_37988176的博客 3720

编码技巧——Redis Pipeline

本文介绍Redis pipeline相关的知识点及代码示例,包括pipeline与client执行多命令的区别、Redis客户端-服务端的一次完整的网络请求、pipeline与redis"事务"、pipeline的使用代码示例;

娜娜米的博客 987

三、Crowd与JIRA、Confluence用户集成并SSO单点登录

补充说明: 通过此方法集成后,用户、组以及用户和组的关系都在Crowd系统中存储,但各个系统的权限仍由各系统控制,也可在JIRA和Confluence中添加和删除用户。 在做步骤4和步骤5的时候,要特别小心,确保当前系统的超级权限用户(一般为admin,具体看当前系统的全局权限配置)和组以及它们的关系已经在Crowd中同样存在了,才可切换并禁用当前系统的内部用户目录,否则可能造成权限丢失等严重问题(因为禁用了内部用户目录,而Crowd中又不存在这个超级权限用户和组或它们的关系,所以权限就丢失了) 维护示例

weixin_38621072的博客 2985

嘉立创封装图下载后必做的3步优化(附批量删除机械层技巧)

本文针对从嘉立创下载的封装图,系统讲解了三步核心优化流程,以解决其直接使用时的常见问题。重点介绍了如何高效批量删除冗余的机械层,避免制造错误;并详细说明了规范丝印层间距、统一焊盘命名等关键步骤,帮助工程师将第三方封装转化为可靠、合规的设计资源,从而提升PCB设计效率与文件质量。

weixin_29227585的博客 431

高并发系统设计:消息队列,解决高并发写问题

为了解决后台将数据库的变化实时更新到前台的问题,我来了解一下消息队列 文章目录1、为什么要使用消息队列2、使用了消息队列会有什么缺点?3、消息队列如何选型?4、如何保证消息队列是高可用的? 1、为什么要使用消息队列 三个最主要的应用场景:解耦、异步、削峰 (1)解耦 传统模式: 传统模式的缺点: 系统间耦合性太强,如上图所示,系统A在代码中直接调用系统B和系统C的代码,如果将来D系统接入,系统...

OceanStar的博客 6946

技术面 - 手撕算法题整理

这篇博客整理了华为OD面试中涉及的算法题,包括LeetCode热门题目、OD原题和需要手写的算法,如二分查找、冒泡排序等。建议优先刷"hot100"的LeetCode题目,全刷OD原题,以及掌握手撕算法的基本原理。

m0_73659489的博客 1024

消息中间件消息介绍 RabbitMQ ActiveMQ RocketMQ Kafka优缺点对比 消息中间件入门详解 消息中间件从入门到放弃

消息队列 一、什么是消息队列 我们可以把消息队列看作是一个存放消息的容器,当我们需要使用消息的时候,直接从容器中取出消息供自己使用即可。 消息队列是分布式系统中重要的组件之一。使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。 我们知道队列 Queue 是一种先进先出的数据结构,所以消费消息时也是按照顺序来消费的。 二、为什么要使用消息队列 我觉得使用消息队列主要有三点好处: 通过异步处理提高系统性能(减少响应所需时间)。 削峰/限流 降低系统耦合性。 如果在面试的时候你被面试官问到

Snails的博客 813

Autosar软件组件分析及ARXML文件分析

Autosar软件组件分析及ARXML文件分析

专注汽车软件开发、AutoSAR、车载以太网、SOA、EE架构。 3601

RDkit入门

今天开始写RDkit的入门教程,每天学习和写一小点,相信一句话“不积跬步无以至千里,不积小流无以成江海”,所以就慢慢来,一点一滴积累叭,从最简单的开始喽希望自己每天都能保持写博客的好习惯,把自己的代码笔记就极在这里,RDkit一块啃了很久的骨头,今天终于要下定决心,好好总结一波了,希望保持这个更新的频率,每天都能有所学。............

博客而已 6682

高并发之消息队列

消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能,成为异步RPC的主要手段之一。 消息被处理的过程相当于流程A被处理。我们这里以一个实际的模型来讨论下,比如用户下单成功时给用户发短信,如果没有这个消息队列,我们会选择同步调用发短信的接口, 并等待短息发送成功,这时候假设短信接口实现出现问题了,或者短信调用端超时了,又或者短信...

weixin_30363509的博客 412

YOLOv8改进-利用图像去雾网络UnfogNet提升检测精度的探索【附核心模块代码】

YOLOv8-UnfogNet联合模型的提出为目标检测和图像去雾领域提供了一个新的思路。通过将图像去雾网络和目标检测网络结合,不仅可以提升在恶劣天气下的目标检测精度,还能够为实际应用中的自动驾驶、监控安防等领域带来更强的鲁棒性和适应性。随着去雾技术和目标检测算法的不断发展,我们相信,这种联合方法将在多个领域中获得更加广泛的应用,并为进一步提升图像质量和检测精度做出重要贡献。

一键难忘的博客 3202

Java请求合并_高并发场景下请求合并的实践

前言项目中一般会请求第三方的接口,也会对外提供接口,可能是RPC,也可能是HTTP等方式。在对外提供接口时,有必要提供相应的批量接口,好的批量实现能够提升性能。高并发场景中,调用批量接口相比调用非批量接口有更大的性能优势。但有时候,请求更多的是单个接口,不能够直接调用批量接口,如果这个接口是高频接口,对其做请求合并就很有必要了。比如电影网站的获取电影详情接口,APP的一次请求是单个接口调用,用户量...

weixin_33042659的博客 1111

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Java高并发下请求合并如何处理

场景描述:在大并发量下每秒有一万个请求向后端查询数据,这样我们就需要向后端请求一万次,甚至查询一万次数据库。我们要做的请求合并就是每隔一段时间(10ms)将这段时间内的请求合并到一起进行批量查询,减少查询数据库的次数。 思考: 1、如何存放一段时间内的请求?这里我们可以用队列。 2、如何每隔一段时间执行任务?用定时任务线程池。 3、每个请求都是单独的线程,如何保证各个请求能得到自己的查询结果?这里...

Soda_lw的博客 3326

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

利用请求合并发挥高并发下批量处理的优势

利用请求合并发挥高并发下批量处理的优势 一、需求分析: 我们经常会写一些查询接口,假设现在我们需要写一个查询用户信息的接口,要求传入用户Id,返回用户名称。那么最简化的流程就是:用户发送请求->controller层->service层->dao层->数据库。每次请求就相当于请求一条用户信息。当这个接口被用户频繁请求时,此接口就不断的在做“请求”到“返回”的操作,服务端同时会开辟许多线程帮我们执行这些操作,这么多的线程会消耗许多系统资源,服务端承受了巨大压力。 //单查询接口 @Ge

chenzihao36的博客 1247

高并发场景下请求合并的实践

项目中一般会请求第三方的接口,也会对外提供接口,可能是RPC,也可能是HTTP等方式。在对外提供接口时,有必要提供相应的批量接口,好的批量实现能够提升性能。高并发场景中,调用批量接口相比调用非批量接口有更大的性能优势。但有时候,请求更多的是单个接口,不能够直接调用批量接口,如果这个接口是高频接口,对其做请求合并就很有必要了。比如电影网站的获取电影详情接口,APP的一次请求是单个接口调用,用户量少的时候请求也不多,完全没问题;

竹林幽深 265

面试官问我:什么是高并发下的请求合并?

作者 |why技术来源 |why技术(ID:hello_hi_why)从一道面试题说起‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍前段时间一个在深圳的,两年经验的小伙伴出去面...

程序人生的博客 649

高并发场景下的请求合并

一. 在项目中,我们经常用到如下方式进行接口调用: 有多少请求访问,就会调用多少次第三方接口或数据库,这样的情况在高并发场景下很容易出现线程被打满,返回结果慢。 为了优化这个接口,后台可以将相同的请求进行合并,然后调用批量的查询接口。 请求合并: 下面上代码: 已查询数据库举例 1.创建请求类: @Data @Builder @AllArgsConstructor @...

rongshisuo的博客 706

高并发请求合并如何自己实现呢

对外提供查询job的接口,这个接口并发查询特别大,如何实现请求合并呢 当然了,请求合并针对并发百万的情况使用,不要滥用..................... 首先我们看到请求参数为jobId,返回结果为job 那我们就要针对它建一个类来操作这些参数,并发其实就是多线程,我们用Request类来存放每个线程的参数 class Request{ Integer jobId; ...

阳光 1467

Java高并发处理:请求合并

Java高并发处理:请求合并 场景:在高并发的查询场景下,如果查询的参数都是相似的,类似id=1,id=2,id=3这种那么就可以通过请求合并来解决 请求合并就是每隔一段时间就将这段时间内的请求合并到一起进行批量查询,减少查询数据库的操作。 请求合并是以时间换空间的方式 类似于Redis就是以空间换时间的方式 技术实现要求: LinkedBlockQueue阻塞队列 ScheduledThreadPoolExecutor 定时任务线程池 CompleteableFuture future阻塞

qq_29898779的博客 2634

高并发场景-请求合并(一)SpringCloud中Hystrix请求合并

背景 在互联网的高并发场景下,请求会非常多,但是数据库连接池比较少,或者说需要减少CPU压力,减少处理逻辑的,需要把单个查询,用某些手段,改为批量查询多个后返回。 如:支付宝中,查询“个人信息”,用户只会触发一次请求,查询自己的信息,但是多个人同时这样做就会产生多次数据库连接。为了减少连接,需要在JAVA服务端进行合并请求,把多个“个人信息”查询接口,合并为批量查询多个“个人信息”接口,然后以个人...

地藏Kelvin 781

高并发处理:请求合并

两者的实现队列添加或移除的锁不一样,ArrayBlockingQueue实现的队列中的锁是没有分离的,即添加操作和移除操作采用的同一个ReenterLock锁,而LinkedBlockingQueue实现的队列中的锁是分离的,其添加采用的是putLock,移除采用的则是takeLock,这样能大大提高队列的吞吐量,也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能。//定时任务线程池,创建一个支持定时、周期性或延时任务的限定线程数目(这里传入的是1)的线程池。

竹林幽深 79

Java面试官:什么是高并发下的请求合并?

还有真实的案例是转账的场景,有的转账渠道是按次收费的,那么作为第三方公司,我们就可以把用户的请求先放到表里记录着,等一小时之后,一起汇总发起,假设这一小时内发生了 10 次转账,那么 10 次收费就变成了 1 次收费,虽然让客户等的稍微久了点,但还是在可以接受的范围内,这操作节约的就是真金白银了。另外一个风险点就是对于支出类的请求,如果被削峰,很明显,我们提前就告诉了用户操作成功,但是真正动账户余额的时候已经延迟了,所以可能会出现账户透支的情况。请求合并的处理速度甚至比单个处理还快,这也是性能的提升。

jcc4261的博客 620
上一篇: Memcached内存管理模型与LRU算法优化
下一篇: 网易云音乐评论模块高并发下的设计思考
Kindle_code
博客等级 码龄12年 21粉丝 66原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值