Spring Cloud의 게이트웨이 구성 요소 소개

게이트웨이 이해

게이트웨이는 海关또는 大门, 와 유사합니다 出入都需要经过这个网关. 다른 사람들은 이 관문을 통과하지 않고는 내부에 무엇이 있는지 결코 볼 수 없습니다. 게이트웨이에서 수행할 수 있습니다 条件过滤. 예를 들어 해당 키만 게이트에 들어갈 수 있습니다. 게이트웨이는 게이트와 마찬가지로 항상 외부에 노출되어 있습니다.

게이트웨이 없음

  • 프런트 엔드는 각 서비스의 IP와 포트를 기억해야 합니다.

  • 서비스의 배포가 여러 개인 경우 프런트 엔드에서 자체적으로 할당해야 합니다.

게이트웨이 사용

  • 프런트 엔드는 각 서비스의 IP와 포트를 기억할 필요가 없으며 게이트웨이에 요청을 보내기만 하면 되며 게이트웨이는 리소스 경로에 따라 이를 수행합니다.路由跳转

  • 게이트웨이는 安全控制토큰 확인, 전류 제한 등과 같은 작업을 수행할 수 있습니다.

  • 할수있다负载均衡

게이트웨이의 이해

Zuul을 대체하기 위해 Spring 공식 웹 사이트에서 출시한 일련의 게이트웨이 구성 요소입니다.

하도록 설계되었지만 路由跳转更加方便、灵活강력한 기능을 제공합니다 过滤器功能. 예: IP 블랙리스트, 토큰 확인 등

webFlux 프레임워크를 기반으로 webFlux 프레임워크의 최하위 계층은 고성능 Reactor 모드 통신 프레임워크인 Netty를 사용합니다.


Gateway는 Spring 5, Spring Boot 2 및 Project Reactor와 같은 기술을 기반으로 Spring 생태계 위에 구축된 API 게이트웨이 서비스입니다.

게이트웨이는 API를 라우팅하는 간단하고 효과적인 방법을 제공하고 회로 차단, 전류 제한, 재시도 등과 같은 몇 가지 강력한 필터 기능을 제공하는 것을 목표로 합니다.

① 게이트웨이 작동 원리

클라이언트가 Gateway에 요청을 보낸 다음 Gateway HandlerMapping이 매핑을 비교하여 일치하는 경로를 찾아 Gateway WebHandler로 보냅니다. Handler는 요청을 지정된 필터를 통해 실제 비즈니스 로직에 배포하고 반환합니다.

필터에 코드를 추가할 수 있습니다.

  • 请求之前[pre] 에서 유효성 검사 등을 수행합니다.

  • 请求之后[포스트] 에서 로그 출력 등을 수행

게이트웨이 핵심 논리: 리소스 경로에 따라 라우팅 및 포워딩을 수행하고 필터 체인을 실행합니다.

② Gateway의 세 가지 핵심 개념

노선

동적 라우팅을 위해 eureka와 결합

구성 요소: 라우팅 ID, 고유한 리소스 로케이터 URI, 어설션 집합, 필터 집합

경로 조건자가 true이면 URL이 구성된 경로와 일치합니다.

단언(Predicate)

부울 표현식을 반환합니다.

필터

게이트웨이의 필터는 게이트웨이 필터 (경로용)와 글로벌 필터 (글로벌) 로 나뉩니다.

유효성 검사 규칙 및 응답 처리를 필터에 작성할 수 있습니다.

③ 게이트웨이와 Nginx의 차이점

Nginx는 현재 제한, 부하 분산 및 라우팅을 위해 nginx.conf 구성 파일을 수정해야 합니다.

Gateway와 eureka의 조합은 자동 라우팅 점프를 구현하고 Ribbon 컬렉션은 로드 밸런싱을 구현합니다. 게이트웨이는 구성을 통해 전류 제한을 구현할 수도 있습니다.

 

 

