Registro de aprendizaje introductorio de Sentinel

1. ¿Qué es Sentinel?

A medida que los sistemas distribuidos se vuelven cada vez más populares, la confiabilidad entre servicios se vuelve más importante que nunca. Sentinel es un poderoso componente de control de flujo, con "flujo" como punto de entrada, que cubre múltiples áreas, incluido el control de flujo, la restricción de concurrencia, la interrupción de circuitos y la protección del sistema adaptativo para garantizar la confiabilidad de los microservicios.
En una palabra, se Spring Cloud Alibabausa para reemplazar la Hystrixtecnología anterior .

2. ¿De qué sirve?

Se utiliza para control de flujo del sistema, degradación de fusibles, protección de carga del sistema, etc.
Inserte la descripción de la imagen aquí

3. Descargue e inicie Sentinel

1. Dirección de descarga
2. Iniciar

java -jar sentinel-dashboard-1.7.2.jar

3. Para acceder al panel, el nombre de usuario y la contraseña sonsentinel
Inserte la descripción de la imagen aquí

4. Preparación de la prueba

1. Cree un nuevo proyecto de springboot
2. Introduzca las dependencias

<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--     sentinel-datasource-nacos 后续持久化用   -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

3. Agrega anotaciones a la clase de inicio.@EnableDiscoveryClient

@SpringBootApplication
@EnableDiscoveryClient
public class AlibabaSentinelServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(AlibabaSentinelServiceApplication.class, args);
    }
}

4. application.propertiesConfigurar

server.port=8401

spring.application.name=cloudalibaba-sentinel-service
spring.cloud.nacos.discovery.server-addr=localhost:8848
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.transport.port=8719
spring.cloud.sentinel.datasource.dsl.nacos.server-addr=localhost:8848
spring.cloud.sentinel.datasource.dsl.nacos.data-id=${spring.application.name}
spring.cloud.sentinel.datasource.dsl.nacos.group-id=DEFAULT_GROUP
spring.cloud.sentinel.datasource.dsl.nacos.data-type=json
spring.cloud.sentinel.datasource.dsl.nacos.rule-type.=flow

management.endpoints.web.exposure.include=*

5. Proporcionar interfaz de prueba

@RestController
public class FlowLimitController {

    private static Logger log = LoggerFactory.getLogger(FlowLimitController.class);

    @GetMapping("/testA")
    public String testA(){
//        try {
//            TimeUnit.MILLISECONDS.sleep(800);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        return "testA-----";
    }

    @GetMapping("/testB")
    public String testB(){
        log.info(Thread.currentThread().getName() + "...testB ");
        return "testB   -----";
    }
    }

6. Empiece sentinely nacos
no entienda que los nacos pueden referirse a

5. Pruebe las reglas de control de flujo

Inserte la descripción de la imagen aquí

  • Nombre del recurso: nombre único, ruta de solicitud predeterminada
  • Para la fuente: Sentinel puede limitar el flujo para la persona que llama, completar el nombre del microservicio y el valor predeterminado default(no distingue la fuente)
  • Tipo de umbral / umbral de una sola máquina
    • QPS (el número de solicitudes por segundo): cuando el QPS que llama a la api alcanza el umbral, limite la corriente
    • Número de subprocesos: cuando el número de subprocesos que llaman a la API alcanza el umbral, limite la corriente
  • Modo de control de flujo
    • Directo: cuando la API alcanza la condición de limitación de corriente, la corriente se limita directamente
    • Asociación: cuando el recurso asociado alcanza el umbral, limita el flujo de sí mismo.
      La interfaz A está asociada con la interfaz B. Cuando la interfaz B alcanza el umbral, el límite actual de la interfaz A se utiliza para proteger la interfaz B. Por ejemplo, la interfaz de pago y la interfaz de pedido, cuando la interfaz de pago alcanza el umbral, la interfaz de pedido tiene un flujo limitado, lo que desempeña un papel en la protección de la interfaz de pago.
    • Enlace: solo registre el tráfico en el enlace especificado (el tráfico que proviene del recurso de entrada de recursos especificado, si alcanza el umbral, limitará el flujo)
  • Efecto de control de flujo
    • Falla rápido: falla directamente y lanza una excepción
    • Calentamiento: De acuerdo con el valor de codeFactor (factor de carga en frío, por defecto 3), desde el umbral / codeFactor, después del tiempo de calentamiento, alcanza el umbral QPS establecido.
      Generalmente se usa para funciones similares a los picos.
    • Esperando en línea: hacer cola a una velocidad constante para permitir que las solicitudes pasen a una velocidad constante. El tipo de umbral debe establecerse en QPS, de lo contrario no es válido.

