花了一个多月用Java NIO写了一个定制的HTTP Server,主要是支持我的WeBuzz.IM网页版聊天服务 。
先介绍一下WeBuzz.IM网页聊天服务。
WeBuzz.IM 是一款网页版即时聊天工具,用于帮助用户通过网页和朋友聊天。Gtalk(Google Talk) 、MSN(Windows Live Messenger) 、Yahoo! Messenger(Yahoo! Chat,又称为雅虎通) 、AIM(AOL Instant Messenger) 、ICQ 、Jabber(支持XMPP协议的聊天服务器) 的用户,可以通过WeBuzz.IM提供的网页界面登录对应的聊天网络,与已有的朋友进行聊天。通过WeBuzz.IM网页版聊天工具,你无需在你本地电脑安装Gtalk、MSN、Yahoo! Messenger、AIM或ICQ等客户端,只需要在浏览器中访问 http://webuzz.im/ ,即可查看好友更新,并与朋友轻松聊天。
- 对于某些没有权限在本地电脑安装各种聊天客户端的用户(譬如在网吧上网的用户)来说,WeBuzz.IM能够帮助他们不安装任何客户端软件即可和他们的朋友联系。
- 对于那些厌烦了电脑一旦启动就启动数个聊天客户端以致电脑速度慢吞吞的用户来说,WeBuzz.IM实现了一个浏览器窗口多个聊天客户端,大大提升电脑的性能和速度。
- 对于某些其禁止或封锁了聊天客户端端口的网络用户(譬如在办公室的工作人士、在学校的学生教师或者在银行机构的公务员)来说,WeBuzz.IM使用了普通网页的HTTP 80端口,不会被防火墙封锁,从而依然能够帮助用户登录聊天网络并和他们的朋友保持联系。
为什么已经有成熟的Tomcat Server不用而非得自己写HTTP Server呢?
1. 网页聊天服务需要处理大量的长连接的HTTP请求,也就是Comet连接请求,而现有的Tomcat Server在这方面不算成熟。
2. WeBuzz.IM后台使用了Java2Script 技术的Simple RPC 和Simple Pipe ,Simple RPC/Pipe原来是面对Servlet API的一个封装,但是Servlet API 2.X没有关于Comet连接处理的相关API,而Servlet 3.0 API刚刚成为JSR标准,尚未有成熟稳定的服务器实现。
2. 在写自己的HTTP Server之前,我已经使用Tomcat Server两三年,在大量Comet连接处理方面已经到达了Tomcat服务器的极限。
普通Tomcat Server和基于Java NIO定制的HTTP Comet应用Server有什么区别呢?
普通Tomcat Server基本都是指提供支持Servlet/JSP标准的容器,可以往其中部署对应的Servlet应用。基于Java NIO定制的HTTP Server,不受限于Servlet的API,可以根据NIO的特性和Comet连接的特性结合WeBuzz.IM网页聊天的需求,修改定制,从而能够充分提高单机Server的性能。
普通Tomcat Server和Java NIO HTTP Server的性能对比
Tomcat达到2000并发连接左右,性能大为折扣,load average甚至高到20。而此时Tomcat server的线程数大概3000左右。
同样专门定制的NIO Server,Comet连接达2000,load average远低于1,而此时线程数大概在100左右,系统响应非常快,应用流畅。而并发连接数继续往上涨,性能也不见有明显下降。
实现过程参考
1. 了解Java NIO相关原理和API
3. 基于Rox例子增加HTTP request decoder,解释HTTP数据包
4. 基于HTTP协议实现静态文件的应答以及动态应用的长连接回复
5. 完善
实现回顾
基本上Java NIO相关原理和API、Rox Tutorial花不了什么时间;而实现HTTP request decoder也不会难,写一些JUnit确保不遗漏特殊情况保证容错性;而实现HTTP应答,就需要对HTTP协议有进一步的理解了,譬如如何支持缓存,如何处理encoding,如何避免被盗链,如何回复出错,如何做应用层面的缓存等;而由于Java2Script Simple RPC/Pipe是我开发的,对应从Servlet API转成NIO的处理,相对轻车熟路,不花太多时间。
真正花时间的是修理NIO Server的bug上,由于NIO是采用单线程处理所有Socket读写,而socket处理有不少例外情况,一旦处理不对就会使得整个NIO处理线程错误百出,也可能出现CPU 100%的情况,这就需要对每一行NIO相关的代码进行复查并考虑可能的出错情况。所以一两周就把NIO Server写好了,而稳定该服务就花了两三周时间。
相关链接:
http://webuzz.im/zh-CN.html
http://java.sun.com/j2se/1.4.2/docs/guide/nio/
http://rox-xmlrpc.sourceforge.net/niotut/index.html
http://j2s.sourceforge.net/
http://inside.java2script.com/2007/06/02/tutorial-of-java2script-swt-and-simple-rpc-application.html
http://inside.java2script.com/2007/08/01/introducing-java2scripts-simple-pipe.html