Grain Mall 24 Sentinel Límite de corriente, disyuntor y degradación

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
Todos los métodos anteriores que agregamos al servicio seckill son porque , además de ser rápidos, también necesitamos garantías 稳定.

No importa qué tan rápido seamos, habrá un valor límite. Ahora supongamos que una sola máquina puede procesar 10,000 pedidos por segundo, que ya es una capacidad de procesamiento súper alta. Cinco servidores están conectados al servicio seckill, y tres de ellos son fuera de línea, pero la puerta de enlace de solicitud de seckill Simplemente suelte 100,000 solicitudes y colóquelas todas, luego los dos servidores restantes no podrán manejarlas. El valor máximo de cada servidor es 10,000, y todas las solicitudes deben ponerse en cola, lo que causará la acumulación de tiempo de solicitud, con el tiempo, los recursos se agotarán y el servidor se bloqueará.

Entonces, cuando está casi garantizado, debemos garantizar la estabilidad.

Cómo asegurar que la estabilidad esté en nuestro sistema distribuido, 限流&熔断&降级no importa que sistema distribuido tengamos, sea de alta concurrencia o no, debemos considerarlo, porque con estos métodos de protección, todo nuestro cluster puede lograr la estabilidad.

Solíamos usar hystrix de springCloud, que ya no se actualiza, y las funciones compatibles son limitadas.
En nuestro sistema, lo usamos springCloud alibaba的Sentinelpara completar todo el sistema 限流&熔断&降级.
Protegerá todo nuestro sistema de manera muy estable Incluso un gran grupo de cientos de servidores, con la protección de Sentinel, será muy estable cuando varios servidores se conecten o se bloqueen.

Limitación de corriente, fusión y degradación

  • ¿Qué es un
    servicio dañado? El servicio A llama a una función del servicio B. Debido a la inestabilidad de la red, o el servicio B está atascado, la función tarda demasiado. Si esto sucede demasiadas veces. Podemos desconectar B directamente (A ya no solicita la interfaz B), y aquellos que llaman a B directamente devuelven los datos degradados sin esperar la ejecución súper larga de B. De esta forma, la falla de B no afectará a A en cascada.

    Si no hay protección, fingir llamadas de forma remota y fingir tiene un período de tiempo de espera predeterminado, por ejemplo, 3 s. Si no se devuelven datos dentro de los 3 segundos, se considera que hay un problema con el servicio llamado y la interfaz de fingir informará un error de tiempo de espera, pero no podemos esperar por esto durante mucho tiempo, porque esto hará que toda la cadena de llamadas 累积效应,
    a llame a b, b llame a c, el método c ahora tiene que esperar 3 segundos, b necesita esperar a c, a debe esperar a b, todos deben esperar, toda la línea se bloqueará y los recursos no se podrán usar. Si se libera, el rendimiento disminuirá y una gran cantidad de solicitudes se pondrán en cola nuevamente, lo que forma una situación Cuanto 死循环peor sea la capacidad, más solicitudes se acumulan, y cuantas más solicitudes requieran más recursos para su asignación y procesamiento, nuestras máquinas se congelarán y colapsarán.
    Entonces, necesitamos agregar un mecanismo de interruptor de circuito. A llama a b. Si se descubre que b no puede regresar normalmente, entonces desconectaremos directamente a b en el futuro. Luego, a llama a b sin prestar atención a si b tiene éxito o no, y vuelve rápidamente a fallar.
    La fusión puede garantizar que todo nuestro servicio no se vea afectado por la conexión en cascada. Si un servicio se cuelga, toda la cadena de llamadas no se bloqueará durante mucho tiempo.

  • ¿Qué es la degradación?
    Todo el sitio web se encuentra en el período pico de tráfico, y la presión sobre el servidor aumenta considerablemente.De acuerdo con la situación comercial actual y el tráfico, algunos servicios y páginas se degradan estratégicamente [停止服务,所有的调用直接返回降级数据]. De esta forma, se alivia la presión sobre los recursos del servidor para garantizar el funcionamiento normal del negocio principal y, al mismo tiempo, se responde adecuadamente a los clientes y a la mayoría de los clientes.

    Suponga que el tráfico está en su apogeo y que ahora hay muchos negocios en funcionamiento, algunos negocios centrales, como carritos de compras, pedidos, etc., y algunos negocios secundarios, como registros, etc., y el sitio web. se encuentra actualmente en el período pico de las ventas flash.. No es suficiente.
    Podemos permitir manualmente que algunos negocios no centrales, como el registro, detengan el negocio de registro del servidor. Si hay otros negocios en el servidor, podemos ceder recursos a otros negocios principales. Esto es degradar.
    Al mismo tiempo, puede volver a una página de degradación, solicitar 此功能暂时不可用.

  • similitudes y diferencias

    • Mismo punto

      1. Para garantizar la disponibilidad y confiabilidad de la mayoría de los servicios en el clúster y evitar fallas, sacrifique el ego
      2. Los usuarios terminan experimentando que una función no está disponible
    • diferencia:

      1. El disyuntor es culpa del llamado, lo que activa la regla activa del sistema.
      2. La degradación se basa en consideraciones globales, deteniendo manualmente algunos servicios normales y liberando recursos
  • ¿Qué es la limitación de flujo?
    Controlar el flujo de solicitudes que ingresan al servicio, para que el servicio pueda soportar la presión del flujo que no exceda su propia capacidad.
    Por ejemplo, la capacidad de procesamiento de todo el clúster es de 1 W por segundo, por lo que la solicitud que devolvemos desde la puerta de enlace es de 1 W. Para aquellos que no tienen suerte, informen el error directamente, vuelvan a intentarlo por su cuenta o cómo hacerlo.
    La limitación de flujo es limitar el flujo de toda la entrada para garantizar que nuestro servicio no se vea completamente abrumado por el flujo que excede su capacidad. Siempre que el tráfico que exceda su capacidad se descarte directamente, no hay necesidad de tratarlo.

