Introducción al componente Gateway de Spring Cloud

comprensión de la puerta de enlace

La puerta de enlace es similar a 海关o 大门, 出入都需要经过这个网关. Otros nunca verán lo que hay dentro sin pasar por este portal. Se puede hacer en la puerta de enlace 条件过滤, por ejemplo, solo la llave correspondiente puede ingresar a la puerta. Las puertas de enlace, como las puertas, siempre están expuestas al exterior.

sin puerta de enlace

  • El front-end necesita recordar la IP y el puerto de cada servicio

  • Si hay múltiples implementaciones de un servicio, el front-end debe asignarlo por sí mismo

usar puerta de enlace

  • El front-end no necesita recordar la IP y el puerto de cada servicio, solo necesita enviar la solicitud a la puerta de enlace, y la puerta de enlace lo hará de acuerdo con la ruta del recurso.路由跳转

  • Gateway puede hacer 安全控制como verificación de token, limitación de corriente, etc.

  • puede hacer负载均衡

Comprensión de la puerta de enlace

Es un conjunto de componentes de puerta de enlace lanzados por el sitio web oficial de Spring para reemplazar a Zuul

Está diseñado para permitir 路由跳转更加方便、灵活, pero ofrecer algo poderoso 过滤器功能. Por ejemplo: lista negra de IP, verificación de token, etc.

Basado en el marco webFlux, la capa inferior del marco webFlux utiliza Netty, un marco de comunicación de modo Reactor de alto rendimiento.


Gateway es un servicio de puerta de enlace API creado sobre el ecosistema Spring, basado en tecnologías como Spring 5, Spring Boot 2 y Project Reactor.

Gateway tiene como objetivo proporcionar una forma simple y efectiva de enrutar las API y proporcionar algunas funciones de filtro potentes, como: ruptura de circuitos, limitación de corriente, reintentos, etc.

① Principio de funcionamiento de la puerta de enlace

El cliente envía una solicitud a Gateway y luego Gateway HandlerMapping compara la asignación para encontrar una ruta coincidente y la envía a Gateway WebHandler. El controlador distribuye la solicitud a la lógica empresarial real a través del filtro especificado y la devuelve.

Puedes agregar código en el filtro:

  • Hacer validación, etc. en 请求之前[pre]

  • Registrar la salida, etc. en 请求之后[post]

Lógica central de la puerta de enlace: enrutamiento y reenvío de acuerdo con la ruta del recurso y ejecución de la cadena de filtro.

② Tres conceptos básicos de Gateway

Ruta

Combine con eureka para enrutamiento dinámico

Componentes: un ID de enrutamiento, un URI de localizador de recursos único, un conjunto de aserciones, un conjunto de filtros

Si el predicado de la ruta es verdadero, la URL coincide con la ruta configurada

Predicado

devuelve una expresión booleana

Filtrar

Los filtros en Gateway se dividen en Gateway Filter (para una ruta) y Global Filter (global)

Las reglas de validación y el procesamiento de respuestas se pueden escribir en el filtro.

③ Diferencia entre Gateway y Nginx

Nginx necesita modificar el archivo de configuración nginx.conf para la limitación actual, el equilibrio de carga y el enrutamiento

La combinación de Gateway y eureka realiza un salto de enrutamiento automático y la recopilación de cintas realiza el equilibrio de carga. Gateway también puede implementar la limitación de corriente a través de la configuración

 

 

Uso de enrutamiento

① Flujo de acceso

② Servicio Loing

@RestController
public class LoginController {

    @GetMapping("doLogin")
    public String doLogin(String username,String password){
        System.out.println(username+" -> "+password);
        String token = UUID.randomUUID().toString();
        return token;
    }
}

② Servidor de puerta de enlace

dependencia de puerta de enlace

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

configurar el enrutamiento

server:
  port: 80
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      enabled: true # 默认开启Gateway
      routes: # 路由组
        - id: login-service-route # 路由ID 保证唯一
          uri: http://localhost:8080 # uri唯一资源定位符 url唯一资源标识符
          predicates: # 断言
            - Path=/doLogin # 和服务中的路径匹配

④ Enrutamiento programático

El enrutamiento y el reenvío se realizan codificando sin la ayuda de archivos de configuración

@Configuration
public class RouteConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("anime-id", r->r.path("/anime").uri("https://www.bilibili.com"))
                .route("variety-id",r->r.path("/variety").uri("https://www.bilibili.com"))
                .build();
    }
}

Si urila ruta de recursos detrás pathes la misma que la ruta de entrada, la puerta de enlace no pathempalmará la ruta de entrada con urila parte de atrás.

Los archivos programáticos y de configuración se pueden combinar

enrutamiento dinámico

