架构解密从分布式到微服务:深入理解网络,AIO

article/2025/9/13 20:13:42

AIO

AIO是I/O模型里一个很高的层次,体现了大道至简的软件美学理念。与NIO相比,AIO的框架和使用方法相对简单很多。

AIO包括两大部分:AIO Files解决了文件的异步处理问题,AIO Sockets解决了Socket的异步处理问题。AIO的核心概念为应用发起非阻塞方式的IO操作,在I/O操作完成时通知应用,同时,应用程序的职责很明确,比如什么时候发起IO操作请求,在I/O操作完成时通知谁来处理。

下图给出了AIO Sockets对读请求的处理流程(写请求同理),应用程序在有读请求时就向Kenel注册此请求,应用的线程就可以继续执行其他操作而无须等待。与此同时,Kernel在发现有数据到达Socket以后,就将数据从内核复制到应用程序的 Buffer里,在复制完成后,回调应用程序的通知接口,应用程序就可以处理此数据了。

架构解密从分布式到微服务:深入理解网络,AIO

 

在编写AIO Socket程序时,我们所要掌握的最关键的一个类是回调接口一CompletionHandler<V,A>,它包括两个方法:void completed(V result,A attachment); voidfailed(Throwable exc,attachment)。

其中,completed方法是异步请求完成时的通知接口,result是返回的结果;attachment则是应用程序捆绑在这个回调接口上的任意对象,可以记录客户端连接对象,或者用来保存Session会话的状态数据,例如已读取的字节信息等。failed方法则表明I/O事件异常,通常是不可恢复的故障.completed方法中的V与A具体是什么对象呢?这取决于调用者,比如在
AsynchronousServerSocketChannel对象中异步接收客户端连接请求的方法签名如下:

AsynchronousServerSocketChannel.accept (A attachment, CompletionHandlAsynchronousSocketChannel, ?super A> handler)

在上述方法中,attachment参数被作为CompletionHandler<V,A>的A参数传递到completed与 failed 回调方法中。下面的代码创建了一个 
AsynchronousServerSocketChannel,并调用accept方法等待客户端异步连接建立完成:

listener = AsynchronousServerSocketChannel.open (asyncChannelGroup) .bind (newInetSocketAddress(port));
listener.accept (listener, new AioAcceptHandler());

AioAcceptHandler这个CompletionHandler的代码则如下:

架构解密从分布式到微服务:深入理解网络,AIO

 

在上述代码中,completed方法先调用
AsynchronousServerSocketChannel的 accept方法,注册下一次的异步连接请求。这个调用很重要,否则 AsynchronousServerSocketChannel就不会再接收新连接的请求了;随后调用startRead(socket)方法发起一个异步读取数据的请求。在说明这个方法之前,我们看看AsynchronousSocketChannel的异步读方法的签名:

read (ByteBuffer dst,Aattachment,CompletionHandler<Integer, ? super A> handler)

上述方法类似于之前分析的accept方法,attachment 参数被作为CompletionHandler<V.的A参数传递到completed 与 failed回调方法里,V参数则是一个整数,用于表明此次读到的字节总数。

下面是 startRead(socket)方法的逻辑,它调用了AioReadHandler来处理读到的数据,注意传递到AioReadHandler里的 Attachment是此次读到的数据——ByteBuffer,最多1024个字节;

架构解密从分布式到微服务:深入理解网络,AIO

 

AioReadHandler负责处理异步读响应事件,下面是其Complete方法的源码:

架构解密从分布式到微服务:深入理解网络,AIO

 

架构解密从分布式到微服务:深入理解网络,AIO

 

如上所示的代码的总体逻辑类似于accept 的处理逻辑,它针对每个客户端Socket 都使用了一个 ByteBuffer 作为 Session 级别的变量,用来保存客户端发送的数据,并且通过 Attachment变量传递到CompletionHandler的下一次读取事件上。