Centinela

Sentinel se puede utilizar para funciones de limitación, fusión y degradación de corriente.

La diferencia entre Sentinel y Hystrix

inserte la descripción de la imagen aquí

1. Estrategia de aislamiento

Supongamos que ahora tenemos 100 solicitudes que vienen a ejecutarse y el sistema no tiene la capacidad suficiente para ejecutar 50

  • Aislamiento del grupo de subprocesos
    Si es Hystrix, como una solicitud de saludo, cree un grupo de subprocesos para esta solicitud, asigne 50 subprocesos y el grupo de subprocesos asigne un subproceso para ejecutar. Si no hay suficientes subprocesos, vuelva a llamar.
    Pero si hay demasiadas solicitudes, cada solicitud corresponderá a un grupo de subprocesos diferente, y habrá demasiados grupos de subprocesos, y cambiar entre grupos de subprocesos también es una pérdida de tiempo, lo que tiene un gran impacto en el rendimiento. Puede ser que el grupo de subprocesos no sea suficiente para usar los recursos, lo que puede provocar un tiempo de inactividad del servicio.

  • Aislamiento de semáforo
    También hay un semáforo en java8, que es el mismo que nuestro semáforo redis. Siempre que entre la solicitud, si el límite es 50, cada solicitud que llama a la solicitud tiene un semáforo correspondiente y un semáforo de solicitud -1 viene. , Después de ejecutar un semáforo de solicitud +1, si se encuentra que la solicitud viene en 50, la próxima vez que entre, se devolverá la llamada directamente.
    No es necesario crear un grupo de subprocesos separado para cada solicitud, lo que genera un consumo de recursos.

El aislamiento del grupo de subprocesos también tiene sus ventajas: cada solicitud utiliza su propio grupo de subprocesos, y su propio grupo de subprocesos se explota y no tiene nada que ver con los demás.
El semáforo es que una vez que alguien explote, habrá algunos problemas en todo nuestro servicio.

2. Estrategia de reducción de interruptores automáticos

  • Según el tiempo de respuesta
    , por ejemplo, cada solicitud no se ejecutará siempre que exceda 1s

  • Tasa anormal
    Una solicitud se solicita cien veces, y el 90% de ellas tiene anomalías, por lo que no solicitaré en el futuro.

  • Número anormal
    Cinco de cada cien solicitudes son anormales y no se realizan más solicitudes.

