1. Conociendo a Sentinel
1. Problema y solución de avalanchas
Una falla de servicio en el enlace de llamada de microservicio ,
Provoca que todos los microservicios en todo el enlace fallen
Disponible , esto es una avalancha.
Hay cuatro soluciones comunes:
① Procesamiento de tiempo de espera : establezca el tiempo de espera y el tiempo de espera de solicitud
Si no hay respuesta después de un cierto período de tiempo, se devolverá un mensaje de error
no esperes para siempre
② Modo mamparo : limitado a los que puede utilizar cada negocio
La cantidad de subprocesos para evitar agotar los recursos de todo el Tomcat.
fuente, también llamado aislamiento de subprocesos
③Rebaja de fusibles : realizada por el negocio de estadísticas de disyuntores
La proporción anormal de, si excede el umbral, se volará
Esta empresa intercepta todas las solicitudes para acceder a esta empresa.
④Control de flujo : QPS que restringe el acceso empresarial,
Evite fallas en el servicio debido a un aumento repentino del tráfico
2. Comparación de tecnologías de protección de servicios.
3. Introducción e instalación de Sentinel
Sentinel es un microservicio de código abierto de Alibaba
componentes de control de flujo
https://sentinelguard.io/zh-cn/index.html Centinela
Tiene las siguientes características:
① Escenarios de aplicación enriquecidos
② Monitoreo completo en tiempo real
③ Amplia ecología de código abierto
④ Punto de extensión SPI perfecto
(2) Instale la consola Sentinel:
① Prepare sentinel-dashboard-1.8.1.jar
② Ejecute java -jar sentinel-dashboard-1.8.1.jar
③ Visite: localhost:8080 para ver la página de la consola,
La cuenta y contraseña predeterminadas son centinela.
(3) Modificar el puerto, la cuenta y la contraseña predeterminados de Sentinel
java -jar sentinel-dashboard-1.8.1.jar -Dserver.port=8080
4. Integración de microservicios Sentinel
Integre Sentinel en el servicio de pedidos y conéctese
Consola Sentinel, los pasos son los siguientes:
(1) Introducir dependencias centinela:
<!--sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
(2) Configurar la dirección de la consola
Modifique el archivo application.yaml y agregue el siguiente contenido:
server:
port: 8088
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
(3) Acceda a cualquier punto final del microservicio para activar el monitoreo centinela
Visita http://localhost:8088/order/101
2. Reglas limitantes actuales
1. Inicio rápido
Enlace de punto de cluster : es el enlace de llamada en el proyecto, el enlace
Cada interfaz que se monitorea es una
recurso
Por defecto, Sentinel monitoreará cada uno de SpringMVC.
Un punto final ( Endpoint ), por lo que SpringMVC
Cada punto final ( Endpoint ) es la cadena de llamadas.
un recurso. El control de flujo, la fusión, etc. están dirigidos a la cadena de puntos del grupo.
recursos en camino, para que podamos hacer clic
Corresponde al botón detrás del recurso para establecer las reglas.
Control de flujo de clics detrás de los recursos /order/{orderId}
botón , el formulario aparecerá y el formulario podrá ser
Agregar reglas de control de flujo
Significado en la imagen: limitar el recurso /order/{orderId}
El QPS independiente es 1, es decir, solo se permite 1 solicitud por segundo .
Las solicitudes excedentes serán interceptadas y se informará un error.
2. Modo de control de flujo
Al agregar una regla de limitación actual, haga clic en la opción avanzada, puede elegir
Elija entre tres modos de control de flujo:
① Directo : estadísticas de solicitudes de recursos actuales, umbral de activación
Cuando se establece el valor , el recurso actual está directamente limitado , que también es el valor predeterminado
modo
②Asociación : Estadísticas relacionadas con otro recurso relacionado con el recurso actual
Recurso, cuando se activa el umbral, el recurso actual es limitado
③Enlace : Estadísticas sobre el acceso a este recurso desde el enlace especificado
solicitud, cuando se activa el umbral, el enlace especificado es limitado
fluir
(2) Asociación
El modo de asociación se puede utilizar si se cumplen las siguientes condiciones:
① Dos recursos en competencia
② Uno con mayor prioridad y otro con menor prioridad
Cuando el acceso al recurso /write activa el umbral, el
Límite actual del recurso /read, evita afectar el recurso /write
(3) enlace
Por ejemplo, hay dos enlaces de solicitud:
/prueba1 → /común
/prueba2 → /común
Si solo desea que las estadísticas ingresen /common desde /test2
solicitud, puedes configurarlo así
① Sentinel solo marca las partes en el Controlador de forma predeterminada.
método como recurso, si desea marcar otros métodos, necesita
Usando la anotación @SentineResource
@SentineResource("goods")
public void queryGoods() {
System.err.println("查询商品");
}
② Sentinel creará el método Controlador de forma predeterminada
Integración de contexto, lo que resulta en una pérdida de control de flujo en el modo de enlace
efecto
Debe modificar application.yml y agregar configuración:
spring:
cloud:
sentinel:
web-context-unify:false # 关闭 context 整合
3. Efecto de control de flujo
El efecto de control de flujo significa que cuando la solicitud alcanza el umbral de control de flujo, el
las medidas tomadas
Incluye tres tipos:
① Fallo rápido : una vez alcanzado el umbral, se rechazarán nuevas solicitudes
Rechazar inmediatamente y lanzar FlowException
(por defecto)
② calentamiento : modo de precalentamiento , por favor
La solicitud también se rechaza y se lanza una excepción, pero este modo
El umbral cambiará dinámicamente , aumentando gradualmente
Agregado al umbral máximo
③Esperar en la fila : dejar que todas las solicitudes sigan el orden
Ejecución en cola , el intervalo entre dos solicitudes no puede ser menor que el especificado
Momento
4. Límite actual del parámetro del punto de acceso
El límite actual anterior es contar todas las solicitudes para acceder a un recurso ,
Determine si se excede el umbral de QPS y el límite actual del parámetro del punto de acceso
Es contar las solicitudes con el mismo valor de parámetro por separado y juzgar si el
Pasó el umbral QPS
(1) Ejemplo de configuración:
Parámetro 0 (el primer parámetro) del recurso activo
Para las estadísticas, el número de solicitudes con el mismo valor de parámetro por segundo no puede ser
más de 5
(2) En las opciones avanzadas, puede configurar algunos parámetros
Configuración de excepción:
Combinado con la configuración anterior, el significado aquí es para el número 0
El límite de corriente del parámetro de tipo largo, el mismo parámetro cada 1 segundo
QPS no puede exceder 5
Hay dos excepciones:
① Si el valor del parámetro es 100, el valor permitido
QPS es 10
② Si el valor del parámetro es 101, el valor permitido
QPS es 15
Nota: El límite actual del parámetro de punto de acceso es para el SpringMVC predeterminado
Recurso no válido
3. Aislamiento y degradación
Aunque la limitación actual puede intentar evitar problemas causados por la alta concurrencia
El servicio falla, pero el servicio también puede fallar por otros motivos.
fallas, pero para controlar estas fallas dentro de un cierto rango, para evitar
Evitar avalanchas depende del aislamiento del hilo (modo Bulkwall) y de la fusión.
Sin medios de degradación, ya sea aislamiento de subprocesos o fusión
La degradación es la protección del cliente (persona que llama)
1. FeignClient integra Sentinel
(1) Modifique el archivo application.yml de OrderService,
Habilitar la función Sentinel de Feign
feign:
sentinel:
enabled: true # 开启Feign的Sentinel功能
(2) Escribir lógica de degradación para FeignClient después de una falla
Método 1: FallbackClass , no se puede llamar de forma remota
manejo de excepciones
Método 2: FallbackFactory , puedes llamar al control remoto
Use la excepción para manejar, elegimos esto
Escriba y registre FallbackFactory para FeignClient
para frijol
@Slf4j
@Bean
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
@Override
public UserClient create(Throwable throwable) {
// 创建UserClient接口实现类,实现其中的方法,编写失败降级的处理逻辑
return new UserClient() {
@Override
public User findById(Long id) {
// 记录异常信息
log.error("查询用户失败", throwable);
// 根据业务需求返回默认的数据,这里是空用户
return new User();
}
};
}
}
(3) En la interfaz UserClient en el proyecto feed-api
Utilice UserClientFallbackFactory
@FeignClient(value = "userservice", fallbackFactory = UserClientFallbackFactory.class)
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
2. Aislamiento de subprocesos (modo de pared divisoria)
El aislamiento de subprocesos se puede lograr de dos maneras:
① Aislamiento del grupo de subprocesos
② Aislamiento de semáforo (Sentinel lo usa de forma predeterminada)
(1) Aislamiento de semáforo
Ventajas: peso ligero, sin gastos generales adicionales
Desventaja: no admite tiempo de espera activo
No admite llamadas asincrónicas
Escenario: llamada de alta frecuencia, distribución alta
(2) Aislamiento del grupo de subprocesos
Ventajas: admite tiempo de espera activo
Soporte para llamadas asincrónicas
Desventajas: la sobrecarga adicional de los subprocesos es relativamente grande
Escenario: despliegue bajo
Fan-out bajo : es decir, una cantidad pequeña o moderada de fan-out en una clase
usar otras clases
Distribución alta (más de aproximadamente 7): indica que una clase utiliza una gran cantidad de
otras clases, ya que puede volverse demasiado complejo
Al agregar una regla de limitación, puede elegir dos tipos de umbral:
QPS: el número de solicitudes por segundo
Número de subprocesos: es el subproceso de Tomcat que este recurso puede utilizar
El valor máximo del número, es decir, limitando el hilo.
Cantidad , implementando el modo mamparo
3. Degradación del fusible
La degradación de los fusibles es un medio importante para resolver el problema de las avalanchas, su
La idea es utilizar el disyuntor para contar la proporción anormal de llamadas de servicio,
Proporción de solicitudes lenta, si se excede el umbral, el servidor explotará
servicio.
Es decir, interceptar todas las solicitudes para acceder al servicio; y cuando el servicio
Cuando se restablezca, el disyuntor permitirá el acceso al servicio.
Hay tres tipos de estrategias de fusión de disyuntores:
① Llamada lenta
② Relación anormal
③ Número anormal
(1) llamada lenta
Solicitudes cuyo tiempo de respuesta del servicio (RT) es mayor que el tiempo especificado
Solicite estadísticas sobre la proporción de llamadas lentas dentro de una unidad de duración, que exceden
Fusible si se excede el umbral
Una llamada con un RT superior a 500 ms es una llamada lenta y las últimas estadísticas
Para solicitudes dentro de 10000 ms, si el número de solicitudes excede 10,
Y la proporción de llamadas lentas no es inferior a 0,5, entonces se activará el fusible .
El tiempo de apagado es de 5 segundos, luego ingrese al estado medio abierto, coloque
Ejecutar una solicitud de prueba
(2) Relación anormal
La proporción de llamadas anormales dentro de la duración de la unidad estadística, que exceden
El umbral luego se derrite
Cuente las solicitudes dentro de los últimos 1000 ms, si el volumen de solicitudes
Más de 10 veces y la proporción anormal no es inferior a 0,5, entonces
Active el fusible, la duración del fusible es de 5 segundos y luego ingrese
Estado medio abierto, liberar una solicitud de prueba
(3) Número anormal
Estadísticas del número de llamadas anormales dentro de la duración de la unidad, que exceden
El umbral se ha superado
4. Reglas de autorización
(1) Reglas de autorización
Las reglas de autorización pueden controlar el origen de la persona que llama,
Hay dos maneras:
Lista blanca: personas que llaman cuyo origen está en la lista blanca
permitir el acceso
Lista negra: personas que llaman cuyo origen está en la lista negra
sin acceso
Por ejemplo, restringimos el acceso solo a solicitudes de la puerta de enlace.
servicio de pedido, luego complete la puerta de enlace en la aplicación de control de flujo
El nombre
① Sentinel es a través de RequestOriginParser
El parseOrigin de esta interfaz para obtener lo solicitado
fuente de
public interface RequestOriginParser {
/**
* 从请求request对象中获取origin,获取方式自定义
*/
String parseOrigin(HttpServletRequest request);
}
En Sentinel, el método parseOrigin de esta interfaz
Siempre se devuelve el valor predeterminado , es decir, independientemente de la solicitud.
Ya sea que el código abierto provenga de la puerta de enlace o del navegador, Sentinel no
No puedo distinguir entre las dos solicitudes.
Necesita implementar esta interfaz , escribir su lógica de negocios, dejar
La solicitud de la puerta de enlace es diferente de la solicitud del navegador.
el resultado de
② Obtener una solicitud denominada origen de la solicitud
encabezado, como el valor de origen
@Component
public class HeaderOriginParser implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest httpServletRequest) {
// 尝试获取请求头
String origin = httpServletRequest.getHeader("origin");
// 非空判断
if (StringUtils.isEmpty(origin)){
origin = "blank";
}
return origin;
}
}
③ En el servicio de puerta de enlace, utilice el proceso global de la puerta de enlace
El filtro agrega un encabezado de origen llamado puerta de enlace.
spring:
cloud:
gateway:
default-filters:
- AddRequestHeader=origin,gateway # 添加名为origin的请求头,值为gateway
④ Configure reglas de autorización para /order/{orderId}:
(2) Resultados anormales personalizados
De forma predeterminada, se producen limitaciones actuales, degradación e interceptación de autorizaciones.
, se lanza una excepción a la persona que llama
Si desea personalizar el resultado devuelto cuando ocurre una excepción, debe implementar
Interfaz BlockExceptionHandler :
public interface BlockExceptionHandler {
// 处理请求被限流、降级、授权拦截时抛出的异常
void handle(HttpServletRequest var1, HttpServletResponse var2, BlockException var3) throws Exception;
}
BlockException contiene muchas subclases para tratar diferentes
escena:
anormal | ilustrar |
---|---|
Excepción de flujo | Excepción del límite actual |
Excepción de flujo de parámetro | Límite de corriente anormal del parámetro del punto de acceso |
DegradeException | excepción de degradación |
AutoridadExcepción | Excepción de regla de autorización |
Excepción de bloqueo del sistema | Excepción de regla del sistema |
Defina una clase en order-service e implemente la interfaz BlockExceptionHandler:
@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
String msg = "未知异常";
int status = 429;
if (e instanceof FlowException){
msg = "请求被限流了";
} else if (e instanceof ParamFlowException){
msg = "请求被热点参数限流了";
} else if (e instanceof DegradeException){
msg = "请求被降级了";
} else if (e instanceof AuthorityException) {
msg = "没有权限访问";
status = 401;
}
httpServletResponse.setContentType("application/json;charset=utf-8");
httpServletResponse.setStatus(status);
httpServletResponse.getWriter().write("{\"msg\": " + msg + ", \"status\":" + status + "}");
}
}
5. Persistencia de las reglas
1. Modo de gestión de reglas
La gestión de reglas de la consola de Sentinel tiene tres modos:
① Modo original: las reglas configuradas en la consola se envían directamente a
Cliente Sentinel, que es nuestra aplicación, y
Guardado en la memoria, se perderá cuando se reinicie el servicio.
② modo pull: la consola empuja las reglas configuradas para
Cliente Sentinel y el cliente guarda las reglas de configuración.
Almacenado en archivos o bases de datos locales , se eliminará periódicamente en el futuro.
Consultar y actualizar reglas locales en archivos o bases de datos locales.
③ modo push: la consola envía las reglas de configuración al control remoto
Centro de configuración , como Nacos o Zookeeper,
El cliente Sentinel monitorea Nocas para obtener cambios de configuración
mensaje push para completar la actualización de la configuración local (recomendado)
2. Implementar el modo push
El modo push es el más complejo de implementar porque depende de
nacos, y es necesario cambiar el código fuente de la consola Sentinel,
Los pasos generales son los siguientes:
(1) Modificar el servicio de servicio de pedidos para que escuche
Centro de configuración de Nacos
① Introducir dependencia
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
② Configurar la dirección de nacos
spring:
cloud:
sentinel:
datasource:
flow:
nacos:
server-addr: localhost:8848 # nacos地址
dataId: orderservice-flow-rules
groupId: SENTINEL_GROUP
rule-type: flow # 还可以是degrade、authority、param-flow
degrade:
nacos:
server-addr: localhost:8848 # nacos地址
dataId: orderservice-degrade-rules
groupId: SENTINEL_GROUP
rule-type: degrade # 还可以是degrade、authority、param-flow
(2) Modificar el código fuente y la configuración del panel de Sentinel
fuente de datos nacos
Modifique el archivo pom del código fuente, el centinela-
Eliminar el alcance del que depende datasource-nacos
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<!--<scope>test</scope>-->
</dependency>
(3) Modificar el código fuente de Sentinel-dashboard y modificar la interfaz
página
① Copie el código nacos en el directorio de prueba al directorio principal
com.alibaba.csp.sentinel.dashboard.rule包
② Modifique NacosConfig en el paquete nacos recién copiado
Clase, modifica la dirección de nacos en ella.
@Bean
public ConfigService nacosConfigService() throws Exception {
return ConfigFactory.createConfigService("localhost:8848");
}
④ Modifique com.alibaba.csp.sentinel.dashboard.
Clase FlowControllerV2 en el paquete controlador.v2
(4) Recompilar y empaquetar el código fuente del panel Sentinel
① Modificar src/main/webapp/resources/app/scripts/
El archivo sidebar.html en el directorio directivas/sidebar/ ,
Activa esta parte del comentario.
② Modificar el texto que contiene.
<li ui-sref-active="active" ng-if="entry.appType==0">
<a ui-sref="dashboard.flow({app: entry.app})">
<i class="glyphicon glyphicon-filter"></i> 流控规则-NACOS</a>
</li>