5.1 Prueba QPS para alcanzar el umbral

La configuración es la siguiente:
Inserte la descripción de la imagen aquí
cuando hace clic continuamente para ver el siguiente mensaje de límite actual (el número de solicitudes de 1 s excede el umbral configurado)
Inserte la descripción de la imagen aquí

5.2 El número de subprocesos de prueba alcanza el umbral

La configuración es la siguiente:
Inserte la descripción de la imagen aquí
para facilitar las pruebas, deje que cada método llamado duerma un rato

@GetMapping("/testA")
    public String testA(){
        //测试线程阈值
        try {
            TimeUnit.MILLISECONDS.sleep(800);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "testA-----";
    }

Cuando hace clic continuamente para ver el siguiente mensaje de límite actual (el número de solicitudes de 1 s excede el umbral configurado)
Inserte la descripción de la imagen aquí

5.3 Límite de corriente de correlación de prueba

La configuración es la siguiente:
Inserte la descripción de la imagen aquí
Utilice cartero para simular y /testAasociar con el /testBumbral
Inserte la descripción de la imagen aquí
alcanzado Después de llamar al cartero, /testApuede ver que la interfaz es limitada.

5.4 Prueba de calentamiento (límite de corriente de arranque en frío)

La configuración es la siguiente (cuando el tráfico de acceso aumenta repentinamente, partiendo del umbral / factor de carga fría, el tiempo de calentamiento alcanza el umbral de acceso por segundo, es decir, puede soportar 2 accesos por segundo desde el inicio del tráfico aumentar, y puede admitir por segundo después de 3 s 6 interfaces de acceso), el factor frío predeterminado (coldFactor) es 3,
Inserte la descripción de la imagen aquí
puede hacer clic para acceder a la /testAprueba de interfaz, comenzar lentamente y hacer clic lentamente sin problema, y ​​luego aumentar la velocidad aparecerá actual límite, después de un tiempo, el límite actual desaparecerá.

5.5. Esperando en fila

La configuración es la siguiente
Inserte la descripción de la imagen aquí
Para facilitar la visualización de la llamada, el nombre del hilo se imprime en la interfaz

@GetMapping("/testB")
    public String testB(){
        log.info(Thread.currentThread().getName() + "...testB ");
        return "testB   -----";
    }

Reinicie la llamada del proyecto, puede ver el registro de la llamada en la consola
Inserte la descripción de la imagen aquí

6. Pruebe las reglas de degradación

Documento oficial

  • RT :
    • Cuando el tiempo de respuesta promedio del recurso excede el umbral (aquí el umbral es el valor de milisegundos configurado por usted mismo) y la solicitud aprobada dentro de la ventana de tiempo es> = 5, las dos condiciones se cumplen al mismo tiempo para desencadenar la degradación del fusible.
    • Cierre el disyuntor después del período de ventana.
    • RT máximo 4900 (mayor a través de -Dcsp.sentinel.statistic.max.rt = xxx para configurar)
  • Proporción anormal: cuando
    QPS> = 5 y la proporción anormal (estadísticas de segundo nivel) excede el umbral, se activa la degradación; una vez que finaliza la ventana de tiempo, la degradación se cierra.
  • Número de excepciones: el número de
    excepciones (estadísticas en minutos) supera el umbral, lo que desencadena la degradación; una vez que finaliza la ventana de tiempo, la degradación se cierra

Sentienl fuse downgrade limitará la llamada de este recurso cuando un determinado recurso en el enlace de llamada de llamada es inestable (por ejemplo, tiempo de espera de llamada o aumento anormal de la proporción), de modo que la solicitud fallará rápidamente y evitará afectar otros recursos y causar el nivel Error de enlace.
Cuando el recurso se degrada, la llamada al recurso se fusiona automáticamente dentro de la siguiente ventana de tiempo degradante (el comportamiento predeterminado es lanzar DegradeException)


6.1 Prueba RT

1. Agregar interfaz de prueba

@GetMapping("/testD")
    public String testD(){
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("testD 测试RT");
        return "testD -----";
    }

Para aumentar el tiempo de respuesta promedio, agregue suspensión al código.
2. Utilice JMater para probar
las /testDinterfaces de acceso de subprocesos de 1s 10.
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
3. La configuración es la siguiente
Inserte la descripción de la imagen aquí
: 4. Inicie JMeter y llámelo usted mismo /testD. Puede ver que la interfaz se ha degradado por fusible.
Inserte la descripción de la imagen aquí
Análisis de fusibles: 1. El tiempo de respuesta promedio (1000 ms) excede el umbral (200 ms) 2. Pasar la solicitud dentro de la ventana de tiempo 10 * 5 = 50> = 5. Se cumplen dos condiciones, por lo que se produce la degradación del fusible

6.2 Tasa de anomalías de prueba

Solicitudes de recursos por segundo> = 5 && La relación entre el número total de excepciones por segundo y el rendimiento excede el umbral , el recurso entra en un estado degradado, es decir, dentro de la próxima ventana de tiempo, las llamadas a este método regresarán automáticamente (service fuse ). El rango de umbral de frecuencia anormal es [0.0,1.0], que representa 0% -100%.

1. Proporcionar una interfaz para probar proporciones anormales.

@GetMapping("/testException")
    public String testException(){
        log.info("testException 异常比例");
        int age = 10 /0 ;
        return "testException -----";
    }

2. Utilice JMater para realizar la prueba de esfuerzo, excepto para la interfaz, otras configuraciones son las mismas que la prueba RT anterior
Inserte la descripción de la imagen aquí
3. Configuración de Sentinel
Inserte la descripción de la imagen aquí
4. Reinicie el proyecto e inicie JMeter para la prueba, llame al /testExceptionmensaje de aviso del fusible de servicio
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

6.3 Número de excepciones de prueba

Cuando el número de recursos anormales en el último minuto supera el umbral, se fusionará. Tenga en cuenta que debido a que la ventana de tiempo estadístico está en el nivel de minutos, si la ventana de tiempo es inferior a 60 segundos, puede volver a entrar en el estado de fusión una vez finalizado el estado de fusión.

1. Proporcionar interfaz de prueba

 @GetMapping("/testExceptionCount")
    public String testExceptionCount(){
        log.info("testExceptionCount 异常数");
        int age = 10 /0 ;
        return "testExceptionCount -----";
    }

2. Configuración de Sentinel
Inserte la descripción de la imagen aquí
3. Reinicie el proyecto para la prueba Las
primeras 5 visitas informaron todos los errores y las visitas posteriores se degradaron después de que se ingresó el fusible.
Inserte la descripción de la imagen aquí
Degradar después de fusionar como se muestra a continuación
Inserte la descripción de la imagen aquí

7. Límite de corriente del parámetro de punto de acceso

Inserte la descripción de la imagen aquí

7.1 Límite actual de parámetros de puntos de acceso comunes

1. Proporcionar una interfaz para realizar pruebas.

	@GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey", blockHandler = "dealTestHotKey")
    public String testHotKey(@RequestParam(value = "p1", required = false) String p1,
                             @RequestParam(value = "p2", required = false) String p2){
        return "testHotKey -----";
    }

    public String dealTestHotKey(String p1, String p2, BlockException blockException){
        return "dealTestHotKey---------";
    }

2. Configuración centinela
Inserte la descripción de la imagen aquí
El primer parámetro p1 en la configuración anterior, cuando el QPS excede 1 clic en 1 segundo, la corriente se limitará inmediatamente.
3. Reinicie la prueba del proyecto.
Inserte la descripción de la imagen aquí

7.2 Límite de corriente de punto caliente de excepción de parámetro

1. La configuración centinela es la siguiente
Inserte la descripción de la imagen aquí
. El significado de la configuración anterior es que cuando el valor del primer parámetro p1 es 5, /testHotKeyel umbral de tráfico de la interfaz es 200

Nota:

@SentinelResource se ocupa de la violación de la configuración de la consola, que es manejada por la configuración del método blockHandler.
Pero @SentinelResource no se preocupa por las excepciones de tiempo de ejecución en el código (RuntimeException)

Inserte la descripción de la imagen aquí

8. Configuración de @ SentinelResource

8.1 Limitar el flujo por nombre de recurso o dirección URL más procesamiento de seguimiento

1. Proporcionar interfaz

    /**
     * (违反sentinel配置)手动配置兜底处理blockHandler
     * @return
     */
    @GetMapping(value = "/byResource")
    @SentinelResource(value = "byResource", blockHandler = "handleException")
    public CommonResult byResource(){
        return new CommonResult(200, "按资源名称限流测试OK");
    }

    public CommonResult handleException(BlockException blockException){
        return new CommonResult<>(444, blockException.getClass().getCanonicalName()+"\t服务不可用" );
    }


    /**
     * 默认处理
     * @return
     */
    @GetMapping("/rateLimit/byUrl")
    @SentinelResource(value = "byUrl")
    public CommonResult byUrl(){
        return new CommonResult(200, "by url限流测试OK");
    }
 

2. Configuración de Sentinel
Nombre del recurso:
Inserte la descripción de la imagen aquí
url:
Inserte la descripción de la imagen aquí

3. Reinicie el
acceso de prueba byResourcecuando acceda más de una vez por segundo, utilizando un proceso de respaldo personalizado.
Inserte la descripción de la imagen aquí
Acceda /rateLimit/byUrlal acceder más de una vez por segundo, utilizando el proceso predeterminado.
Inserte la descripción de la imagen aquí


Hay problemas con la configuración anterior:

  • 1. El sistema predeterminado no refleja nuestras propias necesidades comerciales
  • 2. De acuerdo con las condiciones existentes, nuestro método de procesamiento personalizado y el código comercial están acoplados, lo que no es intuitivo.
  • 3. Cada método comercial tiene un resultado final y la expansión del código aumenta
  • 4. El mismo método de procesamiento global no se refleja

8.1 Resolver problemas existentes

1. Proporcionar interfaz

public class CustomerBlockHandler {

    public static CommonResult handlerException(BlockException exception) {
        return new CommonResult(444, "客户自定义,global handlerException---1");
    }

    public static CommonResult handlerException2(BlockException exception) {
        return new CommonResult(444, "客户自定义,global handlerException---2");
    }
}

 @GetMapping("/rateLimit/customerBlockHandler")
    @SentinelResource(value = "customerBlockHandler",
                    blockHandlerClass = CustomerBlockHandler.class, blockHandler = "handlerException2")
    public CommonResult customerBlockHandler(){
        return new CommonResult(200, "客户自定义 限流测试OK");
    }

2. Configuración en centinela
Inserte la descripción de la imagen aquí
3. Reiniciar la prueba

9. Integre Ribbon y OpenFeign

9.1 Preparación

1. Cree tres proyectos springboot, a saber, alibaba-consumer2, alibaba-provider3 y alibaba-provider4 (alibaba-provider3 / alibaba-provider4 es el mismo)
porque hay demasiadas cosas que no se enumeran aquí, consulte https: // github.com/xiaoxiaoshou / springclouddemo

9.2Serie de cinta

Código de muestra principal:

@RestController
@Slf4j
@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public class CircleBreakerController {
    private static final String SERVICE_URL = "http://nacos-payment-provider";

    @Resource
    private RestTemplate restTemplate;

    @RequestMapping("/consumer/fallback/{id}")
 //    @SentinelResource(value = "fallback") //没有配置
//    @SentinelResource(value = "fallback",fallback = "handlerFallback") //配置了fallback的,fallback只负责业务异常
//    @SentinelResource(value = "fallback",blockHandler = "blockHandler") // 配置了blockHandler,只负责sentinel控制台配置违规
   @SentinelResource(value = "fallback",fallback = "handlerFallback", blockHandler = "blockHandler") // 配置了blockHandler和fallback
 //   @SentinelResource(value = "fallback",fallback = "handlerFallback", blockHandler = "blockHandler", exceptionsToIgnore = {IllegalArgumentException.class}) // 忽略运行时IllegalArgumentException异常不进行自定义处理
    public CommonResult<Payment> fallback(@PathVariable("id") Long id){
        CommonResult<Payment> commonResult = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class);
        if(id == 4){
            throw new IllegalArgumentException("IllegalArgumentException,非法参数异常");
        }else if(commonResult.getData() == null){
            throw new NullPointerException("NullPointerException,该ID没有记录,空指针异常");
        }
        return commonResult;
    }
    // 本例是fallback
    public CommonResult handlerFallback(Long id, Throwable e){
        Payment payment = new Payment(id, null);
        return new CommonResult(444, "兜底异常handler,exception内容"+e.getMessage(), payment);
    }

    public CommonResult blockHandler(Long id, BlockException exception){
        Payment payment = new Payment(id, null);
        return new CommonResult<>(445, "blockHandler-sentinel 限流,无此流水号:blockException" + exception.getMessage(), payment);
    }
}
  • fallbackEl método correspondiente (método handlerFallback) maneja las excepciones durante el tiempo de ejecución del código
  • blockHandlerEl método correspondiente (blockHandler) maneja violaciones en Sentinel
  • exceptionsToIgnoreIgnorar una excepción durante el tiempo de ejecución sin procesamiento personalizado