라우팅 사용

① 액세스 흐름

② 로잉서비스

@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;
    }
}

② 게이트웨이 서버

게이트웨이 종속성

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

라우팅 구성

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 # 和服务中的路径匹配

④ 프로그래밍 방식의 라우팅

라우팅 및 포워딩은 구성 파일의 도움 없이 인코딩하여 실현됩니다.

@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();
    }
}

uri뒤의 리소스 경로가 들어오는 경로 path와 동일한 경우 게이트웨이는 path경로를 uri뒤쪽으로 연결하지 않습니다.

프로그래밍 및 구성 파일을 결합할 수 있습니다.

동적 라우팅

라우팅 및 포워딩 중에 URL이 직접 하드 코딩되어 IP 및 포트도 하드 코딩되면 게이트웨이는 로드 밸런싱 효과를 얻을 수 없습니다. 서비스 이름만 제공한 다음 이 이름을 사용하여 해당 서비스를 찾아 로드 밸런싱 효과를 달성해야 합니다.

게이트웨이 서비스도 등록 센터에 등록하면 게이트웨이가 모든 서비스 정보를 가질 수 있습니다.

게이트웨이는 등록 센터의 서비스 목록에 따라 각 전달에 대한 服务名为路径동적 경로를 생성합니다.

① 제1차 시행방법

lb(Load Balance) 프로토콜을 사용하여 게이트웨이의 로드 밸런싱 기능을 활성화합니다.

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 # 和服务中的路径匹配

 호출: http://localhost/doLogin

② 두 번째 시행방법

서비스 검색을 사용하여 동적 경로를 자동으로 생성하여 로드 밸런싱 달성

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

단언

프로젝트가 시작되면 Gateway는 다음과 같은 일부 라우팅 어설션 팩토리를 로드합니다. After, Query

어설션은 경로에 일부를 추가하는 것입니다 匹配规则. 전송된 요청이 이러한 조건을 충족하면 规则액세스할 수 있습니다. 그렇지 않으면 404입니다. 간단히 말해서 이러한 일치 규칙은 일부 부울 표현식으로, 입력하려면 true, 거부하려면 false입니다.

① 분류

 

② 사용

구성 파일에서 경로에서 작동합니다. 동적 라우팅은 어설션을 사용할 수 없습니다.

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

필터

게이트웨이의 필터는 서블릿의 필터와 유사하며 사용자는 들어오는 HTTP 요청 및 HTTP 응답을 수정합니다.

GatewayFilter(특정 경로용)와 GlobalFilter(글로벌 필터링)로 구분

① 맞춤형 글로벌 필터

토큰 확인 및 전류 제한과 같은 사용자 지정 필터에 비즈니스 로직을 작성합니다.

@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);
    }
}

 필터 순서 정의

@Component
public class TestFilter implements Ordered {

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

반환 값 처리

// 获取响应对象
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();
}

제한

일정 시간 동안 이용자의 접근 빈도를 제한합니다.

① 전류 제한 모델

퍼널 알고리즘, 토큰 패스 알고리즘, 계산기 알고리즘, 윈도우 슬라이딩 알고리즘

생계 유지: 토큰은 사용할 수 있는 만큼 빨리 생산할 수 없습니다.

  1. 시스템은 미리 구성된 비율로 토큰을 생성합니다.

  2. 토큰 버킷의 임계값을 설정합니다. 버킷이 가득 차면 초과 토큰은 바로 폐기됩니다.

  3. 클라이언트는 요청을 보낼 때 토큰을 받아야 합니다.

  4. 토큰을 얻지 못하면 요청에 성공적으로 액세스할 수 없습니다.

  5. 토큰을 얻으면 서비스에 접속하여 업무 처리 완료 후 토큰을 삭제합니다.

  6. 버킷의 토큰 수가 최소 수량에 도달하면 사용된 토큰이 반환됩니다.

