【SpringCloudAlibaba】 Uso centinela

Descripción general

página web oficial

https://github.com/alibaba/Sentinel
chino:
https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
https://sentinelguard.io/zh-cn /docs/introducción.html

problema resuelto

  1. Avalancha de servicio
  2. degradación del servicio
  3. Disyuntor de servicio
  4. Límite actual del servicio

Principales características

Insertar descripción de la imagen aquí

Configuración

Descargue la consola de visualización

https://github.com/alibaba/Sentinel/releases
Insertar descripción de la imagen aquí

POM

<!--SpringCloud ailibaba sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到-->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

YML

server:
  port: 8401

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        #Nacos服务注册中心地址
        server-addr: localhost:8848
    sentinel:
      transport:
        #配置Sentinel dashboard地址
        dashboard: localhost:8080
        #默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
        port: 8719

management:
  endpoints:
    web:
      exposure:
        include: '*'

Carga diferida adoptada por Sentinel

Reglas de control de flujo

Insertar descripción de la imagen aquí

directo (predeterminado)

  1. Nombre del recurso: nombre de ruta de descanso predeterminado
  2. Fuente: predeterminado

Insertar descripción de la imagen aquí

asociado

Cuando el recurso B asociado con A alcanza el umbral, el propio A quedará restringido (B hace que A se bloquee).
B causa problemas y A se bloquea
. 1. Calentamiento

  • Fórmula: el umbral se divide por coldFactor (el valor predeterminado es 3). El umbral se alcanzará después del tiempo de calentamiento.
  • El coldFactor predeterminado es 3, es decir, el QPS solicitado comienza desde el umbral / 3 y aumenta gradualmente hasta el umbral de QPS establecido después del tiempo de calentamiento.
  • Al principio no funcionó, pero poco a poco fue mejorando.

Escenario de aplicación:
por ejemplo: cuando se enciende el sistema de venta flash, aparecerá mucho tráfico, lo que es muy probable que acabe con el sistema. El método de precalentamiento consiste en proteger el sistema dejando entrar el tráfico lentamente y aumentando lentamente el umbral Crece hasta el umbral establecido.
2. Hacer cola a velocidad constante

Para colas uniformes, el umbral debe establecerse en QPS

https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6
Insertar descripción de la imagen aquí
Significado de la configuración: /testA 1 solicitud por segundo, más de Si es así, espere en la fila y el tiempo de espera es de 20000 milisegundos.

enlace

Reglas de degradación

https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7

  • La degradación del disyuntor Sentinel limitará la llamada de este recurso cuando un recurso en el enlace de llamada esté en un estado inestable (como tiempo de espera de llamada o aumento anormal de la proporción), de modo que la solicitud
    falle rápidamente y evite afectar otros recursos y causar degradación. error.

  • Cuando se degrada un recurso, las llamadas al recurso se desconectarán automáticamente dentro del siguiente período de degradación (el comportamiento predeterminado es generar una DegradeException).

Insertar descripción de la imagen aquí

En el estado medio abierto, el sistema detecta automáticamente si hay una anomalía en la solicitud. Si
no hay ninguna anomalía, cerrará el disyuntor y reanudará el uso.
Si hay una anomalía, continuará abriendo el disyuntor. y hacerlo no disponible. Para obtener más información, consulte Hystrix.

Los disyuntores Sentinel no están medio abiertos .

Estrategia de degradación en acción

RT

Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí

proporción anormal

Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
De acuerdo con la configuración anterior,
si accede solo, se informará un error una vez (int age = 10/0) ​​y se producirá un error una vez que lo ajuste;

Después de abrir jmeter, podemos enviar solicitudes directamente con alta concurrencia y varias llamadas pueden cumplir con nuestras condiciones de configuración.
El disyuntor se enciende (el fusible se dispara), el microservicio ya no está disponible y el error ya no se informa pero el servicio se degrada.

numero anormal