Tenemos muchas estrategias para limitar si fusionar o degradar la cadena de llamadas (servicio) detrás.

3. Configuración de reglas dinámicas

Las estrategias anteriores se pueden configurar dinámicamente a través de la fuente de datos, es decir, la configuración se mantiene en la base de datos y la configuración anterior aún se puede usar incluso si se reinicia el servicio.

4. Protección adaptativa del sistema

Después de conocer las capacidades del sistema, permitirá la entrada de todo el tráfico durante los períodos pico bajos y lo limitará durante los períodos pico.

Introducción

Sentinel se puede dividir simplemente en la biblioteca principal de Sentinel y el panel (interfaz visual web, con una interfaz visual, es muy conveniente para ajustar y monitorear). La biblioteca principal no depende de Dashboard, pero puede lograr los mejores resultados en combinación con Dashboard.

El recurso del que estamos hablando puede ser cualquier cosa, un servicio, un método en un servicio o incluso una pieza de código. El uso de Sentinel para la protección de recursos se divide principalmente en varios pasos:

  1. Definir recursos (qué recursos se van a proteger)
  2. Defina reglas (defina reglas de protección, como cuántas veces por segundo la solicitud no permitirá el acceso, y si la carga de la CPU excede el número, se degradará)
  3. Comprobar si la regla está en vigor

definir recursos

Las siguientes son las tres formas más utilizadas para definir los recursos.

Método 1: Adaptación predeterminada de los marcos principales

Para reducir la complejidad del desarrollo, hemos adaptado la mayoría de los marcos principales, como Web Servlet, Dubbo, Spring Cloud, gRPC, Spring WebFlux, Reactor, etc. Solo necesita introducir las dependencias correspondientes para integrar fácilmente Sentinel.

Para los marcos web principales, todas las solicitudes se adaptan de forma predeterminada y todas las solicitudes son recursos que deben protegerse.

Método 2: Definir recursos lanzando excepciones

SphU incluye una API estilo try-catch. De esta forma, se lanzará una BlockException cuando se limite el recurso. En este momento, se pueden capturar excepciones y se puede realizar el procesamiento lógico después de la limitación actual. El código de ejemplo es el siguiente:

// 1.5.0 版本开始可以利用 try-with-resources 特性(使用有限制)
// 资源名可使用任意有业务语义的字符串,比如方法名、接口名或其它可唯一标识的字符串。
try (Entry entry = SphU.entry("resourceName")) {
    
    
  // 被保护的业务逻辑
  // do something here...
} catch (BlockException ex) {
    
    
  // 资源访问阻止,被限流或被降级
  // 在此处进行相应的处理操作
}

Método 4: Definir recursos por anotación

Sentinel admite la definición de recursos a través de la anotación @SentinelResource y la configuración de blockHandler y funciones de respaldo para el procesamiento después de la limitación actual. Ejemplo:

// 原本的业务方法.
@SentinelResource(blockHandler = "blockHandlerForGetUser")
public User getUserById(String id) {
    
    
    throw new RuntimeException("getUserById command failed");
}

// blockHandler 函数,原方法调用被限流/降级/系统保护的时候调用
public User blockHandlerForGetUser(String id, BlockException ex) {
    
    
    return new User("admin");
}

tipos de reglas

Todas las reglas de Sentinel se pueden consultar y modificar dinámicamente en el estado de la memoria, y surtirán efecto inmediatamente después de la modificación. Al mismo tiempo, Sentinel también proporciona API relacionadas para que pueda personalizar sus propias reglas y estrategias.

Sentinel admite los siguientes tipos de reglas: 流量控制规则、熔断降级规则、系统保护规则(cpu、内存超过多少占用率)、来源访问控制规则(设置黑、白名单) 和 热点参数规则.

Reglas de control de flujo

