基于MINA构建简单高性能的NIO应用

所需积分/C币:6 2019-03-14 21:20:47 223KB PDF

基于MINA构建简单高性能的NIO应用,提出了JAVA NIO在MINA上的简单应用
要的方法: // the o/s buffer 相对比较复杂,这里就不一一列举 future. join( 主f( future.主sWr主tten() 它的方法了。简单来说 loFTer就像 WriteEuture write(Object message) cL。 seFuture close() //message has been written ServletFilter,在事件被 loHandler处理 1 else Object getAttribute(String key) /The messsage couldn't be 之前或之后进行一些特定的操作。但 ob]ect setAttribute(String key. //written out completel 是它比 ServletFilte复杂,可以处理很 Object value)i //(e. g Connection is closed) Object removeAttribute(string 多种事件,除了包括 chAndler在内的 key )i 7个事件以外,还有一些内部的事件可 Set<string>. getAttributekeys( 通过调用 future. join,程序就会以进行操作。 b。° lean isconnected() 阻塞直至消息处理结束。我们还能通 MNA提供了一些常用的| oFilter boolean inclosing()i SocketAddress getRemoteAddress() 过危 uture, is Written得知消息是否成功实现,例如有 LoggingFilter(日志 boolean: siDle (Idlestatus 发送。 status) 功能)、B| acklistFilter(黑名单功 在这里笔者顺便说一个实际使用能)、 Compression Filter(压缩功 在这里,笔者把| SEssion的方法大的发现,消息发送是会自动合并的。能)、 SSLFilter(SsL支持)。这 致分成三类 简单来说,如果在很短的时间里,对些过滤器比较简单,通过阅读它们 同一个 loSession进行了两次wre操的源代码能够更进一步理解过滤器 第一类,连接操作功能 作,客户端有可能只收到一条消息,的实现。笔者在这里要重点介绍两 最主要的方法有两个,向客户而这条消息就是服务器发出的两条消个过滤器, Protoco| CodecFilter和 端发送消息和断开连接。可以看出,息前后接起来。这样的设计可以在高 ExecutorFilter Wte接受的变量是一个 Object,但是并发的时候节省网络开销,而笔者的 实际上应该传入什么类型呢?具体还实际使用过程中效果也相当好。但是 Protoco| Codecfilter 得看是否使用了 Protocolcodecfilter如果这样行为会导致客户端工作不正 网络传输的内容其实本质是一个 (下文会详细介绍)。如果使用常,你也可以通过参数关闭它 二进制流,但是业务功能不会,或者 了 ProtocolCodecFilter,那这个 说不应该去直接操作二进制流。M|NA message将可能是一个 String,也可第二类,属性存储操作 默认向 chandler传入的 message 能是一个用户定义的 JavaBean。默认 通常来说,系统是有用户状态的。是一个 Byte Buffer,如果直接在 情况下, message是一个 Byte Buffer。这样就需要在连接上存储用户属性, chAndler操作 Byte Buffer,,会导致大 Byte Buffer是MNA的一个类,跟java.| o Session的 Attribute就是这样一个功量协议分析的代码和实际的业务代码 no. Byte Buffer类同名,MNA20将会能。例如两个连接同时连入服务器,混杂在一起。最适合的做法,就是在 将它改成| bUffer,以避免误会。 个连接是用户A,用户D是13,另 loFilter把By! e Buffer转换成Stng或 另一个值得留意的是 Future类。一个连接是用户B,用户1D是14。我者 JavaBean, ProtocolCodecFilter正 M|NA是一个非阻塞的通信框架,其中们就可以在用户登录成功之后,调用是这样的一个功能的过滤器 个明显的体现就是调用 loSession. o Session setAttribute(" ogin id",13), 使用 ProtocolCodecFiter很简单, Wrt方法是不会阻塞的。用户调用了然后在其后的操作中,通过 lo Session.只要把 ProtocolcodecFilter入到 Wrt方法之后,消息内容会发到底层 getAttribute( login id)获得当前登录 FilterChain就可以了,但是需要提供 等候发送,至于什么时候发出,就不用户|D并进行相应的操作。简单来说, 个 ProtocolCodecFactory。其实 得而知了。当然,调用了wrte之后数就是一个类似 Httpsession的功能,当 ProtocolCodecFilter仅仅是实现了过 据几乎是立刻发出的,这得益于NO然具体的实现方法不一样 滤器部分的功能,它会将最终的转换 的高性能。但是如果必须确认消息发 工作,交给从 ProtocolCodecFactory 出再进行某些处理,我们就需要使用第三类,连接状态 获得的 Encode和 Decode。如果需要 Future类 从方法名上我们就能知道它具体编写自己的 Protocol Codec,就应该从 以下是一个很常见的代码 的功能,这里就不多说了。 ProtocolCodecFactory入手。M|NA内 置了几个 Protocolo 比 工 Session:sess⊥on WriteFuture. future loFilter 较常用的就是 ObjectSerialization Cod session. write(..) 过滤器是MNA的一个很重要的 ecFactory和 TextLine CodecFactory A Wait: until the message is // completely written out to 功能。 loFilter也是一个接口,但是 ObjectSerialization CodecFactory 122程序员 是 Java objec序列化之后的内容优化指南 性,那是因为MINA开发初期,JVM 直接跟 Byte Buffer互相转化,比 MNA默认配置的性能并不是很高并没有现在的强大,带有池效果的 较适合两端都是Java的情况使用。的,部分原因是MNA目前还保留初 direct buffer性能比较好。但是当我们 TextLine CodecFactory就是 String跟期版本的架构,另外一个原因是因为使用Xms×mx等指令增加JM可使 ByteBuffer的转化,说白了就是文本。JM的发展。以下有几个方法可以改用的内存,那仅仅增加了堆的内存空 例如你要实现一个SMTP服务器或者进MNA的性能 间,而 direct memory的空间并没有增 POP服务器,就可以使用它。而笔 首先,可以关闭默认的加,导致M|NA实际使用的时候经常出 者的实际使用,大多数情况都是使用 Thread Model设置 现 OutofMemory Erroro TextLine CodecFactoryo 如果的确想使用 direct memory, IoAcceptor acceptor 这里提及一下 loFilter的顺 IoService config acceptorConfig 可以通过 XX: MaxDirectMemory Size 序问题, loFilter是有加入顺序 acceptor. getDefaul tConfig() 选项来设置。不过笔者不建议这样做, accepto 的,例如,先加入 LoggingFilter再 ThreadModel. MANUAL)i 因为最新的测试表明,在现代的JVM 加入 ProtocolCodecFilter,和先 里面, direct memory比堆的表现更差。 加入 ProtocolcodecFilter再加入 ThreadModel是一个很简单的线这里可能有读者会觉得奇怪,为什么 Logging Filter I的效果是不一样的。前程实现,用手 lo Service。但是它实不用池,而要用堆呢,而且还需要gc。 者 LoggingFilter写入日志的内容是在太弱,以至于在并发环境产生大量那是因为现在的 JVM gc能力已经很强 ByteBuffer,而后者写入日志的是转换题。在MNA20中, Threadmodel了,而且在并发环境里面poo的同步 后具体的类,例如Stin。实际使用的直接被取消。实际使用中,应该使用也是一个性能的问题 时候,一定要处理好过滤器的顺序 ExecutorFilter来实现线程。 我们可以通过这样的代码进行设置 其次,可以增加O处理线程 每一个 Acceptor/ Connector都使 ByteBuffer, setUseDirectBuffers( ExecutorFilter false)i 另一个重要的过滤器就是用一个线程来处理连接,然后把连接 ByteBuffer. setAllocator( Executor Filter。这里需要先说明一下发送给 1/0 processor进行读写操作, new SimpleByteBufferAllocator() MNA的线程工作模式。 我们只可以修改 O processor使用的 M|NA默认是单线程处理所有客线程数,用以下代码设置 MINA20为了提供最好的性能和 稳定性已经默认把直接内存分配改成 户端的消息。也就是说,即使你在 IOAcceptor acceptor 堆 台8CPU的机器上面跑可能也只用 lew SocketAcceptor Runtime. getRuntime() 最后,可以把应用部署在Lnux上, 到一个CPU。另外,如果某次消息 vailableProcessors()+l 并且打开 Java nio使用 Linux epoll的 处理太耗时,就会导致其他消息等 Executors. ne wCachedThreadPool( 功能 待,整体的吞吐量下降。很多朋友 抱怨MNA的性能差,其实是因为他 当然是要将 Executor Filter加入 可能你还没听过epo,但是你应 该听过Lighttpd、N Squid等 们没有加入 ExecutorFilter的缘故 acceptor. getDefaultconfig( 得益于epo‖,它们提供很高的网络性 ExecutorFilter设计的很精巧,大家 getFilterChain(). addLast( 能,还占用非常少的系统资源。JDK6 可以仔细阅读一下源代码,它会将同 new ExecutorFi⊥tex( 已经默认把epo‖配置打开,因此笔者 个连接的消息合并起来按顺序调 E tors. newCachedthreadPool( 建议把应用部署在JDK6上面,也同时 用,不会出现两个线程同时处理同 因为JDK6还有别的优化特性。如果应 个连接的情况 第三,修改内存分配方式。 用必须部署在JDK5上,可以通过参数 这里再次提及 loFitler的顺序问题, 般情况下会将 ExecutorFilter放在 笔者在开发过程中,多次遇到 把epol支持打开。■ Protocol CodecFilter之后,因为不需 OutofMemory Error,经过研究之后 作简介 要多线程地执行 ProtocolCodec操作 才发现原因。MNA默认是使用dect曾冠东闻名 Sparkle a从事互联 用单一线程来进行 ProtocolCodec性能 memory实现 Byte Buffe池的方案(以 会比较高,而具体的业务逻辑可能还下简称 direct buffer,通过JN在内 网业测态D③减白0 设计到数据库操作,因此更适合放在 存开辟一段空间来使用,该方案在早 在数际消作 中使用 MINA. Spring slae3成员 不同的线程中运行。 期的MNA版本中是一个非常好的特 200802123

...展开详情
img
qq_38091134
  • GitHub

    绑定GitHub第三方账户获取

关注 私信 TA的资源

上传资源赚积分,得勋章
相关内容推荐