未完待续》》》

目录:

一)同步、异步、阻塞、非阻塞

二)Java中的NIO

三)Mina 异步请求

四)Mina 同步请求

五)Mina 核心类及处理流程

六)Mina 线程模型

七)Mina 通用通讯框架(协议:ProtoBuf)

八)Mina 其他

 (注:部分内容整理来自网络资源!)


一)同步、异步、阻塞、非阻塞

1)同步阻塞

2)同步非阻塞

3)异步阻塞

4)异步非阻塞

阻塞与非阻塞是一个相对的问题——谁阻塞了谁?是两个“事物”的交互问题。

同步与异步通俗的来说是指——完成一件事的过程是“从头到尾”还是“多线操作”。

大多数认为阻塞就同步,非阻塞就异步。但是上文提到的“同步非阻塞”怎么理解呢?——同步非阻塞中的“非阻塞”是指不阻塞应用线程,如果kernel没有准备好会返回应用线程一个状态,但是应用线程会不停的“主动”检查这个状态,一直等到返回ok状态,因此说他还是个“同步”的操作。

link:

http://www.ibm.com/developerworks/cn/linux/l-async/

http://blog.csdn.net/historyasamirror/article/details/5778378

 二)Java中的NIO

NIO主要关键点:

  • buffer
  • channel
  • selector

三)Mina 异步请求

四)Mina 同步请求

例如Mina的NioSocketConnector建立连接的过程如下(同步):

ConnectFuture connectF = connector.connect(new InetSocketAddress(ip,
port));
connectF.awaitUninterruptibly();
session = connectF.getSession();

ConnectFuture调用awaitUninterruptibly方法后,将阻塞应用线程直到连接建立完成。此时将获得session对象。(如果不awaitUninterruptibly,从ConnectFuture中获取的session极有可能为null。)
因此这里的awaitUninterruptibly方法 将一个异步请求“活生生的”转变成一个同步请求。同理,write、read动作类似处理(同步):

write

WriteFuture writeF = session.write(msg);
writeF.awaitUninterruptibly();
if (writeF.getException() != null) {
//异常处理
} else if (writeF.isWritten()) {
//准备读操作
}

read

ReadFuture readF = session.read();
readF.awaitUninterruptibly();
if (readF.getException() != null) {
//异常处理
} else {
//接收到消息,进行业务处理
}

具体参见实例:

http://www.cnblogs.com/huangfox/p/3461839.html

五)Mina 核心类及处理流程

从上图可以关键的类包括:

IoService,IoFilterChain,IoHandler,IoSession

1)IoService

IoService负责底层IO操作,他的好处主要在于隐藏底层IO操作,方便使用;基于事件机制将同步IO转化成异步IO。

最常用的接口是SocketAcceptor、SocketConnector,用做TCP协议通讯下的服务端和客户端。

2)IoFilterChain

IoFilterChain主要负责数据包的处理工作,包括编码、解码等功能。其主要思想是——与业务逻辑代码分离。当然IofilterChain也是处理流程的扩展点,包括为处理流程添加线程池。

3)IoHandler

IoHandler主要实现业务逻辑(调用业务逻辑接口)。

4)IoSession

IoSession是对底层连接的封装,一个IoSession对应一个底层的IO连接。
发送数据其实是个异步的过程。发送的操作首先会逆向穿过IoFilterChain,到达IoService。但IoService上并不会直接调用底层IO接口来将数据发送出去,而是会将该次调用封装成一个WriteRequest,放入session的writeRequestQueue中,最后由IoProcessor线程统一调度flush出去。所以发送操作并不会引起上层调用线程的阻塞。

处理流程

1)建立连接

开启一个SocketAcceptor(服务端),会创建一个acceptor线程,他负责监听指定端口上的connect事件(维护一个selector)。获取新建的连接后封装成IoSession交由IoProcessor线程处理。
SocketConnector(客户端)类似会创建一个connector线程。

这类acceptor、connector线程可以生动的理解为“前台线程”,负责“接待工作”(connector),有客户来访将其登记(标示成一个业务需求-IoSession)交由具体的业务员(IoProcessor)处理。

2)processor处理

Processor线程主要负责具体的IO操作、filterChain、IoHandler执行。Processor线程的数量默认为cpu数量+1,主要是为了充分利用多核的处理能力。Processor线程的数量可以根据实际情况进行配置。
多个IoSession会被分配到多个Processor线程中,可以理解为一个Processor线程“服务”一个或多个IoSession对象。值得一提的是,N个IoProcessor形成一个处理池(SimpleIoProcessorPoll),分配Processor的时候根据IoSession的id绝对值模N进行分配。

具体代码如下:

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保定具体的processor线程
session.setAttributeIfAbsent(PROCESSOR, processor);
} return processor;
}

在默认情况下filterChain、IoHandler的操作都是有IoProcessor顺序执行(执行完一个再执行下一个),如果IoHandler中的业务处理比较耗时,那么Processor线程将阻塞,后续的请求将得不到处理。即同时处理的请求数最多只有N个(N为Processor线程数量)。在高并发的情况下这种模式有待改进。(六 Mina线程模型 中将解答该问题)

接着上面的类比,前台(acceptor、connector)接待客户(session)分配给业务员(IoProcessor)进行服务, 业务员对客户进行交流(IO操作、编码、解码等)并执行相应的业务服务(IoHandler)。同理业务员每次只能服务一个客户,其他客户只能等待(假设其他业务员都有自己的客户)。

六)Mina 线程模型

接上文,上文提到“若IoHandler中的业务处理比较耗时,将阻塞当前Processor线程”,那么可以通过添加线程池处理这个问题。
Mina提供了一个很好的扩展点,可以在FilterChain添加线程池,让“下面”的业务处理过程并行起来。如图:

第一种模式:Mina默认的模式,IoProcessor全程服务。(One by one)

第二种模式:在FilterChain中加入ThreadPoolFilter,此时的处理流程变为Processor线程读取完数据后,执行IoFilterChain的逻辑。当执行到Thread Pool Filter的时候,该Filter会将后续的处理流程封装到一个Runnable对象中,并交由Filter自身的线程池来执行,而Processor线程则能立即返回来处理下一个IO请求。这样如果后面的IoFilter或IoHandler中有阻塞操作,只会引起Filter线程池里的线程阻塞,而不会阻塞住Processor线程,从而提高了服务器的处理能力。Mina提供了Thread Pool Filter的一个实现:ExecutorFilter。(本段内容为转载)

第三种模式:在合适的环节添加多个线程池,这种适合于FilterChain、IoHandler过程中存在多个计算密集型的任务。一般不需要使用,加大了代码复杂程度。

接着上面的类比,如果公司业务发展很好,客户增多,那么一个业务员(Processor)将很难及时服务到众多客户。于是公司决定业务员只负责与客户交流,具体的业务操作交由专门的业务服务团队(ThreadPool)。大家意会一下即可!

七)Mina 通用通讯框架(协议:ProtoBuf)

八)Mina 其他

 

Mina 专题的更多相关文章

  1. Dubbo面试专题

    Dubbo面试专题 1. 什么是dubbo Dubbo是阿里巴巴SOA服务化治理方案的核心框架,是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案. 2.  ...

  2. 2022GDUT寒假专题学习-1 B,F,I,J题

    专题链接:专题学习1 - Virtual Judge (vjudge.net) B - 全排列 题目 思想 这道题可以用DFS进行求解,但是一看到全排列,其实可以立刻想到一个STL函数:next_pe ...

  3. 2016年中国微信小程序专题研究报告

    2016年12月29日,全球领先的移动互联网第三方数据挖掘和分析机构iiMedia Research(艾媒咨询)权威首发<2016年中国微信小程序专题研究报告>. 报告显示,82.6%手机 ...

  4. JAVA通信系列二:mina入门总结

    一.学习资料 Mina入门实例(一) http://www.cnblogs.com/juepei/p/3939119.html Mina入门教程(二)----Spring4 集成Mina http:/ ...

  5. [.NET领域驱动设计实战系列]专题二:结合领域驱动设计的面向服务架构来搭建网上书店

    一.前言 在前面专题一中,我已经介绍了我写这系列文章的初衷了.由于dax.net中的DDD框架和Byteart Retail案例并没有对其形成过程做一步步分析,而是把整个DDD的实现案例展现给我们,这 ...

  6. Mina、Netty、Twisted一起学(八):HTTP服务器

    HTTP协议应该是目前使用最多的应用层协议了,用浏览器打开一个网站就是使用HTTP协议进行数据传输. HTTP协议也是基于TCP协议,所以也有服务器和客户端.HTTP客户端一般是浏览器,当然还有可能是 ...

  7. 转载:《.NET 编程结构》专题汇总(C#)

    <.NET 编程结构>专题汇总(C#) - M守护神 - 博客园http://www.cnblogs.com/liusuqi/p/3213597.html 前言     掌握一门技术,首要 ...

  8. mina通信 demo

    1,要用到4个jar 2,服务端 package mina.server; import java.io.IOException; import java.net.InetSocketAddress; ...

  9. Mina入门实例(一)

    mina现在用的很多了,之前也有用到,但是毕竟不熟悉,于是查了一些资料,做了一些总结.看代码是最直观的,比什么长篇大论都要好.不过其中重要的理论,也要理解下. 首先是环境,程序运行需要几个包,这里用m ...

随机推荐

  1. Maxscale-在第一个节点的配置

    [maxscale]threads=4 ##### Write Service, need to set address[server1]type=serveraddress=172.16.50.36 ...

  2. tumblr热度

  3. tinyxml2使用

    项目中遇到一个问题,C/C++需要与JAVA通信,JAVA方已经使用了XML序列化传输.本可以考虑JSON/GOOGLE PROTOCOL BUFFER的,但为了使JAVA方不做过多改动,坚持使用XM ...

  4. Spring 注解详细分析解释有实例

    概述 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO ...

  5. Python算法——递归思想

    编程语言在构建程序时的基本操作有:内置数据类型操作.选择.循环.函数调用等,递归实际属于函数调用的一种特殊情况(函数调用自身),其数学基础是数学归纳法.递归在计算机程序设计中非常重要,是许多高级算法实 ...

  6. 2018.4.23 git删除已经add的文件

    使用 git rm 命令即可,有两种选择, 一种是 git rm --cached "文件路径",不删除物理文件,仅将该文件从缓存中删除: 一种是 git rm --f " ...

  7. 《DSP using MATLAB》Problem 6.21

    代码: %% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %% Output In ...

  8. 《DSP using MATLAB》Problem 5.13

    1. 代码: %% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %% Output ...

  9. c# 自定义log4net过滤器

    有时候为了实现自己想要的多个日志文件记录不同的内容,可能需要自定义log4net过滤器,比如我这里需要记录三个文件,这三个文件的内容又不能重复,多次尝试未果. 为了不更改任何现有日志代码的情况下,于是 ...

  10. 依赖注入的方式测试ArrayList和LinkedList的效率(对依赖注入的再次理解)

    9/20 号再进行学习 在C++中,main函数尽可能的简单,只要调用子函数的一句话就实现了功能. java开发中,controller就相同于是main函数,其他类的方法不在本类中时候, 1.可以用 ...