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。

相关文章
|
1月前
|
SpringCloudAlibaba Java 网络架构
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(二)Rest微服务工程搭建
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(二)Rest微服务工程搭建
52 0
|
1月前
|
消息中间件 存储 缓存
Kafka【基础知识 01】消息队列介绍+Kafka架构及核心概念(图片来源于网络)
【2月更文挑战第20天】Kafka【基础知识 01】消息队列介绍+Kafka架构及核心概念(图片来源于网络)
94 2
|
5天前
|
机器学习/深度学习 缓存 监控
linux查看CPU、内存、网络、磁盘IO命令
`Linux`系统中,使用`top`命令查看CPU状态,要查看CPU详细信息,可利用`cat /proc/cpuinfo`相关命令。`free`命令用于查看内存使用情况。网络相关命令包括`ifconfig`(查看网卡状态)、`ifdown/ifup`(禁用/启用网卡)、`netstat`(列出网络连接,如`-tuln`组合)以及`nslookup`、`ping`、`telnet`、`traceroute`等。磁盘IO方面,`iostat`(如`-k -p ALL`)显示磁盘IO统计,`iotop`(如`-o -d 1`)则用于查看磁盘IO瓶颈。
|
1月前
|
SpringCloudAlibaba Java 网络架构
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(七)Spring Cloud Gateway服务网关
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(七)Spring Cloud Gateway服务网关
101 0
|
2月前
|
机器学习/深度学习 测试技术 Ruby
YOLOv5改进 | 主干篇 | 反向残差块网络EMO一种轻量级的CNN架构(附完整代码 + 修改教程)
YOLOv5改进 | 主干篇 | 反向残差块网络EMO一种轻量级的CNN架构(附完整代码 + 修改教程)
129 2
|
1月前
|
Cloud Native 安全 网络安全
构建未来:云原生架构在企业数字化转型中的关键角色网络安全与信息安全:防御前线的关键技术
【2月更文挑战第30天】 随着数字转型的浪潮席卷各行各业,企业正寻求更加灵活、可扩展的解决方案以适应不断变化的市场需求。本文将深入探讨云原生架构如何成为支持这一转型的核心技术,分析其优势和挑战,并提出实施策略。云原生技术的采用不仅加速了开发过程,还提供了自动化运维、弹性伸缩等特性,为企业带来了前所未有的敏捷性和效率。然而,迁移至云原生架构也伴随着技术复杂性增加和安全风险的挑战。文章最后,我们将提供一系列最佳实践,帮助企业在采纳云原生技术的过程中规避风险,实现持续创新。 【2月更文挑战第30天】 在数字化时代,数据成为核心资产,而网络安全与信息安全则是维护这些资产不可或缺的屏障。本文深入探讨了
|
1月前
|
SpringCloudAlibaba 负载均衡 Java
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(目录大纲)
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(目录大纲)
66 1
|
1月前
|
消息中间件 SpringCloudAlibaba Java
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(八)Config服务配置+bus消息总线+stream消息驱动+Sleuth链路追踪
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(八)Config服务配置+bus消息总线+stream消息驱动+Sleuth链路追踪
785 0
|
1月前
|
SpringCloudAlibaba Java 测试技术
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(六)Hystrix(豪猪哥)的使用
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(六)Hystrix(豪猪哥)的使用
39 1
|
1月前
|
NoSQL Java Linux
【Linux IO多路复用 】 Linux 网络编程 认知负荷与Epoll:高性能I-O多路复用的实现与优化
【Linux IO多路复用 】 Linux 网络编程 认知负荷与Epoll:高性能I-O多路复用的实现与优化
62 0