Esta es una configuración en formato json
inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí
La imagen de arriba es un árbol de llamadas clásico, si el nodo A está limitado

  • estrategia llamada relación actual estrategia limitante

    • Directamente
      solo limita el flujo de nodeA

    • Enlace
      Puede especificar el recurso de entrada en el enlace. Si se especifica raíz como la entrada, entonces solo tendrá efecto el límite actual llamado desde la raíz al nodo A. Si Entrada2 (u otro enlace) llama al nodo A, no tendrá efecto.

    • Asociación
      Dos recursos se asocian cuando existe contención de recursos o dependencia entre ellos.
      Por ejemplo, existe una disputa entre las operaciones de lectura y escritura en el mismo campo en la base de datos.Si la velocidad de lectura es demasiado alta, la velocidad de escritura se verá afectada, y si la velocidad de escritura es demasiado alta, la velocidad de lectura se verá afectada. Si se permite que las operaciones de lectura y escritura compitan por los recursos, la sobrecarga provocada por la propia contención reducirá el rendimiento general. La limitación de corriente asociada se puede utilizar para evitar una contención excesiva entre recursos con relaciones asociadas.
      Por ejemplo, los dos recursos read_db y write_db representan la lectura y escritura de la base de datos respectivamente. Podemos establecer reglas de limitación de corriente para read_db para lograr el propósito de prioridad de escritura: Establecer estrategia a RuleConstant.STRATEGY_RELATE y establezca refResource a write_db. De esta forma, cuando la operación de escritura a la biblioteca sea demasiado frecuente, la solicitud de lectura de datos se verá limitada.

  • controlBehavior
    modo de inicio lento: El tráfico aumenta lentamente y finalmente aumenta la capacidad de carga del sistema.

  • comportamiento de control

    • Rechazar directamente
      Rechazar directamente, lanzar una excepción

    • Esperando en línea
      Si se exceden las solicitudes concurrentes del sistema, espere en línea y también podemos establecer un tiempo de espera.

    • calentamiento modo de inicio lento modo de calentamiento
      El sistema puede soportar un máximo de 100 simultáneos, podemos configurar el tiempo de calentamiento, aumentar lentamente el simultáneo dentro del tiempo especificado y finalmente alcanzar el 100 simultáneo después de alcanzar el tiempo especificado

Definir reglas de control de flujo a través del código
Después de comprender la definición de las reglas anteriores, podemos definir reglas de control de flujo de forma codificada llamando al método FlowRuleManager.loadRules(), por ejemplo:

private void initFlowQpsRule() {
    
    
    List<FlowRule> rules = new ArrayList<>();
    FlowRule rule = new FlowRule(resourceName);
    // set limit qps to 20
    rule.setCount(20);
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    rule.setLimitApp("default");
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
}

Al mismo tiempo, estas reglas de control también se pueden configurar con una consola visual (panel centinela).

descarga de la consola

La versión de la consola (un paquete jar) es consistente con la versión de sentinel-core:1.8.0. Use java -jar para comenzar directamente.

Los secretos de la cuenta son todos centinela. Después de iniciar sesión, no hay información en la interfaz. Esta página tiene carga diferida. Enviamos una solicitud y la página solo se mostrará si es un recurso protegido.

Sentinel integra springboot

package com.atlinxi.gulimall.seckill;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;


/**
 * 1. 整合Sentinel
 * 		1)导入依赖 spring-cloud-starter-alibaba-sentinel
 * 		2)下载sentinel的控制台
 * 		3)配置sentinel控制台地址信息
 * 		4)在控制台调整参数。【默认所有的流控设置保存在内存中,重启失效】
 *
 *
 * 	2. 每一个微服务都导入actuator 并配置 management.endpoints.web.exposure.include=*
 * 	3. 自定义sentinel流控返回数据
 * 	4. 使用sentinel来保护feign远程调用:熔断
 * 		1)、调用方的熔断保护:feign.sentinel.enabled=true
 * 		2)、调用方手动指定远程服务的降级策略。远程服务被降级处理。默认触发我们的熔断回调方法。
 * 		3)、超大流量的时候,必须牺牲一些远程服务,在服务的提供方(远程服务)指定降级策略,
 * 			提供方是在运行。但是不运行自己的业务逻辑,返回的是默认的熔断数据(限流后的数据),我们写的config返回的数据
 *
 * 	5. 自定义受保护的资源
 * 		1)、代码
 * 			try (Entry entry = SphU.entry("seckillSkus")){
 * 			 	// 业务逻辑
 * 			}catch(Exception e){}
 *
 * 		2)、基于注解
 * 			@SentinelResource("getCurrentSeckillSkusResource")
 *
 * 		无论是1,2方式一定要配置被限流以后的默认返回
 * 		url级别的请求可以设置统一返回:BlockExceptionHandler
 *
 */
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class GulimallSeckillApplication {
    
    

	public static void main(String[] args) {
    
    
		SpringApplication.run(GulimallSeckillApplication.class, args);
	}

}

