最近,看了一个大牛写的mina源代码分析,转一下,http://www.zoomhoo.com/viewthread.jsp?tid=261&am
apache MINA 源码级分析
如果对MINA不了解请看
http://www.ibm.com/developerworks/cn/opensource/os-cn-apmina/
关键字: mina 线程
最近,项目结束[项目主要是大量文件处理,所以自己用jdk5与spring做了很多线程池异步协作处理],
闲暇回顾哈NIO学习哈MINA;
首先我们需要了解MINA是什么?
我们首先需要明确第一步;一个网络通信到底可以抽象为几步;
方式一:从请求道响应看成一个流水线[呵呵想想福特汽车的流水线]
方式二:服务器接收客户请求,剩下处理[两个车间了哦]
方式三:服务器接收请求,读取客户信息,处理业务[三个车间了]
传统的:tomcat等服务器怎么处理的,简单看做方式二,一般开多线程[线程池]作为第二个车间
问题,线程多了上下文切换等问题,这个网络很多说这个问题的
现在的:grizzly,mina,netty等看做第三种,但是每个车间的写作才是关键,第二个车间 可以注册在第一个车间当来料处理第一个车间自动找到第二个,还有就是第二个车间可以通过回调函数
那看看MINA的结构[图片来源互联网]
从上图我们可以把MINA分作三个车间
1 车间 IoService----主要任务接受客户请求构造session[客户所有信息以及mina上下文信息],调用[异步]2车间处理
2 车间 IoProcessor[IoFilter包括在此车间]--主要任务IO处理意见filter执行然后 同步或者异步执行 3车间
3 车间 IoHandler--主要是我们的业务处理[mina使我们不关心网络,IO只关心这里]
但是实际情况望望比想象的复杂,如果MINA拿过来就用你很可能发现不是那样效率
特别是你的3车间 处理的连接数据库 或者链接其他网络信息,你的服务器编程blocking了
为什么?
请看下篇:
我们首先看一个MINA最简单的服务器代码 如下
Java代码
package org.apache.mina.example.echoserver;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.example.echoserver.ssl.BogusSslContextFactory;
import org.apache.mina.filter.ssl.SslFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public
class Main {
public
static
void main(String[] args) throws Exception {
SocketAcceptor acceptor = new NioSocketAcceptor();
acceptor.setReuseAddress(true);
DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
chain.addLast("logger", new LoggingFilter());
package org.apache.mina.example.echoserver;import java.net.InetSocketAddress;import java.util.concurrent.Executors;import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;import org.apache.mina.example.echoserver.ssl.BogusSslContextFactory;import org.apache.mina.filter.ssl.SslFilter;import org.apache.mina.filter.executor.ExecutorFilter;import org.apache.mina.filter.logging.LoggingFilter;import org.apache.mina.transport.socket.SocketAcceptor;import org.apache.mina.transport.socket.nio.NioSocketAcceptor;public class Main { public static void main(String[] args) throws Exception { SocketAcceptor acceptor = new NioSocketAcceptor(); acceptor.setReuseAddress(true); DefaultIoFilterChainBuilder chain = acceptor.getFilterChain(); chain.addLast("logger", new LoggingFilter());Java代码
//这里是演示所以是单线程,实际是new ProtocolCodecFilter(new ImageCodecFactory(false))
// chain.addLast("threadPool", new ExecutorFilter(Executors.newSingleThreadExecutor()));
// Bind
acceptor.setHandler(new EchoProtocolHandler());
acceptor.bind(new InetSocketAddress(8080));
System.out.println("Listening on port " + 8080);
}
//这里是演示所以是单线程,实际是new ProtocolCodecFilter(new ImageCodecFactory(false)) // chain.addLast("threadPool", new ExecutorFilter(Executors.newSingleThreadExecutor())); // Bind acceptor.setHandler(new EchoProtocolHandler()); acceptor.bind(new InetSocketAddress(8080)); System.out.println("Listening on port " + 8080); }
我们执行这段代码,然后用telnet连接看看 情况如何?
org.apache.mina.example.echoserver.Main
size is 3
[15:26:38] INFO [org.apache.mina.transport.socket.nio.NioSocketAcceptor] - init prepare Selector.open() Thread info--> main
Listening on port 8080
[15:26:41] INFO[org.apache.mina.transport.socket.nio.NioSocketAcceptor] - accept anclient connection thread info-->NioSocketAcceptor-1
[15:26:41]INFO [org.apache.mina.filter.logging.LoggingFilter] - OPENEDThreadinfo--> NioProcessor-1 nextFilter is classorg.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1
[15:26:41] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - OPENED Thread info--> NioProcessor-1
[15:26:43]INFO [org.apache.mina.transport.socket.nio.NioSocketAcceptor] - acceptan client connection thread info-->NioSocketAcceptor-1
[15:26:43]INFO [org.apache.mina.filter.logging.LoggingFilter] - OPENEDThreadinfo--> NioProcessor-2 nextFilter is classorg.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1
[15:26:43] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - OPENED Thread info--> NioProcessor-2
[15:26:45]INFO [org.apache.mina.transport.socket.nio.NioSocketAcceptor] - acceptan client connection thread info-->NioSocketAcceptor-1
[15:26:45]INFO [org.apache.mina.filter.logging.LoggingFilter] - OPENEDThreadinfo--> NioProcessor-3 nextFilter is classorg.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1
[15:26:45] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - OPENED Thread info--> NioProcessor-3
[15:26:50]INFO [org.apache.mina.transport.socket.nio.NioSocketAcceptor] - acceptan client connection thread info-->NioSocketAcceptor-1
[15:27:01] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - --sleeping wake up 20 seconds---
[15:27:01]INFO [org.apache.mina.filter.logging.LoggingFilter] - OPENEDThreadinfo--> NioProcessor-1 nextFilter is classorg.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1
[15:27:01] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - OPENED Thread info--> NioProcessor-1
[15:27:03] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - --sleeping wake up 20 seconds---
[15:27:05] INFO [org.apache.mina.example.echoserver.EchoProtocolHandler] - --sleeping wake up 20 seconds---
以上是执行的日志信息[本人在源代码增加了日志,mina的日志真是差啊]
下面我们分析哈日志看看问题:
首先我们看到2中类型的线程池
一:NioSocketAcceptor
二:NioProcessor
每次客户端连接 服务器都是NioSocketAcceptor接受请求转给NioProcessor
第一次连接NioProcessor-1 执行LoggingFilter在执行EchoProtocolHandler[这里线程我让他sleep 20秒]
第二次连接NioProcessor-2 执行LoggingFilter在执行EchoProtocolHandler[这里线程我让他sleep 20秒]
第三次连接NioProcessor-3 执行LoggingFilter在执行EchoProtocolHandler[这里线程我让他sleep 20秒]
第四次连接NioSocketAcceptor accept以后转交给NioProcessor但是NioProcessor线程池线程用完,只能阻塞[线程池大小是3,为什么是3,下面看代码] 第一个线程执行完毕 来处理第四个请求
这样我们明白 我们的 业务处理实现IOHandler的类和IoProcessor用一个线程,这样一旦我们的处理类阻塞则服务器就停滞了;
这样:就是我第一步内容说的 相当于只有2个车间,我们需要把 2车间拆分为 2个车间异步[流水]作业
具体拆分 上面看代码,打开 注释就ok了
我们简单看看源代码:
我们首先
SocketAcceptor acceptor = new NioSocketAcceptor();
那么到底做了什么我们看看NioSocketAcceptor构造器吧
public NioSocketAcceptor() {
super(new DefaultSocketSessionConfig(), NioProcessor.class);
((DefaultSocketSessionConfig) getSessionConfig()).init(this);
}
我们在看看super(new DefaultSocketSessionConfig(), NioProcessor.class);
这个代码
protected AbstractPollingIoAcceptor(IoSessionConfig sessionConfig,
Class<? extends IoProcessor<T>> processorClass) {
this(sessionConfig, null, new SimpleIoProcessorPool<T>(processorClass),
true);
}
看看上面蓝色色代码,构造IoProcessorPool线程池了 那大小是几
看看构造器
public SimpleIoProcessorPool(Class<? extends IoProcessor<T>> processorType) {
this(processorType, null, DEFAULT_SIZE);
System.out.println("size is "+DEFAULT_SIZE);
}
private static final int DEFAULT_SIZE = Runtime.getRuntime().availableProcessors() + 1;
明白了,就是cpu数+1 本机器是一个cpu双核的 所以是3
但是不要忘记 3要做的事情很多 项目希望把 业务处理的事情不让这个3做
通过分离业务与io处理的线程池 这样 业务的阻塞不会导致IO处理的阻塞
[16:24:14] INFO[org.apache.mina.transport.socket.nio.NioSocketAcceptor] - accept anclient connection thread info-->NioSocketAcceptor-1 [16:24:14] INFO[org.apache.mina.filter.logging.LoggingFilter] - OPENEDThreadinfo--> NioProcessor-1 nextFilter is classorg.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1[16:24:15] INFO[org.apache.mina.example.echoserver.EchoProtocolHandler] - OPENEDThread info--> pool-3-thread-1 [16:24:15] INFO[org.apache.mina.transport.socket.nio.NioSocketAcceptor] - accept anclient connection thread info-->NioSocketAcceptor-1 [16:24:15] INFO[org.apache.mina.filter.logging.LoggingFilter] - OPENEDThreadinfo--> NioProcessor-2 nextFilter is classorg.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1[16:24:16] INFO[org.apache.mina.transport.socket.nio.NioSocketAcceptor] - accept anclient connection thread info-->NioSocketAcceptor-1 [16:24:16] INFO[org.apache.mina.filter.logging.LoggingFilter] - OPENEDThreadinfo--> NioProcessor-3 nextFilter is classorg.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1[16:24:17] INFO[org.apache.mina.transport.socket.nio.NioSocketAcceptor] - accept anclient connection thread info-->NioSocketAcceptor-1 [16:24:17] INFO[org.apache.mina.filter.logging.LoggingFilter] - OPENEDThreadinfo--> NioProcessor-1 nextFilter is classorg.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1[16:24:35] INFO[org.apache.mina.example.echoserver.EchoProtocolHandler] - --sleepingwake up 20 seconds---
从日志可以看出 现在 accept ioprocess iohandler各自自己的线程池 这样才 真的异步
chain.addLast("threadPool", new ExecutorFilter(Executors.newSingleThreadExecutor()));
关键所在 不加则2,3车间公用一个线程池
实践不可能单线 一般
chain.addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));
用什么线程池 自己实际考虑
分享到:
相关推荐
在这个“mina源代码学习”资料中,你将有机会深入理解MINA的核心原理和实现机制。 MINA的核心特性包括: 1. **非阻塞I/O**:MINA基于Java NIO(Non-blocking Input/Output)库,实现了事件驱动和异步通信模型。...
在这个“mina-2.0.0-M6.zip”压缩包中,包含了MINA库的源代码和示例,是学习和理解MINA工作原理的理想资源。 MINA的核心特性包括: 1. **非阻塞I/O**:MINA采用Java NIO(Non-blocking Input/Output)API,允许在...
在“apache-mina-2.0.3”这个压缩包中,包含了MINA框架的源代码,开发者可以通过阅读源码来深入理解MINA的工作原理,定制自己的网络应用,或者参与MINA的二次开发。这个版本的MINA经过了广泛的测试和优化,稳定性和...
3. `src`目录:源代码,供开发者参考和学习MINA的实现。 4. `examples`目录:示例代码,展示如何使用MINA构建网络应用。 5. `build`或`dist`目录:构建脚本和打包好的可部署文件。 总的来说,MINA 2.0.0-M6作为MINA...
《mina通讯源代码详解》 Mina,全称为Apache MINA (Multipurpose Infrastructure for Network Applications),是一个由Apache软件基金会开发的网络应用框架,主要用于简化高效、高性能的网络编程。Mina提供了一种与...
在"开发mina包"中,可能包含的资源有MINA的源代码、文档、示例程序、测试用例等,这些资源可以帮助开发者深入理解MINA的工作原理,并能快速上手开发基于MINA的应用。 通过学习和应用这些知识点,开发者可以构建高效...
在深入分析MINA框架源码之前,我们需要理解几个核心概念: 1. **过滤器(Filter)**:MINA采用过滤器链模式处理网络事件,每个过滤器都可以对入站和出站的数据进行处理。过滤器可以用于数据编码、解码、安全处理、...
- `源代码`:对于开发者来说,查看源码可以帮助深入理解MINA的工作原理和设计思路。 - `构建脚本`:如Ant或Maven文件,用于构建和测试MINA项目。 - `许可证文件`:说明了软件的使用权限和限制。 通过学习和使用MINA...
NIO (Non-blocking Input/Output) 和 MINA (Multipurpose Infrastructure ...通过深入学习这个源代码示例,你可以对NIO和MINA有更深入的理解,并能将这些知识应用于实际项目中,开发出高效率、低延迟的网络应用程序。
源代码包(apache-mina-2.0.7-src.zip)则提供了完整的MINA源代码,开发者可以深入研究其内部实现,进行定制化开发或者贡献自己的代码到MINA项目。 安装MINA通常包括以下几个步骤: 1. **下载**:首先,你需要从...
1. **I/O模型**:Mina基于NIO(Non-blocking I/O)模型,这种模型允许一个线程处理多个连接,提高了服务器的并发能力。与传统的BIO模型相比,NIO更适用于高并发场景。 2. **Filters(过滤器)**:Mina采用Filter ...
这个"apache-mina-2.1.3所有jar和源文件.7z"压缩包包含了MINA框架的最新版本,2.1.3,包括其所有的JAR包和源代码。 首先,让我们详细了解一下Apache MINA的核心概念和特点: 1. **异步事件驱动**:MINA 使用非阻塞...
【标题】:“一个源代码学习服务端,基于Mina” Mina(JavaMinimal Asynchronous Network Library)是一个开源的网络通信框架,由Apache软件基金会维护。它提供了高度可扩展且低级别的网络应用程序接口,用于构建高...
接下来将根据标题和描述的要求详细分析Mina2与Netty4的区别,重点从它们的线程模型、Buffer使用以及Netty4中集成的序列化工具ProtoBuf等方面进行比较。 首先,Mina2和Netty4都是异步事件驱动的网络应用框架。Netty4...
- `src`: 源代码目录,可以查看Mina框架的内部实现细节。 - `docs`: 文档目录,包含API文档和其他技术资料。 - `lib`: 依赖的第三方库文件,这些库是Mina正常运行所必需的。 - `bin`: 可执行文件或脚本,用于快速...
1. **MINA库文件**:jar包或对应的编译后的源代码,供Java项目引用。 2. **文档**:包括用户手册、API文档、示例代码等,帮助开发者快速上手。 3. **示例**:提供了一些简单的示例应用,展示如何使用MINA框架构建...
通过深入研究MINA 2.0.4的源代码,开发者可以更好地理解和掌握Java NIO的精髓,以及如何构建高效、可扩展的网络应用。MINA不仅提供了一个强大的框架,还通过其清晰的设计和良好的文档,帮助开发者快速上手并进行定制...
4. **源码**:如果你解压后发现有源代码,这将允许你深入理解MINA的工作原理,对于想要定制或扩展MINA功能的开发者来说非常有价值。 5. **构建文件**:可能会包含Maven的pom.xml文件,这是一个项目对象模型,用于...
Mina源码解析.zip和mina-example.zip可能包含了MINA的源代码分析和示例项目,对于深入学习MINA的内部工作机制和实际应用开发非常有价值。最后,apache-mina-2.0.7应该是MINA框架的主要库文件,包含了所有必需的类和...
在“apache-mina-2.0.21-src.zip”这个压缩包中,包含了Apache Mina 2.0.21的源代码,这为我们提供了深入理解其内部工作原理的机会。 Apache Mina的核心特性包括: 1. **异步通信**:Mina基于Java NIO(非阻塞I/O...