单个io_service如何接收socket_P8架构师教你如何认识,Mina

认识 Mina

Apache Mina Server 是一个网络通信应用框架,与 Netty 出自同一作者,Netty 借鉴了部分 Mina 的设计思路。

8b9daaca864c74c0b3d88d983751a124.png

Mina 主要是对基于 TCP/IP、UDP/IP 协议栈的通信框架,Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步操作的编程模型,Mina 的异步 IO 默认使用的是 JAVA NIO(New IO)作为底层支持,基于 Channel 的双向通道。Mina 主要有1.x 和2.x 两个分支。Mina 同时提供了网络通信的 Server 端、Client 端的封装,无论是哪端,Mina 在整个网通通信结构中提供了一系列接口 API,Mina 的 API 将真正的网络通信与我们的应用程序隔离开来。

4d92f049ec16bd91b12122249f126ac6.png

Mina 的底层依赖的主要是 Java NIO 库,上层提供的是基于事件的异步接口。其整体的结构如下:

41bf018743d8f28793b38e259ee469eb.png
  • IoService:最底层的是 IOService,负责具体的 IO 相关工作。这一层的典型代表有 IOSocketAcceptor 和 IOSocketChannel,分别对应 TCP 协议下的服务端和客户端的 IOService。IOService 的意义在于隐藏底层 IO 的细节,对上提供统一的基于事件的异步 IO 接口。每当有数据到达时,IOService 会先调用底层 IO 接口读取数据,封装成 IoBuffer,之后以事件的形式通知上层代码,从而将 Java NIO 的同步 IO 接口转化成了异步 IO。所以从图上看,进来的 low-level IO 经过 IOService 层后变成 IO Event。具体的代码可以参考 org.apache.mina.core.polling.AbstractPollingIoProcessor 的私有内部类 Processor。
  • IoProcessor:这个接口在另一个线程上,负责检查是否有数据在通道上读写,也就是说它也拥有自己的 Selector,这是与我们使用 JAVA NIO 编码时的一个不同之处,通常在 JAVA NIO 编码中,我们都是使用一个 Selector,也就是不区分 IoService 与 IoProcessor 两个功能接口。另外,IoProcessor 负责调用注册在 IoService 上的过滤器,并在过滤器链之后调用 IoHandler。
  • IoFilter:这个接口定义一组拦截器,这些拦截器可以包括日志输出、黑名单过滤、数据的编码(write 方向)与解码(read 方向)等功能,其中数据的 encode 与decode 是最为重要的、也是你在使用 Mina 时最主要关注的地方。
  • IoHandler:这个接口负责编写业务逻辑,也就是接收、发送数据的地方。需要有开发者自己来实现这个接口。IoHandler 可以看成是 Mina 处理流程的终点,每个 IoService 都需要指定一个 IoHandler。
  • IoSession:是对底层连接(服务器与客户端的特定连接,该连接由服务器地址、端口以及客户端地址、端口来决定)的封装,一个 IoSession 对应于一个底层的 IO 连接(在 Mina 中 UDP 也被抽象成了连接)。通过 IoSession,可以获取当前连接相关的上下文信息,以及向远程 peer 发送数据。发送数据其实也是个异步的过程。发送的操作首先会逆向穿过 IoFilterChain,到达 IoService。但 IoService 上并不会直接调用底层 IO 接口来将数据发送出去,而是会将该次调用封装成一个 WriteRequest,放入 session 的 writeRequestQueue 中,最后由 IoProcessor 线程统一调度 flush 出去。所以发送操作并不会引起上层调用线程的阻塞。具体代码可以参考 org.apache.mina.core.filterchain.DefaultIoFilterChain 的内部类 HeadFilter 的 filterWrite 方法。

服务端流程:

  • 通过 SocketAcceptor 同客户端建立连接
  • 连接建立之后 I/O 的读写交给了 I/O Processor 线程,I/O Processor 是多线程的
  • 通过 I/O Processor 读取的数据经过 IoFilterChain 里所有配置的 IoFilter,IoFilter 进行消息的过滤,格式的转换,在这个层面可以制定一些自定义的协议
  • 最后 IoFilter 将数据交给 Handler 进行业务处理,完成了整个读取的过程

写入过程也是类似,只是刚好倒过来,通过 IoSession.write 写出数据,然后 Handler 进行写入的业务处理,处理完成后交给 IoFilterChain,进行消息过滤和协议的转换,最后通过 I/O Processor 将数据写出到 socket 通道。

简单的 TCPServer

第一步:编写 IoService

4381e5472793712dffe9d32983071ba8.png

第二步:编写过滤器

cba7a43afa874fbf564c89839f2618d4.png

第三步:编写 IoHandler

4add10d0f639103cb1777d0b1fcbde04.png

把这个 IoHandler 注册到 IoService:

931d4e8a01c85a1645797476f52d0c5f.png

当然这段代码也要在 acceptor.bind() 方法之前执行。完成的代码:

d8285df8d62d349a946b7eca8792d9d9.png

简单的 TCPClient

第一步:编写 IoService 并注册过滤器

1cc3606cbf9938be453c06baf59ec7f1.png

第三步:编写 IoHandler

1c7bce768d833c6d879f384996209fd3.png

注册 IoHandler:

connector.setHandler(new ClientHandler("你好! 大家好!")); 

粉丝福利

Java架构进阶资源

098b7ddabded975ae1d1f756ffb18c3d.png

分析源码

77c7fcacf22dd7ef45025fabd3f84015.png

分布式架构

9fc2e5f1599714382443d4c7263485b6.png

性能优化

9851f356ec3d0d3e6f8612c066c4a528.png

Java面试避坑指南

bf0356b95d0c6d5c13dbac190c63627c.png

Java面试题集锦

8c74229838aa8d9b887f6a75e421aaa8.png

如何获取

后台私信我回复 【资料】 即可获取,

后台私信我回复【资料】 即可获取,

后台私信我回复【资料】 即可获取

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值