Tomcat, HTTP Keep-Alive et Httpsurlconnection de Java
j'ai deux serveurs Tomcat qui ont besoin de maintenir une connexion persistante pour réduire la prise de main SSL. Un serveur (le proxy) s'assoit dans une DMZ tandis que l'autre est en sécurité derrière un autre pare-feu. Le proxy exécute simplement un servlet simple qui fait un peu de contrôle de bon sens avant de transmettre les requêtes à la machine sécurisée. Sur demande initiale, les machines échangent des certificats avant d'effectuer le travail réel. Par conséquent, je voudrais maintenir une connexion persistante avec un délai d'attente de quelques minutes.
pour parler au serveur sécurisé, le servlet sur le proxy utilise HttpsUrlConnection
. J'ai installé WireShark et j'ai remarqué que peu importe la valeur keepAliveTimeout
que j'ai définie pour le connecteur sur la machine sécurisée, la connexion TCP se ferme après environ 5 ou 10 Secondes. Ce nombre semble correspondre à ce que j'ai Lu est le délai par défaut et comment Java gère HTTP Keep-Alive. Ce lien explique que Java honore le Keep-Alive
timeout s'il est envoyé par le serveur, sinon il utilise 5 secondes (connexions directes) ou 10 Secondes (connexions proxy) avant de fermer la connexion.
ce que j'essaie de comprendre c'est comment je peux forcer Tomcat à envoyer L'en-tête Keep-Alive. Pas Connection: Keep-Alive
, mais Keep-Alive: timeout=x
.
j'ai testé le serveur HTTP Apache et modifié le keepAliveTimeout
dans httpd.le conf fait que L'en-tête Keep-Alive change sa valeur de timeout. De plus, Java respecte ce délai.
UPDATE (12/23/11): après quelques expériences supplémentaires, j'ai essayé de préparer du code rapide et sale en utilisant HttpClient (3.1) D'Apache plutôt que HttpsUrlConnection
. Il semble que HttpClient, lorsqu'il utilise Keep-Alive, attend simplement que le serveur ferme la connexion. Je ne sais pas combien de temps il faudra attendre. Je tourne pour garder la connexion HTTP en vie pendant 3 à 5 minutes.
3 réponses
J'ai pu utiliser HttpClient 3.1 Pour maintenir la connexion HTTP ouverte pendant 5 minutes en réglant le keepAliveTimeout dans le connecteur Tomcat à 300000. J'ai vérifié en utilisant WireShark que le serveur terminera la connexion tandis que HttpClient attendra. Les requêtes ultérieures via HttpClient réutilisent la connexion TCP existante (en évitant toute nouvelle prise en main SSL). La clé est d'avoir une seule instance HttpClient (c'est-à-dire de ne pas en créer une à chaque fois). Cela pourrait être c'est évident pour la plupart, mais je n'étais pas sûr de ce que serait la mécanique de L'API pour HTTPClient. En bref, créez une instance HttpClient et pour chaque requête (POST, GET, etc. créer un nouveau PostMethod, GetMethod, etc. Cela entraînera la réutilisation de la connexion TCP.
Dans Tomcat, j'ai réussi à définir les en-têtes dans mon HttpServelet à l'aide de HttpServletResponse.addHeader () comme ceci:
response.addHeader("Connection", "Keep-Alive");
response.addHeader("Keep-Alive", "timeout=60000");
J'ai confirmé avec WireShark que cela fonctionne avec HttpUrlConnection côté client. Il ne fonctionne pas si vous ne définissez pas la "Connexion" en-tête, de sorte que vous devez définir.
Java API Http(s)UrlConnection
Honore de manière transparente les informations Keep-Alive
et gérer un pool de connexions par serveur hôte selon le suivant l'explication détaillée (lire attentivement - chaque détail est important).
dans ce cas, votre code doit lire complètement les tampons, fermer les flux et lire l'erreur dans le cas de IOException
.
bien sûr HttpClient a moins de contraintes mais la meilleure façon de gérer votre situation est d'utiliser son MultiThreadedHttpConnectionManager
grâce à la suivant les directives .