`

netty与tomcat等nio的比较(取自zhh2009在论坛里的发言)

 
阅读更多
源讨论: http://www.iteye.com/topic/909206?page=3

另外见整理:netty相关知识


NIO框架其实内部的核心实现都差不多, 比如在Server端通常开有Acceptor和Poller线程,

Acceptor负责接收请求,得到一个Socket后把它包装一下,比如放到一个Task中,然后再把Task加到一个Queue,

Poller说白了就是在不停的执行一个循环,在这个循环中处理各种Task,Task除了Acceptor新注册的任务外,当然还有读和写。

NIO框架性能表现得好与坏,更多的是作者在一些细节方面的处理,

比如在读写字节时尽量减少来回copy,这方面一些成熟的框架都做得很好了,

比如Tomcat、Jetty、Netty在从Socket中读取字节时一般都自已实现了一套Buffer类来对字节数组进行操作,

而不是直接使用java.nio中的Buffer类,

如果想从Buffer中抽取一个片段(比如在http协议解析中,一个请求行有method,uri,http-version),

只要把offset和片段length记下来就行了。


另一个就是并发问题了,尽量减少不必要的同步,


比如像上面的Queue就是一个很关键的地方,这个地方一般会有三种线程在对它操作,

1. Acceptor把接收到的Socket包装成Task加到Queue(执行Queue.offer)

2. 应用线程要写数据,所以WriteTask也会加到Queue(执行Queue.offer)

3. Poller从Queue中取出Task来执行(执行Queue.poll)

所以这个Queue的实现就很重要了,

Netty的聪明之处在于,它没有使用java.util.concurrent中的Queue实现(比如ArrayBlockingQueue或ConcurrentLinkedQueue),

而是使用Doug Lea大神在jdk1.7中才加入的jsr166y.LinkedTransferQueue,

在Netty中变成了org.jboss.netty.util.internal.LinkedTransferQueue,这两个类有一点点差异,

我无法确认是Trustin Lee自己修改的,还是用了不同版本。

jsr166y.LinkedTransferQueue威力不容忽视,Tomcat、Jetty、Mina都没使用,

如果你刚好又用过BoneCP(一个JDBC数据库链接池框架),它也用了jsr166y.LinkedTransferQueue来对链接进行offer和poll操作,

BoneCP的测试报告出来了(http://jolbox.com/),比DBCP、C3P0快20多倍。


除此之外,Netty的Poller实际上就是org.jboss.netty.channel.socket.nio.NioWorker,

默认情况下,NioWorker的个数是CPU个数的两倍,

并且Netty在NioWorker中建立了两个LinkedTransferQueue,

一个是registerTaskQueue,另一个是writeTaskQueue,



registerTaskQueue给Acceptor、Poller线程用,writeTaskQueue给应用线程和Poller线程用,

这一划分一定程度上减少了并发粒度,起码不用三种线程都挤到一个Queue上。



另一方面,writeTaskQueue是同时给多个应用线程使用的,

应用线程想往Channel中写数据时,这个Channel内部又有一个LinkedTransferQueue( 叫writeBuffer) 用来存放数据,

然后再把这个LinkedTransferQueue间接包装成一个writeTask放入writeTaskQueue,

而不是像传统做法那样每次写数据都直接放到writeTaskQueue,


因为Poller线程在写 应用线程A 放入的数据时,如果所有应用线程共用一个LinkedTransferQueue,

应用线程B必需跟 Poller线程 和 应用线程A 竞争同一个LinkedTransferQueue,


与其这样,还不如为应用线程B单独开一个LinkedTransferQueue,当Poller线程还没处理到应用B的数据时,

应用线程B自己去折腾自己的LinkedTransferQueue好了,

等Poller线程处理完应用A的数据后,再处理应用B的数据。


这种做法也是为了减少并发粒度,因为应用A和应用B的数据没有关联,所以没必要全放入一个Queue,

这样应用线程A和应用线程B在写数据时不会存在竞争。

具体实现更漂亮,有兴趣请看NioWorker和NioSocketChannel的源代码。

最后,再说一下Netty的一个缺点,

大家看到这,发现我都没有提到读数据的情况,Netty读数据也是用Poller线程在读,

不管Acceptor放入多少个Socket,全是Poller线程在一个个地读,

把读到的数据放到Buffer后会触发MessageEvent事件(Netty是一个纯正的事件驱动框架,这是Tomcat、Jetty这类业余选手望尘莫及的),

此时会调用ChannelUpstreamHandler这类处理器的messageReceived方法,

messageReceived方法中的代码通常是业务相关的,但是执行messageReceived方法的线程却是Poller线程,

所以只要在messageReceived这种地方出现问题,比如有个Thead.sleep调用或者出现无限循环,

那么此时Netty跟死了没分别,Poller线程无法往下走了,所有Task都没法处理了。

分享到:
评论
1 楼 dwangel 2014-02-05  
引用
那么此时Netty跟死了没分别,Poller线程无法往下走了,所有Task都没法处理了。


这个 是 nonblocking编程时本身就是要把 工作时间长的处理分到别的线程去做。

相关推荐

    netty与tomcat功能比较

    ### Netty与Tomcat功能比较 #### 一、概述 Netty和Tomcat都是Java领域内非常著名的服务器框架,但它们的设计目标和技术实现路径存在显著差异。本文将深入探讨Netty与Tomcat之间的区别,以及Netty之所以备受青睐的...

    【项目实战】Netty源码剖析&NIO;+Netty5各种RPC架构实战演练三部曲视频教程(未加密)

    ### Netty源码剖析与NIO及Netty5各种RPC架构实战演练三部曲知识点解析 #### 一、Netty概述 Netty是一款基于Java NIO的高性能服务器端编程框架,用于快速开发可维护的网络应用程序。它简化了网络编程的复杂性,使...

    netty实现简易tomcat

    在我们的简易版 Netty Tomcat 中,我们可以直接读取这些静态文件作为响应内容。 通过这个实践,你可以深入了解 Netty 如何处理网络通信,以及如何实现一个基本的 HTTP 服务器容器。这不仅加深了对 Netty 框架的理解...

    NIO+Netty5视频教程与Netty源码剖析视频教程

    《NIO+Netty5视频教程与Netty源码剖析视频教程》是一份全面解析网络编程框架Netty的教育资源,旨在帮助学习者深入理解和应用NIO(非阻塞I/O)以及Netty5的核心技术。该教程分为两个主要部分,分别针对理论分析和实战...

    NIO netty开发

    netty开发之nio netty开发之nio netty开发之nio netty开发之nio netty开发之nio netty开发之nio netty开发之nio netty开发之nio netty开发之nio netty开发之nio netty开发之nio netty开发之nio netty开发之nio netty...

    基于netty的nio使用demo源码

    在Netty中,NIO被用来实现高效的网络通信。 NIO的核心概念包括通道(Channel)、缓冲区(Buffer)、选择器(Selector)和处理器(Handler)。Netty中的NIO系统主要由以下组件组成: 1. **通道(Channel)**:它是...

    Java_NIO框架Netty教程

    资源名称:Java_NIO框架Netty教程资源截图: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。

    websocket+tomcat+jetty+netty

    在WebSocket技术的应用中,Tomcat自4.0版本开始支持WebSocket规范,提供了`org.apache.tomcat.websocket`包来帮助开发者创建WebSocket服务端程序。 Jetty是一个轻量级、高性能的HTTP服务器和Servlet容器,同样也...

    手写 tomcat nio

    【标题】:“手写 Tomcat NIO” 在深入探讨手写Tomcat NIO之前,我们首先需要理解NIO(Non-...在实际项目中,如果需要高性能的Web服务器,可能需要考虑使用成熟的开源产品,如Tomcat本身或Netty等高性能NIO框架。

    java_Netty权威指南,详解nio,tcp,http,netty

    这个权威指南深入探讨了Netty的核心概念和技术,同时也涵盖了与网络编程相关的基础,如非阻塞I/O(NIO)、传输控制协议(TCP)以及超文本传输协议(HTTP)。下面将对这些知识点进行详细解释。 一、非阻塞I/O(NIO)...

    netty示例NIO示例

    myeclipse开发通信示例,框架netty,代码本人写的,而且已测试通过,先运行NettyService,再运行NettyClient即可看到效果。nio示例也有,原理一样,运行先后顺序同netty.

    学习juc、nio、netty、tomcat调优、jvm调优-Advanced-JAVA.zip

    本资料主要涵盖了五个核心领域:Java并发(JUC)、非阻塞I/O(NIO)、Netty框架、Tomcat服务器优化以及Java虚拟机(JVM)调优。以下是这些主题的详细说明: 1. **Java并发(JUC - Java Concurrency Utilities)** ...

    jvm、nio、netty优化使用.txt

    Netty是一个NIO客户端服务器框架,可以快速轻松地开发网络应用程序,例如协议服务器和客户端。它极大地简化和简化了TCP和UDP套接字服务器等网络编程。 “快速简便”并不意味着最终的应用程序将遭受可维护性或性能...

    Netty01-nio.md

    Netty01-nio.md

    详细介绍 NIO与Netty编程-实战讲义详细pdf.7z

    **NIO(非阻塞I/O)与Netty编程**是现代Java网络应用开发中的重要技术,它们在处理高并发、低延迟的网络通信场景中起着关键作用。本讲义详细介绍了这两种技术,旨在帮助开发者更好地理解和运用它们。 ### 一、BIO...

    自己手写nio和netty,不建议下载

    NIO(Non-blocking Input/Output)是Java提供的一种...总之,NIO是一种改进的I/O模型,它提高了处理并发连接的能力,而Netty是建立在NIO之上的网络通信框架,提供了更高级别的抽象和优化,使得网络编程更为便捷高效。

    Java NIO框架Netty教程.pdf

    ### Java NIO框架Netty教程知识点解析 #### 一、Netty框架简介 Netty是一个高性能、异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器与客户端。它提供了对多种协议的支持,如HTTP、WebSocket、...

    Java-NIO-Netty框架学习

    Java NIO (Non-blocking Input/Output) 是Java平台中用于高效处理I/O操作的一种机制,它与传统的IO模型( Blocking I/O)相比,提供了更高级别的抽象,允许应用程序以非阻塞的方式读写数据,提高了并发性能。Netty是...

    BIO、NIO、AIO、Netty 、TCP全网最全解析!Netty中提供了哪些线程模型?

    本文将深入探讨BIO( Blocking I/O)、NIO(Non-blocking I/O)、AIO(Asynchronous I/O)以及Netty框架中的线程模型,并与TCP网络协议相结合,为您提供全网最全面的解析。 首先,让我们从基础开始,了解这些I/O...

Global site tag (gtag.js) - Google Analytics