Resolver el problema de la dependencia.

<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>



<dependency>
			<groupId>com.atlinxi.gulimall</groupId>
			<artifactId>gulimall-common</artifactId>
			<version>0.0.1-SNAPSHOT</version>
			<exclusions>
				<exclusion>
					<groupId>com.alibaba.cloud</groupId>
					<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
				</exclusion>
				<!--
					不知道为什么,有validation-api的时候sentinel启动就报

					Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
					然后把validation-api去掉sentinel就可以成功启动了
				-->
				<exclusion>
					<groupId>javax.validation</groupId>
					<artifactId>validation-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>








<!--
	上面的方法是可以解决这个问题的,但此时又有一个问题,要是必须用到validation-api怎么办
	添加以下依赖即可,就不需要排除validation-api,sentinel也可以正常启动
-->
<dependency>
            <groupId>jakarta.validation</groupId>
            <artifactId>jakarta.validation-api</artifactId>
            <version>2.0.2</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.18.Final</version>
            <scope>compile</scope>
        </dependency>
// 每个微服务都需要配置
spring:
  cloud:
    sentinel:
      transport:
      	// 微服务和控制台之间的通信
        port: 8719
        // 控制台的地址
        dashboard: localhost:8080

Limite el flujo de solicitudes ordinarias

Las solicitudes normales son relativas a las llamadas remotas.

En este momento, cuando solicitamos http://seckill.gulimall.com/currentSeckillSkus, la consola centinela mostrará el servicio seckill, y habrá una solicitud en 簇点链路la barra de menú . Podemos realizar y configurar directamente la solicitud en la consola . Actualizamos rápidamente la página en la página, y aparecerá un aviso y no se ejecutará la impresión del registro en el método. Este es el control de flujo más simple./currentSeckillSkus流控QPS为1Blocked by Sentinel (flow limiting)

Soluciona el problema de que no hay datos en la monitorización en tiempo real de la consola

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>

# 暴露所有资源
management.endpoints.web.exposure.include=*

Los datos devueltos por defecto después de solicitar la limitación de corriente son oficiales centinela por defecto

Aquí usamos nuestro propio definido

package com.atlinxi.gulimall.seckill.config;


import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import com.atlinxi.common.exception.BizCodeEnume;
import com.atlinxi.common.utils.R;
import org.springframework.context.annotation.Configuration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Configuration
public class SeckillSentinelConfig implements BlockExceptionHandler {
    
    
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
    
    
        R error = R.error(BizCodeEnume.TOO_MANY_REQUEST.getCode(), BizCodeEnume.TOO_MANY_REQUEST.getMessage());
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.setContentType("application/json");
        httpServletResponse.getWriter().write(JSON.toJSONString(error));
    }

}

A continuación, introducimos cada microservicio spring-boot-starter-actuatory luego realizamos una serie de operaciones en el centro comercial, como buscar, página de detalles, agregar al carrito de compras, enviar un pedido, etc., y luego podemos ver todos nuestros servicios en el centinela. consola.

Ahora puede ajustar fácilmente el control de flujo de cada microservicio y cada solicitud en la consola.

Mecanismo de protección de fusibles para llamadas remotas

Esto se configura en el llamante, es decir, si a llama a b, se realiza la configuración de a.

Antes de que se habilite el mecanismo de protección de fusibles, si el servicio b se cae o se agota, la página informará directamente un error. Si está
habilitado, la página regresa normalmente, pero la información devuelta originalmente por el servicio b se reemplaza por la fusión método que especificamos.

package com.atlinxi.gulimall.product.feign;

import com.atlinxi.common.utils.R;
import com.atlinxi.gulimall.product.feign.fallback.SeckillFeignServiceFallBack;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;


