未完待续》》》

目录:

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

二)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. A Spy in the Metro(UVA 1025 ACM/ICPC World Finals2003)

    ---恢复内容开始--- 题意:有n(2<=n<=50)个车站,从左到右编号为1~n,有M1辆列车从第1站向右开,还有M2辆列车从第N站向左开.在时刻0,间谍从第1站出发,目的是在时刻T( ...

  2. Uva 816 Abbott's Revenge(BFS)

    #include<cstdio> #include<cstring> #include<vector> #include<queue> using na ...

  3. python------模块定义、导入、优化 ------->xml模块

    1. xml模块 引用参考原文链接:https://www.cnblogs.com/python-gm/p/8032465.html      谢谢 xml是实现不同语言或程序之间进行数据交换的协议, ...

  4. putty登陆sourceforge.net(密钥的设置)

    现在直接启动putty.exe是不能登陆sourceforge.net 的.按vps的方式,输入地址.用户名和密码后,程序就自动关闭.在登入前需要安装密匙,具体做法如下: 首先得生成一个SSH Key ...

  5. servlet创建项目过程中,servlet内容重写的两种搭建,tomcat的配置,class的存放位置,web.xml的搭建等注意事项与易错点

    运行一个servlet项目:需要做这些前提工作: 1.配置tomcat,在server选项卡的设置也就基本的设置,HTTP port与JMX port等端口号:基本都是默认的.这里需要注意的是,有的教 ...

  6. day 4 Socket 和 NIO Netty

    Scoket通信--------这是一个例子,可以在这个例子的基础上进行相应的拓展,核心也是在多线程任务上进行修改 package cn.itcast.bigdata.socket; import j ...

  7. goland 文件头注释

    打开GoLand的setting选项 依次选择Editor,CodeStyle ,File and Code Templates ,Go File 根据自己需要添加即可 /* @Time : ${DA ...

  8. Stateful Kubernetes Applications Made Easier: PSO and FlashBlade

    转自:https://medium.com/@joshua_robinson/stateful-kubernetes-applications-made-easier-pso-and-flashbla ...

  9. Linux系统运维故障排查

    一.思路 1.处理问题要求 2.一般思路 二.具体问题 1.网络问题 (1)网络不通 (2)网络很慢 2.硬件问题 3.操作系统问题 (1)系统无法正常启动 (2)系统运行慢或死机 4.服务或程序问题 ...

  10. 混合pyqt和qtcreator (2): Impl a image viewer (can show FIji ROI manager data)

    # -*- coding: utf-8 -*- """ Simple demonstration of TreeWidget, which is an extension ...