本文以mina 2.0.7为基础,记录mina nio网络接口的内部结构及消息流。
- public static void main(String[] args) {
- SocketAcceptor acceptor = new NioSocketAcceptor();
- acceptor.getFilterChain().addLast(
- "text", new Business0Filter();
- acceptor.setHandler(new ServerHandler());
- try {
- acceptor.bind(new InetSocketAddress(PORT));
- } catch (IOException e) {
- acceptor.dispose();
- }
- }
这是一个典型的基于mina的服务端程序。Mina的大体结构还是很清晰的,绑定一个端口接收消息,经过一个Filter链(上行)预处理request,最后在Handler完成业务逻辑,然后反向经过Filter链(下行)封装response,直至返回客户端。Mina支持TCP/UDP,本文只记录TCP(面向连接)的消息流。
看一下NioSocketAcceptor的内部结构概念图;
可以看出,整体上还是采用多Selector的架构。
Acceptor线程
在NioSocketAcceptor中有个Acceptor线程,它负责将一个ServerSocketChannel注册到主Selector中,注册事件为OP_ACCEPT,当有OP_ACCEPT响应时,取出相应的socket,封装在NioSocketSession中,并给这个NioSocketSession对象分配一个NioProcessor;
SimpleIoProcessorPool
NioSocketAcceptor维护的一个NioProcessor的对象池,这个对象池缺省状态下维护了Runtime.getRuntime().availableProcessors() + 1个NioProcessor对象,每个运行时建立的NioSocketSession对象都会分配一个NioProcessor对象,这个NioProcessor对象与NioSocketSession对象是一对多的关系;
NioProcessor
每个NioProcessor对象内部维护了一个Selector对象及Processor线程,除此还有一些数据结构,用于数据处理,主要的有;
- Queue<S> newSessions = new ConcurrentLinkedQueue<S>()
- Queue<S> flushingSessions = new ConcurrentLinkedQueue<S>()
其中,newSessions就是当给NioSocketSession对象分配NioProcessor时,将此NioSocketSession对象添加到此newSessions queue中,同时将对应的channel以OP_READ注册到这个NioProcessor对象的Selector,给session分配NioProcessor的逻辑是;
- private IoProcessor<S> getProcessor(S session) {
- IoProcessor<S> processor = (IoProcessor<S>) session.getAttribute(PROCESSOR);
- if (processor == null) {
- if (disposed || disposing) {
- throw new IllegalStateException("A disposed processor cannot be accessed.");
- }
- processor = pool[Math.abs((int) session.getId()) % pool.length];
- if (processor == null) {
- throw new IllegalStateException("A disposed processor cannot be accessed.");
- }
- session.setAttributeIfAbsent(PROCESSOR, processor);
- }
- return processor;
- }
这个session id是生成session时产生的。
NioProcessor对象的Processor线程就是从这个newSessions queue里取出新加进来的session对象,以OP_READ注册到自己Selector中,然后针对自己的Selector进行select()操作,当有可读的socket事件响应时就取出socket数据,然后走Filter链直至业务逻辑。当有了response需要返回给客户端时,会将response对象封装并添加到session对象的一个写出缓冲里,然后session对象被添加到NioProcessor对象的flushingSessions中,Processor线程会从flushingSessions中取出session,然后从session的写出缓冲中取出response,写socket。需要注意的是,在处理写的时候还是比较细腻的,进入flushingSessions queue有两种方式,
- 一个是经过业务逻辑处理,产生response,直接将session压入flushingSessions queue;
- 另一个是当执行上述写socket动作时,因为网络闪断或其他什么原因,写socket不能正常完成,这时,会将session对应的channel在Selector中注册OP_WRITE事件,当Processor线程发现这个session对应的channel有OP_WRITE事件时,会重新将这个session压入flushingSessions queue,然后就是走正常逻辑了,看下代码感受一下;
- private boolean flushNow(S session, long currentTime) {
- final WriteRequestQueue writeRequestQueue = session.getWriteRequestQueue();
- WriteRequest req = null;
- try {
- ......
- do {
- req = session.getCurrentWriteRequest();
- if (req == null) {
- // session的写出缓冲中取response
- req = writeRequestQueue.poll(session);
- if (req == null) {
- break;
- }
- session.setCurrentWriteRequest(req);
- }
- int localWrittenBytes = 0;
- Object message = req.getMessage();
- if (message instanceof IoBuffer) {
- //写socket
- localWrittenBytes = writeBuffer(session, req, hasFragmentation, maxWrittenBytes - writtenBytes, currentTime);
- if ((localWrittenBytes > 0) && ((IoBuffer) message).hasRemaining()) {
- //写socket成功,但是buffer中还有需要写的数据
- writtenBytes += localWrittenBytes;
- setInterestedInWrite(session, true);
- return false;
- }
- }
- ......
- //写socket出错,重置channel事件
- if (localWrittenBytes == 0) {
- setInterestedInWrite(session, true);
- return false;
- }
- ......
- } while (writtenBytes < maxWrittenBytes);
- } catch (Exception e) {
- ......
- }
- return true;
- }
- protected void setInterestedInWrite(NioSession session, boolean isInterested) throws Exception {
- SelectionKey key = session.getSelectionKey();
- if (key == null) {
- return;
- }
- int newInterestOps = key.interestOps();
- //注册OP_WRITE事件
- if (isInterested) {
- newInterestOps |= SelectionKey.OP_WRITE;
- } else {
- newInterestOps &= ~SelectionKey.OP_WRITE;
- }
- key.interestOps(newInterestOps);
- }
在各个Selector的维护及session的超时控制等方面,mina在实现的细节上还有很多特别的设计,
相关推荐
Mina PPT 英文高级 Mina 架构设计PPT版
该版本基于mina架构的JTT808协议演示版本程序,网关采用mina+spring+MQ/redis架构,简单配置application.properties中的 MQ:jms.brokerurl=tcp://127.0.0.1:61616; 终端连接对应的端口:3005, 点击bin/目录下面...
基于mina架构的JTT808协议演示版本程序,网关采用mina+spring+MQ/redis架构,简单配置application.properties中的MQ:jms.brokerurl=tcp://127.0.0.1:61616 需要正版可联系QQ:78772895
基于Mina架构开发的可配置的Socket Server,后台采用MySql数据库,可以独立app部署或Tomcat Servlet部署,包括Socket Server全部实现代码,后台MySql数据备份文件,Java测试代码,android端测试代码和iOS端测试代码...
基于mina架构的JTT808协议演示版本程序,网关采用mina+spring+MQ/redis架构,简单配置application.properties中的 MQ:jms.brokerurl=tcp://127.0.0.1:61616; 终端连接对应的端口:3005, 点击bin/目录下面的bin/...
1. **Mina架构**:了解Mina的事件驱动模型和过滤器链,以及如何使用它们来处理网络通信。 2. **NIO原理**:学习非阻塞I/O的工作方式,以及Mina如何利用NIO提高性能和处理大量并发连接。 3. **Mina API**:熟悉Mina...
1. **Mina架构**:理解Mina的核心架构,包括I/O多路复用模型(如NIO和Epoll)以及事件驱动的设计,这些设计使得Mina能够处理大量并发连接。 2. **Filter Chain**:Mina的过滤器链机制是其核心特性之一,它允许...
1. **了解MINA架构**:熟悉MINA的IoSession、IoFilter、IoHandler等核心组件及其职责。 2. **分析源码**:通过阅读MINA的源码,了解其内部处理流程,如读写事件的处理、过滤器链的工作方式等。 3. **编写简单的应用*...
1. **MINA架构** MINA采用非阻塞I/O模型,通过NIO(Non-blocking I/O)库实现。这种模式允许一个线程同时处理多个连接,显著提高了服务器的并发性能。MINA的核心组件包括Acceptor(用于接收新连接)、Session(表示...
1. **Mina 架构** Mina 使用事件驱动和异步处理模型,使得它能够高效地处理大量并发连接。它的架构由三个主要组件组成:Filter、Session 和 ProtocolHandler。 2. **Filter(过滤器)** 过滤器是 Mina 的核心概念...
2. **MINA架构**:介绍MINA的事件驱动模型,如何通过事件触发器(如IoHandler)处理网络事件。 3. **项目配置**:如何设置MINA的项目结构,包括POM.xml文件的配置,以及依赖管理。 4. **编写协议处理器**:如何使用...
1. **Mina架构**:Apache Mina的核心设计基于事件驱动和非阻塞I/O模型,这种模型特别适合处理大量并发连接。它将网络通信层抽象为一组服务,如TCP/IP协议栈,让你专注于业务逻辑而不是底层细节。 2. **IoSession...
1. **Mina架构**:Mina基于事件驱动和非阻塞I/O,提供了一个可扩展的框架,允许开发者专注于业务逻辑,而非底层的网络通信细节。 2. **Filter Chain**:Mina的核心设计之一是过滤器链,它允许开发者添加自定义的处理...
1. **Mina架构概述** Mina采用了事件驱动和异步I/O模型,通过NIO(Non-blocking I/O)提供高效的数据传输。它的核心组件包括Filter、Session和ProtocolCodec。Filter链允许我们插入自定义逻辑,Session是连接管理器...
1. **Mina架构**:Mina的核心是I/O处理器,它处理网络连接的建立、读写数据以及断开连接等操作。用户通过实现特定的事件处理器接口(如`SessionListener`、`MessageDecoder`和`MessageEncoder`)来定义业务逻辑。 2...
1. **Mina架构**:Mina的核心设计理念是事件驱动和异步通信,它采用了I/O多路复用技术,如Java NIO(非阻塞I/O),以提高服务端处理大量并发连接的能力。资料会介绍Mina的组件,如Acceptor、Session和Filter,以及...
1. **MINA架构**:MINA基于NIO(非阻塞I/O),利用Selector进行多路复用,可以在单个线程中处理多个连接,提高系统效率。 2. **长连接**:与传统的Socket短连接不同,长连接保持在客户端和服务器之间长时间打开,...
1. **Mina架构**:Mina采用了事件驱动和异步I/O模型,基于Java NIO(非阻塞I/O)库。它的核心组件包括Acceptor(监听器)、Session(会话)和Filter(过滤器)。Acceptor负责接收连接请求,Session代表每个独立的...
#### 三、Mina架构与核心组件 - **IoService**:负责套接字的建立与管理,包含一个Selector用于监听连接请求。 - **IoProcessor**:独立于IoService,在另一个线程上运行,负责检查通道上的读写操作,也拥有自己的...