Mina2.0工作原理以及配置注意事项
mina总结
![mina总结](https://img.taocdn.com/s3/m/235b726aa45177232f60a276.png)
MINA框架简介Apache MINA(Multipurpose Infrastructure for Network Applications) 是用于开发高性能和高可用性的网络应用程序的基础框架,它对Java中的socket和NIO进行了有效和清晰的封装,方便开发人员开发TCP/UDP 程序,从而抛开在使用原始的socket时需要考虑的各种繁杂而又烦人问题(线程、性能、会话等),把更多精力专著在应用中的业务逻辑的开发上。
Mina 综述Multipurpose Infrastructure for Network Applications。
一个基于非阻塞I/O的网络框架。
高可维护性,高可复用性:网络I/O编码,消息的编/解码,业务逻辑互相分离。
与JMX结合。
使用sfj4作为log支持UDP,支持客户端API。
由Netty2的作者Trustin Lee开始开发的。
相对容易进行单元测试客户端通信过程1.通过SocketConnector同服务器端建立连接2.链接建立之后I/O的读写交给了I/O Processor线程,I/O Processor是多线程的3.通过I/O Processor读取的数据经过IoFilterChain里所有配置的IoFilter,IoFilter进行消息的过滤,格式的转换,在这个层面可以制定一些自定义的协议4.最后IoFilter将数据交给Handler进行业务处理,完成了整个读取的过程5.写入过程也是类似,只是刚好倒过来,通过IoSession.write写出数据,然后Handler进行写入的业务处理,处理完成后交给IoFilterChain,进行消息过滤和协议的转换,最后通过I/O Processor将数据写出到socket通道IoFilterChain作为消息过滤链1.读取的时候是从低级协议到高级协议的过程,一般来说从byte字节逐渐转换成业务对象的过程2.写入的时候一般是从业务对象到字节byte的过程IoSession贯穿整个通信过程的始终整个过程可以用一个图来表现消息箭头都是有NioProcessor-N线程发起调用,默认情况下也在NioProcessor-N线程中执行MINA2网络应用架构基于Apache MINA 的网络应用有三个层次,分别是I/O 服务、I/O 过滤器和I/O 处理器:∙I/O 服务:I/O 服务用来执行实际的I/O 操作。
Mina2.0阅读源码笔记(比较详细)
![Mina2.0阅读源码笔记(比较详细)](https://img.taocdn.com/s3/m/c1d51c1f964bcf84b9d57ba5.png)
Mina源码阅读笔记,详情请关注:/ielts0909/blog写了很多关于Apache Mina的文章,为了方便大家阅读,我将关于mina的一些文章做点儿索引。
Mina官网资料-----------------------------------------------------------------Mina官网是学习mina最重要的地方:Apache MinaMina官网上有教你快速上手的quick start:《Quick Start》Mina官网提供了User Guide,这个手册包含了很多概念和示例:《User Guide》Mina的应用博客--------------------------------------------------------------Mina基于NIO开发中间有个重要的桥梁缓冲区,了解两者不同:《IoBuffer和ByteBuffer》Mina实现自定义协议的通信、对通信的一些思考:《Mina实现自定义协议通信》、《Tcp 传输下的思考》、《NIO开发的思考》Mina提供状态机来实现复杂的业务控制:《Mina状态机State Machine》Mina源码解读-----------------------------------------------------------------《Mina源码阅读笔记(一)-整体解读》《Mina源码阅读笔记(二)- IoBuffer的封装》《Mina源码阅读笔记(三)-Mina的连接IoAccpetor》《Mina源码阅读笔记(四)—Mina的连接IoConnector》《Mina源码阅读笔记(五)—Mina对连接的操作IoSession》《Mina源码阅读笔记(六)—Mina异步IO的实现IoFuture》《Mina源码阅读笔记(七)—Mina的拦截器FilterChain》《Mina源码阅读笔记(八)—Mina拦截器器的末端IoHandler》题外话--------------------------------------------------------------------------Mina的系列就写到这里了,后面如果有心得体会还会再更新上去,接下来我主要想写的是分布式消息系统的内容。
mina中文开发手册
![mina中文开发手册](https://img.taocdn.com/s3/m/4ef0933d0912a2161479299d.png)
李海峰(QQ:61673110)-Andrew830314@
Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于 TCP/IP、UDP/IP 协议栈的通信框架(当然,也可以提供 JAVA 对象的序列化服务、虚拟机管道通信服务等), Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异 步(Mina 的异步 IO 默认使用的是 JAVA NIO 作为底层支持)操作的编程模型。 Mina 主要有 1.x 和 2.x 两个分支,这里我们讲解最新版本 2.0,如果你使用的是 Mina 1.x, 那么可能会有一些功能并不适用。学习本文档,需要你已掌握 JAVA IO、JAVA NIO、JAVA Socket、JAVA 线程及并发库(java.util.concurrent.*)的知识。 Mina 同时提供了网络通信的 Server 端、Client 端的封装,无论是哪端,Mina 在整个网通 通信结构中都处于如下的位置:
_______________________________________________________________________________ 2. 简单的 TCPClient: 这里我们实现 Mina 中的 TCPClient,因为前面说过无论是 Server 端还是 Client 端,在 Mina 中的执行流程都是一样的。唯一不同的就是 IoService 的 Client 端实现是 IoConnector。
可见 Mina 的 API 将真正的网络通信与我们的应用程序隔离开来,你只需要关心你要发送、 接收的数据以及你的业务逻辑即可。 同样的,无论是哪端,Mina 的执行流程如下所示:
MINA2实用手册
![MINA2实用手册](https://img.taocdn.com/s3/m/b5b4e068a45177232f60a2a4.png)
MINA2实用手册作者:李庆丰Email:scholers@MINA框架是对java的NIO包的一个封装,简化了NIO程序开发的难度,封装了很多底层的细节,然开发者把精力集中到业务逻辑上来,最近做了一个相关的项目,为了备忘对MINA做一个总结。
一、服务端初始化及参数配置MINA2初始化很简单。
基本的初始化参数如下://初始化Acceptor—可以不指定线程数量,MINA2里面默认是CPU数量+2 NioSocketAcceptor acceptor = new NioSocketAcceptor(5);java.util.concurrent.Executor threadPool =Executors.newFixedThreadPool(1500);//建立线程池//加入过滤器(Filter)到Acceptoracceptor.getFilterChain().addLast("exector", newExecutorFilter(threadPool));//编码解码器acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new WebDecoder(),newXmlEncoder()));//日志LoggingFilter filter = new LoggingFilter();filter.setExceptionCaughtLogLevel(LogLevel.DEBUG);filter.setMessageReceivedLogLevel(LogLevel.DEBUG);filter.setMessageSentLogLevel(LogLevel.DEBUG);filter.setSessionClosedLogLevel(LogLevel.DEBUG);filter.setSessionCreatedLogLevel(LogLevel.DEBUG);filter.setSessionIdleLogLevel(LogLevel.DEBUG);filter.setSessionOpenedLogLevel(LogLevel.DEBUG);acceptor.getFilterChain().addLast("logger", filter);acceptor.setReuseAddress(true);//设置的是主服务监听的端口可以重用acceptor.getSessionConfig().setReuseAddress(true);//设置每一个非主监听连接的端口可以重用MINA2中,当启动一个服务端的时候,要设定初始化缓冲区的长度,如果不设置这个值,系统默认为2048,当客户端发过来的消息超过设定值的时候,MINA2的机制是分段接受的,将字符是放入缓冲区中读取,所以在读取消息的时候,需要判断有多少次。
MINA 服务器开发文档
![MINA 服务器开发文档](https://img.taocdn.com/s3/m/829e4bc0bb4cf7ec4afed0b7.png)
最近一直在看Mina的源码,用了Mina这么长时间,说实话,现在才开始对Mina有了一些深刻的理解,关于Mina的基本知识的介绍,这里就不多说了,网上已经有很多不错的文章都对Mina做了较深刻的剖析,现在就是想从Mina的最根本的地方来对Mina做一些深层次上的探讨。
还是先从Mina的入口程序来说,每当要启动一个Mina的程序(包括服务器和客户端)时候,这里只是对服务器重点做一些讲解,至于说Mina的客户端的应用,这里只是简单的涉及一点,不会对其做很深入的探讨。
但是Mina的服务器和客户端在很大的程度上都是一样,所以这里就“挂一漏万”的简单讲解一下。
在此之前我一直想找一种“串糖葫芦”的方式来讲解一下Mina,可是一直没有时间来看Mina的源码,真的是无从下手,虽然网上的很多关于Mina的一些文章,讲解的非常透彻了,但是可能对于初学者来说,显得有些深奥,在这里特别的提一下洞庭散人对Mina源码的透彻的分析,如果你对Mina已经有了一定的了解或者是正在学习Mina的源码,建议你去看看他的博客,里面有很多东西讲的是相当到位的。
在这里就不在多举例子了。
写这篇文档主要是想对刚接触Mina的人讲解一些Mina的基本知识,由浅入深,一步一步的学习Mina思想的精髓,我接触Mina的时间也比较长了,几乎天天在和它打交道,每当你发现一个新奇的用法的时候,你真的会被Mina所折服,我这里不是对Mina的吹捧,记得我曾经和同事开玩笑说,“等真正的懂得了Mina,你就知道什么叫Java了”,所以,我现在想急切的把现在所知道和了解的所有关于Mina的一些东西都想在这篇文章里面写出来,如果有写的不到位的地方还请各位同学多多指正,下面就开始对Mina做一个完整的介绍。
第一章Mina的几个类先说说Mina的几个类和接口(1) IoService(2) BaseIoService(3) BaseIoAcceptor(4) IoAcceptor(5) IoConnector这几个类和接口是整个服务器或客户端程序(IoConnector)的入口程序,其中就Mina 的整体上来说,IoService是所有IO通信的入口程序,下面的几个接口和类都是继承或者实现了IoService接口。
mina编码器详解
![mina编码器详解](https://img.taocdn.com/s3/m/70b741ede009581b6bd9ebfd.png)
怎样使用 ProtocolCodecFilter 呢?
应用程序基本上就是接收一串字节并且将这串字节转化为消息(较高级别的对象)。
有三种常用方法可以将字节流分离成消息:
. 使用固定长度的消息。 . 使用固定长度的标头指出消息内容主体的长度。 . 使用分隔符;例如很多基于文本的消息在消息的后面追加换行(或者 CR LF 组合)
this.height = height; this.numberOfCharacters = numberOfCharacters; }
public int getWidth() { return width;
}
public int getHeight() { return height;
}
public int getNumberOfCharacters() { return numberOfCharacters;
public class ImageRequestDecoder extends CumulativeProtocolDecoder {
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
概述一下我们需要的编解码请求和响应类:
. ImageRequest:一个简单 POJO,表示向服务端的请求。 . ImageRequestEncoder:将请求对象编码成特定协议的数据(客户端使用) . ImageRequestDecoder:将特定协议的数据解码成请求对象(服务端使用) . ImageResponse:一个简单 POJO,表示来自服务端的响应。 . ImageResponseEncoder:服务端用来编码响应对象。 . ImageResponseDecoder:客户端用来解码响应对象。 . ImageCodecFactory:这个类用来创建必要的编码器和解码器。
Mina2.0工作原理以及配置注意事项
![Mina2.0工作原理以及配置注意事项](https://img.taocdn.com/s3/m/5ccc7935b90d6c85ec3ac6e7.png)
其中 Reads 操作是指 server/clinet 端从网络上收到 Message 的过程;Writes 操作是指 server/clinet 端将 Message 写到网路上的过程。
(1) IoService:这个接口在一个线程上负责套接字的建立,拥有自己的 Selector,监听是否有连接被建立。
(3) IoFilter:这个接口定义一组拦截器,这些拦截器可以包括日志输出、黑
名单过滤、数据的编码(write 方向)与解码(read 方向)等功能,其中数据的 encode 与 decode 是最为重要的、也是你在使用 Mina 时最主要关注的地方。
(4) IoHandler:这个接口负责编写业务逻辑,也就是接收、发送数据的地方。 这也是实际开发过程中需要用户自己编写的部分代码。
throws Exception {
String str = message.toString();
("The message received is [" + str + "]");
if (str.endsWith("quit")) {
session.close(true);
深入理解Apache_Mina_(5)----_配置Mina的线程模型
![深入理解Apache_Mina_(5)----_配置Mina的线程模型](https://img.taocdn.com/s3/m/28cffa1ea76e58fafab00332.png)
深入理解Apache Mina----配置Mina的线程模型在Mina的使用中,线程池的配置一个比较关键的环节,同时它也是Mina性能提高的一个有效的方法,在Mina的2.0以上版本中已经不再需要对Mina线程池的配置了,本系列文章都是基于当前的稳定版本Mina1.1.7版来进行讲述的,Mina的2.0以上版本现在还都是M(millestone,即里程碑)版的,在1.5版本上2.0M版为稳定版本,但是在1.5+以上则为非稳定版本,所以,为了更好的进行讨论和学习,还是基于Mina1.1.7版本进行讨论,如果使用Mina2.0进行开发要注意JDK的版本问题,当然如果有能力的话也可以自行修改和编译Mina的2.0版本,这里对此就不再多说,使用2.0版本的同学可以不用理会本文的内容。
上面的内容都是基于Apache Mina提供的文档讲述,如有需要,请自行查找相关资料,在此不再赘述。
下面开始对Mina的线程模型的配置、使用、及ExcutorFilter的基本原理进行简单的讲解。
(一)配置Mina的三种工作线程在Mina的NIO模式中有三种I/O工作线程(这三种线程模型只在NIO Socket中有效,在NIO数据包和虚拟管道中没有,也不需要配置):(1)Acceptor thread该线程的作用是接收客户端的连接,并将客户端的连接导入到I/O processor线程模型中。
所谓的I/O processor线程模型就是Mina的I/O processor thread。
Acceptor thread在调用了Acceptor.bind()方法后启动。
每个Acceptor只能创建一个Acceptor thread,该线程模型不能配置,它由Mina自身提供。
(2)Connector thread该线程模型是客户端的连接线程模型,它的作用和Acceptor thread类似,它将客户端与服务器的连接导入到I/O processor线程模型中。
mina原理
![mina原理](https://img.taocdn.com/s3/m/69abc965783e0912a2162a86.png)
客户端通信过程1.通过SocketConnector同服务器端建立连接2.链接建立之后I/O的读写交给了I/O Processor线程,I/O Processor是多线程的3.通过I/O Processor读取的数据经过IoFilterChain里所有配置的IoFilter,IoFilter进行消息的过滤,格式的转换,在这个层面可以制定一些自定义的协议4.最后IoFilter将数据交给Handler进行业务处理,完成了整个读取的过程5.写入过程也是类似,只是刚好倒过来,通过IoSession.write写出数据,然后Handler进行写入的业务处理,处理完成后交给IoFilterChain,进行消息过滤和协议的转换,最后通过I/O Processor将数据写出到socket通道IoFilterChain作为消息过滤链1.读取的时候是从低级协议到高级协议的过程,一般来说从byte字节逐渐转换成业务对象的过程2.写入的时候一般是从业务对象到字节byte的过程IoSession贯穿整个通信过程的始终整个过程可以用一个图来表现消息箭头都是有NioProcessor-N线程发起调用,默认情况下也在NioProcessor-N线程中执行类图/class-diagrams.html#ClassDiagrams-ProtocolDeco derclassdiagramConnector作为连接客户端,SocketConector用来和服务器端建立连接,连接成功,创建IoProcessor Thread(不能超过指定的processorCount),Thread由指定的线程池进行管理,IoProcessor 利用NIO框架对IO进行处理,同时创建IoSession。
连接的建立是通过Nio的SocketChannel进行。
NioSocketConnector connector = new NioSocketConnector(processorCount); ConnectFuture future = connector.connect(new InetSocketAddress(HOSTNAME, PORT));建立一个I/O通道Acceptor作为服务器端的连接接受者,SocketAcceptor用来监听端口,同客户端建立连接,连接建立之后的I/O操作全部交给IoProcessor进行处理IoAcceptor acceptor = new NioSocketAcceptor();acceptor.bind( new InetSocketAddress(PORT) );Protocol利用IoFilter,对消息进行解码和编码,如以下代码通过 MyProtocolEncoder 将java对象转成byte串,通过MyProtocalDecoder 将byte串恢复成java对象Java代码1.connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MyProtocalFactory()));2.......3.public class MyProtocalFactory implements ProtocolCodecFactory{4. ProtocolEncoderAdapter encoder = new MyProtocolEncoder();5. ProtocolDecoder decoder = new MyProtocalDecoder() ;6. public ProtocolDecoder getDecoder(IoSession session) throws Exception {7. return decoder;8. }9. public ProtocolEncoder getEncoder(IoSession session) throws Exception {10. return encoder;11. }12.}13.......14.public class MyProtocalDecoder extends ProtocolDecoderAdapter{15.16. public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out)17. throws Exception {18.19. int id = in.getInt();20. int len = in.getInt();21. byte[] dst = new byte[len];22.23. in.get(dst);24.25. String name = new String(dst,"GBK");26.27. Item item = new Item();28. item.setId(id);29. item.setName(name);30. out.write(item);31. }32.}33.......34.public class MyProtocolEncoder extends ProtocolEncoderAdapter {35.36. public void encode(IoSession session, Object message,37. ProtocolEncoderOutput out) throws Exception {38. Item item = (Item)message;39. int byteLen = 8 + item.getName().getBytes("GBK").length ;40. IoBuffer buf = IoBuffer.allocate(byteLen);41. buf.putInt(item.getId());42. buf.putInt(item.getName().getBytes("GBK").length);43. buf.put(item.getName().getBytes("GBK"));44. buf.flip();45. out.write(buf);46.47. }48.}handler具体处理事件,事件包括:sessionCreated、sessionOpened、sessionClosed、sessionIdle、exceptionCaught、messageReceived、messageSent。
Java 远程通讯_MINA
![Java 远程通讯_MINA](https://img.taocdn.com/s3/m/45f9fb4cbe23482fb4da4c32.png)
第一章MINA前述1.1线程模型MINA线程模型采用了Reactors in threads模型,即Main Reactor + Sub Reactors的模式。
由main reactor处理连接相关的任务:accept、connect等,当连接处理完毕并建立一个socket连接(称之为session)后,给每个session分配一个sub reactor,之后该session的所有IO、业务逻辑处理均交给了该sub reactor。
每个reactor均是一个线程,sub reactor中只靠内核调度,没有任何通信且互不打扰。
现在来讲讲我对线程模型演进的一些理解:Thread per Connection:在没有nio之前,这是传统的java网络编程方案所采用的线程模型。
即有一个主循环,socket.accept阻塞等待,当建立连接后,创建新的线程/从线程池中取一个,把该socket连接交由新线程全权处理。
这种方案优缺点都很明显,优点即实现简单,缺点则是方案的伸缩性受到线程数的限制。
Reactor in Single Thread:有了nio后,可以采用IO多路复用机制了。
我们抽取出一个单线程版的reactor模型,时序图见下文,该方案只有一个线程,所有的socket连接均注册在了该reactor上,由一个线程全权负责所有的任务。
它实现简单,且不受线程数的限制。
这种方案受限于使用场景,仅适合于IO密集的应用,不太适合CPU密集的应用,且适合于CPU资源紧张的应用上。
Reactor + Thread Pool:方案2由于受限于使用场景,但为了可以更充分的使用CPU资源,抽取出一个逻辑处理线程池。
reactor仅负责IO任务,线程池负责所有其它逻辑的处理。
虽然该方案可以充分利用CPU资源,但是这个方案多了进出thread pool的两次上下文切换。
Reactors in threads: 基于方案3缺点的考虑,将reactor分成两个部分。
ApacheMINA线程模型配置
![ApacheMINA线程模型配置](https://img.taocdn.com/s3/m/86aa2c25366baf1ffc4ffe4733687e21af45ffd5.png)
ApacheMINA线程模型配置本文内容是配置基于MINA的应用中的线程模型。
1 禁止缺省的ThreadModel设置MINA2.0及以后版本已经没有ThreadModel了,如果使用这些版本的话,可以跳过本节。
ThreadModel设置是在MINA1.0以后引入的,但是使用ThreadModel增加了配置的复杂性,推荐禁止掉缺省的TheadModel 配置。
IoAcceptor acceptor = ...;IoServiceConfig acceptorConfig = acceptor.getDefaultConfig();acceptorConfig.setThreadModel(ThreadModel.MANUAL);注意在相关指南中,假定你已经如本节所说的禁止了ThreadModel的缺省配置。
2 配置I/O工作线程的数量这节只是NIO实现相关的,NIO数据包以及虚拟机管道等的实现没有这个配置。
在MINA的NIO实现中,有三种I/O工作线程:>>Acceptor线程接受进入连接,并且转给I/O处理器线程来进行读写操作。
>>每一个SocketAcceptor产生一个Acceptor线程,线程的数目不能配置。
>>Connector线程尝试连接远程对等机,并且将成功的连接转给I/O处理器线程来进行读写操作。
>>每一个SocketConnector产生一个Connector线程,这个的数目也不可以配置。
>>I/O处理器线程执行实际上的读写操作直到连接关闭。
>>每一个SocketAcceptor或SocketConnector都产生它们自己的I/O处理线程。
这个数目可以配置,缺省是1。
因此,对于每个IoService,可以配置的就是I/O处理线程的数目。
下面的代码产生一个有四个I/O处理线程的SocketAcceptor。
MINA官方教程(中文版)
![MINA官方教程(中文版)](https://img.taocdn.com/s3/m/499817c44028915f804dc2ac.png)
简介:Apache MINA 2 是一个开发高性能和高可伸缩性网络应用程序的网络应用框架。
它提供了一个抽象的事件驱动的异步API,可以使用TCP/IP、UDP/IP、串口和虚拟机内部的管道等传输方式。
Apache MINA 2 可以作为开发网络应用程序的一个良好基础。
本文将介绍Apache MINA 2 的基本概念和API,包括I/O 服务、I/O 会话、I/O 过滤器和I/O 处理器。
另外还将介绍如何使用状态机。
本文包含简单的计算器服务和复杂的联机游戏两个示例应用。
Apache MINA 2 是一个开发高性能和高可伸缩性网络应用程序的网络应用框架。
它提供了一个抽象的事件驱动的异步API,可以使用TCP/IP、UDP/IP、串口和虚拟机内部的管道等传输方式。
Apache MINA 2 可以作为开发网络应用程序的一个良好基础。
下面将首先简单介绍一下Apache MINA 2。
Apache MINA 2 介绍Apache MINA 是Apache 基金会的一个开源项目,目前最新的版本是 2.0.0-RC1。
本文中使用的版本是 2.0.0-M6。
从参考资料中可以找到相关的下载信息。
下面首先介绍基于Apache MINA 的网络应用的一般架构。
基于Apache MINA 的网络应用的架构基于Apache MINA 开发的网络应用,有着相似的架构。
图1中给出了架构的示意图。
图 1. 基于Apache MINA 的网络应用的架构如图1所示,基于Apache MINA 的网络应用有三个层次,分别是I/O 服务、I/O 过滤器和I/O 处理器:⎽I/O 服务:I/O 服务用来执行实际的I/O 操作。
Apache MINA 已经提供了一系列支持不同协议的I/O 服务,如TCP/IP、UDP/IP、串口和虚拟机内部的管道等。
开发人员也可以实现自己的I/O 服务。
⎽I/O 过滤器:I/O 服务能够传输的是字节流,而上层应用需要的是特定的对象与数据结构。
MINA2.0用户手册中文随笔翻译
![MINA2.0用户手册中文随笔翻译](https://img.taocdn.com/s3/m/a77efc250066f5335a8121b5.png)
第一章——开始在这一章中,我们将给你什么是MINA、NIO的第一感觉,以及为什么我们在NIO上构建框架。
我们还展示了如何运行一个基于MINA 的非常简单的程序例子。
1、NIO综述NIO APIs在Java 1.4中被给出,如今它已经在在大量的程序中被使用了。
NIO APIs允许非阻塞IO操作。
注意:首先,知道MINA是在NIO 1的基础上开发的是很重要的,如今在Java 7中一个新版本的NIO-2已经被设计出来,但是我们还没有从这个版本所带有的特性中获益。
注意:知道N在NIO中的意思是New也是重要的,但是我们将在很多地方使用非阻塞(Non-Blocking)这个术语。
NIO-2需要被看为New New I/O……java.nio.*包包含以下关键结构∙Buffers——数据容器∙Chartsets——bytes和Unicode之间的翻译容器∙Channels——代表I/O操作的连接实体∙Selectors——提供可选择的多路复用非阻塞IO∙Regexps——提供一些操作正则表达式的工具我们将集中关注MINA框架的Channels、Selectors以及Buffers部分,其它部分我们将对用户进行隐藏。
本手册将集中关注在这些内部组件上构建我们所需要的系统。
NIO vs BIO知道BIO和Clocking IO这两种APIs之间的不同是很重要的,在阻塞模型中依赖普通的sockets链接:当你读、写或者在socket上做任何操作的时候,被调用的操作将会阻塞调用者,知道操作完成。
在一些例子中,关键是能够调用操作,并期望被调用的操作在操作完成之后能够通知调用者:这使得调用者在平均的运行时间里可以做更多的事情。
这也就是NIO的优点,当你有很多的socket链接时,NIO能帮你更好的处理它们:你不需要为每一个链接创建指定的进程,你只需要使用少量的进程来做同样的事情。
如果你想获得有关于NIO的更多信息,网上有很多不错的文章,还有几本书讲述了有关NIO的问题。
MINA2官方教程翻译.
![MINA2官方教程翻译.](https://img.taocdn.com/s3/m/539297f758f5f61fb73666ad.png)
MINA2官方教程翻译(1)2.x与1.x的变化文章分类:Java编程一、包与命名所有的类和方法严格使用驼峰法命名。
例如SSLFilter被更名为SslFilter,其它很多类也是如此。
所有NIO传输类在命名时增加‘Nio’前缀。
因为NIO并不只是socket/datagram传输的实现,所有‘Nio’前缀加在了所有的NIO传输类上。
改变之前:Java代码1.SocketAcceptor acceptor=new SocketAcceptor();改变之后:Java代码1.SocketAcceptor acceptor=new NioSocketAcceptor();Filter类被重新整理进多重子包内。
随着框架自带的filter实现的数量的增加,所有的filter都被移动到适当的子包中(例如,StreamWriteFilter移至org.apache.mina.filter.stream)。
*.support的所有包被移动到了其父包(或者其他包)中。
为了避免循环依赖,*.support包中的所有类都被移至其父包或者其他包中。
你可以在IDE(例如Eclipse)中简单的修正这些包的导入从而避免编译错误。
二、BuffersMINA ByteBuffer被重命名为IoBuffer。
因为MINA ByteBuffer与JDK中NIO ByteBuffer同名,很多用户发现与其组员沟通时存在很多困难。
根据用户的反馈,我们将MINA ByteBuffer重命名为IoBuffer,这不仅使类名称简化,也是类名称更加明晰。
放弃Buffer池,默认使用IoBuffer.allocate(int)来分配heap buffer。
•acquire()与release()两个方法将不再是容易发生错误的。
如果你愿意,你可以调用free()方法,但这是可选的。
请自己承担使用这个方法的风险。
•在大多数JVM中,框架内置的IoBuffer性能更加强劲、稳定。
MINA2实用手册
![MINA2实用手册](https://img.taocdn.com/s3/m/b5b4e068a45177232f60a2a4.png)
MINA2实用手册作者:李庆丰Email:scholers@MINA框架是对java的NIO包的一个封装,简化了NIO程序开发的难度,封装了很多底层的细节,然开发者把精力集中到业务逻辑上来,最近做了一个相关的项目,为了备忘对MINA做一个总结。
一、服务端初始化及参数配置MINA2初始化很简单。
基本的初始化参数如下://初始化Acceptor—可以不指定线程数量,MINA2里面默认是CPU数量+2 NioSocketAcceptor acceptor = new NioSocketAcceptor(5);java.util.concurrent.Executor threadPool =Executors.newFixedThreadPool(1500);//建立线程池//加入过滤器(Filter)到Acceptoracceptor.getFilterChain().addLast("exector", newExecutorFilter(threadPool));//编码解码器acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new WebDecoder(),newXmlEncoder()));//日志LoggingFilter filter = new LoggingFilter();filter.setExceptionCaughtLogLevel(LogLevel.DEBUG);filter.setMessageReceivedLogLevel(LogLevel.DEBUG);filter.setMessageSentLogLevel(LogLevel.DEBUG);filter.setSessionClosedLogLevel(LogLevel.DEBUG);filter.setSessionCreatedLogLevel(LogLevel.DEBUG);filter.setSessionIdleLogLevel(LogLevel.DEBUG);filter.setSessionOpenedLogLevel(LogLevel.DEBUG);acceptor.getFilterChain().addLast("logger", filter);acceptor.setReuseAddress(true);//设置的是主服务监听的端口可以重用acceptor.getSessionConfig().setReuseAddress(true);//设置每一个非主监听连接的端口可以重用MINA2中,当启动一个服务端的时候,要设定初始化缓冲区的长度,如果不设置这个值,系统默认为2048,当客户端发过来的消息超过设定值的时候,MINA2的机制是分段接受的,将字符是放入缓冲区中读取,所以在读取消息的时候,需要判断有多少次。
Mina2.0完全自学手册要点
![Mina2.0完全自学手册要点](https://img.taocdn.com/s3/m/45cb3d7848d7c1c708a145c8.png)
远程通信Mina2 学习笔记引言 (3)一.Mina入门 (3)第一步.下载使用的Jar包 (3)第二步.工程创建配置 (3)第三步.服务端程序 (4)第四步.客户端程序 (7)第五步.长连接VS短连接 (9)二.Mina基础 (11)1.IoService接口 (12)2.1.1 类结构 (12)2.1.2 应用 (13)2.IoFilter接口 (15)2.2.1 类结构 (15)2.2.2 应用 (17)添加过滤器 (17)自定义编解码器 (18)制定协议的方法: (20)IoBuffer常用方法: (20)Demo1:模拟根据文本换行符编解码 (21)Demo2:改进Demo1的代码 (23)Demo3:自定义协议编解码 (33)3.IoHandler接口 (51)三.Mina实例 (51)四.其他................................................ 错误!未定义书签。
引言最近使用Mina开发一个Java的NIO服务端程序,因此也特意学习了Apache 的这个Mina框架。
首先,Mina是个什么东西?看下官方网站(/)对它的解释:Apache的Mina(Multipurpose Infrastructure Networked Applications)是一个网络应用框架,可以帮助用户开发高性能和高扩展性的网络应用程序;它提供了一个抽象的、事件驱动的异步API,使Java NIO在各种传输协议(如TCP/IP,UDP/IP协议等)下快速高效开发。
Apache Mina也称为:●NIO框架●客户端/服务端框架(典型的C/S架构)●网络套接字(networking socket)类库总之:我们简单理解它是一个封装底层IO操作,提供高级操作API的通讯框架!(本文所有内容仅针对Mina2.0在TCP/IP协议下的应用开发)一.Mina入门先用Mina做一个简单的应用程序。
Mina2.0框架源码剖析
![Mina2.0框架源码剖析](https://img.taocdn.com/s3/m/849ce500e518964bcf847cc9.png)
Mina2.0框架源码剖析整个框架最核心的几个包是:org.apache.mina.core.service,org.apache.mina.core.session, org.apache.mina.core.polling以及org.apache.mina.transport.socket。
这一篇先来看org.apache.mina.core.service。
第一个要说的接口是IoService,它是所有IoAcceptor和IoConnector的基接口.对于一个IoService,有哪些信息需要我们关注呢?1)底层的元数据信息TransportMetadata,比如底层的网络服务提供者(NIO,ARP,RXTX等),2)通过这个服务创建一个新会话时,新会话的默认配置IoSessionConfig。
3)此服务所管理的所有会话。
4)与这个服务相关所产生的事件所对应的监听者(IoServiceListener)。
5)处理这个服务所管理的所有连接的处理器(IoHandler)。
6)每个会话都有一个过滤器链(IoFilterChain),每个过滤器链通过其对应的IoFilterChainBuilder来负责构建。
7)由于此服务管理了一系列会话,因此可以通过广播的方式向所有会话发送消息,返回结果是一个WriteFuture集,后者是一种表示未来预期结果的数据结构。
8)服务创建的会话(IoSession)相关的数据通过IoSessionDataStructureFactory 来提供。
9)发送消息时有一个写缓冲队列。
10)服务的闲置状态有三种:读端空闲,写端空闲,双端空闲。
11)还提供服务的一些统计信息,比如时间,数据量等。
IoService这个服务是对于服务器端的接受连接和客户端发起连接这两种行为的抽象。
再来从服务器看起,IoAcceptor是IoService 的子接口,它用于绑定到指定的ip和端口,从而接收来自客户端的连接请求,同时会fire相应的客户端连接成功接收/取消/失败等事件给自己的IoHandle去处理。
Mina状态机介绍
![Mina状态机介绍](https://img.taocdn.com/s3/m/be12a85e804d2b160b4ec039.png)
Mina状态机介绍(Introduction to mina-statemachine)如果你使用Mina开发一个复杂的网络应用时,你可能在某些地方会遇到那个古老而又好用的状态模式,来使用这个模式解决你的复杂应用。
然而,在你做这个决定之前,你或许想检出Mina的状态机的代码,它会根据当前对象的状态来返回对接收到的简短的数据的处理信息。
注意:现在正式发布Mina的状态机。
因此你要自己在Mina的SVN服务器上检出该代码,并自己编译,请参考开发指南,来获取更多的关于检出和编译Mina源码的信息。
Mina的状态机可以和所有已经发布的版本Mina配合使用(1.0.x, 1.1.x 和当前发布的版本)。
一个简单的例子让我们使用一个简单的例子来展示一下Mina的状态机是如何工作的。
下面的图片展示了一个录音机的状态机。
其中的椭圆是状态,箭头表示事务。
每个事务都有一个事件的名字来标记该事务。
初始化时,录音机的状态是空的。
当磁带放如录音机的时候,加载的事件被触发,录音机进入到加载状态。
在加载的状态下,退出的事件会使录音机进入到空的状态,播放的事件会使加载的状态进入到播放状态。
等等......我想你可以推断后后面的结果:)现在让我们写一些代码。
外部(录音机中使用该代码的地方)只能看到录音机的接口:public interface TapeDeck {void load(String nameOfTape);void eject();void start();void pause();void stop();}下面我们开始编写真正执行的代码,这些代码在一个事务被触发时,会在状态机中执行。
首先我们定义一个状态。
这些状态都使用字符串常量来定义,并且使用@state标记来声明。
public class TapeDeckHandler {@State public static final String EMPTY = "Empty";@State public static final String LOADED = "Loaded";@State public static final String PLAYING = "Playing";@State public static final String PAUSED = "Paused";}现在我们已经定义了录音机中的所有状态,我们可以根据每个事务来创建相应的代码。
Mina使用教程
![Mina使用教程](https://img.taocdn.com/s3/m/60a62bc7370cba1aa8114431b90d6c85ec3a88bb.png)
Mina使⽤教程Mina框架简介⼀、Mina基本概念1、BIO、NIO、AIOJava BIO :同步并阻塞,服务器实现模式为⼀个连接⼀个线程,即客户端有连接请求时服务器端就需要启动⼀个线程进⾏处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
使⽤API:ServerSocket、SocketJava NIO :同步⾮阻塞,服务器实现模式为⼀个请求⼀个线程,即客户端发送的连接请求都会注册到多路复⽤器上,多路复⽤器轮询到连接有I/O请求时才启动⼀个线程进⾏处理。
使⽤API:ServerSocketChannel、SocketChannel、SelectorJava AIO(NIO.2) :异步通道提供⽀持连接、读取、以及写⼊之类⾮锁定操作的连接,并提供对已启动操作的控制机制。
Java 7 中⽤于Java Platform(NIO.2)的More New I/O APIs,通过在 java.nio.channels 包中增加四个异步通道,从⽽增强了Java 1.4 中的New I/O APIs(NIO)。
使⽤API:AsynchronousServerSocketChannel、AsynchronousSocketChannel、CompletionHandler2、NIO线程模型单⼀线程单⼀Selector模型:与多线程处理BIO相⽐减少了线程数量,⽤⼀个线程循环处理ACCEPT、READ、WRITE。
但是如果某⼀次READ 或者WRITE处理时间过长,都会影响后⾯的事件响应。
3、Mina2.0的线程模型与单⼀线程处理单⼀Selector相⽐,Mina采⽤三种线程:IoAcceptor/IoConnector线程、IoProcessor线程、IoHandler线程在服务器端,bind⼀个端⼝后,会创建⼀个Acceptor线程来负责监听⼯作。
这个线程的⼯作只有⼀个:调⽤Java NIO接⼝在该端⼝上select connect事件,获取新建的连接后,封装成IoSession,交由后⾯的Processor线程处理。
Mina编程的两个注意点
![Mina编程的两个注意点](https://img.taocdn.com/s3/m/86f9861ce3bd960590c69ec3d5bbfd0a7956d516.png)
Mina编程的两个注意点•1. 首先,这是一个nio的框架,仍然是采用reactor模式,知道这一点后,那么编程就没有什么难的。
nio的编程,无外乎就是这些套路,再进一步说,网络编程,也就是这些套路了。
•2. 那么剩下编程的注意点,也就是编解码的处理以及最后的业务逻辑的处理。
2.1 编解码的注意点:因为在网络编程中,client和server之间,往往需要完整的接收到一条消息的后,才交给业务逻辑处理。
具体可以参看,其中,我们常常是继承自CumulativeProtocolDecoder来实现自己的解码器,主要的docode的方法,其作用是将本次数据和上次接收到的数据(如果doDecode方法没有处理完的话),统一放到一个buffer中,之后扔给 doDecode方法处理,若处理完之后,还有剩下的数据,则继续缓存。
Java代码可以看一个具体的实现:PrefixedStringDecoder的doDecode 方法,这个decode是消息长度+具体字节流的消息格式。
Java代码其中,prefixedDataAvailable方法是判断得到IoBuffer里的数据是否满足一条消息了,如果再进去看这个方法的实现化,读取是,使用ByteBuffer的绝对位置的读取方法(这种读取不影响position的值的);当已经有一条完整的消息时,则用getPrefixedString读取(使用的是ByteBuffer的相对位置的读取方法,这会影响position的值,从而实际的消费掉数据).2.2 业务逻辑的处理注意点,一般都会使用一个线程池处理。
这里就有一个问题,有时候同一个连接的消息处理,是希望按照顺序来进行的。
这也很简单,不需要保证一个连接的所有的业务处理都限定在一个固定的线程中,但是需要保证当有消息需要处理时,这些消息的处理,都在同一个线程中完成。
当然了,mina中也有了相应的实现OrderedThreadPoolExecutor。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
接上节,介绍基于 mina 开发的一般步骤: 简单的 TCPServer 第一步:编写 IoService 按照上面的执行流程,我们首先需要编写 IoService,IoService 本身既是服
务端,又是客户端,我们这里编写服务端,所以使用 IoAcceptor 实现,由于 IoAcceptor 是 与 协 议 无 关 的 , 因 为 我 们 要 编 写 TCPServer , 所 以 我 们 使 用 IoAcceptor 的 实 现 NioSocketAcceptor , 实 际 上 底 层 就 是 调 用 java.nio.channels.ServerSocketChannel 类。当然,如果你使用了 Apache 的 APR 库,那么你可以选择使用 AprSocketAcceptor 作为 TCPServer 的实现,据传说 Apache APR 库的性能比 JVM 自带的本地库高出很多。 IoProcessor 是由指定的 IoService 内部创建并调用的,我们并不需要关心。 public class MyServer {
private final static Logger log = LoggerFactory .getLogger(MyIoHandler.class);
@Override public void messageReceived(IoSession session, Object message)
(3) IoFilter:这个接口定义一组拦截器,这些拦截器可以包括日志输出、黑
名单过滤、数据的编码(write 方向)与解码(read 方向)等功能,其中数据的 encode 与 decode 是最为重要的、也是你在使用 Mina 时最主要关注的地方。
(4) IoHandler:这个接口负责编写业务逻辑,也就是接收、发送数据的地方。 这也是实际开发过程中需要用户自己编写的部分代码。
4.线程机制
Mina 中的很多执行环节都使用了多线程机制,用于提高性能,图 3 所示为 Mina 的线程模型图。
图 3 是 Mina 的 Server 端内部运行图,Client 处表示外部的客户端通过 Socket 建立连接。
图中 IoAcceptor 对应 NioSocketAcceptor 类,是用来接受 Socket 请求的。 图中用灰色的齿轮表示,小齿轮表示它一直可以干活,运转不息。黄色的小 齿轮则表示一个运行在线程池上的任务,表示它是运转在线程池之上的。 1、服务端在创建 NioSocketAcceptor 实现时,会生成一个线程池,此线程 池用来执行一个接受请求的任务,这个任务叫 Acceptor(可以在 AbstractPollingIoAcceptor 类中找到其实现类),Acceptor 会开一个 Selector, 用来监听 NIO 中的 ACCEPT 事件。任务初始化时并没有执行,而在调用 NioSocketAcceptor 实例的 bind 方法时,则会启动对指定端口的 ACCEPT 事件的 监听。
throws Exception {
String str = message.toString();
("The message received is [" + str + "]");
if (str.endsWith("quit")) {
session.close(true);
return;
public class MyClient { mainmainmainmain 方法:
IoConnector connector=new NioSocketConnector();
connector.setConnectTimeoutMillis(30000); connector.getFilterChain().addLast("codec",
session.write(values); }
} 注册 IoHandler:
connector.setHandler(new ClientHandler("你好!\r\n 大家好!")); 然后我们运行 MyClient,你会发现 MyServer 输出如下语句: The message received is [你好!] The message received is [大家好!] 我们看到服务端是按照收到两条消息输出的,因为我们用的编解码器是以换 行符判断数据是否读取完毕的。
}
}
} 然后我们把这个 IoHandler 注册到 IoService:
acceptor.setHandler(new MyIoHandler()); 当然这段代码也要在 acceptor.bind()方法之前执行。 然后我们运行 MyServer 中的 main 方法,你可以看到控制台一直处于阻塞 状态,此时,我们用 telnet 127.0.0.1 9123 访问,然后输入一些内容,当按下回 车键,你会发现数据在 Server 端被输出,但要注意不要输入中文,因为 Windows 的命令行窗口不会对传输的数据进行 UTF-8 编码。当输入 quit 结尾的字符串时, 连接被断开。 这里注意你如果使用的操作系统,或者使用的 Telnet 软件的换行符是什么, 如果不清楚,可以删掉第二步中的两个红色的参数,使用 TextLineCodec 内部 的自动识别机制。 2.简单的 TCPClient 这里我们实现 Mina 中的 TCPClient,因为前面说过无论是 Server 端还是 Client 端,在 Mina 中的执行流程都是一样的。唯一不同的就是 IoService 的 Client 端实现是 IoConnector。 第一步:编写 IoService 并注册过滤器
2. 框架架构和执行流程
框架同时提供了网络通信的 server 端和 client 的封装,无论在哪端,mina 都 处于用户应用程序和底层实现的中间层,起到了软件分层的作用。在实际开发过
程中,用户只需要关心要发送的数据和处理逻辑就可以了。
mina 的执行流程如下:
图 1 mina 架构图
图 2 mina 工作流程图
.getLogger(ClientHandler.class); private final Strin values) {
this.values = values; } @Override public void sessionOpened(IoSession session) {
public static void main(String[] args){ IoAcceptor acceptor=new NioSocketAcceptor(); acceptor.getSessionConfig().setReadBufferSize(2048); acceptor.getSessionConfig.setIdleTime(IdleStatus.BOTH_IDLE,10); acceptor.bind(new InetSocketAddress(9123));
} }
这段代码我们初始化了服务端的 TCP/IP 的基于 NIO 的套接字,然后调用 IoSessionConfig 设置读取数据的缓冲区大小、读写通道均在 10 秒内无任何操作
就进入空闲状态。 第二步:编写过滤器 这 里 我 们 处 理 最 简 单 的 字 符 串 传 输 , Mina 已 经 为 我 们 提 供 了
Mina 2.0 工作原理以及配置中的注意事项
1. Mina 是什么?
Apache MINA 是一个网络应用程序框架,用来帮助用户简单地开发高性能 和高可靠性的网络应用程序。它提供了一个通过 Java NIO 在不同的传输例如 TCP/IP 和 UDP/IP 上抽象的事件驱动的异步 API。
Apache MINA 也称为: ● NIO 框架库 ● 客户端服务器框架库 ● 一个网络套接字库
其中 Reads 操作是指 server/clinet 端从网络上收到 Message 的过程;Writes 操作是指 server/clinet 端将 Message 写到网路上的过程。
(1) IoService:这个接口在一个线程上负责套接字的建立,拥有自己的 Selector,监听是否有连接被建立。
SSL·TLS·StartTLS 支持 ● 超载保护和传输流量控制 ● 利用模拟对象进行单元测试 ● JMX 管理能力 ● 通过 StreamIoHandler 提供基于流的 I/O 支持 ● 和知名的容器(例如 PicoContainer、Spring)集成 ● 从 Netty 平滑的迁移到 MINA, Netty 是 MINA 的前辈。
TextLineCodecFactory 编解码器工厂来对字符串进行编解码处理。 acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName("UTF-8"), LineDelimeter. WINDOWS.getValue(), LineDelimiter. WINDOWS.getValue() ) ) ); 这段代码要在 acceptor.bind()方法之前执行,因为绑定套接字之后就不能再做
MINA 虽然简单但是仍然提供了全功能的网络应用程序框架: ● 为不同的传输类型提供了统一的 API: ○ 通过 Java NIO 提供 TCP/IP 和 UDP/IP 支持 ○ 通过 RXTX 提供串口通讯(RS232) ○ In-VM 管道通讯 ○ 你能实现你自己的 API! ● 过滤器作为一个扩展特性; 类似 Servlet 过滤器 ● 低级和高级的 API: ○ 低级: 使用字节缓存(ByteBuffers) ○ 高级: 使用用户定义的消息对象(objects)和编码(codecs) ● 高度定制化线程模型: ○ 单线程 ○ 一个线程池 ○ 一个以上的线程池(也就是 SEDA) ● 使用 Java5 SSL 引擎提供沙盒(Out-of-the-box)