SpringCloud Microservice Xiaobaiは(Hoxton.SR8)(7)ゲートウェイ|サービスゲートウェイも利用できます

開始して直接コピーするだけで、マイクロサービスを構築できます(Hoxton.SR8)2020.8.28がリリースされ、SpringCloudによって構築された記事が整理されています。乾物をお見逃しなく

概要

Spring Cloud Gatewayは、強力なインテリジェントルーティングおよびフィルター機能を備えたSpringBootアプリケーションのAPIゲートウェイサポートを提供します。Gatewayは、Spring 5、Spring Boot 2、ProjectReactorなどのテクノロジーに基づいてSpringエコシステム上に構築されたAPIゲートウェイサービスです。Gatewayは、APIをルーティングするためのシンプルで効果的な方法を提供し、ヒューズ、電流制限、再試行などの強力なフィルター機能を提供することを目的としています。

Spring CloudGatewayには次の機能があります。

  • Spring Framework 5、Project Reactor、Spring Boot2.0に基づいています。
  • 動的ルーティング:任意の要求属性に一致できます。
  • 述語(アサーション)とフィルター(フィルター)をルーティングに指定できます。
  • Hystrixの統合回路ブレーカー機能。
  • SpringCloudサービス検出機能を統合します。
  • 述語(アサーション)とフィルター(フィルター)を簡単に記述できます。
  • 電流制限機能を要求します。
  • パスの書き換えをサポートします。

構成構成

  • ルート:ルーティングは、ゲートウェイを構築するための基本モジュールであり、ID、ターゲットURI、一連のアサーション、およびフィルターで構成されます。アサーションがtrueの場合、ルートが一致します。
  • 述語(アサーション):Java8の関数述語を参照します。入力タイプは、SpringフレームワークのServerWebExchangeです。これにより、開発者は、リクエストヘッダーやリクエストパラメータなど、HTTPリクエストのすべてのコンテンツを照合できます。リクエストがアサーションと一致する場合、ルーティングされます。
  • フィルタ(フィルタ):SpringフレームワークのGatewayFilterのインスタンスを参照します。フィルタを使用すると、リクエストがルーティングされる前後にリクエストを変更できます。

1.api-gatewayモジュールを作成します

 

  

2ゲートウェイのみを使用する

2.1pom.xmlの新しいゲートウェイ依存関係

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud-hoxton-sr8</artifactId>
        <groupId>com.zqh.www</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>api-gateway</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2.2起動

package com.zqh.www;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.Environment;

@SpringBootApplication
public class ApiGatewayApplication {

    private final static Logger logger = LoggerFactory.getLogger(ApiGatewayApplication.class);

    public static void main(String[] args) {
        Environment env = SpringApplication.run(ApiGatewayApplication.class, args).getEnvironment();
        logger.info(
                "\n----------------------------------------------------------\n\t"
                        + "Application '{}' is running! Access URLs:\n\t"
                        + "Local: \t\thttp://localhost:{}{}"
                        + "\n----------------------------------------------------------",
                env.getProperty("spring.application.name"), env.getProperty("server.port"),
                env.getProperty("server.servlet.context-path") != null ? env.getProperty("server.servlet.context-path") : "");
    }
}

2.3 ed

server:
  port: 8093

service-url:
  user-service: http://localhost:8084

spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # 路由的ID
        - id: user-service
          # 匹配后路由地址
          uri: ${service-url.user-service}
          predicates:
            # 发送指定路径的请求会匹配该路由。
            - Path=/api/user/*
#            # 发送指定方法的请求会匹配该路由。
#            - Method=GET
#            # 在指定时间之后的请求会匹配该路由。
#            - After=2020-10-20T12:00:00+08:00[Asia/Shanghai]
#            # 在指定时间之前的请求会匹配该路由。
#            - Before=2020-10-20T12:00:00+08:00[Asia/Shanghai]
#            # 在指定时间区间内的请求会匹配该路由。
#            - Between=2020-10-20T12:00:00+08:00[Asia/Shanghai], 2020-10-30T12:00:00+08:00[Asia/Shanghai]
#            # 带有指定Cookie的请求会匹配该路由
#            - Cookie=username,jourwon
#            # 带有指定请求头的请求会匹配该路由。
#            - Header=auth
#            #带有指定Host的请求会匹配该路由。
#            - Host=www.zqh.com
#            # 从指定远程地址发起的请求可以匹配该路由。
#            - RemoteAddr=192.168.1.1/24
          filters:
#            - AddRequestParameter=username,z
#            - StripPrefix=1
#            - PrefixPath=/api

logging:
  level:
    org.springframework.cloud.gateway: debug

2.4述語-テストケース

注:複数の条件がある場合、関連するルートに一致するようにすべての条件が満たされている必要があります

2.4.1述語-パス

説明:パスに一致するか、ルートに一致するリクエストを送信します。
yml構成:-Path = / api / user / *
インターフェイス要求:http:// localhost:8093 / api / user / getUserListは次と
同等です:http:// localhost:8084 / api / user / getUserList

2.4.2述語-方法

説明:指定されたメソッドのリクエストを送信すると、ルートが一致します。
インターフェイスリクエスト:http:// localhost:8093 / api / user / getUserList

  

2.4.3述語-後

説明:指定された時間以降のリクエストはルートと一致します。
インターフェイスリクエスト:http:// localhost:8093 / api / user / getUserList

  

2.4.4述語-前

説明:指定された時間より前のリクエストはルートと一致します。

2.4.5述語-間

説明:指定された時間間隔内のリクエストは、このルートに一致します。

2.4.6述語-Cookie

説明:指定されたCookieを持つリクエストはルートと一致します。
構成:

predicates:
    # 带有指定Cookie的请求会匹配该路由
    - Cookie=username,z

インターフェイスリクエスト:

2.4.7述語-ヘッダー

説明:指定されたリクエストヘッダーを持つリクエストはルートと一致します。
設定:

predicates:
    # 带有指定请求头的请求会匹配该路由。
    - Header=auth

インターフェイスリクエスト:
 

2.4.8述語-ホスト

説明:指定されたホストのリクエストはルートと一致します。
設定:

predicates:
    #带有指定Host的请求会匹配该路由。
    - Host=www.zqh.com

2.4.9述語-RemoteAddr

説明:指定されたパスからのリクエストはルートと一致します。
設定:

predicates:
    #从指定远程地址发起的请求可以匹配该路由。
    - RemoteAddr=192.168.0.100

2.5フィルター-テストケース

2.5.1フィルター-AddRequestParameter

説明:リクエストパラメータをGETリクエストに追加します
設定:

service-url:
  user-service: http://localhost:8084
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # 路由的ID
        - id: user-service
          # 匹配后路由地址
          uri: ${service-url.user-service}
          predicates:
            # 发送指定路径的请求会匹配该路由。
            - Path=/api/user/*
          filters:
            - AddRequestParameter=username,z

リクエスト:http:// localhost:8093 / api / user / getUserListは次と
同等です:http:// localhost:8084 / api / user / getUserList?username = z

2.5.2フィルター-StripPrefix

説明:最初のリクエストのパスは、指定されたビット数を削除します。
構成:

service-url:
  user-service: http://localhost:8084
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # 路由的ID
        - id: user-service
          # 匹配后路由地址
          uri: ${service-url.user-service}
          predicates:
            # 发送指定路径的请求会匹配该路由。
            - Path=/api/user/*
          filters:
            - StripPrefix=1

リクエスト:http:// localhost:8093 / api / user / getUserListは次と
同等です:http:// localhost:8084 / user / getUserList

2.5.3フィルター-PrefixPath

説明:指定されたパスプレフィックスをすべてのGETリクエストに追加します
構成:

service-url:
  user-service: http://localhost:8084
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # 路由的ID
        - id: user-service
          # 匹配后路由地址
          uri: ${service-url.user-service}
          predicates:
            # 发送指定路径的请求会匹配该路由。
            - Path=/user/*
          filters:
            - PrefixPath=/api

リクエスト:http:// localhost:8093 / user / getUserListは次と
同等です:http:// localhost:8084 / api / user / getUserList

2.5.3フィルター-hystrix

説明:Hystrixフィルターを使用すると、ゲートウェイルーティングに回路ブレーカー機能を追加して、サービスをカスケード障害から保護し、サービス劣化処理を提供できます。
pom.xml:

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

 fr:

service-url:
  user-service: http://localhost:8084
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # 路由的ID
        - id: user-service
          # 匹配后路由地址
          uri: ${service-url.user-service}
          predicates:
            # 发送指定路径的请求会匹配该路由。
            - Path=/api/user/*
          filters:
            - name: Hystrix
              args:
                name: fallbackcmd
                #转发路径
                fallback-uri: forward:/fallback

コントローラ:

package com.zqh.www.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class FallbackController {

    @GetMapping("/fallback")
    public Object fallback() {
        Map<String, Object> result = new HashMap<>();
        result.put("data", null);
        result.put("message", "Get request fallback!");
        result.put("code", 500);
        return result;
    }
}

 テスト:
通常の状況:サービスの例外:(サービスの切断をシミュレートするためにユーザーサービスサービスを閉じます)

     

2.5.3フィルター-RequestRateLimiter

説明:RequestRateLimiterフィルターは、現在の制限に使用できます。RateLimiterの実装は、現在の要求の続行を許可するかどうかを決定するために使用されます。要求が大きすぎる場合、デフォルトでHTTP429ステータスが返されます。
pom.xml:

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

fr:

service-url:
  user-service: http://localhost:8084

spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # 路由的ID
        - id: user-service
          # 匹配后路由地址
          uri: ${service-url.user-service}
          predicates:
            # 发送指定路径的请求会匹配该路由。
            - Path=/api/user/*
          filters:
            - name: RequestRateLimiter
              args:
                # 每秒允许处理的请求数量
                redis-rate-limiter.replenishRate: 1
                # 每秒最大处理的请求数量
                redis-rate-limiter.burstCapacity: 2
                # 限流策略,对应策略的Bean
                key-resolver: "#{@ipKeyResolver}"

設定:

package com.zqh.www.config;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

import java.util.Objects;

@Configuration
public class RedisRateLimiterConfig {

    // 如果你是采用第二个的策略,那么第一个策略的@Bean记得要注释掉,否则他会报找到2个参数
    //    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getQueryParams().getFirst("username")));
    }

    @Bean
    public KeyResolver ipKeyResolver() {
        return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getHostName());
    }
}

テスト:
正常な状況:異常な状況:迅速な要求の場合は429を返します
  

2.5.4フィルター-再試行

説明:ルーティング要求を再試行するためのフィルターは、ルーティング要求によって返されたHTTPステータスコードに基づいて再試行するかどうかを決定できます。

yml:

service-url:
  user-service: http://localhost:8084
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        # 路由的ID
        - id: user-service
          # 匹配后路由地址
          uri: ${service-url.user-service}
          predicates:
            # 发送指定路径的请求会匹配该路由。
            - Path=/api/user/*
          filters:
            - name: Retry
              args:
                #需要进行重试的次数
                retries: 1
                #返回哪个状态码需要进行重试,返回状态码为5XX进行重试
                statuses: BAD_GATEWAY 
                backoff:
                  firstBackoff: 10ms
                  maxBackoff: 50ms
                  factor: 2
                  basedOnPreviousValue: false

テスト:
通常:例外:(サービスプロバイダーにnullポインターを追加)、2つのエラーが出力されます。これは、1回の再試行を意味します。
   

3.マイクロサービスはゲートウェイを使用します

3.1pom.xmの依存関係

<dependencies>
        <!-- 配合注册中心使用 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
    </dependencies>

3.2起動

package com.zqh.www;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.core.env.Environment;

/**
 * 开启服务发现客户端
 *
 * @EnableEurekaClient只适用于Eureka作为注册中心,@EnableDiscoveryClient 可以是其他注册中心。
 */