Configure Sentinel (el umbral de reserva de recursos es 1) e inicie la prueba del proyecto. Puede ver que puede manejar violaciones de Sentinel durante el proceso de invocación y también manejar excepciones durante el tiempo de ejecución.

9.3 Serie OpenFeign

1. Configuración principal

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

2. Vinculación del servicio correspondiente

@FeignClient(value = "nacos-payment-provider", fallback = PaymentFallbackService.class)
public interface PaymentService {

    @GetMapping("/paymentSQL/{id}")
    CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
}

@Component
public class PaymentFallbackService implements PaymentService {
    @Override
    public CommonResult<Payment> paymentSQL(Long id) {
        return new CommonResult<>(444, "fallback");
    }
}

3. Proporcionar interfaz de acceso

    @Resource
    private PaymentService paymentService;

    @GetMapping("/consumer/paymentSQL/{id}")
    public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id){
        return paymentService.paymentSQL(id);
    }

4. Reinicie el proyecto para omitir la interfaz del consumidor y llamar a la interfaz de terceros.


Comparación de varios fusibles:
Inserte la descripción de la imagen aquí

10. Persistencia de la regla

Cuando reinicie el servicio correspondiente cada vez, encontrará que las reglas correspondientes configuradas en Sentinel se han ido. En el entorno de producción, debemos configurar la persistencia de las reglas (las herramientas de persistencia están disponibles y Nacos se recomienda oficialmente).

1. Introducir dependencias

  <!--     sentinel-datasource-nacos 后续持久化用   -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

2. Configuración del archivo de configuración

spring.cloud.sentinel.datasource.dsl.nacos.server-addr=localhost:8848
spring.cloud.sentinel.datasource.dsl.nacos.data-id=${spring.application.name}
spring.cloud.sentinel.datasource.dsl.nacos.group-id=DEFAULT_GROUP
spring.cloud.sentinel.datasource.dsl.nacos.data-type=json
spring.cloud.sentinel.datasource.dsl.nacos.rule-type=flow

3. Configurar en nacos

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

Inserte la descripción de la imagen aquí
Significado del elemento de configuración:

  • recurso: nombre del recurso
  • limitApp: aplicación de origen
  • grado: tipo de umbral, 0 significa el número de subprocesos, 1 significa QPS
  • recuento: umbral independiente
  • estrategia: modo de control de flujo, 0 significa directo, 1 significa cascada, 2 significa enlace
  • controlBehavior: efecto de control de flujo, 0 significa falla rápida, 1 significa calentamiento, 2 significa esperar en la fila
  • clusterMode: si se debe agrupar

Supongo que te gusta

Origin blog.csdn.net/qq_41262903/article/details/107107513
Recomendado
Clasificación