2010-07-14 9 views
0

Je commence tout juste à écrire un simple moteur de balayage Web pour obtenir des informations sur les liens que nous avons avec notre système. J'utilise httpclient 4.x. J'ai environ 100 threads allant chercher des liens et faire des requêtes de tête sur eux, cela fonctionne très bien pendant les premières heures puis il ralentit à un crawl hurlant. Je ne suis pas sûr si je configure le gestionnaire de connexion correctement ou non.confus au sujet des performances de httpclient

Voici le code que j'ai pour créer un objet httpclient. Quelqu'un voit-il quelque chose qui déclencherait une alarme avec ce bloc de code? Lorsque j'arrête le serveur et le redémarre, tout redevient comme neuf. Au cours de la phase où il est lent, la mémoire semble toujours correcte à 500K par processus, ce qui ne donne pas l'impression d'une fuite de mémoire.

HttpParams httpParams = new BasicHttpParams(); 
HttpConnectionParams.setConnectionTimeout(httpParams, 5000); 
HttpConnectionParams.setSoTimeout(httpParams, 5000); 
ConnManagerParams.setMaxTotalConnections(httpParams, 200); 
HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1); 

// set request params 

httpParams.setParameter("http.protocol.cookie-policy", CookiePolicy.BROWSER_COMPATIBILITY); 
httpParams.setParameter("http.useragent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"); 


SchemeRegistry schemeRegistry = new SchemeRegistry(); 
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
schemeRegistry.register(new Scheme("https", PlainSocketFactory.getSocketFactory(), 443)); 

final ClientConnectionManager cm = new ThreadSafeClientConnManager(httpParams,schemeRegistry); 

HttpClient httpClient = new DefaultHttpClient(cm, httpParams); 

httpClient.getParams().setParameter("http.conn-manager.timeout", 10000L); 
httpClient.getParams().setParameter("http.protocol.wait-for-continue", 10000L); 

J'utilise aussi ce code dans un thread pour nettoyer les connexions expirés comme mentionné dans la documentation

final Runnable cleanUp = new Runnable() { 
     public void run() { 

     cm.closeExpiredConnections(); 
     // Optionally, close connections 
     // that have been idle longer than 30 sec 
     cm.closeIdleConnections(30, TimeUnit.SECONDS); 

     } 
    }; 

MISE À JOUR: je courais VM visuel pour une heure et est ici la mémoire graphique sur le processus à distance, la mémoire est maintenant épuisée

http://img64.imageshack.us/f/screenshot20100714at204.png/

+0

Je sais que vous avez dit que la mémoire semble stable, mais avez-vous activé la journalisation GC? Passez-vous du temps en GC? – bwawok

+0

Je ne ai pas fait, assez nouveau à Java, donc je ne sais pas où je pourrais définir que – James

+0

vous êtes lié aux E/S réseau, 100 threads sont probablement saturant votre connexion réseau. Ensuite, vous êtes lié aux E/S disque après cela. –

Répondre

1

Utilisez VisualVM (il est également livré avec JD K) et surveillez votre application pendant un moment avec JMX. Installez également le plugin Visual GC, il offre un intérieur de ce qui se passe avec votre GC (ce qui peut ralentir beaucoup l'application s'il n'y a pas assez de mémoire). En cas de ralentissement, consultez l'onglet Threads pour voir à quoi il ressemble en ce qui concerne le verrouillage. Verrouiller ou pas assez de mémoire (fuites de mémoire) devrait être le problème dans votre cas.

Si vous voulez aller plus loin, je vous recommande YourKit Java Profiler.

0

Je voudrais également essayer de peaufiner le nombre de threads pour voir si cela fait une différence.