zoukankan      html  css  js  c++  java
  • Mina2 研究总结

    一、Mina框架。

    Mina的框架大概是这么个样子:

    底层由Java 的NIO 1.0实现 核心架构应该是这样:


    内部有三个层次:

    I/O Service:实际运行的 I / O ,能够选择现成的Services 如 Acceptor 也能够自己实现。

    I/O Filter Chain :由多个过滤器组成的过滤器链。在这个环节将字节过滤或转换为预想的数据结构,反之亦然。

    I/O Handler :实际的业务逻辑部分。

    Server 端应用,创建一个基于 MINA 的应用程序,主要分为三步、

    1、Create I/O Service 。IOAcceptor 监听指定的port。处理网络连接请求;一旦一个新的连接到达,IOAcceptor 产生一个session,兴许全部从这个IP和port发送过来的请求都将被这个Session处理。

    2、Create Filter Chain。从现有的Filters 中选择或者创建一个传输 Request / Response 的自己定义的Filter 。Session创建之后全部的数据包都被放到过滤器链中。通过过滤器将原始的字节码转变为高层的对象,继承这两个接口完毕自己的编码解码 ProtocolEncoderAdapter     ProtocolDecoderAdapter 。

    3、Create I/O Handler。

    终于数据包或者对象被传送给Handler 做业务逻辑处理。

    二、IoService。

    IoService 是一个接口,两种实现方式:IoAcceptor  IoConnector .IoAcceptor是针对Server端。IoConnector 是针对Client端。IoService的主要职责:监听器管理、IoHandler、IoSession管理、FilterChain管理、Statistics 管理


    三、IoAcceptor:

    主要用于创建新的连接,Mina提供了多种实现,基本不用自己再去实现。

    NioSocketAcceptor:无堵塞的Socket 传输 Acceptor 针对TCP。

    NioDatagramAcceptor:无堵塞的Socket传输Acceptor 针对UDP。

    AprSocketAcceptor:堵塞的Socket 传输 Acceptor 基于 APR。

    VmPipeSocketAcceptor :the in VM Acceptor

    IoConnector:

    针对Client端的Socket连接。也有多种实现。

    NioSocketConnector:无堵塞的Socket 传输 Acceptor 针对TCP

    NioDatagramConnector:无堵塞的Socket 传输 Acceptor 针对UDP

    AprSocketConnector:堵塞的Socket传输Connector 基于 APR

    ProxyConnector:支持代理服务的Connector,通过截取连接的请求,并将终端指向代理设置的地址

    SerialConnector:针对串口传输的Connector

    VmPipeConnector:the in vm Connector

    四、Session。不论什么时候仅仅要有新的连接到来,都会生成一个Session对象。而且保存在内存中,直到断开连接

    Session状态包含:


    五、IoBuffer。IoBuffer是MINA内部的byte buffer,是对Java NIO ByteBuffer的封装,同一时候扩展了一些更加有用的方法。

    capacity属性描写叙述这个缓冲区最多能缓冲多少个元素。也是Buffer的最大存储元素数,这个值在创建Buffer的时候指定,不能改动。

    Limit 是从Buffer中向Channel中写入数据时,limit变量指示还剩多少数据能够读取,在从Channel中读取数据到Buffer 中时,limit变量指定还剩多少空间能够存放数据。position正常情况应该小于等于 limit

    Position Buffer实际上也是一个Array。当从Channel 读取数据时。将读出来的数据放进底层array,position 变量用来跟踪截止眼下为止已经写入多少数据。

    它指示假设下次写入Buffer时数据应该进入那个Array位置,比方已经读取10字节,position被置为10。指向array第四个位置。

    Mark:一个能够记忆的Position位置的值。调用 reset() 方法时会将Position重置为该索引的值,可是Mark并不总是须要定义。可是须要定义时不能定义为负数,不能大于Position,假设定义了Mark 则该Position 或 Limit 调整为小于Mark值时,Mark将被丢弃。例:

    i、初始状态下:

    此时position为0,limit和capacity都被设为9;

    image

     

    ii、从Channel中读入4个字节数据到Buffer,这时position指向4(第5个):

    image

     

    iii、在做写操作之前,我们必须调用一次flip()方法,这种方法做了两件重要的事情: 
    1. 将limit设置到当前的position处。 
    2. 设置position为0。

    image

     

    iiii、运行写操作后;

    image

    iv、运行clear后,position设为0,limit设为capition,mark则丢弃。

    image

    IoBuffer是一个抽象类。不能直接实例化,所以使用的时候须要调用allocate 方法进行内存分配

    IoBuffer buf = IoBuffer.allocate(len);
    			IoBuffer buf1 = IoBuffer.allocate(len, true);
    默认direct 是false。得到 heap buffer。假设是true 得到 direct buffer。

    Direct Buffer 不是分配在堆上,不被GC管理(可是java对象归GC管理。所以GC回收了对象。direct申请的空间也会被释放)。

    Heap Buffer 分配在堆上,可以理解为byte[]的封装。可是当我们把heap buffer写入Channel时,底层会先构建一个暂时DirectBuffer,然后复制heap buffer内容,再把这个 direct buffer写出去,由于 direct buffer写入Channel速度快,可是创建和销毁的代价高。所以在可以重用的地方使用。

    大文件时,heap buffer复制代价高。用DirectBuffer可以提高性能。下载文件除了SendFile机制还有 内存映射 MappedByteBuffer 直接将文件写入SocketChannel。降低数据复制,提高性能。

    总之反复可用的信息可以放在 Direct Buffer。

     IoBuffer同意生成一个自己主动扩展的buffer,设置 AutoExpand属性实现,

    IoBuffer buffer = IoBuffer.allocate(8);
    			 buffer.setAutoExpand(true);
    			 buffer.putString("12345678", encoder);
    			 // Add more to this buffer
    			 buffer.put((byte)10);

     clear() : limit = capacity  position = 0;重置 mark 。不清空数据,而是从头開始存放新的数据,相当于覆盖老数据。

    reset():清空数据

    remaining() :返回  limit - position的值。

    hasRemaining() :推断当前是否有数据,返回position < limit 的boolean 值

    六、优化指南。

    1、mina能够指定使用 direct 或者 heap memory实现buffer池。1.X版本号须要自己设置

    <span style="font-size:18px;">ByteBuffer.setUseDirectBuffers(false);
    		ByteBuffer.setAllocator(new SimpleByteBufferAllocator());</span>
    2.x已经默认把直接内存分配改成堆。


    2、将应用部署在linux上面而且打开 epoll 功能。

    JDK6 已经默认打开,其它版本号能够通过參数打开。








  • 相关阅读:
    【译】第26节---配置一对多关系
    【译】第25节---配置一对一关系
    【译】第24节---Fluent API
    pycharm 更改创建文件默认路径和修改字体大小
    软件工程----自我介绍
    课堂作业---读取文件实现求数组中所有子数组和的最大值
    实现数组中连续子数组值和最大
    android-----实现不两个不同的activity的跳转和数据传递
    android------解决editText只输入一行和textView不显示过多的内容
    android-------实现底部导航的模板
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5183427.html
Copyright © 2011-2022 走看看