`
BradyZhu
  • 浏览: 248420 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

NIO系列6:流行 NIO Framework netty 和 mina 性能测评与分析

 
阅读更多
测试方法
采用 mina 和 netty 各实现一个 基于 nio 的EchoServer,测试在不同大小网络报文下的性能表现





测试环境
客户端-服务端:
model name: Intel(R) Core(TM) i5-2320 CPU @ 3.00GHz
cache size: 6144 KB
cpu cores:4
jdk:1.6.0_30-b12
network:1000Mb
memory: -Xms256m -Xmx256m
Linux:centos 5.7, kernel 2.6.18-274.el5

测试工具:
jmeter v2.4

版本:
mina2.0.7
netty 3.6.2.Final


配置:
mina
io-processor cpu 核数
executor cpu 核数
buffer 初始 buffer 大小,设置为 2048(2k)
netty
boss netty 默认配置 1
worker cpu 核数
executor cpu 核数
其实,从理论上来说, echo 型的应用不配置 executor 业务执行线程池会获得更好的性能和更低的消耗,但考虑在真实业务应用中,真实的业务场景处理通常涉及各种复杂逻辑计算,缓存、数据库、外部接口访问,为避免业务执行延时阻塞 io 线程执行导致吞吐降低,通常都会分离 io 处理线程 和 业务处理线程,因此我们的测试案例中也配置了业务执行线程池考查它们线程池的调度效能。

mina 线程池设置
io processor:
IoAcceptor acceptor =newNioSocketAcceptor(Integer.parseInt(ioPool));
executor:
acceptor.getFilterChain().addLast("threadPool",newExecutorFilter(Integer.parseInt(executorPool)));
netty 线程池设置
io worker:
newNioWorkerPool(Executors.newCachedThreadPool(), Integer.parseInt(ioPool))
executor:
newOrderedMemoryAwareThreadPoolExecutor(Integer.parseInt(executorPool), 0, 0)







测试结果


mina tps cpu network io art(average response time)
90%rt(90% response time)
1k 45024/sec
150%
50MB/sec
< 1ms
1ms
2k 35548/sec
170% 81MB/sec
< 1ms
1ms
5k 10155/sec
90%
55MB/sec
3 ms
1ms
10k 8740/sec
137% 98MB/sec 3ms 4ms
50k 1873/sec 128% 100MB/sec 16ms 19ms
100k 949/sec 128% 100MB/sec 33ms 43ms

netty tps cpu network io art(average response time)
90%rt(90% response time)
1k 44653/sec
155%
50MB/sec
< 1ms
1ms
2k 35580/sec
175% 81MB/sec
< 1ms
1ms
5k 17971/sec
195%
98MB/sec
3 ms
1ms
10k 8806/sec
195% 98MB/sec 3ms 4ms
50k 1909/sec 197% 100MB/sec 16ms 18ms
100k 964/sec 197% 100MB/sec 32ms 45ms





测试点评
mina 和 netty 在 1k、2k、10k、50k、100k 报文大小时 tps 接近
mina 在 5k 报文时有个明显的异常(红色标注),tps 较低,网络 io 吞吐较低,比较 netty 在 5k 报文的网络 io 吞吐 98MB/sec(基本接近前兆网卡极限)
5k 报文以上基本都能压满网络 io,瓶颈在 io,所以 tps 和 响应时间基本相差不大。

疑问,为什么 mina 会在 5k 报文时 io 吞吐出现明显降低?





测试分析

通过分析 mina 和 netty 的源码,发现处理 io 读事件时 buffer 分配策略上,两个框架有一些区别。
在网络 io 处理上,程序每次调用 socket api 从 tcp buffer 读取的字节数是随时变化的,它会受到报文大小,操作系统 tcp buffer 大小、tcp 协议算法实现、网络链路带宽各种因素影响。
因此 NIO 框架在处理每个读事件时,也需要每次动态分配一个 buffer 来临时存放读到的字节,buffer 分配的效能是影响网络 io 框架程序性能表现的关键因素。

下面分别分析下 mina 和 netty buffer 的动态分配实现
mina
buffer 分配方式:
默认实现采用了 HeapByteBuffer,每次都是直接调用ByteBuffer.allocate(capacity) 直接分配
buffer 分配大小预测:
根据每次读事件实际读到的字节数计算分配 buffer 的大小,若实际读到字节将 ByteBuffer 装满,说明来自网络的数据量可能较大而分配 buffer 容量不足,则扩大 buffer 一倍。
若连续 2 次读到的实际字节数小于 buffer 容量的一半,则缩小 buffer 为原来的一半

netty
buffer 分配方式
默认实现采用了 DirectByteBuffer,并且实现了 buffer cache,只要 buffer 大小不改变会重复利用已经分配的 buffer
buffer 分配大小预测:
初始化了一张 buffer size 静态分配表如下(截取部分),假如当前默认 buffer 为 2048
[1024, 1152, 1280, 1408, 1536, 1664, 1792, 1920, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4096]
| | | |
A D B C
根据每次读事件实际读到的字节数,进行预测下一次应该分配的 buffer 大小。
若实际读到的字节数大于等于当前 buffer(上图 B 位置) 则将当前 buffer 增大到上图示 C 位置,每次增大步进为 4
若连续 2 次实际读到的字节数小于等于 A 位置指示的 buffer 大小,则缩小 buffer 到 D 位置
从上面的对比分析可以看出,mina 采用了相对简单的 buffer 分配和预测方式,buffer 的增长和缩小比例相同。
而 netty 采用了一种相对复杂点的 buffer 分配方式,buffer increment faster decrement slower。
事实证明 netty 的分配方式更有效的避免的 buffer 分配中的抖动问题(忽大忽小),而 buffer 分配抖动正是影响 io 吞吐的罪魁祸首。
mina 测试中 5k 报文正好产生了 buffer 分配抖动导致 io 吞吐大受影响,通过修改 mina 源码采用固定 buffer 大小来测试则有效避免了 buffer 抖动,io 吞吐也恢复正常。
但实际情况下,固定 buffer 肯定不是有效的方式,不能很好的适应各种网络环境的复杂性,但采用动态 buffer 分配时算法需首要考虑避免抖动。

另外可以看出 netty 的 cpu 消耗明显高出 mina 不少,怀疑 netty 采用的 executor 实现(OrderedMemoryAwareThreadPoolExecutor)存在比较多的锁竞争和线程上下文切换。
下面是一组不使用 executor 时 netyy 的测试数据,其他指标都差不多但 cpu 明显下降不少
netty cpu
1k 75%
2k 125%
5k 126%
10k 126%
50k 118%
100k 116%






测试总结

mina: 需进一步优化其 buffer 分配,避免分配抖动导致的 io 吞吐波动
netty: 需进一步优化默认 executor 的实现,降低 cpu 消耗

其实 netty2 和 mina 都出自同一人Trustin Lee,后来他转投 apache 项目组将 netty 交给了社区继续维护,之后重新设计 mina 这个框架。
从使用者感受上来说 mina 的 api 接口设计明显比 netty 更优雅。
分享到:
评论

相关推荐

    Java视频教程 Java游戏服务器端开发 Netty NIO AIO Mina视频教程

    jaca视频教程 jaca游戏服务器端开发 Netty NIO AIO Mina视频教程 课程目录: 一、Netty快速入门教程 01、第一课NIO 02、第二课netty服务端 03、第三课netty客户端 04、第四课netty线程模型源码分析(一) 05、...

    NIO Netty框架

    NIO 框架 netty 与 mina

    Netty nio protocolbuf视频课程

    包含了Netty,NIO AIO,Mina知识的详解以及netty结合spring protocolbuf的源码

    Netty权威指南(第2版)

    长期从事高性能通信软件的架构设计和开发工作,有多年在NIO领域的设计、开发和运维经验,精通NIO编程和Netty、Mina等主流NIO框架。目前负责华为软件公司下一代SOA中间件和PaaS平台的架构设计工作。

    Netty权威指南 第2版 带书签目录

    长期从事高性能通信软件的架构设计和开发工作,有多年在NIO领域的设计、开发和运维经验,精通NIO编程和Netty、Mina等主流NIO框架。目前负责华为软件公司下一代SOA中间件和PaaS平台的架构设计工作。

    Netty 3.0.2.GA 的源码--- Mina的兄弟

    Netty、Mina、Cindy都是不错的NIO开源框架,后两者都是在Netty的基础上演化出来的。所以要学习好Java的异步通信框架,这三个都是不可多得的好材料。 本资源仅供学习和参考使用,若要进行开发,请下载相应的Jar包。

    nety nio 视频.txt

    Java NIO基础视频教程、MINA视频教程、Netty快速入门视频 [有源码] 网盘地址

    NIO学习-Java源代码分享(含netty)

    NIO学习-Java源代码分享(含netty)

    Java Netty技术研究

    快速开发高性能、可靠网络服务器和客户端程序 目的:快速开发高性能、可靠网络服务器和客户端程序 目的:快速开发高性能、可靠网络服务器和客户端程序 目的:快速开发高性能、可靠网络服务器和客户端程序 目的:快速...

    基于Netty4实现的UDP双向通信源码

    本源码是《NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战》一文的服务端源码实现(Netty4版),详见:http://www.52im.net/thread-378-1-1.html

    架构师-深入浅出Netty 书签版

    李林锋,2007 年毕业...软件的设计和开发工作,有7 年NIO 设计和开发经验,精通Netty、Mina 等 NIO 框架和平台中间件,现任华为软件平台开放实验室架构师,《Netty 权威 指南》、《分布式服务框架原理与实践》作者。

    Netty原理和使用

    Netty是一个高性能事件驱动的异步的非堵塞的IO(NIO)框架,用于建立TCP等底层的连接,基于Netty可以建立高性能的Http服务器。支持HTTP、WebSocket、Protobuf、BinaryTCP|和UDP,Netty已经被很多高性能项目作为其...

    Java NIO基础视频教程、MINA视频教程、Netty快速入门视频 [有源码]-附件资源

    Java NIO基础视频教程、MINA视频教程、Netty快速入门视频 [有源码]-附件资源

    基于Java NIO反应器模式设计与实现

    Java NIO反应器模式讲解,目前热门的Java网络通信框架中Mina,Netty等都采用NIO

    基于Netty的Android点对点聊天软件-源码

    基于Netty的Android点对点聊天软件-源码 Netty是基于NIO的JAVA异步通讯框架,比Mina在性能上更具有优势,其作者也正是Mina的原作者之一。

    Mina 文档doc

    • Multipurpose Infrastructure for Network Applications • 一个基于非阻塞I/O的网络框架。...如果你使用MINA,你将不需要直接使用NIO buffers,因为仅使用MINA buffers就可以完成大多数buffer操作

    nio_stream_parse_json:在NIO的环境里如何解析json

    场景: 在一些nio的网络框架, 比如netty, mina等, 读取数据时异步的, 也就是不能通过InputStream.read来以阻塞的方式读取数据. 而大多数json的库, 如FastJSON, jackson等都只能解析一个阻塞式的InputStream. 在nio...

    基于MINA2实现的UDP双向通信源码

    本源码是《NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战》一文的服务端实现(MINA2版),详见:http://www.52im.net/thread-378-1-1.html

Global site tag (gtag.js) - Google Analytics