2017-06-29 124 views
0

我试图使用Netty4Http组件发送大量的HTTPS请求。 下面是一个示例代码来测试:确保只有一个TCP连接使用Netty4Http

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.现在只有一个端口被打开,但这也意味着只发送一个请求。看起来像为每个发送的请求打开一个端口。这是我需要避免的。

[更新]我已经添加了连接:保持在标题中,但没有帮助。我认为核心问题是每个请求都打开一个新的连接。我看到这在日志中:

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.[email protected]4d814f1e, resolver: [email protected])) 
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.[email protected]4d814f1e, resolver: [email protected])) 
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.[email protected]4d814f1e, resolver: [email protected])) 
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.[email protected]4d814f1e, resolver: [email protected])) 
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.[email protected]4d814f1e, resolver: [email protected])) 

回答

0

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