Netty 针对特定请求使用OMATPE的体系结构设计建议

Netty 针对特定请求使用OMATPE的体系结构设计建议,netty,Netty,我有一个典型的netty服务器设置,只是对实现特定类型请求的“正确”方法有点困惑,或者更确切地说,将OrderedMemoryAwareThreadPoolExecutor添加到pipelinefactory中。对于大多数请求,典型的NIO请求/响应是可以接受的。但是,对于特定类型的请求,我希望使用传统的线程I/O(ala OMATPE),因为它可能是一个长时间运行的请求。我现在要做的是解析URI以获得特定类型的请求。短请求将正常处理,类型为“/long/running/request”的请求将

我有一个典型的netty服务器设置,只是对实现特定类型请求的“正确”方法有点困惑,或者更确切地说,将OrderedMemoryAwareThreadPoolExecutor添加到pipelinefactory中。对于大多数请求,典型的NIO请求/响应是可以接受的。但是,对于特定类型的请求,我希望使用传统的线程I/O(ala OMATPE),因为它可能是一个长时间运行的请求。我现在要做的是解析URI以获得特定类型的请求。短请求将正常处理,类型为“/long/running/request”的请求将继续向上游发送,该请求将通过OMATPE传递给相应的处理程序。这是路吗?管道的外观如下所示:

 public ChannelPipeline getPipeline() {
     return Channels.pipeline(
             new HttpMessageEncoder(),
             new HttpMessageDecoder(),
             new shortLivedRequestHandler(),
             executionHandler,
             new longLivedRequestHandler());
 }

在“shortLivedRequestHandler”中,将处理与“短期”正则表达式匹配的URI,然后将其发送到下游。如果这些URI与“长寿命”正则表达式匹配,那么我们将向上游传递到“longLivedRequestHandler”,理论上它将在非阻塞I/O线程中进行处理,并在完成后向下游发送响应。

您可以尝试使用OMATPE并手动配置和使用自己的线程池

// Stored as a private field in your pipeline and passed into the constructor of your handler
Executor executor = Executors.newFixedThreadPool(16); 

// In your handler
public class MyRequestHandler extends SimpleChannelUpstreamHandler {
    private Executor _executor = null;

    public MyRequestHandler (Executor executor) {
        _executor = executor;
    }

    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        if (requestThatUseThreadPool) {
            _executor.execute(new Runnable() {
                @Override
                public void run() {
                   // Do some work in another thread
                   HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK);
                   res.setContent(ChannelBuffers.copiedBuffer("hello".toString(), UTF_8_CHARSET));
                   ChannelFuture f = ctx.getChannel().write(res);
                }
            });
        } else {
            // Do some work in this thread
            HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK);
            res.setContent(ChannelBuffers.copiedBuffer("hello".toString(), UTF_8_CHARSET));
            ChannelFuture f = ctx.getChannel().write(res);
        }
    }
}

希望这有帮助。

另一个解决方案是添加自定义ExecutionHandler

大概是这样的:

public class AdvancedExecutionHandler extends ExecutionHandler{



    public AdvancedExecutionHandler(Executor executor) {
        super(executor);
    }

    @Override
    public void handleUpstream(ChannelHandlerContext context, ChannelEvent e) throws Exception {
        if (useExecutionHandler(e)) {
            super.handleUpstream(context, e);
        } else {
            // use no thread-pool
            context.sendUpstream(e);
        }
    }

    private boolean useExecutionHandler(ChannelEvent event) {

        // Add some logic here....
        return true;
    }

}

唯一的问题是,除非我积累了一些东西,否则我的每个请求处理程序都需要返回一些特定的东西。需要的不仅仅是200美元。基本上,这些请求/处理程序中的计算结果以某种形式返回。而我相信你的解决方案是假设对客户做出一般性的回应。不。您可以将结果写入频道。我已经修改了上面的例子来帮助你。这很有趣。。。那么,这样做是否本质上与我上面列出的相同,只是没有净“开销”?是的。我相信它也在做类似的事情,并且已经看到其他几个开源项目使用了类似的技术(例如webbit web服务器)。请注意,您的请求可能不会按照OMATPE保证的顺序处理。如果确实需要有序的请求处理,请尝试按照Norman在下一个答案中的建议自定义执行处理程序。