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

另外见整理:[url=http://vanadiumlin.iteye.com/blog/1144989]netty相关知识[/url]

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的源代码。

[color=red]最后,再说一下Netty的一个缺点,[/color]

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

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

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

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

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

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

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

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

  1. 性能追击:万字长文30+图揭秘8大主流服务器程序线程模型 | Node.js,Apache,Nginx,Netty,Redis,Tomcat,MySQL,Zuul

    本文为<高性能网络编程游记>的第六篇"性能追击:万字长文30+图揭秘8大主流服务器程序线程模型". 最近拍的照片比较少,不知道配什么图好,于是自己画了一个,凑合着用,让 ...

  2. java移动文件导致tomcat死掉_原 netty导致tomcat假死

    一.系统需求: 保证后台系统在大并发下正常处理每一个业务连接请求. 二.运作方式: Netty+tomcat.在tomcat的web.xml配置文件中配置一个Listener类用来在tomcat初始化 ...

  3. Netty学习笔记一NIO基础

    Netty学习笔记一 一. NIO 基础 non-blocking io 非阻塞IO (也可称为new IO, 因为是JDK1.4加入的) 1. 三大组件 1.1 Channel 通道:数据的传输通道 ...

  4. Tomcat 比 nio 、aio性能更好的apr介绍

    Tomcat 比 nio .aio性能更好的apr介绍 apr:这个玩意儿可以提高Tomcat对静态文件以及https的处理性能.(更多好处百度我也不懂) Tomcat的下载解压 Tomcat 下载 ...

  5. NIO的空轮询bug是什么?netty是如何解决NIO空轮询bug的?

    文章目录 1. NIO的空轮询bug 2. netty如何解决NIO空轮询bug的? 1. NIO的空轮询bug JDK1.5开始引入了epoll基于事件响应机制来优化NIO.相较于select和po ...

  6. 【Java网络编程】:Netty实现OIO和NIO

    承接上文:https://blog.csdn.net/hxcaifly/article/details/85274664 前言 单纯地使用Java JDK来实现网络NIO是一件开发成本非常高的事情.然 ...

  7. java nio netty 教程,4. 彤哥说netty系列之Java NIO实现群聊(自己跟自己聊上瘾了),netty实现...

    4. 彤哥说netty系列之Java NIO实现群聊(自己跟自己聊上瘾了),netty实现 你好,我是彤哥,本篇是netty系列的第四篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识 ...

  8. Jetty、Netty、Tomcat、Undertow

    文章目录 Jetty.Netty.Tomcat.Undertow 优势 劣势 应用场景 基本原理 优势 劣势 应用场景 基本原理 Servlet Jetty.Netty.Tomcat.Undertow ...

  9. netty入门前置知识-NIO

    netty入门前置知识-NIO Netty简介 Netty 的介绍 Netty 的应用场景 互联网行业 游戏行业 大数据领域 其它开源项目使用到 Netty Netty 的学习资料参考 Java BI ...

最新文章

  1. boost::mpl::divides相关的测试程序
  2. Jerry的Fiori原创文章合集
  3. PC软件开发技术之一:在WinCC中通过VBS操作SQL Server2005
  4. 为什么说IT科技公司应该留住35岁员工?
  5. 职场人如何做好「公开表达」,提升个人影响力?
  6. Jboss jar包冲突及jar加载顺序
  7. mysql的sql分页查询语句怎么写_sql 分页查询语句(mysql分页语句)
  8. python读取二进制文件,转成十六进制格式
  9. H5 活动利用Canvas把用户信息和二维码合并到图片内。
  10. 机器视觉及视觉传感器
  11. html隐藏或显示不出来,win7隐藏文件显示不出来
  12. 把脉大连接:“多端协同”的大动脉与“多人协作”的主动脉
  13. ARCore:ARCore的初体验
  14. 重要的表格数据误删了,用EasyRecovery快速恢复!
  15. Qt常见make编译错误:/usr/bin/ld:cannot find -lxxx
  16. 【二维码营销案例】圣诞促销活动如何设计二维码能拉新留存促活转化?
  17. c语言 等概率随机数,等概率随机函数的实现(转)
  18. 执行Python语言能不能破解通达信接口api股票数据?
  19. html关灯游戏,关灯游戏
  20. aerospike小白老手都爱的使用经验

热门文章

  1. 每个游戏人前世都是大编剧 你来当评委
  2. 梅科尔工作室-任采薇-鸿蒙笔记1
  3. 双十一红包集结令二维码
  4. 全世界的人注意了,我要在兄弟连这里华丽变身了~!
  5. linux隐藏源ip,linux – NAT后关闭源IP
  6. 设计一个可玩性与可重复性高的游戏关卡
  7. 木马核心技术剖析读书笔记之木马实例解析
  8. Hevc Cabac<二>
  9. 阿里云腾讯云 云服务器 性价比对比
  10. 调试经验——任意字符对应的Unicode查询方法及Unicode对应字符的查询