Cómo reducir el MTTR (tiempo medio de recuperación) de la aplicación en estado de ejercicio caótico | Equipo técnico de JD Cloud

En el campo de los negocios empresariales, Jinli es una solución integral para escenarios de contratación de empleados, como beneficios, marketing e incentivos, incluida una plataforma SAAS de incentivos flexible para empleados y miembros. Dado que está orientado directamente a todos los empleados de la empresa, la alta disponibilidad de sus servicios es particularmente importante.Este artículo presentará cómo reducir el MTTR de la aplicación a través de ejercicios de ingeniería del caos en vísperas de la promoción de Jinli Mall.

MTTR (tiempo medio de recuperación) es el tiempo medio necesario para recuperarse de un fallo del sistema o del producto . Esto incluye la duración total de la interrupción, desde el momento en que falla el sistema o el producto hasta que se restablece su funcionamiento completo.

¿Cómo reducir el MTTR de la aplicación en el escenario de caos drill, debe basarse en monitoreo y posicionamiento, y luego retroalimentación manual para el procesamiento? ¿Se puede automatizar y existe una solución para reducir el impacto durante el ejercicio del caos? De esta forma, se puede lograr una hemostasia rápida y se puede mejorar aún más la estabilidad del sistema.

Este artículo responderá a las preguntas anteriores en base a un poco de pensamiento y práctica.

Las fallas son omnipresentes e inevitables.

Comenzaremos con la investigación y las medidas del problema de reinicio de la máquina host y el simulacro de caos del servicio subyacente.

fondo

[Perspectiva del cliente]: hay una gran cantidad de interfaces (incluidos los conocimientos de embarque), informes de errores de tiempo extra, saltos en la tasa de disponibilidad, algunos clientes se ven afectados, lo que genera quejas de los clientes.

A través del posicionamiento, descubrimos los motivos del reinicio de la máquina anfitriona y el ejercicio caótico de los servicios subyacentes en la etapa inicial de preparación para la gran promoción, que afectó la disponibilidad y el rendimiento de nuestro sistema secundario durante mucho tiempo. Especialmente, la implementación y aplicación de la interfaz central afectará la disponibilidad de múltiples interfaces a gran escala y afectará aún más la experiencia de compra de los clientes finales.

Especialmente en el campo TOB, hay un efecto de boca en boca de los principales clientes.Si un cliente importante se encuentra con este problema, se magnificará e intensificará fácilmente.

imagen-20230531224953524.png

medidas temporales

Por un lado, coopere con el equipo de operación y mantenimiento para confirmar que la máquina host se reinicia sin notificación oportuna y, por otro lado, sincronice el impacto del taladro con el proveedor de servicios subyacente. Se recomienda que cumplan con el principio de taladro para minimice el radio de explosión, controle el alcance del impacto y asegúrese de que el taladro sea controlable.

Además de la coordinación anterior con la situación externa, también tenemos el pensamiento interno. En primer lugar, la falla de la situación en sí misma es incontrolable. Independientemente de la máquina host o del simulacro de caos, la escena real tiene una probabilidad de suceder (y ha sucedido). ). Entonces, ¿solo podemos monitorear y ubicar, y luego eliminar manualmente la máquina o notificar al proveedor de servicios para que se encargue de ello? ¿Se puede automatizar y hay opciones para reducir el impacto? De esta forma, se puede lograr una hemostasia rápida y se puede mejorar aún más la estabilidad del sistema.

Plan a largo plazo: práctica de capacidad de middleware JSF

Dado que las fallas no se pueden evitar, acepte las fallas y desarrolle la capacidad de obtener fallas de aplicaciones a través de algunos medios técnicos para garantizar una alta disponibilidad de las aplicaciones.

Dado que más del 90 % de las llamadas internas son llamadas RPC (JSF), aún nos enfocamos en la tolerancia a fallas del middleware JSF. A continuación, se presentan principalmente el tiempo de espera y el reintento, el equilibrio de carga adaptativo y la fusión de servicios del middleware JSF. Teoría y práctica de la conmutación por error .

La práctica es el único criterio para probar la verdad.

Acerca de los tiempos de espera y los reintentos

En el proceso de desarrollo real, creo que ha visto demasiadas fallas causadas por tiempos de espera no establecidos y configuraciones incorrectas. Cuando no se establece el tiempo de espera o la configuración no es razonable, la respuesta de la solicitud se ralentizará y la acumulación continua de solicitudes lentas provocará una reacción en cadena e incluso provocará una avalancha de aplicaciones.

No solo nuestros propios servicios, sino también los servicios dependientes externos, no solo los servicios HTTP, sino también los servicios de middleware, deben establecer una estrategia de reintento de tiempo de espera razonable y prestarle atención.