// 如果远程调用失败,就用SeckillFeignServiceFallBack实现类方法返回的信息
@FeignClient(value = "gulimall-seckill",fallback = SeckillFeignServiceFallBack.class)
public interface SeckillFeignService {
    
    

    @GetMapping("/sku/seckill/{skuId}")
    R getSkuSeckillInfo(@PathVariable("skuId") Long skuId);
}








package com.atlinxi.gulimall.product.feign.fallback;

import com.atlinxi.common.exception.BizCodeEnume;
import com.atlinxi.common.utils.R;
import com.atlinxi.gulimall.product.feign.SeckillFeignService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class SeckillFeignServiceFallBack implements SeckillFeignService {
    
    


    @Override
    public R getSkuSeckillInfo(Long skuId) {
    
    
        log.info("熔断方法调用。。。getSkuSeckillInfo");
        return R.error(BizCodeEnume.TOO_MANY_REQUEST.getCode(),BizCodeEnume.TOO_MANY_REQUEST.getMessage());
    }
}

La persona que llama especifica manualmente la política de degradación del servicio remoto

熔断和降级的关系
Hemos escrito el método que se llamará de forma predeterminada después de escribir el fusible en el código anterior, pero el código del fusible no se ejecutará hasta que se agote el tiempo de espera de la llamada remota fingida o el servidor esté inactivo.
Usamos la degradación, como especificar RT como 1, si lo excede, llame al código de fusible y espere a que expire la ventana de tiempo establecida, luego intente llamar al método original nuevamente.

Antes de habilitar la degradación del fusible, si el servicio a llama al servicio b y el servicio b cuelga, el servicio a generará una excepción directamente.

En nuestro proyecto, cuando el servicio del producto consulta la página de detalles del producto, llamará de forma remota al servicio seckill para confirmar si el producto tiene un seckill.

Habilitamos la degradación del disyuntor en el servicio del producto, de modo que si percibimos que la llamada de servicio seckill falla, habilitaremos el disyuntor y nuestra página de detalles del producto seguirá siendo normal, y la página no informará directamente un error debido a el fracaso de la llamada de servicio seckill.

reglas de degradación
inserte la descripción de la imagen aquí

  • RT, tiempo de respuesta promedio
    Cuando continúan ingresando 5 solicitudes dentro de 1 segundo y el tiempo de respuesta promedio supera el umbral (la cifra anterior, especificamos 1 ms), luego, dentro de la siguiente ventana de tiempo, las llamadas a este método se bloquearán automáticamente.
    Una vez que expira la ventana de tiempo, se realiza otro intento de llamar al método.

Cuando nuestra estrategia de degradación entra en vigor, todavía se llama a nuestro método de corte de circuito personalizado.

Personalice los recursos protegidos

basado en código

public List<SeckillSKuRedisTo> getCurrentSeckillSkus() {
    
    

        // 1. 确定当前时间属于哪个秒杀场次
        long time = new Date().getTime();

        /**
         * sentinel,我们假设这段逻辑运行时间可能会较长,进行自定义受保护资源
         *
         * seckillSkus,受保护资源的名称,就可以在sentinel dashboard进行流量控制,熔断降级等所有的策略
         */
        try (Entry entry = SphU.entry("seckillSkus")){
    
    

            Set<String> keys = stringRedisTemplate.keys(SESSIONS_CACHE_PREFIX + "*");

            for (String key : keys) {
    
    
                // seckill:sessions:1682784000000_1682791200000
                String replace = key.replace(SESSIONS_CACHE_PREFIX, "");
                String[] s = replace.split("_");
                long start = Long.parseLong(s[0]);
                long end = Long.parseLong(s[1]);

                if (time>=start && time<=end){
    
    

                    // 2. 获取这个秒杀场次需要的所有商品信息

                    // -100到100,代表的就是长度,我们秒杀的商品肯定没有这么多,所以肯定能取全
                    List<String> range = stringRedisTemplate.opsForList().range(key, -100, 100);

                    BoundHashOperations<String, String, String> hashOps = stringRedisTemplate.boundHashOps(SKUKILL_CACHE_PREFIX);

                    List<String> list = hashOps.multiGet(range);

                    if (list!=null){
    
    
                        List<SeckillSKuRedisTo> collect = list.stream().map(item -> {
    
    
                            SeckillSKuRedisTo redis = JSON.parseObject(item.toString(), SeckillSKuRedisTo.class);

                            return redis;

                        }).collect(Collectors.toList());

                        return collect;
                    }

                    break;

                }
            }

        }catch (BlockException e){
    
    
            log.error("资源被限流,{}",e.getMessage());


        }





        return null;
    }

