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