② Gateway에서의 전류 제한

게이트웨이에는 토큰 버킷 알고리즘으로 Redis와 결합된 RequestRateLimiterGatewayFilterFactory가 내장되어 있습니다. Redis 종속성을 가져와야 합니다.

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

 트래픽 제한 규칙 구성

@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());
    }
}

구성 파일 수정

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 # 令牌桶中的容量

특정 노선에 대해서만

교차 도메인 구성

교차 도메인: CORS동일 출처 정책.

게이트웨이는 서비스의 에지이므로 모든 요청은 게이트웨이를 통과해야 하며 교차 도메인 구성은 게이트웨이에 기록됩니다.

프로그래매틱

@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);
    }
}

구성 파일

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

인터뷰 질문들

마이크로서비스 게이트웨이란?

Spring Cloud Gateway는 Spring 5.x, Spring Boot 2.0 및 Project Reactor와 같은 기술을 기반으로 Spring에서 개발한 게이트웨이로, Spring Cloud Gateway는 마이크로 서비스 아키텍처를 위한 간단하고 효과적인 통합 API 라우팅 관리 방법을 제공하는 것을 목표로 합니다. Spring Cloud 생태계 의 게이트웨이로서 Spring Cloud Gateway는  Netflix Zuul을 대체하는 것을 목표로 하며  통일된 라우팅 방법을 제공할 뿐만 아니라 Filter 체인을 기반으로 게이트웨이의 기본 기능인 보안, 모니터링/지표 및 탄력.

 

게이트웨이 사용의 이점

Spring Cloud Gateway는 Zuul 1.x의 업그레이드 버전 및 대체품으로 볼 수 있으며 Netty를 사용하여 Zuul 2 이전의 비동기 IO를 구현하여 Zuul 1.x보다 간단하고 효율적이며 Spring Cloud에 가깝습니다. API 게이트웨이. Spring Cloud Gateway는 Router와 Filter 를 명확하게 구분하며, 즉시 사용 가능한 기능이 많이 내장되어 있고 모두 SpringBoot 구성 또는 수동 코딩 체인 호출을 통해 사용할 수 있다는 것이 큰
특징입니다 . 예를 들어 10개의 내장 라우터가 있으므로 직접 구성하고 헤더, 경로, 호스트 또는 쿼리에 따라 라우팅을 할 수 있습니다. 예를 들어 일반 Filter와 Global Filter를 구분하여 20종의 Filter와 9종의 Global Filter를 내장하여 모두 직접 사용할 수 있습니다. 물론 커스텀 필터도 매우 편리합니다.

zuul 과 스프링 클라우드 게이트웨이 의 비교

  • zuul: Netflix에 속하며 servlet 기반으로 구현되며 차단 API이며 긴 연결을 지원하지 않습니다.
  • gateway: springcloud에서 자체적으로 개발한 마이크로 서비스 게이트웨이로, Spring5 기반으로 구축되어 응답성이 뛰어난 non-blocking API를 구현하고 긴 연결을 지원할 수 있습니다.

게이트웨이의 구성

  • 라우팅: ID, 대상 URI, 어설션 세트 및 필터 세트로 구성된 게이트웨이의 기본 모듈
  • 어설션: 둘러보기에 액세스하기 위한 액세스 규칙이며 헤더 또는 매개변수와 같은 http 요청의 모든 콘텐츠를 일치시키는 데 사용할 수 있습니다.
  • 필터: 이것은 일반적으로 필터라고 합니다. 일부 요청을 필터링하는 데 사용됩니다. 게이트웨이에는 자체 기본 필터가 있습니다. 자세한 내용은 공식 웹 사이트를 참조하십시오. 필터를 사용자 정의할 수도 있지만 두 가지를 구현해야 합니다. 인터페이스, 주문 및 전역 필터

추천

출처blog.csdn.net/weixin_45934981/article/details/130151588