En primer lugar, la estrategia de reintento de tiempo de espera de los servicios de lectura y escritura también es muy diferente. Los servicios de lectura son naturalmente adecuados para el reintento (por ejemplo, reintentar dos veces después de establecer un tiempo de espera razonable), pero la mayoría de los servicios de escritura no se pueden reintentar, pero si son todo Diseño idempotente también es posible.

Además, antes de configurar el período de tiempo de espera de la persona que llama, es necesario comprender el tiempo de respuesta TP99 del servicio dependiente (si el rendimiento del servicio dependiente fluctúa mucho, también puede consultar TP95). se puede agregar 50% sobre esta base. Por supuesto, el tiempo de respuesta del servicio no es constante, y es posible que se requiera más tiempo de cómputo bajo ciertas condiciones de cola larga, por lo que para tener suficiente tiempo para esperar las respuestas de solicitud de cola larga, debemos establecer el tiempo de espera. bastante razonablemente.

Finalmente, el número de reintentos no debe ser demasiado (la alta concurrencia puede causar una serie de problemas (generalmente 2 veces, hasta 3 veces), aunque a mayor número de reintentos, mayor disponibilidad del servicio, pero la alta concurrencia conducirá al tráfico de solicitudes múltiples, similar a simular un ataque DDOS, en casos severos, incluso puede acelerar la cascada de fallas, por lo tanto, es mejor usar reintento de tiempo de espera en conjunto con fusibles, fallas rápidas y otros mecanismos para obtener mejores resultados, lo que mencionarse más adelante.

Además de introducir medios, es importante verificar la eficacia de los medios.

Escena de simulación (los otros dos métodos posteriores también usan esta escena)

Solución : use la inyección de fallas (50% de retraso en la red de la máquina 3000-5000ms) para simular escenarios similares y verificar.

El despliegue de la máquina es el siguiente :

imagen-20230601101805966.png

Monitoreo del valor clave de la interfaz de prueba de presión (QPS-300) y la interfaz de falla :

1. Interfaz de medición de presión: jdos_b2b2cplatform.B2b2cProductProviderImpl.queryProductBpMap

2. Consumo de servicios: jdos_b2b2cplatform.ActivityConfigServiceRPCImpl.queryActivityConfig

3. Prestación de servicios: jdos_b2b2cshop.com.jd.ka.b2b2c.shop.service.impl.sdk.ActivityConfigServiceImpl.queryActivityConfig

【Aviso】

Los escenarios de red no admiten las siguientes situaciones:

1. La sala de ordenadores donde se encuentra el contenedor de la aplicación: lf04, lf05, lf07, ht01, ht02, ht05, ht07, htmysql, lfmysql02, yn02, hk02, hk03

2. La versión del kernel de la máquina física: 2.6x, 3.8x, 3.10x

Caso normal (sin falla inyectada)

imagen.png

imagen.png

Fallo de inyección: cuando la configuración del tiempo de espera no es razonable (tiempo de espera de 2000 ms, reintento 2)

imagen.png

imagen.png

Fallo de inyección: cuando la configuración del tiempo de espera es razonable (tiempo de espera de 10 ms, reintento 2)

La interfaz TP99 está en 6 ms, establezca el tiempo de espera en 10 ms, vuelva a intentarlo 2. A saber: jsf:methodname="queryActivityConfig"timeout="10"retries="2"/

imagen.png

imagen.png

Resumen de reintentos de tiempo de espera

A través de reintentos de tiempo de espera razonables, la solicitud general es estable y la conmutación por error después de los reintentos mejora en gran medida la disponibilidad de la interfaz.

suplemento de reintento de tiempo de espera

En el caso de una división irrazonable de la dimensión de la interfaz, podemos usar la configuración de reintento de tiempo de espera de la dimensión del método de una manera más detallada. Sin embargo, hay una nota aquí. El método de anotación actual de JSF no admite el reintento de tiempo de espera. configuración de la dimensión del método, solo admite la dimensión de la interfaz. , si se ha utilizado la clase de anotación, se puede configurar y utilizar mediante la migración de XML.

Acerca del equilibrio de carga adaptativo

El propósito del diseño de equilibrio de carga adaptativo de respuesta corta es resolver el problema de las capacidades desiguales del nodo del proveedor, de modo que los proveedores con capacidades de procesamiento más débiles puedan aceptar menos tráfico, de modo que los proveedores individuales con un rendimiento más bajo no afecten la solicitud de los consumidores que consume mucho tiempo. en su totalidad y disponibilidad.

Los que son capaces trabajan más que los que son torpes, y los que son sabios se preocupan más que los que son tontos.

Sin embargo, hay algunos problemas con esta estrategia:

  1. La concentración excesiva de tráfico en instancias de alto rendimiento y el límite de tráfico de una sola máquina del proveedor de servicios pueden convertirse en un cuello de botella.
  2. La longitud de la respuesta a veces no representa el rendimiento de la máquina.
  3. En la mayoría de los escenarios, cuando no hay una diferencia obvia en la duración de la respuesta de los diferentes proveedores, la respuesta corta es lo mismo que aleatoria (aleatoria).

El mecanismo de implementación de respuesta corta existente es similar al algoritmo P2C (Power of Two Choice), pero el método de cálculo no utiliza el número de conexiones que se están procesando actualmente, sino que selecciona aleatoriamente dos proveedores de servicios para participar en el cálculo de comparación de respuesta más rápida de forma predeterminada. a saber: estadísticas Solicitud que consume mucho tiempo, visitas, excepciones y solicitudes simultáneas para cada proveedor, compare el tiempo de respuesta promedio * número actual de solicitudes y utilícelo para calcular la carga de respuesta más rápida. Elija ganadores para evitar el arreo. De esta forma, la capacidad de rendimiento de la máquina del lado del proveedor se mide de forma adaptativa y luego el tráfico se asigna a la máquina con una capacidad de rendimiento alta tanto como sea posible para mejorar el rendimiento general del servicio del sistema.

    <jsf:consumer id="activityConfigService"
                  interface="com.jd.ka.b2b2c.shop.sdk.service.ActivityConfigService"
                  alias="${jsf.activityConfigService.alias}" timeout = "3000" filter="jsfLogFilter,jsfSwitchFilter"
                  loadbalance="shortestresponse">
        <jsf:method name="queryActivityConfig" timeout="10" retries="2"/>
    </jsf:consumer>

Inyectar fallas (configurar equilibrio de carga adaptativo)

imagen.png

imagen.png

imagen.png

Resumen del Equilibrio de carga adaptativo

Al introducir el equilibrio de carga adaptativo, el modo "hombre capaz trabaja más" comienza desde la llamada inicial de la interfaz, y la máquina elegida transporta un mayor tráfico. Después de que se inyecta la falla, la ventana a corto plazo de disponibilidad de la interfaz desaparece y la disponibilidad rate jumps.point, lo que garantiza aún más la alta disponibilidad y rendimiento del servicio.

Acerca del disyuntor de servicio

Cuando el circuito sufre un cortocircuito o una sobrecarga grave, el fusible del fusible se fusionará automáticamente para proteger el circuito. Evita impactos importantes en los equipos, incluso incendios.

La fusión de servicios es un mecanismo de protección de enlaces para escenarios de servicios inestables.

La idea básica detrás de esto es muy simple, envolver una llamada de función protegida en un objeto de interruptor de circuito, que monitorea las fallas. Cuando un servicio del enlace de llamada no está disponible o el tiempo de respuesta es demasiado largo, lo que hace que la falla alcance el umbral establecido, el servicio se interrumpirá y no habrá más llamadas al servicio de nodo dentro de la ventana quemada, de modo que Evitar en la mayor medida posible la inestabilidad de los servicios de aguas abajo Impacto en los servicios de aguas arriba.

<!-- 服务熔断策略配置 -->
<jsf:reduceCircuitBreakerStrategy id="demoReduceCircuitBreakerStrategy"
    enable="true"   <!-- 熔断策略是否开启 -->
    rollingStatsTime="1000" <!-- 熔断器指标采样滚动窗口时长,单位 ms,默认 5000ms -->
    triggerOpenMinRequestCount="10" <!-- 单位时间内触发熔断的最小访问量,默认 20 -->
    triggerOpenErrorCount="0"   <!-- 单位时间内的请求异常数达到阀值,默认 0,小于等于0 代表不通过异常数判断是否开启熔断  -->
    triggerOpenErrorPercentage="50" <!-- 单位时间内的请求异常比例达到阀值,默认 50,即 默认 50% 错误率  -->
    <!-- triggerOpenSlowRT="0" 判定请求为慢调用的请求耗时,单位 ms,请求耗时超过 triggerOpenSlowRT 则认为是慢调用 (默认为 0,即默认不判定)-->
    <!-- triggerOpenSlowRequestPercentage="0"  采样滚动周期内触发熔断的慢调用率(默认为 0,即默认不触发慢调用熔断 -->
    openedDuration="10000"   <!-- 熔断开启状态持续时间,单位 ms,默认  5000ms -->
    halfOpenPassRequestPercentage="30"  <!-- 半闭合状态,单位时间内放行流量百分比,默认 40-->
    halfOpenedDuration="3000"   <!-- 半闭合状态持续时间设置,需要大于等于 rollingStatsTime ,默认为 rollingStatsTime  -->
    <!-- failBackType="FAIL_BACK_EXCEPTION" failBack策略, 取值:FAIL_BACK_EXCEPTION抛出异常、FAIL_BACK_NULL返回null、FAIL_BACK_CUSTOM配置自定义策略,配合 failBackRef 属性 -->
    <!-- failBackRef="ref" 如果 failBackStrategy 配置为 FAIL_BACK_CUSTOM 则必填,用户自定义的failback策略com.jd.jsf.gd.circuitbreaker.failback.FailBack<Invocation> 接口实现类 -->
/>

<jsf:consumerid="activityConfigService"interface="com.jd.ka.b2b2c.shop.sdk.service.ActivityConfigService"
                alias="${consumer.alias.com.jd.ka.b2b2c.shop.sdk.service.ActivityConfigService}" timeout="2000"check="false"
                serialization="hessian"loadbalance="shortestresponse"
                connCircuitBreakerStrategy="demoCircuitBreakerStrategy">
      <jsf:methodname="queryActivityConfig"timeout="10"retries="2"/>
</jsf:consumer>

Aquí viene un pequeño episodio. Debido al mecanismo de latido del propio JSF, después de detectar una falla, la máquina correspondiente se elimina automáticamente (se detecta una vez cada 30 segundos y se elimina si los tres tiempos son anormales). El mecanismo de fusible que configuramos nosotros mismos no es obvio, por lo que restablecemos la falla (Retardo de red 800-1500ms) para volver a perforar.

Fallo de inyección (disyuntor de servicio)

imagen.png

Resumen del disyuntor de servicio

Desde la perspectiva de la disponibilidad, es cierto que el acceso a los nodos anormales de la máquina se cerrará dentro de la ventana. Sin embargo, debido a que la estrategia de conmutación por recuperación no está implementada y la ventana de apertura para la fusión es breve, la disponibilidad aún devolverá directamente el mensaje de falla de llamada. después de que se abre la ventana, lo que afecta la disponibilidad. Por lo tanto, en comparación con la falla después de la fusión, la mejor manera es cooperar con la capacidad de degradación del servicio llamando a la lógica de degradación del servicio preestablecida y usar el resultado de la lógica de degradación como el resultado final de la llamada para devolverlo a la persona que llama al servicio. más elegantemente.

Suplemento del disyuntor de servicio

  1. El grupo ha construido un componente de fusible unificado y ha establecido las capacidades de plataforma correspondientes en el Monte Tai. Si el equipo necesita introducir la capacidad de disyuntor, se puede acceder directamente y utilizar para evitar la duplicación de la construcción . Para obtener más información, consulte: http://taishan.jd.com/flowControl/limitIndex
> 一种机制可能会击败另一种机制。

De hecho, con el fin de mejorar la flexibilidad y la solidez del sistema para hacer frente a varios fallos y situaciones impredecibles, en los sistemas distribuidos, por lo general se diseña para que pueda fallar parcialmente. Incluso si no puede satisfacer a todos los clientes, aún puede enviar Ciertos clientes prestan servicios. Pero la fusión está diseñada para convertir una falla parcial en una falla completa, evitando así una mayor propagación de la falla. Por lo tanto, existe una relación restrictiva mutua entre la interrupción del circuito de servicio y los principios de diseño de los sistemas distribuidos, por lo que se requiere un análisis y una reflexión cuidadosos, así como un ajuste posterior, antes de su uso.

en conclusión

La habilidad es solo un medio, la estabilidad es la meta.

Independientemente del método que se utilice para generar estabilidad, siempre debemos pensar en cómo encontrar un equilibrio entre las necesidades comerciales y la creación de estabilidad, a fin de construir una arquitectura de alta disponibilidad que respalde el crecimiento comercial a largo plazo.


Esta vez escribí esto, si tiene alguna pregunta, bienvenido a comunicarse. Espero que algo de la experiencia en el artículo le brinde algunas ganancias, o en otras palabras, es posible que desee pensar en qué soluciones técnicas y medios utilizará para resolver problemas similares. Bienvenido a dejar un mensaje e intercambio, y esperamos comunicarnos con más socios de ideas afines.

documentos de referencia

documento externo

El poder de dos elecciones aleatorias:  https://brooker.co.za/blog/2012/01/17/two-random.html

Equilibrio de carga : https://cn.dubbo.apache.org/zh-cn/overview/core-features/load-balance/#shortestresponse

Autor: JD Retail Li Mengdong

Fuente de contenido: comunidad de desarrolladores de JD Cloud

Supongo que te gusta

Origin blog.csdn.net/JDDTechTalk/article/details/131162088
Recomendado
Clasificación