ClosedChannelException with concurrent connections - what am I doing wrong?
Marc-André Laverdière
marcandre.laverdiere at gmail.com
Wed Aug 11 06:32:28 EDT 2010
Did you try explicitely setting your cached thread pool maximum size?
Marc-André LAVERDIÈRE
"Perseverance must finish its work so that you may be mature and
complete, not lacking anything." -James 1:4
mlaverd.theunixplace.com/blog
/"\
\ / ASCII Ribbon Campaign
X against HTML e-mail
/ \
2010/8/10 Nate Murray <nate at natemurray.com>:
>
> Hey Friends,
>
> I'm trying to build the most basic webserver using Netty. I'm not able to
> make more than 300 concurrent connections without it throwing exceptions and
> closing connections.
>
> My long term goal is to have an asynchronous server that will take an
> incoming request, perform a job that will take 3-5 seconds and then handle
> the next request. This is why I am using
> OrderedMemoryAwareThreadPoolExecutor.
>
>
> Here is the stack trace I'm getting:
>
> java.nio.channels.ClosedChannelException
> message received
> at
> org.jboss.netty.channel.socket.nio.NioWorker.cleanUpWriteBuffer(NioWorker.java:646)
> at
> org.jboss.netty.channel.socket.nio.NioWorker.writeFromUserCode(NioWorker.java:367)
> at
> org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:137)
> at
> org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:76)
> at org.jboss.netty.channel.Channels.write(Channels.java:632)
> at
> org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:70)
> at
> org.jboss.netty.handler.execution.ExecutionHandler.handleDownstream(ExecutionHandler.java:167)
> at org.jboss.netty.channel.Channels.write(Channels.java:611)
> at org.jboss.netty.channel.Channels.write(Channels.java:578)
> at
> org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:259)
> at clobie.HttpRequestHandler.writeResponse(Unknown Source)
> at clobie.HttpRequestHandler.messageReceived(Unknown Source)
> at
> org.jboss.netty.handler.execution.ChannelEventRunnable.run(ChannelEventRunnable.java:69)
> at
> org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor$ChildExecutor.run(Ordermessage
> received
> edMemoryAwareThreadPoolExecutor.java:316)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> at java.lang.Thread.run(Thread.java:637)
>
>
>
> and here is my server code:
>
>
> package sample;
>
> import java.net.InetSocketAddress;
> import java.util.List;
> import java.util.Map.Entry;
> import java.util.Map;
> import java.util.Set;
> import java.util.concurrent.Executors;
> import org.jboss.netty.bootstrap.ServerBootstrap;
> import org.jboss.netty.buffer.ChannelBuffer;
> 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.ExceptionEvent;
> import org.jboss.netty.channel.MessageEvent;
> import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
> import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
> import org.jboss.netty.handler.codec.http.Cookie;
> import org.jboss.netty.handler.codec.http.CookieDecoder;
> import org.jboss.netty.handler.codec.http.CookieEncoder;
> import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
> import org.jboss.netty.handler.codec.http.HttpChunk;
> import org.jboss.netty.handler.codec.http.HttpChunkTrailer;
> import org.jboss.netty.handler.codec.http.HttpContentCompressor;
> 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.QueryStringDecoder;
> import org.jboss.netty.handler.execution.ExecutionHandler;
> import
> org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor;
> import org.jboss.netty.util.CharsetUtil;
> import static org.jboss.netty.channel.Channels.*;
> import static org.jboss.netty.handler.codec.http.HttpHeaders.*;
> import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
> import static org.jboss.netty.handler.codec.http.HttpResponseStatus.*;
> import static org.jboss.netty.handler.codec.http.HttpVersion.*;
>
> public class TestHttpServer {
> public static void main(String[] args) {
> System.out.println("starting webserver");
> // Configure the server.
> ServerBootstrap bootstrap = new ServerBootstrap(
> new NioServerSocketChannelFactory(
> Executors.newCachedThreadPool(),
> Executors.newCachedThreadPool()));
>
> // Set up the event pipeline factory.
> bootstrap.setPipelineFactory(new HttpServerPipelineFactory());
>
> // Bind and start to accept incoming connections.
> bootstrap.bind(new InetSocketAddress(3335));
> }
> }
>
> class HttpServerPipelineFactory implements ChannelPipelineFactory {
> public ChannelPipeline getPipeline() throws Exception {
> ChannelPipeline pipeline = pipeline();
> pipeline.addLast("decoder", new HttpRequestDecoder());
> pipeline.addLast("encoder", new HttpResponseEncoder());
> pipeline.addLast("pipelineExecutor",
> new ExecutionHandler(new
> OrderedMemoryAwareThreadPoolExecutor(1000, 0, 0)));
> pipeline.addLast("handler", new HttpRequestHandler());
> return pipeline;
> }
> }
>
> class HttpRequestHandler extends SimpleChannelUpstreamHandler {
> @Override
> public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
> throws Exception {
> System.out.println("message received");
> StringBuilder buf = new StringBuilder();
> buf.setLength(0);
> buf.append("hello\r\n");
> buf.append("\r\n");
>
> writeResponse(e, buf);
> }
>
> private void writeResponse(MessageEvent e, StringBuilder buf) {
> HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
> ChannelBuffer content = ChannelBuffers.copiedBuffer(buf.toString(),
> CharsetUtil.UTF_8);
> response.setContent(content);
> response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
> response.setHeader(CONTENT_LENGTH, String.format("%d",
> content.readableBytes()));
>
> ChannelFuture future = e.getChannel().write(response);
> future.addListener(ChannelFutureListener.CLOSE);
> }
>
> @Override
> public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
> throws Exception {
> e.getCause().printStackTrace();
> System.out.println("Got an Exception: " +
> e.getCause().getMessage());
> e.getChannel().close();
> }
> }
>
>
> compile then run with:
>
>
> java -cp target/classes:$(cat .classpath) -Xmx2g sample.TestHttpServer
>
>
> then test:
>
>
> $ ab -n 500 -c 500 http://127.0.0.1:3335/
>
> Benchmarking 127.0.0.1 (be patient)
>
> Test aborted after 10 failures
>
> apr_socket_connect(): Connection refused (61)
>
>
> Given that I've read reports of Netty solving the c10k problem, it seems to
> me that 500 concurrent connections is fairly small.
>
> What am I doing wrong here? What can I change to handle more concurrent
> connections?
>
> Thanks for your help,
>
> Nate
> --
> View this message in context: http://netty-forums-and-mailing-lists.685743.n2.nabble.com/ClosedChannelException-with-concurrent-connections-what-am-I-doing-wrong-tp5394059p5394059.html
> Sent from the Netty User Group mailing list archive at Nabble.com.
> _______________________________________________
> netty-users mailing list
> netty-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/netty-users
>
More information about the netty-users
mailing list