// 如果你是启动的是alone的配置,请注释@EnableDiscoveryClient,并且注释 pom.xml 里面的 eureka-client 依赖,不然会出现链接错误
@EnableDiscoveryClient
@SpringBootApplication
public class ApiGatewayApplication {

    private final static Logger logger = LoggerFactory.getLogger(ApiGatewayApplication.class);

    public static void main(String[] args) {
        Environment env = SpringApplication.run(ApiGatewayApplication.class, args).getEnvironment();
        logger.info(
                "\n----------------------------------------------------------\n\t"
                        + "Application '{}' is running! Access URLs:\n\t"
                        + "Local: \t\thttp://localhost:{}{}"
                        + "\n----------------------------------------------------------",
                env.getProperty("spring.application.name"), env.getProperty("server.port"),
                env.getProperty("server.servlet.context-path") != null ? env.getProperty("server.servlet.context-path") : "");
    }
}

3.3マージン

server:
  port: 8093

eureka:
  client:
    service-url:
      #注册地址
      defaultZone: http://root:root@localhost:8081/eureka/
  #显示服务器IP加端口
  instance:
    hostname: localhost
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${server.port}

spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      discovery:
        locator:
          #开启从注册中心动态创建路由的功能
          enabled: true
          #使用小写服务名
          lower-case-service-id: true
      routes:
        # 路由的ID
        - id: user-service
          # 在结合注册中心使用过滤器的时候,uri的协议为lb,这样才能启用Gateway的负载均衡功能。
          uri: lb://user-service
          predicates:
            # 发送指定路径的请求会匹配该路由。
            - Path=/api/user/*
#            # 发送指定方法的请求会匹配该路由。
#            - Method=GET
#            # 在指定时间之后的请求会匹配该路由。
#            - After=2020-10-20T18:00:00+08:00[Asia/Shanghai]
#            # 在指定时间之前的请求会匹配该路由。
#            - Before=2020-10-20T12:00:00+08:00[Asia/Shanghai]
#            # 在指定时间区间内的请求会匹配该路由。
#            - Between=2020-10-20T12:00:00+08:00[Asia/Shanghai], 2020-10-30T12:00:00+08:00[Asia/Shanghai]
#            # 带有指定Cookie的请求会匹配该路由
#            - Cookie=username,z
#            # 带有指定请求头的请求会匹配该路由。
#            - Header=auth
#            #带有指定Host的请求会匹配该路由。
#            - Host=www.zqh.com
#            # 从指定远程地址发起的请求可以匹配该路由。
#            - RemoteAddr=192.168.1.1/24
          filters:
            - name: Retry
              args:
                #需要进行重试的次数
                retries: 3
                #返回哪个状态码需要进行重试,返回状态码为5XX进行重试
                statuses: BAD_GATEWAY
                backoff:
                  firstBackoff: 10ms
                  maxBackoff: 50ms
                  factor: 2
                  basedOnPreviousValue: false
#            - name: RequestRateLimiter
#              args:
#                # 每秒允许处理的请求数量
#                redis-rate-limiter.replenishRate: 1
#                # 每秒最大处理的请求数量
#                redis-rate-limiter.burstCapacity: 2
#                # 限流策略,对应策略的Bean
#                key-resolver: "#{@ipKeyResolver}"
#            - name: Hystrix
#              args:
#                name: fallbackcmd
#                #转发路径
#                fallback-uri: forward:/fallback
#            - AddRequestParameter=username,z
#            - StripPrefix=1
#            - PrefixPath=/api

logging:
  level:
    org.springframework.cloud.gateway: debug

3.4テスト

4.giteeアドレス

ソースリファレンス

おすすめ

転載: blog.csdn.net/itjavaee/article/details/109119266