MyCat - 架构剖析 - 网络 IO 架构 | 学习笔记

简介: 快速学习 MyCat - 架构剖析 - 网络 IO 架构

开发者学堂课程【全面讲解开源数据库中间件MyCat使用及原理(三):MyCat - 架构剖析 - 网络 IO 架构 】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/757/detail/13294


MyCat - 架构剖析 - 网络 IO 架构


内容介绍:

一、BIO、NIO 与 AIO 的概念

二、实现

 

一、回顾 BIO、NIO 与 AIO 的概念

1) . BIO

BIO (同步阻塞 I/O )是我们比较熟悉的一个模型,在讲解 TCP/IP 以及网络编程时使用 BIO,由每一个客户端建立连接,然后服务端为客户端创建一个新的线程来处理请求。

当请求处理完后该线程就会销毁。意味着一个线程只能处理一个客户端的连接,处理完后就会销毁。此时系统中会创建大量的处理线程,每个线程又需要分配一定的空间以及 CPU,而且多个线程在进行切换时线程的上下文切换会造成性能浪费。

总结:通常由一个单独的 Acceptor 线程负责监听客户端的连接,接收到客户端的连接请求后,然后会为每个客户端创建一个新的线程进行处理,处理完成之后,再给客户端返回结果,销毁线程。

每个客户端请求接入时,都需要开启一个线程进行处理,一个线程只能处理一个客户端连接。当客户端变多时,会创建大量的处理线程,每个线程都需要分配栈空间和 CPU,并且频繁的线程上下文切换也会造成性能的浪费。所以该模式,无法满足高性能、高并发接入的需求。

2) . NIO

NIO (同步非阻塞 I/O )基于 Reactor 模式作为底层通信模型,机制基于事件驱动,当触发了服务器端的某一个 I/O 事件后就会对该事件进行处理,将客户端发送过来的请求再派发给合适的处理类 handler,通过 handler 进行处理,此时有一个特点:对于 NIO 来说,这并不是一个客户端连接后就进行分配一个线程,而是一个有效的请求对应一个线程,当没有数据时,就没有工作线程。

总结:Reactor 模式可以将事件驱动的应用进行事件分派,将客户端发送过来的服务请求分派给合适的处理类( handler )。当 socket 有流可读或可写入 socket 时,操作系统会通知相应的应用程序进行处理,应用程序再将流读取到缓冲区或写入操作系统。这时已经不是一个连接对应一个处理线程了,而是一个有效的请求对应一个线程,当没有数据时,就没有工作线程来处理。

NIO 的最大优点体现在线程轮询访问 Selector,当 read 或 write 到达时则处理,未到达时则继续轮询。

NIO 相对于 BIO 工作性能大大提升,所以 NIO(同步非阻塞 I/O )在很多通信框架中都会使用到,比如阿里巴巴的框架。

3) .  AIO

AIO,全程 Asynchronous IO (异步非阻塞的 IO ),是一种非阻塞异步的通信模式。在 NIO 的基础上引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。AIO  中客户端的 I/O 请求都是由 os 先完成了再通知服务器应用去启动线程进行处理。

AIO 与 NIO 的主要区别在于回调与轮询,AIO 的机制客户端不需要关注服务处理事件是否完成,也不需要轮询,只需要关注自己的回调函数。

 

二、实现

以上简单介绍 BIO、NIO、AIO 三种模型,也进行了简单的性能对比,那么在mycat 中选用哪种模型呢?

在 Mycat 中实现了 NIO 与 AIO 两种 I/O 模式,在使用 mycat 时可以通过配置文件 server.xml 进行指定选用 NIO 还是 AIO:

<property name="usingAIO">1</property>

加上如上配置,usingAIO 为1 代表使用 AIO 模型,为 0 表示使用 NIO 模型; mycat 在启动时就会读取该值来选择到底使用哪个模型。

接下来通过跟踪源码的方式来了解 mycat  的 AIO 以及 NIO 架构和流程。

image.png

先打开我们的源码,导入进的源码中有 src 源码目录,src 下的 main 下的 java 就是核心源码

image.png

其中存在一个入口类 MycatStartup,打开 MycatStartup 会发现存在一个 main 方法:

public static void main(String[] args){

zkConfig-getInstance ( ) .initZk ( ) ;

try {

String home = SystemConfig . getHomePath();

if( home == null) {

system.out.println (SystemConfig.SYS_HOME + " is not set." );

system.exit( status: -1) ;

}

Mycatserver server = Mycatserver.getInstance ( ) ;

//这个方法执行的代码,上面 systemConfig. getHomePath() 已经执行过了,建议注释掉。/ / server.beforeStart();

server.startup();

System.out.println(“MyCAT Server startup successfully.see logs in logs/mycat.log”);

}

对于 java 程序,任何入口都是 main 方法。

String home = SystemConfig . getHomePath() 拿到 mycat 的安装目录,Mycatserver server = Mycatserver.getInstance ( ) 初始化一个mycatserver,然后调用一个 startup 方法。

点击 startup,在该方法中调用了如下:

aio=(system.getUsingAIO() ==1)

该配置是在 server.xml 中配置,拿到 aio 后往下存在一个if判断:是否是 AIO 的 IO 模型

if(aio) 中有一系列操作,其中:

manager = new AIOAcceptor( name:NAME+“Manager",system.getBindIp(),

system.getManagerPort(),mf,this.asyncChannelGroups[0] ) ;

//startup server

server =new AIOAcceptor ( name:NANE + "Server",system.getBindIp(),

system. getserverPort (), sf,this.asyncchannelGroups[0]);

new 了一个 AIOAcceptor,manager 是供后台的一个管理界面,AIOAcceptor 就是进去的服务,构造了这两个 AIOAcceptor 后往下看,会有 manager.start(); 和 server.start(); 就是调用上述代码的一个 start 方法

当我们点击 manager.start() 方法时,进入后点击 void start() 接口选择AIOAcceptor(io.mycat.net) Mycat-server。

之后代码中存在一个 this.pendingAccept,点击后会看到

private void pendingAccept () {

if (serverChannel.isOpen ( ) ){

serverChannel.accept ( ID_GENERATOR. getId(),handler: this);

}else {

throw new 工llegalstateException (

""MycaT Server Channel has been closed");

代码中有一个 accept,再点击,我们需要找到它的实现,可以看到它又调用了implAccept 抽象方法,继续找实现,调用了 invokeIndirectly 方法,

点击后选择

invokeIndirectly(AsynchronousChannel,CompletionHandler

(rt.jar),进入后发现调用了 invokeUnchecked 方法,

继续点击就会找到

AIOAcceptor.completed(AsynchronousSocketChannel,Long)(io.mycat.net),点进后会发现调用了 accept 方法,再点击后就跟踪到了AIOAcceptor.java 中的 accept 方法。

在该方法中就会接受请求,而在此方法中又调用了 factory 方法,传递了 channel对象,创建一个连接对象 FrontendConnetion,如下:

FrontendConnection c = factory.make (channel) ;

c.setAccepted (true) ;

c.setId (id);

再设置一系列参数,再往下有 NIOAProcessor,又调用了一个方法 register:

NIOProcessorprocessor=MycatServer.getInstance ( ) .nextProcessor();

c.setProcessor (processor) ;

c.register() ;

那么 register 在此处需要注册什么呢?进行点击发现任务是需要发送数据包,发送认证的数据包,MySQL 握手协议包就在此时发送。此处内容涉及到以后内容Mycat 实现 MySQL 协议。

register 处的代码就是通过 java 在模拟 mysql 协议。

再回到最初,我们进入的是 if,接着来看 else,如果不是 AIO,就会走 else,在下面创建的就是 NIOAcceptor。

以上就是提到的在 mycat 中的 IO 架构,都是可以自己进行选择。选择 IO 架构只需要在 server.xml 中配置一项 property,设置为 1 代表 AIO,0 为 NIO。Mycat中支持的 IO 模型就是 AIO 或 NIO。

相关文章
|
2月前
|
自然语言处理 JavaScript Java
《鸿蒙HarmonyOS应用开发从入门到精通(第2版)》学习笔记——HarmonyOS架构介绍
HarmonyOS采用分层架构设计,从下至上分为内核层、系统服务层、框架层和应用层。内核层支持多内核设计与硬件驱动;系统服务层提供核心能力和服务;框架层支持多语言开发;应用层包括系统及第三方应用,支持跨设备调度,确保一致的用户体验。
185 81
|
4月前
|
Ubuntu 网络安全 图形学
Ubuntu学习笔记(二):ubuntu20.04解决右上角网络图标激活失败或者消失,无法连接有线问题。
在Ubuntu 20.04系统中解决网络图标消失和无法连接有线网络问题的方法,其中第三种方法通过检查并确保Windows防火墙中相关服务开启后成功恢复了网络连接。
1161 0
Ubuntu学习笔记(二):ubuntu20.04解决右上角网络图标激活失败或者消失,无法连接有线问题。
|
8天前
|
缓存 网络协议 Java
JAVA网络IO之NIO/BIO
本文介绍了Java网络编程的基础与历史演进,重点阐述了IO和Socket的概念。Java的IO分为设备和接口两部分,通过流、字节、字符等方式实现与外部的交互。
|
4月前
|
网络协议 前端开发 Java
网络协议与IO模型
网络协议与IO模型
221 4
网络协议与IO模型
|
4月前
|
安全 NoSQL Java
一文搞懂网络通信的基石✅IO模型与零拷贝
【10月更文挑战第1天】本文深入探讨了网络通信中的IO模型及其优化方法——零拷贝技术。首先介绍了IO模型的概念及五种常见类型:同步阻塞、同步非阻塞、多路复用、信号驱动和异步IO模型。文章详细分析了每种模型的特点和适用场景,特别是多路复用和异步IO在高并发场景中的优势。接着介绍了零拷贝技术,通过DMA直接进行数据传输,避免了多次CPU拷贝,进一步提升了效率。最后总结了各种模型的优缺点,并提供了相关的代码示例和资源链接。
一文搞懂网络通信的基石✅IO模型与零拷贝
|
3月前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
1456 2
|
3月前
|
网络协议 物联网 API
Python网络编程:Twisted框架的异步IO处理与实战
【10月更文挑战第26天】Python 是一门功能强大且易于学习的编程语言,Twisted 框架以其事件驱动和异步IO处理能力,在网络编程领域独树一帜。本文深入探讨 Twisted 的异步IO机制,并通过实战示例展示其强大功能。示例包括创建简单HTTP服务器,展示如何高效处理大量并发连接。
83 1
|
4月前
|
开发者
什么是面向网络的IO模型?
【10月更文挑战第6天】什么是面向网络的IO模型?
37 3
|
4月前
|
数据挖掘 开发者
网络IO模型
【10月更文挑战第6天】网络IO模型
75 3
|
4月前
|
数据挖掘 开发者
网络IO模型如何选择?
网络IO模型如何选择?【10月更文挑战第5天】
47 2

热门文章

最新文章