Si la URL está codificada directamente durante el enrutamiento y el reenvío, de modo que la IP y el puerto también estén codificados, la puerta de enlace no podrá lograr el efecto de balanceo de carga. Solo debe proporcionar el nombre del servicio y luego usar este nombre para encontrar el servicio correspondiente, a fin de lograr el efecto de balanceo de carga.

Deje que el servicio Gateway también se registre en el centro de registro, luego el Gateway podrá tener toda la información del servicio

服务名为路径Gateway creará una ruta dinámica para cada reenvío de acuerdo con la lista de servicios en el centro de registro

① El primer método de implementación

Use el protocolo lb (Load Balance) para habilitar la función de balanceo de carga del Gateway

server:
  port: 80
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      enabled: true # 默认开启Gateway
      routes: # 路由组
        - id: login-service-route # 路由ID 保证唯一
          # uri: http://localhost:8080 # uri唯一资源定位符 url唯一资源标识符
          uri: lb://login-service # lb://服务名
          predicates:
            - Path=/doLogin # 和服务中的路径匹配

 Llame: http://localhost/doLogin

② El segundo método de implementación

Use el descubrimiento de servicios para crear automáticamente rutas dinámicas para lograr el equilibrio de carga

server:
  port: 80
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      enabled: true # 默认开启Gateway
      discovery:
        locator:
           enabled: true # 开启动态路由
           lower-case-service-id: true # 将注册列表中的服务名小写

Afirmación

Cuando se inicia el proyecto, Gateway cargará algunas fábricas de afirmaciones de enrutamiento, como: Después, Consulta

La aserción es para agregar algunos a la ruta.Si 匹配规则la solicitud enviada cumple con estos 规则, puede acceder a él, de lo contrario 404. En pocas palabras, estas reglas de coincidencia son algunas expresiones booleanas, verdaderas para ingresar o falsas para rechazar.

① clasificación

 

② uso

En el archivo de configuración, operar en una ruta. El enrutamiento dinámico no puede usar aserciones

spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      enabled: true # 默认开启Gateway
      routes:
        - id: login-service-route
          uri: lb://login-service
          predicates:
            - Path=/doLogin
            - Method=GET,POST # GET,POST请求能够访问
            - After=2022-11-02T17:23:16.423+08:00[Asia/Shanghai] # 在指定时间后才能访问 通过ZonedDateTime获取
            - Query=username,admin. # 必须给username传值 后面的值必须是:adminx

filtrar

El filtro en el Gateway es similar al filtro en el Servlet, y el usuario modifica la solicitud HTTP entrante y la respuesta HTTP

Dividido en GatewayFilter (para una determinada ruta) y GlobalFilter (filtrado global)

① Filtro global personalizado

Escriba la lógica empresarial en filtros personalizados, como la verificación de tokens y la limitación actual.

@Component
public class TestFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求对象
        ServerHttpRequest request = exchange.getRequest();
        RequestPath path = request.getPath();
        // 打印路由以及服务名
        System.out.println(path);
        HttpHeaders headers = request.getHeaders();
        // 获取主机IP
        String ip = headers.getHost().getHostName();
        System.out.println(ip);
        // 获取响应对象
        ServerHttpResponse response = exchange.getResponse();
        // 放过
        return chain.filter(exchange);
    }
}

 Definir orden de filtro

@Component
public class TestFilter implements Ordered {

    @Override
    public int getOrder() {
        // 数字越小 越往前
        return 0;
    }
}

Procesamiento de valor de retorno

// 获取响应对象
ServerHttpResponse response = exchange.getResponse();
// 设置响应头
response.getHeaders().set("content-Type","application/json;charset=UTF-8");
// 封装返回数据
Map<String,Object> map = new HashMap<>();
map.put("code", 401);
map.put("msg","没有该权限");
ObjectMapper objectMapper = new ObjectMapper();
try {
    // 将map集合转为byte数组
    byte[] bytes = objectMapper.writeValueAsBytes(map);
    // 将byte数组包装成一个数据缓冲包
    DataBuffer wrap = response.bufferFactory().wrap(bytes);
    // 返回
    return response.writeWith(Mono.just(wrap));
} catch (JsonProcessingException e) {
    e.printStackTrace();
}

limitando

Dentro de un cierto período de tiempo, limitar la frecuencia de acceso del usuario.

① Modelo de limitación de corriente

Algoritmo de embudo, algoritmo de pase de token, algoritmo de calculadora, algoritmo de deslizamiento de ventana

Llegar a fin de mes: los tokens no se pueden producir tan rápido como se pueden usar

  1. El sistema produce tokens a una tasa configurada de antemano.

  2. Establezca un umbral para el cubo de tokens. Cuando el cubo está lleno, los tokens sobrantes se descartan directamente

  3. Los clientes necesitan obtener tokens al enviar solicitudes

  4. Si no se obtiene el token, no se puede acceder a la solicitud con éxito

  5. Si obtiene el token, accederá al servicio y eliminará el token después de completar el procesamiento comercial.

  6. Cuando la cantidad de tokens en el depósito alcanza la cantidad mínima, se devuelven los tokens usados