basado en anotaciones

public List<SeckillSKuRedisTo> blockHandler(BlockException e){
    
    
        log.error("getCurrentSeckillSkusResource被限流了。。。");
        return null;

    }

    /**
     * 返回当前时间可以参与的秒杀商品信息
     * @return
     *
     *
     * sentinel
     *
     *  blockHandler 限流/降级之后要调用的方法
     *      返回值需要与原方法保持一致
     *      我们也可以在限流方法中获取到原方法的参数

		fallback 函数名称,可选项,用于在抛出异常的时候提供fallback处理逻辑,可以针对所有类型的异常进行处理
			方法的返回值类型必须与原函数保持一致
			方法的参数列表需要为空,或者可以额外多一个Throwable类型的参数用来接收对应的异常
			需与原方法在一个类中,如果不在,需定义为静态方法,用fallbackClass来指定在哪个类中
     */
    @Override
    @SentinelResource(value = "getCurrentSeckillSkusResource",blockHandler = "blockHandler")
    public List<SeckillSKuRedisTo> getCurrentSeckillSkus() {
    
    

Control de flujo de puerta de enlace

Anteriormente, usábamos Sentinel para realizar operaciones como el control de flujo/degradación en cada solicitud de microservicio y nuestros recursos personalizados, pero en este caso, la solicitud ingresó al microservicio antes de que Sentinel la controlara.
Si agregamos control centinela en la capa de puerta de enlace, la solicitud se bloqueará directamente en la capa de puerta de enlace sin reenviar al microservicio, por lo que el efecto será más evidente.
Ahora integremos Sentinel en la capa de puerta de enlace.

引入之后需要重启服务和sentinel控制台jar包,在控制台的gateway菜单就可以看到页面的变化
<dependency>
			<groupId>com.alibaba.cloud</groupId>
			<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
			<version>2021.1</version>
		</dependency>

inserte la descripción de la imagen aquí

  • Nombre de la API
    La identificación de la regla de enrutamiento configurada en la puerta de enlace predeterminada es el nombre del recurso de Sentinel

  • Intervalo
    cuánto tiempo contar una vez

  • El tamaño de ráfaga
    es el número de solicitudes adicionales permitidas al responder a solicitudes de ráfaga.

  • Los atributos de la solicitud
    se pueden restringir en función de los atributos de la solicitud

Datos de retorno personalizados después del límite actual

package com.atlinxi.gulimall.gateway.config;

import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import com.alibaba.fastjson.JSON;
import com.atlinxi.common.exception.BizCodeEnume;
import com.atlinxi.common.utils.R;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Configuration
public class SentinelGatewayConfig {
    
    

    public SentinelGatewayConfig() {
    
    
        GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
    
    

            // 网关限流了请求,就会调用此回调
            @Override
            public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
    
    

                R error = R.error(BizCodeEnume.TOO_MANY_REQUEST.getCode(), BizCodeEnume.TOO_MANY_REQUEST.getMessage());

                String errJson = JSON.toJSONString(error);

                Mono<ServerResponse> body = ServerResponse.ok().body(Mono.just(errJson), String.class);


                return body;
            }
        });
    }
}

Cada vez que hablaba con la escuela, Su Yinglan lo compartía con Xiaoyi de inmediato: "Ven aquí, te informaré sobre mi trabajo". Omitió el proceso de negociación específico y resumió las cosas en un lenguaje que un niño pudiera entender.

https://baijiahao.baidu.com/s?id=1760481532554271247

La "batalla" de una madre contra la violencia escolar

Supongo que te gusta

Origin blog.csdn.net/weixin_44431371/article/details/130501172
Recomendado
Clasificación