Re: [xSocket-develop] Netty Vs XSockets
Status: Inactive
Brought to you by:
grro
|
From: <da...@id...> - 2011-02-10 13:36:40
|
Hi Kasper,
Terribly sorry about the HTML. Below is my post in plain text. The
issue is not about Netty. I am merely trying to ask if my test case on
the XSocket side is valid. There seems to be a huge discrepancy between
the performance of XSocket and Netty. Netty seems to perform much
better. And because they are both based on Java NIO I find that hard to
believe. That is why I am asking for some help from the XSocket
community to see if there is something I am not doing correctly in the
XSocket test case. I thought that this is what open source communities
were about, the sharing, collaboration and support of the community.
Best regards,
Dayne
Hi,
I was curious to test the differences between Netty and xLightweb and
found a strange issue with XlightWeb that I'm hoping someone here can
help me clear up.
I have setup the following testing environment:
3 Test machines with the following spec:
2.2GHz AMD X2 Athlon
512MB of RAM
8GB HDD
Sun Java JRE 6 update 22
Ubuntu 10.04 Server
fs.file-max = 100000
net.ipv4.tcp_tw_recycle = 1
security limits set nofile = 100000 for all users and root
One system is running the Netty 3.2.2 simple HTTP server
One system is running the xLightweb 2.13.2 simple HTTP server
One system is running httperf (This is the test client machine)
XSocket Sample code:
package com.example.server;
import org.xlightweb.HttpResponse;
import org.xlightweb.IHttpExchange;
import org.xlightweb.IHttpRequest;
import org.xlightweb.IHttpRequestHandler;
import org.xlightweb.IHttpResponse;
import org.xlightweb.server.HttpServer;
import java.io.IOException;
/**
* @author Dayne Lucas
*/
public class XLightWeb
{
public static void main(String[] args) throws Exception
{
final HttpServer server = new HttpServer(8007, new
MethodInfoHandler());
new Thread()
{
@Override
public void run()
{
while (!server.isOpen())
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
// Ignore.
}
}
System.out.println("xLightweb EchoServer is ready to serve
at port " + 8007 + ".");
}
}.start();
server.run();
}
private static final class MethodInfoHandler implements
IHttpRequestHandler
{
public void onRequest(IHttpExchange iHttpExchange) throws
IOException
{
IHttpRequest req = iHttpExchange.getRequest();
IHttpResponse response = new HttpResponse("text/plain",
"Method called=" + req.getMethod());
iHttpExchange.send(response);
}
}
}
Netty sample code:
package com.example.server;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.channel.StaticChannelPipeline;
import
org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.http.HttpVersion;
import org.jboss.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
/**
* @author Dayne Lucas
*/
public class NettyEcho
{
public static void main(String[] args)
{
// Configure the server.
final ServerBootstrap bootstrap = new ServerBootstrap(
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
// Set up the pipeline factory.
bootstrap.setPipelineFactory(new ChannelPipelineFactory()
{
public ChannelPipeline getPipeline() throws Exception
{
HttpRequestDecoder decoder = new HttpRequestDecoder();
HttpResponseEncoder encoder = new HttpResponseEncoder();
EchoServerHandler echoServerHandler = new
EchoServerHandler();
return new StaticChannelPipeline(decoder, encoder,
echoServerHandler);
}
});
// Bind and start to accept incoming connections.
bootstrap.bind(new InetSocketAddress(8007));
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()
{
public void run()
{
bootstrap.releaseExternalResources();
}
}));
}
private static final class EchoServerHandler extends
SimpleChannelUpstreamHandler
{
private static final Logger logger = LoggerFactory.getLogger(
EchoServerHandler.class.getName());
public void messageReceived(ChannelHandlerContext ctx,
MessageEvent e)
{
HttpRequest req = (HttpRequest) e.getMessage();
boolean keepAlive = isKeepAlive(req);
HttpResponse response = new
DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
String content = "Method called=" + req.getMethod().getName();
response.setContent(ChannelBuffers.copiedBuffer(content,
CharsetUtil.UTF_8));
ChannelFuture write = e.getChannel().write(response);
if(!keepAlive)
{
write.addListener(ChannelFutureListener.CLOSE);
}
}
public void exceptionCaught(ChannelHandlerContext ctx,
ExceptionEvent e)
{
// Close the connection when an exception is raised.
logger.warn("Unexpected exception from downstream.",
e.getCause());
e.getChannel().close();
}
}
}
When hitting the XLightWeb server with more than 30000 connections it
fails and CPU and Memory consumption is through the roof. However with
the Netty server it can handle far more 60000+ connections without
batting an eye (CPU and Memory are low).
Is the test case for XSocket incorrect? Am I not closing something I
should?
Any help would be appreciated.
Best regards,
Dayne
On Thu, 10 Feb 2011 13:01:50 +0100, Kasper Grubbe wrote:
You ask a Netty related problem on the xsocket mailinglist.
And your mail is filled with disgusting HTML-code which make your
posting
unreadable.
Fix your message and think about whether you want to post it here, or
in
the Netty community.
Thanks,
--
Kasper Grubbe
Computer Science AP
Phone: (+45) 42 42 42 74
Mail: kas...@gm... [1]
On Thu, Feb 10, 2011 at 11:57 AM, wrote:
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.
I have setup the following testing
environment:
3 Test machines with the following spec:
/>
2.2GHz AMD X2 Athlon
512MB of RAM
8GB HDD
Sun
Java JRE 6 update 22
Ubuntu 10.04 Server
fs.file-max =
100000
net.ipv4.tcp_tw_recycle = 1
security limits set
nofile = 100000 for all users and root
One system is
running the Netty 3.2.2 simple HTTP server
One system is running
the xLightweb 2.13.2 simple HTTP server
One system is running
httperf (This is the test client machine)
Sample code:
XSocket:
package com.example.server;
import
org.xlightweb.HttpResponse;
import org.xlightweb.IHttpExchange;
/>import org.xlightweb.IHttpRequest;
import
org.xlightweb.IHttpRequestHandler;
import
org.xlightweb.IHttpResponse;
import
org.xlightweb.server.HttpServer;
import
java.io.IOException;
/**
* @author Brendt
Lucas
*/
public class XLightWeb
{
/> public static void main(String[] args) throws
Exception
{
final
HttpServer server = new HttpServer(8007, new MethodInfoHandler());
/>
new Thread()
/> {
/> @Override
/> public void run()
/> {
/>
while (!server.isOpen())
/>
{
/>
try
/>
{
/>
Thread.sleep(1000);
/>
}
/>
catch (InterruptedException e)
/>
{
/>
// Ignore.
/>
}
/>
}
/>
System.out.println("xLightweb EchoServer is ready to serve at port " +
8007 + ".");
}
/> }.start();
/> server.run();
}
/>
private static final class MethodInfoHandler
implements IHttpRequestHandler
{
/> public void onRequest(IHttpExchange
iHttpExchange) throws IOException
{
IHttpRequest
req = iHttpExchange.getRequest();
/> IHttpResponse
response = new HttpResponse("text/plain", "Method called=" +
req.getMethod());
/>
iHttpExchange.send(response);
}
/> }
}
Netty:
package com.example.server;
import
org.jboss.netty.bootstrap.ServerBootstrap;
import
org.jboss.netty.buffer.ChannelBuffers;
import
org.jboss.netty.channel.ChannelFuture;
import
org.jboss.netty.channel.ChannelFutureListener;
import
org.jboss.netty.channel.ChannelHandlerContext;
import
org.jboss.netty.channel.ChannelPipeline;
import
org.jboss.netty.channel.ChannelPipelineFactory;
import
org.jboss.netty.channel.Channels;
import
org.jboss.netty.channel.ExceptionEvent;
import
org.jboss.netty.channel.MessageEvent;
import
org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import
org.jboss.netty.channel.StaticChannelPipeline;
import
org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
/>import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
/>import org.jboss.netty.handler.codec.http.HttpRequest;
import
org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import
org.jboss.netty.handler.codec.http.HttpResponse;
import
org.jboss.netty.handler.codec.http.HttpResponseEncoder;
import
org.jboss.netty.handler.codec.http.HttpResponseStatus;
import
org.jboss.netty.handler.codec.http.HttpVersion;
import
org.jboss.netty.util.CharsetUtil;
import org.slf4j.Logger;
/>import org.slf4j.LoggerFactory;
import
java.net.InetSocketAddress;
import
java.util.concurrent.Executors;
/**
* @author
Brendt Lucas
*/
public class NettyEcho
{
/> public static void main(String[] args)
{
// Configure the server.
/> final ServerBootstrap bootstrap = new
ServerBootstrap(
new NioServerSocketChannelFactory(
/>
Executors.newCachedThreadPool(),
/>
Executors.newCachedThreadPool()));
// Set up the pipeline factory.
bootstrap.setPipelineFactory(new ChannelPipelineFactory()
/> {
/> public
ChannelPipeline getPipeline() throws Exception
/> {
/>
HttpRequestDecoder decoder = new HttpRequestDecoder();
/>
HttpResponseEncoder encoder = new HttpResponseEncoder();
/>
EchoServerHandler echoServerHandler = new EchoServerHandler();
/>
return new StaticChannelPipeline(decoder, encoder,
echoServerHandler);
/> }
/> });
/> // Bind and start to accept incoming
connections.
bootstrap.bind(new
InetSocketAddress(8007));
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()
/> {
/> public void run()
/> {
/>
bootstrap.releaseExternalResources();
/> }
/> }));
}
/> private static final class EchoServerHandler extends
SimpleChannelUpstreamHandler
{
/> private static final Logger logger =
LoggerFactory.getLogger(
/>
EchoServerHandler.class.getName());
/> public void
messageReceived(ChannelHandlerContext ctx, MessageEvent e)
/> {
/> HttpRequest req =
(HttpRequest) e.getMessage();
/> boolean keepAlive =
isKeepAlive(req);
/> HttpResponse
response = new DefaultHttpResponse(HttpVersion.HTTP_1_1,
HttpResponseStatus.OK);
/> String content =
"Method called=" + req.getMethod().getName();
/>
response.setContent(ChannelBuffers.copiedBuffer(content,
CharsetUtil.UTF_8));
/> ChannelFuture write
= e.getChannel().write(response);
/> if(!keepAlive)
/> {
/>
write.addListener(ChannelFutureListener.CLOSE);
/> }
/> }
/> public void
exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
/> {
/> // Close the
connection when an exception is raised.
/>
logger.warn("Unexpected exception from downstream.", e.getCause());
/>
e.getChannel().close();
}
/> }
}
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?
Any help would
be appreciated.
Best regards,
------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio
XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb [3]
_______________________________________________
xSocket-develop mailing list
xSo...@li... [4]
https://lists.sourceforge.net/lists/listinfo/xsocket-develop [5]
Links:
------
[1] mailto:kas...@gm...
[2] mailto:da...@id...
[3] http://p.sf.net/sfu/intel-dev2devfeb
[4] mailto:xSo...@li...
[5] https://lists.sourceforge.net/lists/listinfo/xsocket-develop
|