使用Netty4Http

时间:2017-06-29 10:35:57

标签: apache-camel netty camel-http

我正在尝试使用Netty4Http组件发送大量HTTPS请求。 以下是测试此内容的示例代码:

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import org.apache.camel.CamelContext;
import org.apache.camel.CamelExecutionException;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.component.netty4.http.NettyHttpComponent;
import org.apache.camel.impl.DefaultCamelContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DataWriter {

    private static final Logger LOG = LoggerFactory.getLogger(DataWriter.class);
    private static DataWriter dataWriter;
    private final CamelContext context;
    private final Map<String, Object> headers = new HashMap<>();
 // private NettyHttpEndpoint nettyHttpEndpoint;
    private ProducerTemplate template;
    private String endpoint;

public static void createDataWriterInstance() {
    if (dataWriter == null) {
        dataWriter = new DataWriter();
    }
}

public static DataWriter getDataWriterInstance() {
    return dataWriter;
}

private DataWriter() {
    this.context = new DefaultCamelContext();
    try {
        final NettyHttpComponent nettyHttpComponent = this.context.getComponent("netty4-http",
                org.apache.camel.component.netty4.http.NettyHttpComponent.class);
        this.context.addComponent("fcpnettyhttpComponent", nettyHttpComponent);
        this.template = this.context.createProducerTemplate();
        this.headers.put("Content-Type", "application/json");
        this.headers.put("Connection", "keep-alive");
        this.headers.put("CamelHttpMethod", "POST");
        String trustCertificate = "&ssl=true&passphrase=" + "123456" + "&keyStoreFile="
                + "C:/Users/jpisaac/certs/publicKey.store"
                + "&trustStoreFile=C:/Users/jpisaac/certs/publicKey.store" ;

        this.endpoint = "netty4-http:"+ "https://xx.xx.xx.xx:8443/server"
                + "?useByteBuf=true&disableStreamCache=true&connectTimeout=30000&requestTimeout=30000&reuseChannel=true"
                + "&keepAlive=true&tcpNoDelay=true&sync=false&reuseAddress=true&sendBufferSize=1000"
                + trustCertificate;
        this.template.start();
        this.context.start();
    } catch (final Exception e) {
        LOG.error("Exception while starting Camel context ", e);
    }
}

public void sendData(final String message) {
    try {
        CompletableFuture<Object> future=this.template.asyncRequestBodyAndHeaders(this.endpoint, message, this.headers);
        System.err.println("Sent data "+message);
    } catch (final CamelExecutionException e) {
        LOG.error("Error while sending data", e);
    }
}

public void stop() {
    try {
        this.template.stop();
        this.context.stop();
    } catch (final Exception e) {
        LOG.error("Exception while stopping Camel context ", e);
    }
}

public static void main(String[] args) throws Exception {
    createDataWriterInstance();
    DataWriter test = getDataWriterInstance();
    int i = 0;
    while (i<50) {
        test.sendData("Hello " + i++);
    }
    while (true) {}
}
}

此代码有效,但我们发现在以异步模式发送数据时会打开多个端口。这可以通过查看Wireshark来验证。

当我们分析JVisualVM上的程序时,我们可以看到创建了几个NettyClientTCPWorker和ProducerTemplate线程。我看到我们可以通过workerCount设置来控制工作线程的数量。

我对在客户端计算机上打开以将数据发送到服务器的端口数量有所限制。我需要将其保持在可配置的值(通常为1 )。

如何确保客户端计算机上只打开一个端口并仍然使用异步模式?

我尝试将producerPoolMaxActive属性设置为1.现在只打开一个端口,但这也意味着只发送一个请求。看起来为每个发送的请求打开了一个端口。这是我需要避免的事情。

[更新]我在标题中添加了Connection:keep-alive,但这没有帮助。我认为核心问题是为每个请求打开一个新连接。我在日志中看到了这一点:

2017-07-03 11:25:32.367 [Camel (camel-1) thread #0 - ProducerTemplate] DEBUG o.a.c.component.netty4.NettyProducer.openConnection(NettyProducer.java:436) - Created new TCP client bootstrap connecting to 10.194.242.10:8443 with options: Bootstrap(BootstrapConfig(group: NioEventLoopGroup, channelFactory: NioSocketChannel.class, options: {SO_KEEPALIVE=true, TCP_NODELAY=true, SO_REUSEADDR=true, CONNECT_TIMEOUT_MILLIS=30000}, handler: org.apache.camel.component.netty4.http.HttpClientInitializerFactory@4d814f1e, resolver: io.netty.resolver.DefaultAddressResolverGroup@488dff6f))
2017-07-03 11:25:32.366 [Camel (camel-1) thread #4 - ProducerTemplate] DEBUG o.a.c.component.netty4.NettyProducer.openConnection(NettyProducer.java:436) - Created new TCP client bootstrap connecting to 10.194.242.10:8443 with options: Bootstrap(BootstrapConfig(group: NioEventLoopGroup, channelFactory: NioSocketChannel.class, options: {SO_KEEPALIVE=true, TCP_NODELAY=true, SO_REUSEADDR=true, CONNECT_TIMEOUT_MILLIS=30000}, handler: org.apache.camel.component.netty4.http.HttpClientInitializerFactory@4d814f1e, resolver: io.netty.resolver.DefaultAddressResolverGroup@488dff6f))
2017-07-03 11:25:32.366 [Camel (camel-1) thread #3 - ProducerTemplate] DEBUG o.a.c.component.netty4.NettyProducer.openConnection(NettyProducer.java:436) - Created new TCP client bootstrap connecting to 10.194.242.10:8443 with options: Bootstrap(BootstrapConfig(group: NioEventLoopGroup, channelFactory: NioSocketChannel.class, options: {SO_KEEPALIVE=true, TCP_NODELAY=true, SO_REUSEADDR=true, CONNECT_TIMEOUT_MILLIS=30000}, handler: org.apache.camel.component.netty4.http.HttpClientInitializerFactory@4d814f1e, resolver: io.netty.resolver.DefaultAddressResolverGroup@488dff6f))
2017-07-03 11:25:32.367 [Camel (camel-1) thread #1 - ProducerTemplate] DEBUG o.a.c.component.netty4.NettyProducer.openConnection(NettyProducer.java:436) - Created new TCP client bootstrap connecting to 10.194.242.10:8443 with options: Bootstrap(BootstrapConfig(group: NioEventLoopGroup, channelFactory: NioSocketChannel.class, options: {SO_KEEPALIVE=true, TCP_NODELAY=true, SO_REUSEADDR=true, CONNECT_TIMEOUT_MILLIS=30000}, handler: org.apache.camel.component.netty4.http.HttpClientInitializerFactory@4d814f1e, resolver: io.netty.resolver.DefaultAddressResolverGroup@488dff6f))
2017-07-03 11:25:32.366 [Camel (camel-1) thread #2 - ProducerTemplate] DEBUG o.a.c.component.netty4.NettyProducer.openConnection(NettyProducer.java:436) - Created new TCP client bootstrap connecting to 10.194.242.10:8443 with options: Bootstrap(BootstrapConfig(group: NioEventLoopGroup, channelFactory: NioSocketChannel.class, options: {SO_KEEPALIVE=true, TCP_NODELAY=true, SO_REUSEADDR=true, CONNECT_TIMEOUT_MILLIS=30000}, handler: org.apache.camel.component.netty4.http.HttpClientInitializerFactory@4d814f1e, resolver: io.netty.resolver.DefaultAddressResolverGroup@488dff6f))

1 个答案:

答案 0 :(得分:0)

添加HTTP标头Connection: keep-alive,否则服务器应在每次请求后关闭连接。