② Limitación de corriente en Gateway

Gateway tiene RequestRateLimiterGatewayFilterFactory incorporado, combinado con Redis como algoritmo de depósito de tokens. Las dependencias de Redis deben importarse

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

 Configurar reglas de limitación de tráfico

@Configuration
public class RequestLimiterConfig {

    /*
      基于IP做限流
     */
    @Bean
    @Primary // 主候选
    public KeyResolver ipKeyResolver(){
        return exchange-> Mono.just(exchange.getRequest().getHeaders().getHost().getHostName());
    }

    /*
      基于API接口最限流
     */
    @Bean
    public KeyResolver apiKeyResolver(){
        return exchange -> Mono.just(exchange.getRequest().getPath().toString());
    }
}

Modificar el archivo de configuración

spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      enabled: true # 默认开启Gateway
      routes:
        - id: login-service-route
          uri: lb://login-service
          predicates:
            - Path=/doLogin
          filters:
            - name: RequestRateLimiter # 过滤器名称
              args:
                key-resolver: '#{@ipKeyResolver}' # Bean对象的名字
                redis-rate-limiter.replenishRate: 1 # 每秒钟生产多少令牌
                redis-rate-limiter.burstCapacity: 3 # 令牌桶中的容量

solo para una determinada ruta

configuración entre dominios

Cross-domain: CORSpolítica del mismo origen.

Debido a que la puerta de enlace es el borde del servicio, todas las solicitudes deben pasar por la puerta de enlace y la configuración entre dominios se escribe en la puerta de enlace.

programático

@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}

archivo de configuración

spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]': # 针对那些路径
            allowCredentials: true # 可以携带Cookie
            allowedHeaders: '*'
            allowedMethods: '*'
            allowedOrigins: '*'

preguntas de entrevista

¿Qué es una puerta de enlace de microservicios?

Spring Cloud Gateway es una puerta de enlace desarrollada por Spring basada en tecnologías como Spring 5.x, Spring Boot 2.0 y Project Reactor. Spring Cloud Gateway tiene como objetivo proporcionar un método de gestión de enrutamiento API unificado simple y eficaz para la arquitectura de microservicios. Como puerta de enlace en el ecosistema de Spring Cloud , Spring Cloud Gateway  pretende reemplazar  a Netflix Zuul No solo proporciona un método de enrutamiento unificado, sino que también proporciona funciones básicas de la puerta de enlace basadas en la cadena de filtros, tales como: seguridad, monitoreo/indicadores y elasticidad.

 

Ventajas de usar Gateway

Spring Cloud Gateway se puede considerar como una versión mejorada y un reemplazo de Zuul 1.x Utiliza Netty para implementar IO asíncrono antes que Zuul 2, logrando así un sistema simple, más eficiente que Zuul 1.x y cercano a Spring Cloud. Puerta de enlace API.
Spring Cloud Gateway distingue claramente entre enrutador y filtro, y una gran característica es que tiene muchas funciones integradas listas para usar, y todas ellas se pueden usar a través de la configuración de SpringBoot o llamadas en cadena de codificación manual .
Por ejemplo, hay 10 enrutadores incorporados, por lo que podemos configurarlos directamente y hacer el enrutamiento de acuerdo con el encabezado, la ruta, el host o la consulta que deseemos.
Por ejemplo, se distinguen el filtro general y el filtro global, se integran 20 tipos de filtros y 9 tipos de filtros globales, y todos ellos se pueden usar directamente. Por supuesto, el filtro personalizado también es muy conveniente.

Comparación entre zuul y spring cloud gateway

  • zuul: Pertenece a Netflix y está implementado en base a servlet, es una API de bloqueo y no soporta conexiones largas.
  • puerta de enlace: es una puerta de enlace de microservicio desarrollada por la propia springcloud. Está construido en base a Spring5 y puede implementar API receptivas sin bloqueo y admitir conexiones largas.

La composición de la puerta de enlace.

  • Enrutamiento: el módulo básico de la puerta de enlace, que consta de ID, URI de destino, un conjunto de aserciones y un conjunto de filtros
  • Aserción: es la regla de acceso para acceder al recorrido, que se puede usar para hacer coincidir cualquier contenido de la solicitud http, como encabezados o parámetros.
  • Filtro: esto es lo que solemos llamar un filtro. Se utiliza para filtrar algunas solicitudes. La puerta de enlace tiene su propio filtro predeterminado. Para obtener más información, consulte el sitio web oficial. También podemos personalizar el filtro, pero necesitamos implementar dos interfaces, ordenado y filtro global

Supongo que te gusta

Origin blog.csdn.net/weixin_45934981/article/details/130151588
Recomendado
Clasificación