netty客户端设计的并发性

时间:2012-10-28 10:44:19

标签: client-server netty

感谢很棒的图书馆网络,我使用的是最新的3.5.8版本。我的应用程序设计如下

  1. 我有一个Web应用程序,它接收来自最终用户(MyWebApp)的请求
  2. 此Web应用程序修改收到的数据并构造MyBean对象并连接到MyServer(构建在netty上)进行处理
  3. MyServer执行一些业务逻辑并返回修改后的MyBean对象
  4. MyWebApp收到此消息并通过JSP
  5. 移交给最终用户

    MyServer工作正常且能够处理请求。

    我发现客户端在有并发请求时会延迟请求。虽然很多请求都是以毫秒为单位处理的,但有些请求会被延迟。延迟请求有时需要1-4分钟。但我观察到这些请求很晚才被服务器接收,但立即处理。所以,我只能怀疑客户端的实现。我尝试实现'Channel'的连接池,但请求和响应不匹配。由于这两种实现都是由我完成的,因此我可以自由地更改双方的代码。所以,我已经修改了服务器messageReceived源代码,即使在处理完响应之后也不要关闭连接。现在是客户端在收到响应后打开发出请求的频道并关闭频道。

    理想情况下,我想使用一个通道或通道池或任何其他实现来处理并发请求。我觉得Netty对于服务器实现来说非常容易,但客户端实现并不适合我的设计。如果这可以成为netty库本身的一部分,那就太棒了

    任何想法都会受到赞赏。

    我的代码如下所示

        public class NioConnectorImpl implements ICoreConnector{
    
    private String host;
    private int port;
    private static ChannelFactory channelFactory;
    
    public NioConnectorImpl(String host, int port){
        this.host = host;
        this.port = port;
    }
    
    
    @Override
    public MyBean processRequest(MyBean bean) {
        return (MyBean) callMyServer(bean);
    }
    
    
    public Object callMyServer(Object requestObject) throws RuntimeException{
    
    
        if(channelFactory==null){
            System.out.println("createFactory with 3 Boss Threads and "+Runtime.getRuntime().availableProcessors() * 2+ " Child Threads");
            channelFactory  =  new NioClientSocketChannelFactory(
                    Executors.newCachedThreadPool(),
                    Executors.newCachedThreadPool(),3, Runtime.getRuntime().availableProcessors() * 2);
        }
    
    ClientBootstrap bootstrap = new ClientBootstrap(channelFactory);
    
        // Set up the event pipeline factory.
        bootstrap.setPipelineFactory(new MyChannelPipelineFactory(requestObject));
        //Connection timeOut for initial connection...
        bootstrap.setOption("connectTimeoutMillis", 10000);
        bootstrap.setOption("tcpNoDelay", true);
        bootstrap.setOption("keepAlive", true);
    
        ChannelFuture connectFuture = bootstrap.connect(new InetSocketAddress(host, port));
    
    // Wait until the connection is made successfully.
        Channel channel = connectFuture.awaitUninterruptibly().getChannel();
    
        // Get the handler instance to retrieve the answer.
        MyChannelHandler handler = (MyChannelHandler) channel.getPipeline().getLast();
    
        Object  object = handler.getObjectBean();
    
        channel.close().awaitUninterruptibly();
    
        //bootstrap.releaseExternalResources();
        //channelFactory.releaseExternalResources();
    
    return object;
    
    }
    
    @Override
    public void safeReleaseResources() {
        System.out.println("Releasing External Resources::::::::::::");
        if(channelFactory!=null)
        channelFactory.releaseExternalResources();
    
        try {
            Thread.sleep(5000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    
    }
    

    }

    MyChannelHandler代码

        public class MyChannelHandler extends SimpleChannelUpstreamHandler{
    
        private static final Logger logger = Logger.getLogger(MyChannelHandler.class.getName());
        private final Object object;
        final BlockingQueue<Object> answer = new LinkedBlockingQueue<Object>();
    
        public MyChannelHandler(Object object) {
            this.object= object;
        }
    
        public Object getObjectBean() {
            boolean interrupted = false;
            for (;;) {
                try {
                    Object object = answer.take();
                    if (interrupted) {
                        Thread.currentThread().interrupt();
                    }
                    return object;
                } catch (InterruptedException e) {
                    interrupted = true;
                }
            }
        }
    
    
        @Override
        public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
            sendObject(e);
        }
    
    
    
        @Override
        public void messageReceived(ChannelHandlerContext ctx, final MessageEvent e) {
            if (e.getMessage() != null) {
                // Offer the answer after closing the connection.
                e.getChannel().close().addListener(new ChannelFutureListener() {
                    public void operationComplete(ChannelFuture future) {
                        boolean offered = answer.offer((Object) e.getMessage());
                        assert offered;
                    }
                });
            }
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
            logger.log(Level.WARNING,"Naga: Unexpected exception from downstream.",e.getCause());
            e.getChannel().close();
        }
    
        private void sendObject(ChannelStateEvent e) {
            Channel channel = e.getChannel();
           if(channel.isWritable()) channel.write(object);
        }
    }
    

    MyServer代码

         public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
    
    
        Object object = MyServerController().handleRequest(e.getMessage(), e.getRemoteAddress().toString());
    
        final ChannelFuture future =  e.getChannel().write(object);
             future.addListener(new ChannelFutureListener() {
                    public void operationComplete(ChannelFuture f) {
                        Channel ch = future.getChannel();
                        //ch.close(); // expect client closes the connection
                    }
             });
    }
    

0 个答案:

没有答案