2017-06-29 4 views
0

J'essaye d'envoyer un grand nombre de requêtes HTTPS en utilisant le composant Netty4Http. Voici un exemple de code pour tester ceci:Assurez-vous qu'une seule connexion TCP utilisant 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) {} 
} 
} 

Ce code fonctionne, mais nous voyons que plusieurs ports sont ouverts pendant l'envoi des données en mode asynchrone. Cela peut être vérifié en vérifiant sur Wireshark.

De même, lorsque nous analysons le programme sur JVisualVM, nous pouvons voir que plusieurs threads NettyClientTCPWorker et ProducerTemplate sont créés. Je vois que nous pouvons contrôler le nombre de threads de travail par le paramètre workerCount.

J'ai une restriction sur le nombre de ports que j'ouvre sur mon ordinateur client pour envoyer des données au serveur. Je vais devoir le garder à une valeur configurable (habituellement 1).

Comment puis-je m'assurer qu'un seul port est ouvert sur l'ordinateur client et que j'utilise toujours le mode asynchrone?

J'ai essayé de définir la propriété producerPoolMaxActive sur 1. Maintenant, un seul port est ouvert, mais cela signifie également qu'une seule requête est envoyée. On dirait qu'un port est ouvert pour chaque requête envoyée. C'est quelque chose que je dois éviter.

[Mise à jour] J'ai ajouté Connection: keep-alive dans les en-têtes, mais cela n'a pas aidé. Je pense que le problème principal est qu'une nouvelle connexion est ouverte pour chaque demande. Je vois cela dans les journaux:

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.apache.camel.component.netty4.http.HttpClientInitializerFa[email protected], 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])) 

Répondre

0

Ajouter en-tête HTTP Connection: keep-alive, sinon le serveur doit fermer la connexion après chaque demande.