Prefacio
Este artículo presenta principalmente las trampas de @scheduled y httpclient en primavera. Los compartiremos para su referencia y aprendizaje. No diré mucho a continuación, echemos un vistazo a la introducción detallada juntos.
Una vez pisé un gran pozo:
Debido a la particularidad del negocio, muchas tareas cronometradas se ejecutarán regularmente y compensarán los datos comerciales.
Durante el uso de la primavera, podemos usar la anotación @scheduled para implementar fácilmente tareas de tiempo.
Una mañana de repente me di cuenta de que desde un momento determinado la noche anterior, todas las tareas cronometradas se atascaron y dejaron de correr.
@ScheduledDefault solo hilo
Después de la investigación, se descubrió que si usamos la anotación @Scheduled para explicar la configuración predeterminada, todas las tareas serán ejecutadas por un solo hilo. Después de escribir una tarea de prueba para dormir, es fácil descubrir que todas las demás tareas no se activan cuando llega el momento.
Si necesita habilitar múltiples subprocesos, debe realizar la siguiente configuración y establecer el número de subprocesos:
@ConfigurationPublic Class ScheduleconFig implementa ProgramingConfigurer {@Override public void ConfigurETasks (ProchuledTaskRegistrrar TaskRegistrar) {TaskRegistrar.SetsCheduler (ejecutores.newscheduledThreadPool (5)); }}Esto resuelve el problema de que si una tarea está atascada, hará que todas las tareas se estancen.
Pero, ¿por qué hay tareas atascadas?
Configuración de parámetros predeterminada de httpClient
Resulta que algunas tareas solicitarán la interfaz RESTFUL de los servicios externos regularmente, y la configuración de HTTPClient es la siguiente:
PoolinghttpClientConnectionManager Connmanager = new PoolingHttpClientConnectionManager (); connmanager.setMaxToTal (maxconnection); httpclient = httpclients.custom () .setConnectionManager (connmanager) .Build ();
Cuando usé por primera vez httpclient, no pensé tanto en eso y básicamente usé la configuración predeterminada.
El seguimiento del código fuente puede encontrar que al configurar el uso del método anterior, el tiempo de tiempo de espera de HttpClient es en realidad -1, lo que significa que si hay un problema con el servicio de la otra parte, la solicitud de httpclient nunca será de tiempo y esperará. El código fuente es el siguiente:
Builder () {super (); this.staleconnectionCheckEnabled = false; this.RedirectSenabled = true; this.maxredirects = 50; this.relativeredirectsAllowed = true; this.authenticationEnabled = true; this.ConnectionRequestTimeOut = -1; this.connecttimeout = -1; this.socketTimeout = -1; this.ContentCompressionEnabled = true;}Por lo tanto, debemos especificar manualmente el tiempo de tiempo de espera en este momento, y el problema se resuelve. Por ejemplo:
PoolinghttpClientConnectionManager Connmanager = new PoolingHttpClientConnectionManager (); connmanager.setMaxToTal (maxconnection); RequestConfig DeFaulTequestConfig = requestConfig.custom () .setsocketTimeout (3000) .SetConnectTimeOut (3000) .SetConnectionRequestTimeOut (3000) .Build (); httpClient = httpclients.custom () .setDefaulTequestConfig (DeFaulTequestConfig) .SetConnectionManager (connmanager) .Build ();
Recordar otro problema
De hecho, otro problema de configuración encontrado durante el uso de httpclient, que es el parámetro predeterminadoMaxperRoute.
No presté atención a este parámetro cuando lo usé por primera vez, pero solo establecí el número máximo de conexiones en el grupo de conexión Maxtotal.
El parámetro predeterminadoMaxperRoute en realidad representa el número máximo de conexiones por ruta. Por ejemplo, su sistema necesita acceder a otros dos servicios: Google.com y Bing.com. Si su maxtotal está configurado en 100 y el defaultMaxperRoute se establece en 50, entonces el número máximo de solicitudes para cada servicio puede ser de 50.
Entonces, si no se establece el defaultMaxperRoute, rastrea el código fuente:
Public PoolingHttpClientConnectionManager (final httpclientConnectionOperator httpclientConnectionOperator, final httpconnectionFactory <httproute, managedHttpClientConnection> connfactory, Timetolive largo final, tiempo de tiempo final Tunit) {super (); this.configData = new configData (); // El método del constructor Cpool utilizado aquí, el segundo parámetro es predeterminadoMaxperRoute, que es el valor predeterminado es 2. This.pool = new Cpool (new InternalConnectionFactory (this.configData, ConnFactory), 2, 20, Timetolive, Tunit); this.pool.setValidatAftterinactivity (2000); this.connectionOperator = args.notnull (httpClientConnectionOperator, "httpClientConnectionOperator"); this.isshutdown = new AtomicBoolean (falso);}Se descubrió aquí que el valor predeterminado era solo 2. No es de extrañar que siempre hubiera un tiempo de espera en situaciones de alta concurrencia en ese momento, Maxtotal estaba claramente establecido muy alto.
Entonces, si su servicio accede a muchos servicios externos diferentes y tiene una gran concurrencia, debe configurar los dos parámetros Maxtotal y DefaultMaxperRoute.
Entonces, cuando use cualquier cosa nueva más adelante, verá bien qué configuraciones tiene. Si tiene alguna pregunta, debe verificarlo primero. No copie un código en línea y lo use directamente. Puede estar bien en ese momento, pero tal vez me engañen en el futuro.
Resumir
Lo anterior es todo el contenido de este artículo. Espero que el contenido de este artículo tenga cierto valor de referencia para el estudio o el trabajo de todos. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse. Gracias por su apoyo a Wulin.com.