Правильный и эффективный способ делать массовые http сообщения с помощью netty - PullRequest
0 голосов
/ 13 мая 2018

Мне нужно выполнить массовые http-посты с помощью netty 4.1, где http-тело является статическим (= всегда одинаковым) для всех сообщений.

Я придумал это (упрощенное) решение, но я не уверен, что это самый эффективный и эффективный способ сделать это.Этот вопрос особенно сфокусирован на обработке ByteBuf и предотвращении OOM.

    final String requestBody = "... huge static post content ...";

    EventLoopGroup group = new NioEventLoopGroup();
    try {
        Bootstrap b = new Bootstrap();
        b.group(group).channel(NioSocketChannel.class).handler(new HttpClientInitializer());

        b.option(ChannelOption.TCP_NODELAY, true);

        int requestCount = Integer.MAX_VALUE;
        latch = new CountDownLatch(requestCount);
        ByteBuf requestBodyBuf = Unpooled.copiedBuffer(requestBody, StandardCharsets.UTF_8).asReadOnly();
        DefaultFullHttpRequest postRequest = postRequest(requestBodyBuf);

        Channel ch = b.connect("localhost", 8080).sync().channel();

        //write a lot (and as fast as possible) post messages which are are all equal
        //is .retainedDuplicate() correct and ressource efficient?
        for(int i=0; i<requestCount; i++) {
            ch.writeAndFlush(postRequest.retainedDuplicate());
        }

        latch.await();
        ch.close();
    } finally {
        group.shutdownGracefully();
    }

Полный код здесь: https://gist.github.com/salyh/3360af420a4ce2f9af5d9accc48c89b1

1 Ответ

0 голосов
/ 13 мая 2018

Вы должны изменить его на:

    for(int i=0; i<requestCount; i++) {
        ch.write(postRequest.retainedDuplicate());
    }
    // This will ensure you can do a gathering write (writev).
    ch.flush();

    // As you retain on each write you should release the last reference after done.
    postRequest.release();

Это позволит вам просто сделать один системный вызов (когда вызывается flush ()).

...