AIO异步写的操作类似于异步读的处理,这里不做分析。从 AIO 的代码来看,我们发现AIO也有类似于NIO 的一面,即如果还有I/O事件要操作,则仍然需要把它们“注册”到系统里。不同的是,在AIO框架下,客户端收到反馈事件时,数据已经准备好了,应用程序可以直接处理,在NIO框架下则还需要应用调用底层的读写API完成具体的IO操作。

AIO框架不仅仅止步于此,我们知道,在 JDK的NIO模型下,多路复用的Reactor模型及多线程的Reactor模型都不是官方JDK提供的,这也大大增加了应用编程的复杂度。AIO框架则将复杂的多线程处理机制融入JDK的AIO框架中,让我们可以轻松写出高级又优雅的AIO程序。

从之前的NIO经验来看,在处理很多个Socket 的IO事件时,多线程(线程池)成为必然的选择,很直观的推理就是CompletionHandler需要一个线程池来实现高性能并发回调机制,于是就有了AsynchronousChannelGroup对象,它内部包括一个线程池:

ExecutorService service = Executors.newFixedThreadPool(25);
AsynchronousChannelGroup channelGroup = AsynchronousChannelGroup.withThreadPool(service);


AsynchronousServerSocketChannel可以被绑定到某个ChannelGroup上,以便共用其线程池:

AsynchronousSocketChannel socketChannel = AsynchronousSocketChannel.open (channelGroup);

注意到ChannelGroup后面捆绑的线程池可以有多种选择,例如固定大小的线程池、弹性扩展的线程池、缓存的线程池等,于是编程的灵活性很大。此外,如果是每个CPU核心都对应一个ChannelGroup,这就接近多线程Reactor模型的设计了。

从上面的分析来看,JDK里的AIO框架设计的确很优雅,而且很妥善地解决了JDK里NIO框架没有考虑到的复杂问题。从诞生的那天开始,Java AIO 的一切看上去都很美,但是现在,“它美丽而晴朗的天空却被一朵乌云笼罩了”,这朵“乌云”就是Linux的AIO泥潭。

早在2003年,Linux kernel AIO项目就启动并且制定了设计方案。2004年,IBM觉得异步状态机的实现跟已存在的代码不协调并且太复杂,于是做出了Retry模型,但Retry模型的阻塞问题(block point)始终无法得到解决。Oracle负责OSS的部门接管了Retry模型,后来又觉得IBM的Retry模型有很多问题,发现Retry & Exit 在他们的一个产品上会有很大的性能问题,于是重起炉灶,开发了一个Syslet方案,却以失败告终。直到2016年5月,还有人发现在Linux 3.13内核里有AIO内存溢出的严重漏洞(Ubuntu Kylin 14.04 LTS版本就采用了这个内核),Docker则要求使用AIO的宿主机所安装的版本不低于Linux 3.19(在这个版本里又有好几处AIO代码的修复)。

目前Linux 上的AIO实现主要有两种: Posix AIO与Kernel Native AIO,前者是以用户态实现的,而后者是以内核态实现的,所以Kernel Native AIO 的性能及前景要好于它的前辈PosixAIO。比较知名的软件如Nginx、MySQL、InnoDB等的高版本都支持Kernel Native AIO,但基本上都只将文件传输到Socket 中,即 AIO Files 的特性。Netty后来也实现了AIO,但又取消了,这个做法与Mycat的尝试过程殊途同归。其原因其实很简单,Linux 下 AIO的实现充斥着各种Bug,并且AIO Socket还不是真正的异步IO机制,性能的改进并不明显和可靠;而另外一种值得重视的观点是:AIO是为了未来的高带宽大数据传输而准备的技术,还不适应当前的硬件和软件环境。

本文给大家讲解的内容是架构解密从分布式到微服务:深入理解网络,AIO

  1. 下篇文章给大家讲解的是架构解密从分布式到微服务:深入理解网络,网络传输中的对象序列化问题;
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持!

http://chatgpt.dhexx.cn/article/WYnuHHUu.shtml

相关文章

BIO,NIO,AIO区别

BIO,NIO,AIO 总结 Java 中的 BIO、NIO和 AIO 理解为是 Java 语言对操作系统的各种 IO 模型的封装。程序员在使用这些 API 的时候&#xff0c;不需要关心操作系统层面的知识&#xff0c;也不需要根据不同操作系统编写不同的代码。只需要使用Java的API就可以了。 在讲 BIO,NIO,…

Apache CXF - 快速指南

Apache CXF - 简介 在当今的环境中&#xff0c;您可以使用多个选项来创建 Web 服务应用程序。您可以使用多种标准和广泛接受的协议中的一种或多种进行通信。例如SOAP、XML/HTTP、RESTful HTTP和CORBA&#xff08;通用对象请求代理架构&#xff0c;在过去非常流行&#xff0c;但…

java cxf 安全_CXF client在并发下的线程安全问题

这个是发生在上周周末的真实案例&#xff0c;因为cxf client 端线程安全导致的错误&#xff0c;总结出来希望其他使用cxf的兄弟注意。 首先描述一下背景&#xff0c;简单的说就是使用cxf作为web service的客户端&#xff0c;运行在weblogic上&#xff0c;连接外部的服务器。为了…

linux cxf服务端,Apache CXF 框架应用实战

一、概述 Apache CXF提供了用于方便地构建和开发WebService的可靠基础架构。它允许创建高性能和可扩展的服务&#xff0c;可以部署在Tomcat和基于Spring的轻量级容器中&#xff0c;也可以部署在更高级的服务器上&#xff0c;例如Jboss、WebSphere或WebLogic。 CXF提供了以下功能…

使用CXF调用WSDL

简介 时隔多年&#xff0c;再次遇到需要调用WebService的业务&#xff0c;对方给予的wsdl说明文档还是内网的链接&#xff0c;并且设有基础访问权限&#xff0c;即在浏览器打开wsdl链接时需要输入【用户名密码】登录后方可查看wsdl文档&#xff0c;这需要设置代理&#xff08;我…

spring5.x cxf3.4.x 服务端和客户端 非maven版本

文章目录 一、资料准备1. 官网链接2. 解压3. 依赖梳理 二、spring集成cxf2.1.创建spring项目2.2. 创建接口2.3. impl2.4. spring-cxf.xml2.5. 客户端2.6. 开源项目 一、资料准备 1. 官网链接 http://cxf.apache.org/download.html 下载apache-cxf-3.4.5.zip 2. 解压 3. 依赖…

CXF实现WebService

一、CXF简介 Apache CXF Celtix XFire&#xff0c;开始叫 Apache CeltiXfire&#xff0c;后来更名为 Apache CXF 了&#xff0c;以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华&#xff0c;提供了对 JAX-WS 全面的支持&#xff0c;并且提供了多种 Binding …

SpringBoot2 整合 CXF 服务端和客户端

文章目录 一、CXF服务端1. 导入依赖2. 创建service接口3. 接口实现类4. cxf配置类5. 查看wsdl结果 二、CXF客户端2.1. 客户端2.2. 断点调试2.3. 发起调用服务开源源码. 一、CXF服务端 1. 导入依赖 <properties><cxf.version>3.3.1</cxf.version></proper…

CXF客户端乱码

CXF客户端乱码 解决办法一&#xff0c;设置服务端代码&#xff1a; 在使用CXF与其他系统对接时&#xff0c;发现对方系统响应的汉字乱码&#xff0c;使用soapui调用测试就没有问题&#xff0c;但是程序里面调用就乱码&#xff0c;很奇怪&#xff0c;乱码如下&#xff1a; 由…

SpringBoot集成CXF

CXF入门篇https://blog.csdn.net/tongxin_tongmeng/article/details/126482362Server端项目结构 Server端pom.xml <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"…