La ventana de tiempo debe ser mayor o igual a 60 segundos.

Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí

Límite actual de la clave de hotspot

Sitio web oficial:
https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6% B5 %81¿Qué
es un hotspot
? Los hotspots son datos a los que se accede con frecuencia. Muchas veces queremos contar o limitar los datos TopN con la mayor frecuencia de acceso en determinados datos del hotspot y realizar limitaciones actuales u otras operaciones en su acceso.

Método de ida y vuelta:
dividido en predeterminado del sistema y definido por el cliente, dos tipos,
desde HystrixCommand hasta @SentinelResource

El modo de limitación actual solo admite el modo QPS, que está fijo hasta la muerte. (esto se llama punto caliente)

  • El índice del parámetro del método de la anotación @SentinelResource, 0 representa el primer parámetro, 1 representa el segundo parámetro, y así sucesivamente.
  • El umbral independiente y la duración de la ventana estadística indican que el flujo será limitado si el tiempo de la ventana excede el umbral.
  • La captura de pantalla anterior muestra que si el primer parámetro tiene un valor, el QPS por segundo es 1. Si excede el límite actual, se llama al método de soporte dealHandler_testHotKey después del límite actual.

Ejemplo:

class TestController{
    
    
	// 此处value的值是资源名可以为abc都行与之后dashboard中配置的资源名对应就可以
	@GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
    public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                             @RequestParam(value = "p2",required = false) String p2)
    {
    
    
        //int age = 10/0;
        return "------testHotKey";
    }
    public String deal_testHotKey (String p1, String p2, BlockException exception)
    {
    
    
        return "------deal_testHotKey,o(╥﹏╥)o";  //sentinel系统默认的提示:Blocked by Sentinel (flow limiting)
    }
}

Insertar descripción de la imagen aquí

Opciones avanzadas: excepciones de parámetros

Requisitos previos
Nota: Puntos a tener en cuenta para los parámetros activos; los parámetros deben ser tipos básicos o Cadena

Cuando p1 es igual a 5, el umbral pasa a ser 200
Insertar descripción de la imagen aquí

otro

@SentinelResource
maneja las violaciones de la configuración de la consola Sentinel y tiene el procesamiento ascendente de la configuración del método blockHandler;

RuntimeException
int age = 10/0, esta es la excepción de tiempo de ejecución que RunTimeException genera cuando se ejecuta Java, a @SentinelResource no le importa

Resumen
@SentinelResource error de configuración del supervisor, error de operación, se debe realizar una operación anormal

// 有fallback解决后面会细看
 @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey" fallBack="")

Reglas del sistema

Sitio web oficial:
https://github.com/alibaba/Sentinel/wiki/%E7%B3%BB%E7%BB%9F%E8%87%AA%E9%80%82%E5%BA%94%E9% 99 %90%E6%B5%81
solo es efectivo para el tráfico de entrada

  • Carga adaptable (solo efectiva para máquinas tipo Linux/Unix): la carga1 del sistema se utiliza como indicador de inspiración para la protección adaptable del sistema. La protección del sistema (fase BBR) se activará cuando la carga del sistema1 exceda el valor heurístico establecido y el número actual de subprocesos simultáneos en el sistema exceda la capacidad estimada del sistema. La capacidad del sistema se estima mediante maxQps * minRt del sistema. El valor de referencia de configuración es generalmente núcleos de CPU * 2,5.
  • Uso de CPU (versión 1.5.0+): cuando el uso de CPU del sistema excede el umbral, se activa la protección del sistema (rango de valores 0.0-1.0), que es relativamente sensible.
  • RT promedio: cuando el RT promedio de todo el tráfico de entrada en una sola máquina alcanza el umbral, se activa la protección del sistema y la unidad es de milisegundos.
  • Número de subprocesos simultáneos: cuando el número de subprocesos simultáneos para todo el tráfico de entrada en una sola máquina alcanza el umbral, se activa la protección del sistema.
  • QPS de ingreso: cuando el QPS de todo el tráfico de ingreso en una sola máquina alcanza el umbral, se activa la protección del sistema.
    Insertar descripción de la imagen aquí

