论坛首页 Java企业应用论坛

关于高性能网络应用的研究总结

浏览 14259 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (3) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-12-17  
女儿的出生中断了一段时间的开发。现在就高性能网络处理方式的问题做个总结

所谓高性能,我们这里指在大量并发连接时还有相当高的请求处理速度。提高单连接的请求处理速度这里不讨论。我们这里采用 p=处理速度/连接数 作为衡量性能的指标。

java中最传统的socket处理方法是同步socket,每个连接建立一个线程阻塞等待数据的到达,这种方式很适合于低连接数的应用,但是在大量连接时会由于频繁的线程间切换导致性能大幅降低。这种方式下只能优化线程创建时间,也就是使用线程池。

jdk1.4中引入了nio处理网络连接,实际上,sun对于nio的实现也仅仅是使用了select(见jdk源代码)。socket函数中的select实现了一个基于事件的解决方案,可以只用一个线程去等待多个socket事件的发生,在一定程度上解决了多线程切换带来的性能降低。它的缺点是一次只能处理一个事件,而且其监视的句柄也有限制。实际使用中它对性能的提升也非常有限。(winsock和bsd的select区别这里也暂不讨论)

纯java中能够使用的方法基本上只有上述两种,所以如果选择使用纯java,是很难应付高性能的应用的。所幸我们还有JNI.....

超越了java,我们不得不谈到本地平台的区别上来.....

windows平台下比较先进的模型是完成端口+重叠IO,完成端口可以看作增强版的select,它可以支持更大量的句柄,并且可以一次返回多个事件。重叠IO是另一个强大的工具,它允许用户异步的进行通讯操作,而且还能允许用户自己管理传输缓冲。使用这二者的组合,完全可以把所有端口的所有传输数据分成一个个等长的小块,让cpu进行基于定长数据块的处理。看起来像什么?是不是更像流水线?这种方式可以处理大量的连接而不会使性能降低很多。

linux平台下使用的是epoll,功能很像完成端口,也支持一次返回多个事件。只不过没有重叠io的支持,不知道这种模型赶不赶得上windows下的方案?

(补充一点:jdk1.5 update9 之后,linux下的nio已经支持了epoll)

无论是完成端口还是epoll,我们的程序中都不再需要大量的线程了,但是仅仅使用一个线程完成所有请求的处理这种方式也是不可取的,因为很多情况下,系统都可能会对某些资源进行等待,这样就会降低综合的连接处理速度。比较好的方法是按需使用线程,在不大可能出现等待的逻辑中使用单独线程完成,在可能出现等待的逻辑中建立少量线程用多条流水线的处理方式去完成任务。

使用完成端口或者epoll的解决方案,java在大连接处理上的能力将会大大提高,只不过这时候java就不会再成为项目中的主导,看起来会更像一个嵌入式的解释器...


   发表时间:2007-12-18  
完成端口不是什么新鲜事儿了,您能不能具体谈一下这个技术通过JNI怎么和Java的服务器结合呢?
0 请登录后投票
   发表时间:2007-12-18  
2种方式。

1.由本地代码作为主要部分,负责网络连接和文件io处理,动态链入jvm.dll当作java解释器使用。这种方式只用在本地代码中实现相应servlet各接口即可支持现有j2ee程序。

2.由java作为主导,将网络处理部分包装成dll,用jni调用。这也是现在jdk实现网络功能的方法。这种方法对现有应用服务器结构影响不大,适合优化现有应用服务器。

这两种方法在现有应用服务器中都有实例。
0 请登录后投票
   发表时间:2007-12-18  
用JNI会非常不可取的,会为系统增加不稳定的因素,用纯JAVA的方案会比较好。事实上,一些超大访问量的系统,也可以用纯JAVA来做的。
0 请登录后投票
   发表时间:2007-12-18  
一般对java底层不了解的人都会反对jni,不过大可不必敌视它。因为java中对于底层的操作全部是通过jni实现的,包括那些耳熟能详的ServerSocket,FileInputStream等等...

对于超大访问量的系统,用纯java来做应该是糟糕的设计...除非硬件成本能大大低于软件成本.

J2EE的优势在于快速开发,而不在于性能优化。
0 请登录后投票
   发表时间:2007-12-18  
timerri 写道
一般对java底层不了解的人都会反对jni,不过大可不必敌视它。因为java中对于底层的操作全部是通过jni实现的,包括那些耳熟能详的ServerSocket,FileInputStream等等...

