Рекомендации по архитектуре с использованием OMATPE для конкретных запросов - PullRequest
0 голосов
/ 30 декабря 2011

У меня типичная настройка сервера netty, только немного запутанная по поводу «правильного» способа реализации или, скорее, добавления OrderedMemoryAwareThreadPoolExecutor в конвейерную фабрику для конкретных типов запросов. Для большинства запросов подходит типичный запрос / ответ NIO. Однако для конкретного типа запроса я бы хотел использовать традиционный многопоточный ввод / вывод (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», который теоретически будет обрабатывать в неблокирующем потоке ввода-вывода и отправлять ответ в нисходящем направлении после завершения.

Ответы [ 2 ]

1 голос
/ 05 января 2012

Другое решение - добавить пользовательский 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;
    }

}
1 голос
/ 30 декабря 2011

Вы можете попробовать , а не , используя OMATPE и настраивая вручную и используя свой собственный ThreadPool.

// 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);
        }
    }
}

Надеюсь, это поможет.

...