转自:

http://blog.csdn.net/mindfloating/article/details/8622930

测试方法

采用 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
 
版本:
     mina            2.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 = new NioSocketAcceptor(Integer.parseInt(ioPool)); 
          executor:     
             acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Integer.parseInt(executorPool))); 
     netty 线程池设置
          io worker:     
               new NioWorkerPool(Executors.newCachedThreadPool(), Integer.parseInt(ioPool))
          executor:      
               new OrderedMemoryAwareThreadPoolExecutor(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 更优雅。

(转)netty、mina性能对比分析的更多相关文章

  1. 浅谈C++之冒泡排序、希尔排序、快速排序、插入排序、堆排序、基数排序性能对比分析之后续补充说明(有图有真相)

    如果你觉得我的有些话有点唐突,你不理解可以想看看前一篇<C++之冒泡排序.希尔排序.快速排序.插入排序.堆排序.基数排序性能对比分析>. 这几天闲着没事就写了一篇<C++之冒泡排序. ...

  2. ArrayList和LinkedList的几种循环遍历方式及性能对比分析

    最新最准确内容建议直接访问原文:ArrayList和LinkedList的几种循环遍历方式及性能对比分析 主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性 ...

  3. ArrayList和LinkedList遍历方式及性能对比分析

    ArrayList和LinkedList的几种循环遍历方式及性能对比分析 主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性能测试对比,根据ArrayLis ...

  4. list 、set 、map 粗浅性能对比分析

    list .set .map 粗浅性能对比分析   不知道有多少同学和我一样,工作五年了还没有仔细看过list.set的源码,一直停留在老师教导的:"LinkedList插入性能比Array ...

  5. Java 集合 ArrayList和LinkedList的几种循环遍历方式及性能对比分析 [ 转载 ]

    Java 集合 ArrayList和LinkedList的几种循环遍历方式及性能对比分析 @author Trinea 原文链接:http://www.trinea.cn/android/arrayl ...

  6. ArrayList和LinkedList的几种循环遍历方式及性能对比分析(转)

    主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性能测试对比,根据ArrayList和LinkedList的源码实现分析性能结果,总结结论. 通过本文你可以 ...

  7. HBase在单Column和多Column情况下批量Put的性能对比分析

    作者: 大圆那些事 | 文章可以转载,请以超链接形式标明文章原始出处和作者信息 网址: http://www.cnblogs.com/panfeng412/archive/2013/11/28/hba ...

  8. ArrayList和LinkedList的几种循环遍历方式及性能对比分析(转载)

    原文地址: http://www.trinea.cn/android/arraylist-linkedlist-loop-performance/ 原文地址: http://www.trinea.cn ...

  9. 【转】ArrayList和LinkedList的几种循环遍历方式及性能对比分析

    原文网址:http://www.trinea.cn/android/arraylist-linkedlist-loop-performance/ 主要介绍ArrayList和LinkedList这两种 ...

随机推荐

  1. SoapUI 使用变量

    登录问题不好解决, 只能临时用cookie来执行 1.变量定义 2.引用变量 3.调用Header

  2. Java设计模式应用——备忘录模式

    备忘录模式主要用于存档.游戏中我们打boss前总会存档,如果打boss失败,则读取存档,重新挑战boss. 可以看出来,备忘录模式一般包括如下数据结构 1. 存档文件:用于恢复备份场景的必要数据: 2 ...

  3. excel第一次打开报错 向程序发送命令时出错 多种解决办法含终极解决方法

    excel第一次打开报错 向程序发送命令时出错 多种解决办法含终极解决方法 office2007应该遇到“向程序发送命令时出现 问题”,设置为以管理员运行也不好用,重装office也不好用,下面介绍下 ...

  4. nginx 配置https没有ssl_module以及一些错误

    一:开始Nginx的SSL模块 1.1 Nginx如果未开启SSL模块,配置Https时提示错误 1 nginx: [emerg] the "ssl" parameter requ ...

  5. Maven(一)如何用Eclipse创建一个Maven项目

    1.什么是Maven Apache Maven 是一个项目管理和整合工具.基于工程对象模型(POM)的概念,通过一个中央信息管理模块,Maven 能够管理项目的构建.报告和文档. Maven工程结构和 ...

  6. Oracle查询session连接数和inactive以及 概要文件IDLE_TIME限制用户最大空闲连接时间

    -----############oracle会话和进程################----------------查询会话总数select count(*) from v$session;--查 ...

  7. Python学习笔记之面向对象编程(三)Python类的魔术方法

    python类中有一些方法前后都有两个下划线,这类函数统称为魔术方法.这些方法有特殊的用途,有的不需要我们自己定义,有的则通过一些简单的定义可以实现比较神奇的功能 我主要把它们分为三个部分,下文也是分 ...

  8. 09: xmltodict 模块将xml格式转成json格式

    1.1 : xmltodict 模块将xml格式转成json格式 <?xml version="1.0"?> <!--#版本号--> <data> ...

  9. go-restful 实现一个web server

    go web server 1. 在ubuntu上安装go. 在ubuntu14.04上目前,最高的版本是golang-1.6 $ sudo apt-get install  golang-1.6 $ ...

  10. 20145313张雪纯Exp8 Web基础

    回答问题 (1)什么是表单 表单在网页中主要负责数据采集功能.一个表单有三个基本组成部分: 表单标签:这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法. 表单域:包含了文本框. ...