@SentinelResource

Limitación actual por nombre de recurso + procesamiento posterior

Insertar descripción de la imagen aquí

Limitación actual basada en la dirección URL + procesamiento posterior

Insertar descripción de la imagen aquí

el problema al que nos enfrentamos

  1. El valor predeterminado del sistema no refleja nuestros propios requisitos comerciales.
  2. Según las condiciones existentes, nuestro método de procesamiento personalizado se combina con el código comercial, que no es intuitivo.
  3. Agregar una cobertura a cada método comercial aumentará la sobrecarga del código.
  4. No se refleja un enfoque globalmente unificado.

Lógica de procesamiento de limitación de corriente definida por el cliente

@GetMapping("/rateLimit/customerBlockHandler")
@SentinelResource(value = "customerBlockHandler",
        blockHandlerClass = CustomerBlockHandler.class,//异常处理类
        blockHandler = "handlerException2")//异常处理方法
public CommonResult customerBlockHandler()
{
    
    
    return new CommonResult(200,"按客戶自定义",new Payment(2020L,"serial003"));
}
public class CustomerBlockHandler
{
    
    
    public static CommonResult handlerException(BlockException exception)
    {
    
    
        return new CommonResult(4444,"按客戶自定义,global handlerException----1");
    }
    public static CommonResult handlerException2(BlockException exception)
    {
    
    
        return new CommonResult(4444,"按客戶自定义,global handlerException----2");
    }
}

Insertar descripción de la imagen aquí

Función de interrupción del circuito de servicio

Sentinel integra cinta + openFeign + respaldo

La administración alternativa se ejecuta de manera anormal (administrar Java)
blockHandler administra las violaciones de configuración de la consola (administra la configuración en el panel)

@SentinelResource(value = "fallback",
fallback = "handlerFallback",
blockHandler = "blockHandler")

Si se configuran tanto blockHandler como el respaldo, solo se ingresará la lógica de procesamiento de blockHandler cuando se genere una BlockException debido a una degradación de limitación actual.
excepciones para ignorar

//exceptionsToIgnore 忽略该种异常,sentinel不进行流量拦截
@SentinelResource(value = "fallback",
fallback = "handlerFallback",blockHandler = "blockHandler", 
exceptionsToIgnore = {
    
    IllegalArgumentException.class})

AbiertoFingimiento

POM

<!--SpringCloud openfeign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

Activar el soporte de Sentinel para Feign

# 激活Sentinel对Feign的支持
feign:
  sentinel:
    enabled: true  

Interfaz empresarial con anotación @FeignClient

/**
 * 使用 fallback 方式是无法获取异常信息的,
 * 如果想要获取异常信息,可以使用 fallbackFactory参数
 */
@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class)//调用中关闭9003服务提供者

Servicio de respaldo de pago

@Component
public class PaymentFallbackService implements PaymentService
{
    
    
    @Override
    public CommonResult<Payment> paymentSQL(Long id)
    {
    
    
        return new CommonResult<>(444,"服务降级返回,没有该流水信息",new Payment(id, "errorSerial......"));
    }
}

Controlador

//==================OpenFeign
@Resource
private PaymentService paymentService;