走进cxf

一、什么是cxf 有很多人认为cxf就是webservice&#xff0c;其实cxf只是发布调用webservice的工具而已 Apache CXF Celtix Xfire&#xff0c;开始叫 Apache CeltiXfire&#xff0c;后来更名为 Apache CXF 了&#xff0c;以下简称为 CXF。Apache CXF 是一个开源的 web Service…

NewSQL ---- Mysql.8.0 与 MemSQL 7.0 大数据量查询性能对比

目录 1测试环境以及测试用例设计 1.1测试环境 1.2测试用例设计 2 千万级数据量性能测试对比 2.1 MemSQL时间范围分页查询 2.1.1 性能测试数据 2.2任务信息查询 2.2.1 性能测试数据 2.3 执行批次范围查询 2.3.1 性能测试数据 2.4 批次任务查询 2.4.1 性能测试数据 …

memsql架构2

接上次的MemSQL分布式架构介绍(一)&#xff0c;原文在这里&#xff1a;http://docs.memsql.com/latest/concepts/distributed_architecture/ 首先上张图&#xff0c;是我根据自己的理解画的&#xff0c;如有错误还请大家指出 几个概念 1、MemSQL有两种类型的表&#xff1a; ref…

MemSQL性能测试结果

1.查询的SQL select count(subie.user_id) as count from sum_user_basic_info_exp subie join sum_user_lend_info_exp sulie on sulie.user_idsubie.user_id where subie.curr_user_role_cd1 and subie.reg_dt >2016-08-29 and subie.reg_dt <2016-08-29 结…

【MySQL】SQL优化

SQL优化 1 插入数据 1.1 insert优化 如果我们需要一次性往数据库表中插入多条记录&#xff0c;可以从以下三个方面进行优化。 insert into tb_test values(1,tom); insert into tb_test values(2,cat); insert into tb_test values(3,jerry); .....1.批量插入数据 Insert…

MySQL慢SQL探究

文章目录 前言1、慢SQL捕获慢查询追踪配置方式 2、情况分析为什么查询会慢&#xff1f; 2.1 SQL执行计划分析explain执行计划分析PROFILE分析OPTIMIZER_TRACE分析 3、引擎参数配置分析I/O性能分析MySQL I/O参数 其他原因分析网络抖动单表数据量过大 总结 前言 我们在日常开发中…

【Mysql】SQL性能分析

【Mysql】SQL性能分析 文章目录 【Mysql】SQL性能分析1. SQL执行频率2. 慢查询日志3. profile详情4. explain 1. SQL执行频率 在控制台中通过命令 show [session|global] status 命令可以提供服务器状态信息。通过如下指令&#xff0c;可以查看当前数据库的 insert,update,del…

MemSQL可以为时间序列应用做些什么

版权声明&#xff1a;本文由腾讯云数据库产品团队整理&#xff0c;页面原始内容来自于db weekly英文官网&#xff0c;若转载请注明出处。翻译目的在于传递更多全球最新数据库领域相关信息&#xff0c;并不意味着腾讯云数据库产品团队赞同其观点或证实其内容的真实性。如果其他媒…

MySQL-SQL优化

文章目录 一、插入数据1、insert2、大批量插入数据 二、主键优化&#xff08;1&#xff09;数据组织方式&#xff08;2&#xff09;页分裂&#xff08;3&#xff09;页合并&#xff08;4&#xff09;索引设计原则 三、order by优化四、group by优化五、limit优化六、count优化1…

每秒1.28万亿行,最快的分布式关系数据库MemSQL又破记录了!

众所周知&#xff0c;如果交互式响应时间小于四分之一秒&#xff0c;那么人们会获得令人难以置信的满意度。当你提供的响应时间下降到大约四分之一秒时&#xff0c;交互对用户而言是即时的。 但是&#xff0c;由于大数据集和并发需求&#xff0c;给所有客户提供的速度水平似乎…