影响Java NIO框架性能的因数

开发 后端
最近打算用kilim做一个rpc框架, kilim有自己的nio框架而在业界有强劲的netty和mina。

最近打算用kilim做一个rpc框架, kilim有自己的nio框架 而在业界有强劲的netty和mina。

所以问了一下kilim的作者,他的回答说 因为底层用的都是java nio的api,所以留给nio框架最主要的问题是这2点:

(i) 为了处理很多socket连接和优化吞吐量,会导致了大量的线程切换。

Amount of thread switching done to handle n numbers of sockets and optimizing for throughput.

(ii) 有很多次的selector的中断和调用,唤醒seletor是很费资源的操作。

所以能做的优化有以下几点:

1、对read writer process操作分别作轻量级的scheduler,基于actor。

2、有个trick,就是read或者write操作时候,但没有读满或者写完的情况下,并不是立即返回并再次注册channel到selector,而是再尝试若干次(3次),再返回并注册到selector。在mina中也有同样的处理。不同之处在于kilim会yield的当前task,而mina为了避免线程切换,只是做了简单的while循环。但目的都是减少线程切换和避免多次注册 selector。

mina 处理代码

  1. for (int i = WRITE_SPIN_COUNT; i > 0; i --)  
  2. {  
  3. localWrittenBytes = ch.write(buf.buf());  
  4. if (localWrittenBytes != 0 || !buf.hasRemaining())  
  5. {  
  6. break;  
  7. }  

kilim nio的处理

  1. while (remaining > 0)  
  2. {  
  3. if (n == 0)  
  4. {  
  5. yieldCount++;  
  6. if (yieldCount < YIELD_COUNT)  
  7. {  
  8. Task.yield(); // don't go back to selector yet.  
  9. else  
  10. {  
  11. pauseUntilWritable();  
  12. yieldCount = 0;  
  13. }  
  14. }  
  15. n = ch.write(buf);  
  16. remaining -= n;  

除了上面说的2个因素以外,还有有哪些因素会影响nio的性能?

原文如下:

I have not tested netty, but here's my experience. All NIO frameworks, Kilim included, are comparable because they use the same underlying NIO API. The difference in performance _may_ stem from the following two sources:

(i) Amount of thread switching done to handle n numbers of sockets and optimizing for throughput.

(ii) Number of times the selector is interrupted and invoked. Waking up the selector is an expensive operation.

The first one is entirely up to the user of the Kilim NIO library. A typical server request consists of one or more reads to accumulate the frame, processing the packet, and one or more writes to write a packet to the socket. One can split up this work between multiple schedulers if you wish. By default, all reading and writing is done outside of the selector's thread. Which brings me to the next point.

I have optimized the access to the selector, by avoiding using it as much as possible. If a socket read or write is unable to transfer any bytes, then the task simply yields. Other runnable tasks get a chance to run. When the task is subsequently resumed, it retries the operation. This goes on for a fixed number of times (3), and if it still fails, it sends a message to the selector thread to wake it up whenever the socket is ready. See the comments on kilim.nio.EndPoint.

Please keep us posted about your netty experiments.

原文地址:http://wangscu.iteye.com/blog/664688

【编辑推荐】

  1. java.nio.Buffer的一些基础知识的备忘
  2. Java与Cobol对决:Cobol软件质量最过硬
  3. 甲骨文Java专利遭拒 起诉Android侵权受挫
  4. Java企业应用问题代码最多
  5. 微软警告称Java乃入侵目标之首
责任编辑:林师授 来源: wang_scu的博客
相关推荐

2011-12-15 09:55:47

javanio

2015-06-19 12:17:49

JAVA性能影响

2014-02-11 14:36:14

UPS

2011-03-11 09:51:47

Java NIO

2023-07-12 08:24:19

Java NIO通道

2015-06-26 09:27:14

Java调用性能

2011-12-23 11:33:25

JavaGrizzly

2011-12-15 13:28:57

2009-11-30 09:40:23

Java 7 NIO2HTTP Server

2022-11-17 08:00:18

JavaScript错误性能

2022-12-15 08:00:38

JavaScript错误性能

2019-05-17 09:05:54

MySQL查询性能数据库

2011-12-07 16:12:29

JavaNIO

2013-07-25 14:56:37

JavaEE 性能

2011-08-31 10:54:25

Java性能

2013-06-21 14:36:02

JavaEEx性能

2011-04-15 10:26:38

JavaMVC

2013-06-28 09:45:58

vSphere虚拟机

2012-05-07 08:18:42

程序日志性能

2021-06-28 17:21:49

MySQL性能Java
点赞
收藏

51CTO技术栈公众号