@GetMapping(value = "/consumer/openfeign/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id)
{
    
    
    if(id == 4)
    {
    
    
        throw new RuntimeException("没有该id");
    }
    return paymentService.paymentSQL(id);
}

arranque principal

@EnableFeignClients

Comparación de varios marcos de fusibles.

Insertar descripción de la imagen aquí

Persistencia de reglas

Configuración

POM

<!--SpringCloud ailibaba sentinel-datasource-nacos -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

YML

spring:
  application:
    name: cloudalibaba-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos服务注册中心地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
        port: 8719
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: cloudalibaba-sentinel-service
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

Agregar configuración de reglas comerciales de Nacos

Insertar descripción de la imagen aquí

[
    {
    
    
        "resource": "/rateLimit/byUrl",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

Después de actualizar Sentinel
y reiniciar el servicio, se puede llamar a la interfaz varias veces antes de que se pueda pasar la verificación de persistencia.

Otros ejemplos

Extraído del sitio web oficial.

Ejemplo de limitación de corriente adaptativa

https://github.com/alibaba/Sentinel/blob/master/sentinel-demo/sentinel-demo-basic/src/main/java/com/alibaba/csp/sentinel/demo/system/SystemGuardDemo.java

public class SystemGuardDemo {
    
    

    private static AtomicInteger pass = new AtomicInteger();
    private static AtomicInteger block = new AtomicInteger();
    private static AtomicInteger total = new AtomicInteger();

    private static volatile boolean stop = false;
    private static final int threadCount = 100;

    private static int seconds = 60 + 40;

    public static void main(String[] args) throws Exception {
    
    

        tick();
        initSystemRule();

        for (int i = 0; i < threadCount; i++) {
    
    
            Thread entryThread = new Thread(new Runnable() {
    
    
                @Override
                public void run() {
    
    
                    while (true) {
    
    
                        Entry entry = null;
                        try {
    
    
                            entry = SphU.entry("methodA", EntryType.IN);
                            pass.incrementAndGet();
                            try {
    
    
                                TimeUnit.MILLISECONDS.sleep(20);
                            } catch (InterruptedException e) {
    
    
                                // ignore
                            }
                        } catch (BlockException e1) {
    
    
                            block.incrementAndGet();
                            try {
    
    
                                TimeUnit.MILLISECONDS.sleep(20);
                            } catch (InterruptedException e) {
    
    
                                // ignore
                            }
                        } catch (Exception e2) {
    
    
                            // biz exception
                        } finally {
    
    
                            total.incrementAndGet();
                            if (entry != null) {
    
    
                                entry.exit();
                            }
                        }
                    }
                }

            });
            entryThread.setName("working-thread");
            entryThread.start();
        }
    }

    private static void initSystemRule() {
    
    
        SystemRule rule = new SystemRule();
        // max load is 3
        rule.setHighestSystemLoad(3.0);
        // max cpu usage is 60%
        rule.setHighestCpuUsage(0.6);
        // max avg rt of all request is 10 ms
        rule.setAvgRt(10);
        // max total qps is 20
        rule.setQps(20);
        // max parallel working thread is 10
        rule.setMaxThread(10);

        SystemRuleManager.loadRules(Collections.singletonList(rule));
    }

    private static void tick() {
    
    
        Thread timer = new Thread(new TimerTask());
        timer.setName("sentinel-timer-task");
        timer.start();
    }

    static class TimerTask implements Runnable {
    
    
        @Override
        public void run() {
    
    
            System.out.println("begin to statistic!!!");
            long oldTotal = 0;
            long oldPass = 0;
            long oldBlock = 0;
            while (!stop) {
    
    
                try {
    
    
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
    
    
                }
                long globalTotal = total.get();
                long oneSecondTotal = globalTotal - oldTotal;
                oldTotal = globalTotal;

                long globalPass = pass.get();
                long oneSecondPass = globalPass - oldPass;
                oldPass = globalPass;

                long globalBlock = block.get();
                long oneSecondBlock = globalBlock - oldBlock;
                oldBlock = globalBlock;

                System.out.println(seconds + ", " + TimeUtil.currentTimeMillis() + ", total:"
                    + oneSecondTotal + ", pass:"
                    + oneSecondPass + ", block:" + oneSecondBlock);
                if (seconds-- <= 0) {
    
    
                    stop = true;
                }
            }
            System.exit(0);
        }
    }
}

Supongo que te gusta

Origin blog.csdn.net/qq_45742250/article/details/132468322
Recomendado
Clasificación