Préface
Cet article présente principalement les pièges de @Scheduled et HttpClient au printemps. Nous les partagerons pour votre référence et votre apprentissage. Je ne dirai pas beaucoup ci-dessous, jetons un coup d'œil à l'introduction détaillée ensemble.
J'ai une fois marché sur une grande fosse:
En raison de la particularité de l'entreprise, de nombreuses tâches chronométrées seront exécutées régulièrement et compensées pour les données de l'entreprise.
Pendant l'utilisation du printemps, nous pouvons utiliser l'annotation @Scheduled pour implémenter facilement les tâches de synchronisation.
Un matin, j'ai soudainement réalisé que depuis un certain moment la veille, toutes les tâches chronométrées étaient coincées et ont cessé de courir.
@Scheduleddefault simple thread
Après enquête, il a été constaté que si nous utilisons une annotation @Scheduled pour expliquer la configuration par défaut, toutes les tâches seront exécutées par un seul thread. Après avoir écrit une tâche de test pour dormir, il est facile de constater que toutes les autres tâches ne sont pas déclenchées le moment venu.
Si vous devez activer le multi-lancement, vous devez effectuer la configuration suivante et définir le nombre de threads:
@ConfigurationPublic Class ScheduleConfig implémente SchedulingConfigurer {@Override public void configureTasks (ScheduledTaskRegistrar TaskRegistrar) {TaskRegistrar.SetScheduler (Executor.NewScheduledThreadPool (5)); }}Cela résout le problème que si une tâche est bloquée, cela entraînera toutes les tâches.
Mais pourquoi y a-t-il des tâches?
Configuration du paramètre par défaut httpclient
Il s'avère que certaines tâches demanderont régulièrement l'interface Restful des services externes et que la configuration de HttpClient est la suivante:
PACLINGHTTPCLIENTCONNECTIONMANGER CONCONNANGER = NOUVEAU PACHORDHTTPCLIENTCONNECTIONMANGER (); ConnManager.SetMextotal (MaxConnection); httpClient = httpclients.custom () .setConnectionManager (ConnManager) .Build ();
Lorsque j'ai utilisé HttpClient pour la première fois, je n'y ai pas pensé et j'ai utilisé la configuration par défaut.
Le suivi du code source peut constater que lors de la configuration de l'utilisation de la méthode ci-dessus, l'heure de délai de temps de HttpClient est en fait -1, ce qui signifie que s'il y a un problème avec le service de l'autre partie, la demande de httpclient ne sera jamais l'allée et attendra. Le code source est le suivant:
Builder () {super (); this.staleConnectionCheckEnabled = false; this.redirectSenabled = true; this.maxRedirect = 50; this.relativeRedirectsallowed = true; this.AuthenticationEnabled = true; this.connectionRequestTimeout = -1; this.connectTimeout = -1; this.sockettimeout = -1; this.ContentCompressionEnabled = true;}Nous devons donc spécifier manuellement le temps mort pour le moment et le problème est résolu. Par exemple:
PACLINGHTTPCLIENTCONNECTIONMANGER CONCONNANGER = NOUVEAU PACHORDHTTPCLIENTCONNECTIONMANGER (); ConnManager.SetMextotal (MaxConnection); RequestConfig defaulTeQuestConfig = requestConfig.Custom () .SetSoCHetTimeout (3000) .SetConnectTimeout (3000) .SetConnectionRequestTimeout (3000) .Build (); httpClient = httpclients.custom () .setDefaulTeQuestConfig (DefaulTReQuestConfig) .SetConnectionManager (ConnManager) .Build ();
Rappeler un autre problème
En fait, un autre problème de configuration rencontré lors de l'utilisation de HttpClient, qui est le paramètre defaultMaxPerRoute.
Je n'ai pas fait attention à ce paramètre lorsque je l'ai utilisé pour la première fois, mais je définis le nombre maximum de connexions dans le pool de connexions maxtotal.
Le paramètre defaultMaxPerRoute représente en fait le nombre maximum de connexions par itinéraire. Par exemple, votre système doit accéder à deux autres services: Google.com et Bing.com. Si votre maxtotal est défini sur 100 et que DefaultMaxPerRoute est défini sur 50, le nombre maximum de demandes pour chaque service peut être de 50.
Donc, si defaultMaxPerRoute n'est pas défini, suivez le code source:
Public PooringHttpClientConnectionManager (Final HttpClientConnectionOperator httpClientConnectionOperator, final httpConnectionFactory <httproute, managedhttpclientconnection> conforfactory, final long timetolive, final tunit) {super (); this.configData = new configData (); // La méthode du constructeur CPOOL utilisé ici, le deuxième paramètre est defaultMaxPerRoute, qui est la valeur par défaut est 2. This.pool = new Cpool (new InternalConnectionFactory (this.configData, connfactory), 2, 20, timetolive, tunit); this.pool.setvalidatefterinactivity (2000); this.connectionOperator = args.notnull (httpClientConnectionOperator, "httpClientConnectionOperator"); this.isshutdown = new atomicboolean (false);}Il a été constaté ici que la valeur par défaut n'était que de 2. Pas étonnant qu'il y ait toujours eu un délai d'attente dans des situations de concurrence élevées à ce moment-là, Maxtotal était clairement très élevé.
Donc, si votre service accède à de nombreux services externes différents et a une grande concurrence, vous devez configurer les deux paramètres maxtotal et defaultMaxPerRoute.
Ainsi, lorsque vous utilisez de nouvelles choses plus tard, vous aurez un bon aperçu des configurations dont vous avez. Si vous avez des questions, vous devez d'abord le vérifier. Ne copiez pas un morceau de code en ligne et utilisez-le directement. Ça pourrait être bien à ce moment-là, mais je serai peut-être trompé à l'avenir.
Résumer
Ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article a une certaine valeur de référence pour l'étude ou le travail de chacun. Si vous avez des questions, vous pouvez laisser un message pour communiquer. Merci pour votre soutien à wulin.com.