聊聊java高并发系统之异步非阻塞

2023-11-18

聊聊java高并发系统之异步非阻塞

几种调用方式

同步阻塞调用

即串行调用,响应时间为所有服务的响应时间总和;


半异步(异步Future)

线程池,异步Future,使用场景:并发请求多服务,总耗时为最长响应时间;提升总响应时间,但是阻塞主请求线程,高并发时依然会造成线程数过多,CPU上下文切换;


全异步(Callback)

Callback方式调用,使用场景:不考虑回调时间且只能对结果做简单处理,如果依赖服务是两个或两个以上服务,则不能合并两个服务的处理结果;不阻塞主请求线程,但使用场景有限。


异步回调链式编排

异步回调链式编排(JDK8 CompletableFuture),使用场景:其实不是异步调用方式,只是对依赖多服务的Callback调用结果处理做结果编排,来弥补Callback的不足,从而实现全异步链式调用。


接下来看看如何设计利用全异步Callback调用和异步回调链式编排处理结果来实现全异步系统设计。


同步阻塞调用:

public class Test {
   public static void main(String[] args) throws Exception {
       RpcService rpcService = new RpcService();
       HttpService httpService = new HttpService();
       //耗时10ms
       Map result1 = rpcService.getRpcResult();
       //耗时20ms
       Integer result2 = httpService.getHttpResult();
       //总耗时30ms
    }
   static class RpcService {
       Map getRpcResult() throws Exception {
           //调用远程方法(远程方法耗时约10ms,可以使用Thread.sleep模拟)
       }
    }
   static class HttpService {
       Integer getHttpResult() throws Exception {
           //调用远程方法(远程方法耗时约20ms,可以使用Thread.sleep模拟)
           Thread.sleep(20);
           return 0;
       }
    }
}
  半异步(异步Future):

public class Test {
   final static ExecutorService executor = Executors.newFixedThreadPool(2);
   public static void main(String[] args) {
       RpcService rpcService = new RpcService();
       HttpService httpService = new HttpService();
       Future> future1 = null;
       Future future2 = null;
       try {
           future1 = executor.submit(() -> rpcService.getRpcResult());
           future2 = executor.submit(() -> httpService.getHttpResult());
           //耗时10ms
           Map result1 = future1.get(300, TimeUnit.MILLISECONDS);
           //耗时20ms
           Integer result2 = future2.get(300, TimeUnit.MILLISECONDS);
           //总耗时20ms
       } catch (Exception e) {
           if (future1 != null) {
                future1.cancel(true);
           }
           if (future2 != null) {
                future2.cancel(true);
           }
           throw new RuntimeException(e);
       }
    }
   static class RpcService {
       Map getRpcResult() throws Exception {
           //调用远程方法(远程方法耗时约10ms,可以使用Thread.sleep模拟)
       }
    }
   static class HttpService {
       Integer getHttpResult() throws Exception {
           //调用远程方法(远程方法耗时约20ms,可以使用Thread.sleep模拟)
       }
    }
}<strong>

</strong>

全异步(callback):

public class AsyncTest {
public staticHttpAsyncClient httpAsyncClient;
   public static CompletableFuture getHttpData(String url) {
       CompletableFuture asyncFuture = new CompletableFuture();
       HttpPost post = new HttpPost(url);
       HttpAsyncRequestProducer producer = HttpAsyncMethods.create(post);
       AsyncCharConsumer consumer = newAsyncCharConsumer() {
            HttpResponse response;
           protected HttpResponse buildResult(final HttpContext context) {
                return response;
           }
…...
       };
       FutureCallback callback = new FutureCallback() {
           public void completed(HttpResponse response) {
               asyncFuture.complete(EntityUtils.toString(response.getEntity()));
           }
…...
       };
       httpAsyncClient.execute(producer, consumer, callback);
       return asyncFuture;
    }
 
   public static void main(String[] args) throws Exception {
       AsyncTest.getHttpData("http://www.jd.com");
       Thread.sleep(1000000);
    }
}

异步回调链式编排:

CompletableFuture提供了50多个API,可以满足所需的各种场景的异步处理的编排,下面举一个场景:

三个服务并发异步调用,返回CompletableFuture,不阻塞主线程;


   public static void test1() throws Exception {
       HelloClientDemoTest service = new HelloClientDemoTest();
       /**
        * 场景1 两个以上服务并发异步调用,返回CompletableFuture,不阻塞主线程
        * 并且两个服务也是异步非阻塞调用
        */
       CompletableFuture future1 = service.getHttpData("http://www.jd.com");
       CompletableFuture future2 = service.getHttpData("http://www.jd.com");
       CompletableFuture future3 =service.getHttpData("http://www.jd.com");
       List futureList = Lists.newArrayList(future1,future2, future3);
       CompletableFuture allDoneFuture =CompletableFuture.allOf(futureList.toArray(newCompletableFuture[futureList.size()]));
       CompletableFuture future4 =allDoneFuture.thenApply(v -> {
            List result =futureList.stream().map(CompletableFuture::join)

                   .collect(Collectors.toList());
            //注意顺序
            String result1 = (String)result.get(0);
            String result2 = (String)result.get(1);
            String result3 = (String)result.get(2);
            //处理业务....
            return result1 + result2 + result3;
        }).exceptionally(e -> {
            //e.printStackTrace();
            return "";
        });
       //返回
    }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

聊聊java高并发系统之异步非阻塞 的相关文章

  • Serverless架构模式简介

    Serverless架构模式简介 一 简介 Serverless是一种无服务的架构 类似aws lambda Serverless与跟传统架构不同 由开发者实现的服务端逻辑运行在无状态的计算容器中 它是由事件触发 短暂的 可能只存在于一次请
  • 构建高并发高可用的电商平台架构大纲

    构建高并发高可用的电商平台架构大纲 参考 http blog csdn net yangbutao article details 12242441
  • 阿里云飞天系统

    阿里云飞天系统 有幸在阿里云飞天部门工作几年 下面给出基础架构一览
  • Quorum Journal Manager原理

    Quorum Journal Manager原理 在一个典型的HA集群 两个独立的物理节点配置为NameNodes 在任何时间点 其中之一NameNodes是处于Active状态 另一种是在Standby状态 Active NameNode
  • 分布式系统的自主服务

    分布式系统的自主服务 分布式系统作为server运行在机器上 需要很好的自动化运维来操作集群上的复杂的分布式系统 自动化运维要做到基础数据的完整收集 关键信息的准确推送 运维流程的正确 简便执行和确认 进程内部数据按需获取 对象运行状况的长
  • 分布式配置管理系统QConf

    分布式配置管理系统QConf 分布式配置管理系统QConf是360公司开源的系统 详见 https github com Qihoo360 QConf 整体架构图如下 资料 1 https github com Qihoo360 QConf
  • 分布式系统的正确性验证方法

    分布式系统的正确性验证方法 1 Jepsen框架 Jepsen是一个开源的分布式一致性验证框架 可用于验证分布式数据库 分布式消息队列 分布式协调系统 Jepsen探索特定故障模式下分布式系统是否满足一致性 Jepsen框架是一个
  • 一种多级缓存的系统架构

    一种多级缓存的系统架构 下面这个也是比较常用的多级缓存的系统架构图 整体流程如上图所示 1 首先接入Nginx将请求负载均衡到应用Nginx 此处常用的负载均衡算法是轮询或者一致性哈希 轮询可以使服务器的请求更加均衡 而一致性哈希可以提升应
  • Tachyon内存文件系统

    Tachyon内存文件系统 Tachyon是以内存为中心的分布式文件系统 拥有高性能和容错能力 能够为集群框架 如Spark MapReduce 提供可靠的内存级速度的文件共享服务 从软件栈的层次来看 Tachyon是位于现有大数据计算框架
  • Nginx+Redis+Ehcache:大型高并发与高可用的三层缓存架构总结

    Nginx Redis Ehcache 大型高并发与高可用的三层缓存架构总结 Nginx 对于中间件nginx常用来做流量的分发 同时nginx本身也有自己的缓存 容量有限 我们可以用来缓存热点数据 让用户的请求直接走缓存并返回 减少流向服
  • 实现一个高性能网络通讯库的要点

    实现一个高性能网络通讯库的要点 由于硬件的发展速度快 本来占时间消耗小头的软件层 变成了大头 原本占性能比例非常小的的中断 上下文切换 也成为了性能优化的方向 许多bypass kernel的方案开始发展起来 以前在千兆网卡普及的时代 就有
  • 架构师需要了解的Paxos原理、历程及实战

    架构师需要了解的Paxos原理 历程及实战 数据库高可用性难题 数据库的数据一致和持续可用对电子商务和互联网金融的意义不言而喻 而这些业务在使用数据库时 无论 MySQL 还是 Oracle 都会面临一个艰难的取舍 就是如何处理主备库之间的
  • 分布式系统的时间

    分布式系统的时间 事件的顺序 大家都知道 Linearizability在一些系统 譬如分布式数据库 里面是非常重要的 我们不能允许数据更新之后仍然能读到原先的值 譬如银行转账 用户A有100元 转给用户B 10元 这个操作之后用户A只可能
  • API网关

    API网关 api gateway 即 api 网关 所有的请求首先会经过这个网关 这有点类似于前端控制器模式 也有点类似于 Facade模式 如下图所示 由于所有的请求会先经过这个 api 网关 所以 可以在 这里做 权限控制 安全 负载
  • zookeeper session实现机制

    zookeeper session实现机制 TO DO
  • condition update在分布式系统中设计

    condition update在分布式系统中设计 1 定义 condition update称为条件更新 用于分布式系统中数据一致性 能够保证在并发操作数据时的正确性 2 方式 1 可以通过version来保证condition upda
  • 分布式系统全链路监控方案设计

    分布式系统全链路监控方案设计 在分布式系统中 全链路监控系统 跟踪requestid经过了哪些server 方便定位log的位置 能在一定程度上缓解维护压力 下面给出我们团队的架构设计图
  • DNS在架构设计中的巧用

    DNS在架构设计中的巧用 一 缘起 一个http请求从客户端到服务端 整个执行流程是怎么样的呢 一个典型流程如上 1 客户端通过域名daojia com请求dns server 2 dns server返回域名对应的外网ip 1 2 3 4
  • 聊聊java高并发系统之异步非阻塞

    聊聊java高并发系统之异步非阻塞 几种调用方式 同步阻塞调用 即串行调用 响应时间为所有服务的响应时间总和 半异步 异步Future 线程池 异步Future 使用场景 并发请求多服务 总耗时为最长响应时间 提升总响应时间 但是阻塞主请求
  • 大规模分布式消息中间件简介

    大规模分布式消息中间件简介 当前各种 RPC 中间件技术已经广泛应用于各个领域 其中 服务器之间消息通讯这种功能广泛应用于这些中间件中 于是 将这种面向消息的中间件 Message Oriented Middleware MOM 抽象出来

