从Jetty、Tomcat和Mina中提炼NIO构架网络服务器的经典模式

转自:http://blog.csdn.net/cutesource/article/details/6192016

http://blog.csdn.net/cutesource/article/details/6192145

http://blog.csdn.net/cutesource/article/details/6192163

如何正确使用NIO来构架网络服务器一直是最近思考的一个问题,于是乎分析了一下Jetty、Tomcat和Mina有关NIO的源码,发现大伙都基于类似的方式,我感觉这应该算是NIO构架网络服务器的经典模式,并基于这种模式写了个小小网络服务器,压力测试了一下,效果还不错。废话不多说,先看看三者是如何使用NIO的。

Jetty Connector的实现

先看看有关类图:

其中:

SelectChannelConnector负责组装各组件

SelectSet负责侦听客户端请求

SelectChannelEndPoint负责IO的读和写

HttpConnection负责逻辑处理

在整个服务端处理请求的过程可以分为三个阶段,时序图如下所示:

阶段一:监听并建立连接

这一过程主要是启动一个线程负责accept新连接,监听到后分配给相应的SelectSet,分配的策略就是轮询。

阶段二:监听客户端的请求

这一过程主要是启动多个线程(线程数一般为服务器CPU的个数),让SelectSet监听所管辖的channel队列,每个SelectSet维护一个Selector,这个Selector监听队列里所有的channel,一旦有读事件,从线程池里拿线程去做处理请求

阶段三:处理请求

这一过程就是每次客户端请求的数据处理过程,值得注意的是为了不让后端的业务处理阻碍Selector监听新的请求,就多线程来分隔开监听请求和处理请求两个阶段。

由此可以大致总结出Jetty有关NIO使用的模式,如下图所示:

最核心就是把三件不同的事情隔离开,并用不同规模的线程去处理,最大限度地利用NIO的异步和通知特性

========================================================================

下面再来看看Tomcat是如何使用NIO来构架Connector这块的。

先看看Tomcat Connector这块的类图:

其中:

NioEndpoint负责组装各部件

Acceptor负责监听新连接,并把连接交给Poller

Poller负责监听所管辖的channel队列,并把请求交给SocketProcessor处理

SocketProcessor负责数据处理,并把请求传递给后端业务处理模块

在整个服务端处理请求的过程可以分为三个阶段,时序图如下所示:

阶段一:监听并建立连接

这一阶段主要是Acceptor监听新连接,并轮询取一个Poller ,把连接交付给Poller

阶段二: 监听客户端的请求

这一过程主要是让每个Poller监听所管辖的channel队列,select到新请求后交付给SocketProcessor处理

阶段三:处理请求

这一过程就是从多线程执行SocketProcessor,做数据和业务处理

于是乎我们发现抛开具体代码细节,Tomcat和Jetty在NIO的使用方面是非常一致的,采用的模式依然是下图:

================================================================

最后我们再看看NIO方面最著名的框架Mina,抛开Mina有关session和处理链条等方面的设计,单单挑出前端网络层处理来看,也采用的是与Jetty和Tomcat类似的模式,只不过它做了些简化,它没有隔开请求侦听和请求处理两个阶段,因此,宏观上看它只分为两个阶段。

先看看它的类图:

其中:

SocketAcceptor起线程调用SocketAcceptor.Work负责新连接侦听,并交给SocketIoProcessor处理

SocketIoProcessor起线程调用SocketIoProcessor.Work负责侦听所管辖的channel队列, select到新请求后交给IoFilterChain处理

IoFilterChain组装了mina的处理链条

在整个服务端处理请求的过程可以分为两个阶段,时序图如下所示:

阶段一:监听并建立连接

阶段二: 监听并处理客户端的请求

总结来看Jetty、tomcat和Mina,我们也大概清楚了该如何基于NIO来构架网络服务器,通过这个提炼出来的模式,我写了个很简单的NIO Server,在保持连接的情况下,可以很轻松的保持6万连接(由于有65535连接限制),并能在负载只有3左右的情况下(4核),承担3到4万的TPS请求(当然做的事情很简单,仅仅是把buffer转化为自定义协议的包,然后再把包转为buffer写到客户端)。因此简单地实践一下可以证明这个模式的有效性,不妨再看看这个图,希望对大伙以后写server有用:

时间: 2024-10-02 22:06:16

从Jetty、Tomcat和Mina中提炼NIO构架网络服务器的经典模式的相关文章

在VS2013中强制IIS Express应用程序池使用经典模式

直接在文件夹地址栏输入 %userprofile%\documents\iisexpress\config\applicationhost.config 会打开上边的配置文件 将 <siteDefaults><logFile logFormat="W3C" directory="%IIS_USER_HOME%\Logs" /><traceFailedRequestsLogging directory="%IIS_USER_HO

Tomcat插件与Jetty插件在MyEclipse中的配置

-Djetty.port=8101 jetty:run tomcat6:run <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat6-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8888</port>

JAVA 中BIO,NIO,AIO的理解

JAVA 中BIO,NIO,AIO的理解 博客分类: 网络编程 [转自]http://qindongliang.iteye.com/blog/2018539 在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同步阻塞? 6 什么是同步非阻塞? 7 什么是异步阻塞? 8 什么是异步非阻塞? 散仙不才,在查了一部分资料后,愿试着以通俗易懂的方式解释下这几个名词.如有不足之处,还

Java中的NIO和IO的对比分析

总的来说,java中的IO和NIO主要有三点区别: IO                  NIO 面向流     面向缓冲 阻塞IO  非阻塞IO  无   选择器(Selectors) 1.面向流与面向缓冲 Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的. Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方.此外,它不能前后移动流中的数据.如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区. Java

sitemesh2在tomcat和weblogic中同时使用的配置问题

(一)拦截*.do,装饰器中匹配do tomcat 可行 weblogic 不可行 web.xml ~~~ <filter> <filter-name>sitemesh</filter-name> <filter-class> com.opensymphony.module.sitemesh.filter.PageFilter </filter-class> </filter> <filter-mapping> <f

tomcat在eclipse中起动成功,主页却打不开

tomcat在eclipse中启动成功,主页却打不开 症状: tomcat在eclipse里面能正常启动,而在浏览器中访问http://localhost:8080/不能访问,且报404错误.同时其他项目页面也不能访问. 关闭eclipse里面的tomcat,在tomcat安装目录下双击startup.bat手动启动tomcat服务器.访问htt://localhost:8080/能正常访问tomcat管理页面. 症状原因: eclipse将tomcat的项目发布目录(tomcat 目录中的we

MSM实现tomcat集群中session共享的高可用

目录 1.测试环境概述 2.MSM简介 2.1.MSM的特性 2.2.MSM要解决的问题 2.3.MSM的工作原理 3.环境搭建 3.1.memcached安装 3.2.jkd与tomcat安装配置 3.3.MSM sticky session + kryo模式的配置 3.4.MSM no-sticky session + kryo模式的配置 4.思考与总结 1.测试环境概述 采用两台linux x64主机,主机上分别安装memcached与tomcat,memcached提供key/value

(20140714作业)超必杀都是从小招数中提炼出来的!C#基础技能汇总

作业要求是汇总之前学过的基础知识,可以说 学的乱七八糟,一塌糊涂! 这里写了石头提及的几个重点,比如泛型,委托. 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Reflection; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace ConsoleApplication1 9 { 10

Mina中关于多个同类型Filter(如ProtocolCodecFilter)实例共存问题的解决

最近在研读Mina框架的源码,刚好手头上有项目就直接用上了.直接进入正题-- 对Mina有点了解的人都知道,Mina中有一条FilterChain,我们可以向其中加入Filter实现链式处理.从源码看来,多数Filter(如ProtocolCodecFilter)在使用过程只允许有一个实例.若FilterChain中存在多个相同的实例,则有可能出现各种莫明其妙的问题,这些问题往往是超出你预料之外的,而且调试起来比较困难,除非你熟知Mina整个框架.究其原因,主要是在AttributeKey的问题