[xSocket-develop] Netty Vs XSockets
Status: Inactive
Brought to you by:
grro
|
From: <da...@id...> - 2011-02-10 11:18:34
|
<p>I was curious to test the differences between Netty and xLightweb
and found a strange issue with Netty that I'm hoping someone here can
help me clear up. <br /><br />I have setup the following testing
environment: <br /><br />3 Test machines with the following spec: <br
/><br />2.2GHz AMD X2 Athlon <br />512MB of RAM <br />8GB HDD <br />Sun
Java JRE 6 update 22 <br />Ubuntu 10.04 Server <br />fs.file-max =
100000 <br />net.ipv4.tcp_tw_recycle = 1 <br />security limits set
nofile = 100000 for all users and root <br /><br />One system is
running the Netty 3.2.2 simple HTTP server <br />One system is running
the xLightweb 2.13.2 simple HTTP server <br />One system is running
httperf (This is the test client machine) <br /><br />Sample code:</p>
<p> </p>
<p>XSocket:</p>
<p> </p>
<p>package com.example.server;<br /><br />import
org.xlightweb.HttpResponse;<br />import org.xlightweb.IHttpExchange;<br
/>import org.xlightweb.IHttpRequest;<br />import
org.xlightweb.IHttpRequestHandler;<br />import
org.xlightweb.IHttpResponse;<br />import
org.xlightweb.server.HttpServer;<br /><br />import
java.io.IOException;<br /><br />/**<br /> * @author Brendt
Lucas<br /> */<br />public class XLightWeb<br />{<br
/> public static void main(String[] args) throws
Exception<br /> {<br /> final
HttpServer server = new HttpServer(8007, new MethodInfoHandler());<br
/><br /> new Thread()<br
/> {<br
/> @Override<br
/> public void run()<br
/> {<br
/>
while (!server.isOpen())<br
/>
{<br
/>
try<br
/>
{<br
/>
Thread.sleep(1000);<br
/>
}<br
/>
catch (InterruptedException e)<br
/>
{<br
/>
// Ignore.<br
/>
}<br
/>
}<br /><br
/>
System.out.println("xLightweb EchoServer is ready to serve at port " +
8007 + ".");<br /> }<br
/> }.start();<br /><br
/> server.run();<br /> }<br
/><br /> private static final class MethodInfoHandler
implements IHttpRequestHandler<br /> {<br
/> public void onRequest(IHttpExchange
iHttpExchange) throws IOException<br />
{<br /> IHttpRequest
req = iHttpExchange.getRequest();<br /><br
/> IHttpResponse
response = new HttpResponse("text/plain", "Method called=" +
req.getMethod());<br /><br
/>
iHttpExchange.send(response);<br /> }<br
/> }<br />}<br /><br /></p>
<p> </p>
<p>Netty:</p>
<p> </p>
<p>package com.example.server;<br /><br />import
org.jboss.netty.bootstrap.ServerBootstrap;<br />import
org.jboss.netty.buffer.ChannelBuffers;<br />import
org.jboss.netty.channel.ChannelFuture;<br />import
org.jboss.netty.channel.ChannelFutureListener;<br />import
org.jboss.netty.channel.ChannelHandlerContext;<br />import
org.jboss.netty.channel.ChannelPipeline;<br />import
org.jboss.netty.channel.ChannelPipelineFactory;<br />import
org.jboss.netty.channel.Channels;<br />import
org.jboss.netty.channel.ExceptionEvent;<br />import
org.jboss.netty.channel.MessageEvent;<br />import
org.jboss.netty.channel.SimpleChannelUpstreamHandler;<br />import
org.jboss.netty.channel.StaticChannelPipeline;<br />import
org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;<br
/>import org.jboss.netty.handler.codec.http.DefaultHttpResponse;<br
/>import org.jboss.netty.handler.codec.http.HttpRequest;<br />import
org.jboss.netty.handler.codec.http.HttpRequestDecoder;<br />import
org.jboss.netty.handler.codec.http.HttpResponse;<br />import
org.jboss.netty.handler.codec.http.HttpResponseEncoder;<br />import
org.jboss.netty.handler.codec.http.HttpResponseStatus;<br />import
org.jboss.netty.handler.codec.http.HttpVersion;<br />import
org.jboss.netty.util.CharsetUtil;<br />import org.slf4j.Logger;<br
/>import org.slf4j.LoggerFactory;<br /><br />import
java.net.InetSocketAddress;<br />import
java.util.concurrent.Executors;<br /><br />/**<br /> * @author
Brendt Lucas<br /> */<br />public class NettyEcho<br />{<br
/> public static void main(String[] args)<br />
{<br /> // Configure the server.<br
/> final ServerBootstrap bootstrap = new
ServerBootstrap(<br />
new NioServerSocketChannelFactory(<br
/>
Executors.newCachedThreadPool(),<br
/>
Executors.newCachedThreadPool()));<br />
// Set up the pipeline factory.<br />
bootstrap.setPipelineFactory(new ChannelPipelineFactory()<br
/> {<br
/> public
ChannelPipeline getPipeline() throws Exception<br
/> {<br
/>
HttpRequestDecoder decoder = new HttpRequestDecoder();<br
/>
HttpResponseEncoder encoder = new HttpResponseEncoder();<br
/>
EchoServerHandler echoServerHandler = new EchoServerHandler();<br /><br
/>
return new StaticChannelPipeline(decoder, encoder,
echoServerHandler);<br
/> }<br /><br
/> });<br
/> // Bind and start to accept incoming
connections.<br /> bootstrap.bind(new
InetSocketAddress(8007));<br /><br />
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()<br
/> {<br
/> public void run()<br
/> {<br
/>
bootstrap.releaseExternalResources();<br
/> }<br
/> }));<br /> }<br /><br
/> private static final class EchoServerHandler extends
SimpleChannelUpstreamHandler<br /> {<br
/> private static final Logger logger =
LoggerFactory.getLogger(<br
/>
EchoServerHandler.class.getName());<br /><br
/> public void
messageReceived(ChannelHandlerContext ctx, MessageEvent e)<br
/> {<br
/> HttpRequest req =
(HttpRequest) e.getMessage();<br /><br
/> boolean keepAlive =
isKeepAlive(req);<br /><br
/> HttpResponse
response = new DefaultHttpResponse(HttpVersion.HTTP_1_1,
HttpResponseStatus.OK);<br
/> String content =
"Method called=" + req.getMethod().getName();<br
/>
response.setContent(ChannelBuffers.copiedBuffer(content,
CharsetUtil.UTF_8));<br /><br
/> ChannelFuture write
= e.getChannel().write(response);<br
/> if(!keepAlive)<br
/> {<br
/>
write.addListener(ChannelFutureListener.CLOSE);<br
/> }<br
/> }<br /><br
/> public void
exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)<br
/> {<br
/> // Close the
connection when an exception is raised.<br
/>
logger.warn("Unexpected exception from downstream.", e.getCause());<br
/>
e.getChannel().close();<br /> }<br /><br
/> }<br />}<br /><br /><br />When hitting the Netty server
with 40000 connections total @ 400 connections a second and 10
requests per connection it works with no issues and very little CPU or
memory overhead. However when we hit the XSocket server with the same
load, CPU sky rockets and memory is heavily used. Also the test has
several errors ( connection resets etc.) In fact we were able to hit
the Netty server with more than 40000 connections with ease. I was
wondering if there was something I was doing wrong in the XSocket code
that could be causing the poor performance?<br /><br />Any help would
be appreciated. <br /><br />Best regards,</p>
|