随机推荐

  • 5.x Linux RT-Preempt补丁和ARM平台RT-test编译

    1 在make menuconfig中 5 x版本内核的RT Preempt设置在General Setup下面 2 ARM平台的RT test编译 git clone git git kernel org pub scm utils rt
  • springboot 集成elasticsearch遇到的坑

    最近开始学习elasticsearch 所以就想着在springboot里面集成一下elasticsearch 结果遇到了不少麻烦 下面总结一下 但愿大家和自己以后都少走弯路 首先声明下 本人开始学习elasticsearch的时候 官网最
  • python-类变量(类属性),实例变量(实例属性),self作用

    类中定义的变量又称之为属性 类中定义的函数又称之为方法 类中 所有函数 方法 之外 此范围定义的变量 称为类属性或类变量 类中 所有函数 方法 内部 以 self 变量名 的方式定义的变量 称为实例属性或实例变量 类中 所有函数 方法 内部
  • nuxt3 pinia pinia-plugin-persistedstate

    安装pinia yarn add pinia pinia nuxt 或者使用 npm npm install pinia pinia nut 安装pinia plugin persistedstate npm npm i pinia plu
  • x-studio(Lua调试器,粒子编辑器,UI编辑器,代码编辑器,csb恢复工具)

    最新版本 x studio 10 0 9000 29 2020年4月14日更新 官网 https x studio net 官方教程 https docs x studio net x studio是一款强大的游戏开发IDE 由作者历时5年
  • 如何从零开始写小程序

    看了这篇文章 即使让我现在就从头写一个能够正常运行的小程序 也没有原本想象中的那么难了 在本文中 我们将会以一个具体的小程序为例 带领大家从零到一完成一个小程序的开发流程 并将这个小程序上传到 FinClip com 进行小程序提审与上架操
  • 信息收集之 绕过CDN获取真实IP地址

    作者主页 士别三日wyx 作者简介 CSDN top100 阿里云博客专家 华为云享专家 网络安全领域优质创作者 专栏简介 此文章已录入专栏 网络安全快速入门 CDN绕过 一 为什么要绕过CDN 二 如何识别CDN 1 nslookup解析
  • 多线程总结

  • Android 5.0 API新增和改进

    API 级别 21 Android 5 0 LOLLIPOP 为用户和应用开发者提供了新的功能 本文档介绍了最值得注意的新 API 有关新平台功能的扼要介绍 另请参阅 Android Lollipop 集锦 开始开发 要构建 Android
  • 硬件设计---了解电源篇

    1 概述 在高速电路设计中一块单板上常存在多种电源 3 3V 1 8V 1 2V 1 0V 0 9V 0 75V等 有时光是对FPGA供电就需要五六种电源 为了便于使用往往用户只需要提供一种或几种电源 然后经过板上电源模块转换到各个目标电源
  • 二、Docker安装及使用教程(Windows版)

    Docker安装及使用教程 Windows版 1 下载安装 2 启用windows Hyper V虚拟引擎 1 打开设置 2 搜索 启用或关闭 windows 功能 3 勾选Hyper V服务 4 根据提示重启电脑 等待更新即可 2 启动D
  • iOS 开发之 AutoLayout 自动布局

    iOS 开发之 AutoLayout 自动布局 frame 原点自身的尺寸 来确定自身的位置 autoLayout 根据参照视图的位置来定义自己的位置 autoLayout 约束视图和视图的关系来分配屏幕上的位置 使用VFL Visual
  • python计算机视觉KNN算法、稠密Dense-sift及图像手势识别

    KNN算法 一 KNN算法概述 1 kNN算法又称为k近邻分类 k nearest neighbor classification 算法 最简单平凡的分类器也许是那种死记硬背式的分类器 记住所有的训练数据 对于新的数据则直接和训练数据匹配
  • BigDecimal的使用

    在计算金额的时候 实际上整数 浮点数有时候有点捉襟见肘 于是math包提供了一个Bigdecimal类 所以可以学习一下这个BigDecimal的源码和使用 首先是看一下他的构造方法 看起来构建的方式很多 但实际上之间的差别很大 举个例子就
  • 计算机音乐花之舞谱,Flower Dance(花之舞)简谱 DJ OKAWARI 空灵、自然、唯美的花之舞,花儿舞了,我醉了。...

    DjOkawari 的作曲风格一向是空灵却又自然的 FlowerDance 作为广为人知的一首曲子非常完美的体现出来了他自己的风格 它将流行曲的跳跃激昂与古典乐曲的优美完美的结合在一起 给人最直观的感受便是它那种空灵的美感 你甚至可以想象到
  • 数学建模代码速成~赛前一个月~matlab~代码模板~吐血总结~三大模型代码(预测模型、优化模型、评价模型)

    目录 一 预测模型 1 BP神经网络预测 2 灰色预测 3 拟合插值预测 线性回归 4 时间序列预测 5 马尔科夫链预测 6 微分方程预测 7 Log
  • nacos安装配置

    1 下载 sentos安装 先下在安装包 nacos server 2 0 3 tar gz nacos官网 https nacos io zh cn 2 解压安装 上传安装包至linux系统 使用 tar zxvf nacos serve
  • 快速入门XPath语法,轻松解析爬虫时的HTML内容

    快速入门XPath语法 轻松解析爬虫时的HTML内容 爬虫时 很多网站返回的是HTML文件 可以用正则表达式 re库 或XPath语法来匹配目标内容 这两种方法属于爬虫的基本技能 实战中要会灵活运用 对于一些结构和内容复杂的HTML 用re
  • 通达信接口怎么样抓取股票实时数据?

    通达信接口怎么样抓取股票实时数据 股票爬取接口在股票交易中常常使用到的一些辅助工具 股票爬取接口主要是利用l1和l2接口来执行获取股票实时行情数据的原理 将自己需要查询的需求就可以在接口软件上搜索就可以很快的获取数据了 那么 在获取的过程中
  • 聊聊java高并发系统之异步非阻塞

    聊聊java高并发系统之异步非阻塞 几种调用方式 同步阻塞调用 即串行调用 响应时间为所有服务的响应时间总和 半异步 异步Future 线程池 异步Future 使用场景 并发请求多服务 总耗时为最长响应时间 提升总响应时间 但是阻塞主请求