对于超大访问量的系统,用纯java来做应该是糟糕的设计...除非硬件成本能大大低于软件成本.

J2EE的优势在于快速开发,而不在于性能优化。


超大访问量的系统不能用纯JAVA来做这种观点是非常错误的。怎样才算超大访问量?千万级别的算不算?我手头上就有N个N千万级别的系统,有些还是单机上千万级别的,纯JAVA打造。事实上,JDK1.4和JDK5.0与及现在的JDK6.0,性能上的提升是非常惊人的。现在在server端,没什么是纯JAVA做不了的。不止千万,亿级别的系统,同样可以用JAVA来做,而且性能不会比C/C++的要低。
0 请登录后投票
   发表时间:2007-12-18  
timerri 写道
一般对java底层不了解的人都会反对jni,不过大可不必敌视它。因为java中对于底层的操作全部是通过jni实现的,包括那些耳熟能详的ServerSocket,FileInputStream等等...

对于超大访问量的系统,用纯java来做应该是糟糕的设计...除非硬件成本能大大低于软件成本.

J2EE的优势在于快速开发,而不在于性能优化。


不赞成J2EE的优势是在于快速开发,想要追求速度的人肯定不会选用J2EE的。。J2EE是在于稳定。
0 请登录后投票
   发表时间:2007-12-19  
xgyxgy 写道
timerri 写道
一般对java底层不了解的人都会反对jni,不过大可不必敌视它。因为java中对于底层的操作全部是通过jni实现的,包括那些耳熟能详的ServerSocket,FileInputStream等等...

对于超大访问量的系统,用纯java来做应该是糟糕的设计...除非硬件成本能大大低于软件成本.

J2EE的优势在于快速开发,而不在于性能优化。


超大访问量的系统不能用纯JAVA来做这种观点是非常错误的。怎样才算超大访问量?千万级别的算不算?我手头上就有N个N千万级别的系统,有些还是单机上千万级别的,纯JAVA打造。事实上,JDK1.4和JDK5.0与及现在的JDK6.0,性能上的提升是非常惊人的。现在在server端,没什么是纯JAVA做不了的。不止千万,亿级别的系统,同样可以用JAVA来做,而且性能不会比C/C++的要低。


对于超大访问量的系统,用纯java来做应该是糟糕的设计...除非硬件成本能大大低于软件成本.

请仔细看我这句话,我并没有说大型系统不能用java实现。
只不过,在同样的硬件配置下,使用纯java开发的系统将比经过c或c++性能低。要弥补这样的差距,就只能提高硬件配置达到。而在超大型系统中,提高硬件配置的代价是惊人的,一般情况下远远大于通过软件优化的方式的成本。所以,局限于纯java来解决是十分不明智的。

不要盲目相信java的性能,jdk中的实现大部分只是最通用的,而不是最优化的。某些时候,我们必须用自己的本地代码去替换掉jdk中的本地代码的实现以取得更优化的性能。
0 请登录后投票
   发表时间:2007-12-19  
julyboxer 写道
timerri 写道
一般对java底层不了解的人都会反对jni,不过大可不必敌视它。因为java中对于底层的操作全部是通过jni实现的,包括那些耳熟能详的ServerSocket,FileInputStream等等...

对于超大访问量的系统,用纯java来做应该是糟糕的设计...除非硬件成本能大大低于软件成本.

J2EE的优势在于快速开发,而不在于性能优化。


不赞成J2EE的优势是在于快速开发,想要追求速度的人肯定不会选用J2EE的。。J2EE是在于稳定。


J2EE实际上只是接口,它的稳定还是需要依赖于具体实现。各个厂商的J2EE实现我绝对不敢完全等同看待。
J2EE最大的优势就是统一了一些常用功能需求的接口,他更像一个工业标准而不是一个特定工具。
0 请登录后投票
   发表时间:2007-12-19  
让java来撑住超高访问量。 优化程序,尽可能耗内存,降低磁盘读写,加机器是不二选择。 相比较,如果要低成本实现高性能,还不如用php+zend+apache+自己写module. 现在国外大部分网站都是用php作为首要开发语言。 比如facebook, yahoo.. 而且, php在5.0以后, 开始重视OO。往年的一次性脚本编写,将成为历史。 php的开发将参照标准的软件开发过程来执行。 另外, 楼上有位仁兄说, 一台机器撑住千万访问量?不知道,这个机器是什么型号? 小型机?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics