Spring Cloud Gateway

目录

一、 Spring Cloud Gateway 简介

1 概述

2 核心概念

2.1 API 网关

2.2 路由

2.3 过滤器

二、 使用 Spring Cloud Gateway 实现路由功能

1 入门案例

1.1 创建 Gateway 项目

1.1.1 POM 文件

 1.1.2 配置文件

1.1.3 启动类  

2 配置文件手工绑定路由规则 

2.1 POM 文件

2.2 配置文件

2.3 启动类

三、 使用 Spring Cloud Gateway 实现过滤器功能

1 Spring Cloud Gateway 内置过滤器

2 自定义过滤器 

2.1 自定义 GatewayFilter - 网关过滤器

 2.2 自定义 GlobalFilter - 全局过滤器

 四、 使用 Spring Cloud Gateway 实现熔断功能

1 POM 依赖

2 熔断处理代码 

3 配置文件

​ 

4 启动类  


一、 Spring Cloud Gateway 简介

1 概述

Spring cloud gateway spring 官方基于 Spring 5.0 Spring Boot2.0 Project Reactor
等技术开发的网关, Spring Cloud Gateway 旨在为微服务架构提供简单、有效和统一的 API
路由管理方式, Spring Cloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代
Netflix Zuul ,其不仅提供统一的路由方式,并且还基于 Filer 链的方式提供了网关基本的
功能,例如:安全、监控 / 埋点、限流等。

2 核心概念

2.1 API 网关

API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,
而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与
各个微服务通信,会有以下的问题:
客户端会多次请求不同的微服务,增加了客户端的复杂性。
存在跨域请求,在一定场景下处理相对复杂。
认证复杂,每个服务都需要独立认证。
难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并
成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很难实
施。
某些微服务可能使用了防火墙 / 浏览器不友好的协议,直接访问会有一定的困难。
以上这些问题可以借助 API 网关解决。 API 网关是介于客户端和服务器端之间的中
间层,所有的外部请求都会先经过 API 网关这一层。也就是说, API 的实现方面更多的
考虑业务逻辑,而安全、性能、监控可以交由 API 网关来做,这样既提高业务灵活性又
不缺安全性。
使用 API 网关后示意图:
使用 API 网关后的优点如下:
易于监控。可以在网关收集监控数据并将其推送到外部系统进行分析。
易于认证。可以在网关上进行认证,然后再将请求转发到后端的微服务,而无须在每
个微服务中进行认证。
统一接入。减少了客户端与各个微服务之间的交互次数。

2.2 路由

路由是网关最基础的部分,路由信息有一个 ID 、一个目的 URL 、一组断言和一组 Filter
组成。如果断言路由为真,则说明请求的 URL 和配置匹配。

2.3 过滤器

一个标准的 Spring webFilter Spring cloud gateway 中的 filter 分为两种类型的 Filter
分别是 Gateway Filter Global Filter 。过滤器 Filter 将会对请求和响应进行修改处理。执 行示意图如下:
如上图所示, Spring cloudGateway 发出请求。然后再由 Gateway Handler Mapping
找到与请求相匹配的路由,将其发送到 Gateway web handler Handler 再通过指定的过滤
器链将请求发送到我们实际的服务执行业务逻辑,然后返回。

二、 使用 Spring Cloud Gateway 实现路由功能

1 入门案例

1.1 创建 Gateway 项目

1.1.1 pom文件

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.11.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.star</groupId>
    <artifactId>springcloud-06-gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springcloud-06-gateway</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR4</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>


    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

 1.1.2 配置文件

#设置端口号
server:
  port: 8081
#设置应用名称
spring:
  application:
    name: cloud-gateway

  cloud:
    gateway:
      discovery:
        locator:
          enabled: false #关闭Gateway服务注册和发现的功能
          lower-case-service-id: true #将请求路径上的服务名配置为小写
      #手工绑定路由规则
      routes:
        - id: service01 #唯一命名
          uri: lb://service01  # 转发路径,lb 代表 loadbalance,即从 Eureka 中获取的服务列表负载均衡器。
                               #openfeign-client 即服务名称,相当于openfeign-client 即服务名称,相当于 http://localhost:8081/
          predicates:  # 定义映射
            - Path=/aaa/**  # 发送到 Gateway 网关上的请求路径映射,此映射匹 配的路径都会转发到 uri 上。
                            #具体地址为: lb://openfeign-client/client/**
          filters:
            - StripPrefix=1 # 请求转发时,会自动过滤请求转发的第一节地址,即 client。最终地址为: lb://openfeign-client/**
            - AddRequestParameter=age,30
            - AddRequestParameter=name,TeacherWu
            - AddRequestParameter=token,123
            - AddRequestHeader=myHeader,myHeaderValue
            - Authentication=token
            - name: Hystrix  #开器Hystrix过滤器
              args:
                 name: fallbackcmd
                 fallbackUri: forward:/fallback  #设置Hystrix回调方法的请求路径

        - id: service02
          uri: lb://service02
          predicates:
            - Path=/bbb/**
          filters:
            - StripPrefix=1
#设置注册中心连接信息
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8080/eureka
#hystrix服务降级
hystrix:
  command:
    default:
      execution:
        timeout:
          # 如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为容错根据
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 1000 # 超时时间,默认1000ms

1.1.3 启动类  

@SpringBootApplication
@EnableCircuitBreaker
public class Springcloud06GatewayApplication {

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

}

2 配置文件手工绑定路由规则 

2.1 POM 文件

不需要修改

2.2 配置文件

通过routes绑定

#设置端口号
server:
  port: 8081
#设置应用名称
spring:
  application:
    name: cloud-gateway

  cloud:
    gateway:
      discovery:
        locator:
          enabled: false #关闭Gateway服务注册和发现的功能
          lower-case-service-id: true #将请求路径上的服务名配置为小写
      #手工绑定路由规则
      routes:
        - id: service01 #唯一命名
          uri: lb://service01  # 转发路径,lb 代表 loadbalance,即从 Eureka 中获取的服务列表负载均衡器。
                               #openfeign-client 即服务名称,相当于openfeign-client 即服务名称,相当于 http://localhost:8081/
          predicates:  # 定义映射
            - Path=/aaa/**  # 发送到 Gateway 网关上的请求路径映射,此映射匹 配的路径都会转发到 uri 上。
                            #具体地址为: lb://openfeign-client/client/**
          filters:
            - StripPrefix=1 # 请求转发时,会自动过滤请求转发的第一节地址,即 client。最终地址为: lb://openfeign-client/**
            - AddRequestParameter=age,30 # 在请求中自动增加一个请求参数,参数名为 age,参数值为 30。可以用于提供固定参数。
            - AddRequestParameter=name,TeacherWu # 每个 AddRequestParameter 过滤器,只能提供一个请求参数,提供多请求参数,需要定义多个过滤器
            - AddRequestParameter=token,123
            - AddRequestHeader=myHeader,myHeaderValue e # 在请求中自动增加 一个请求头参数,参数名为 my-header,参数值为 test-header-value。
            - Authentication=token

            - name: Hystrix  #开器Hystrix过滤器
              args:
                 name: fallbackcmd
                 fallbackUri: forward:/fallback  #设置Hystrix回调方法的请求路径

        - id: service02
          uri: lb://service02
          predicates:
            - Path=/bbb/**
          filters:
            - StripPrefix=1
#设置注册中心连接信息
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8080/eureka
#hystrix服务降级
hystrix:
  command:
    default:
      execution:
        timeout:
          # 如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为容错根据
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 1000 # 超时时间,默认1000ms

2.3 启动类

不需要修改 

三、 使用 Spring Cloud Gateway 实现过滤器功能

Spring Cloud gateway filter 分为两种: GatewayFilter Globalfilter GlobalFilter
应用到所有的路由上,而 Gatewayfilter 将应用到单个路由或者一个分组的路由上。
多个过滤器会根据配置文件中的定义来决定执行顺序。
如果提供的自定义过滤器实现了 Ordered 接口,则可以通过接口中的方法 getOrder
决定执行顺序。具体顺序由 getOrder 方法返回结果升序排列。

1 Spring Cloud Gateway 内置过滤器

GatewayFilter 是一个接口,通过查看源码,其有很多实现类,不同的实现类实现不同
的过滤功能。具体如下:
常用过滤器有:
AddRequestParameterGatewayFilterFactory - 在指定请求中增加请求参数的过滤器。
AddRequestHeaderGatewayFilterFactory - 在指定请求中增加请求头参数的过滤器。
StripPrefixGatewayFilterFactory - 在指定请求中处理路径前缀的过滤器。
Gateway 中使用过滤器的方式非常简单,只要在配置文件中通过过滤器命名前缀即
可 快 速 使 用 , 如 使 用 AddRequestParameterGatewayFilterFactory , 可 以 通 过
AddRequestParameter 在配置文件中配置使用;如使用 StripPrefixGatewayFilterFactory ,可
以通过 StripPrefix 在配置文件中配置使用。
具体配置过程如下:
#设置端口号
server:
  port: 8081
#设置应用名称
spring:
  application:
    name: cloud-gateway

  cloud:
    gateway:
      discovery:
        locator:
          enabled: false #关闭Gateway服务注册和发现的功能
          lower-case-service-id: true #将请求路径上的服务名配置为小写
      #手工绑定路由规则
      routes:
        - id: service01 #唯一命名
          uri: lb://service01  # 转发路径,lb 代表 loadbalance,即从 Eureka 中获取的服务列表负载均衡器。
                               #openfeign-client 即服务名称,相当于openfeign-client 即服务名称,相当于 http://localhost:8081/
          predicates:  # 定义映射
            - Path=/aaa/**  # 发送到 Gateway 网关上的请求路径映射,此映射匹 配的路径都会转发到 uri 上。
                            #具体地址为: lb://openfeign-client/client/**
          filters:
            - StripPrefix=1 # 请求转发时,会自动过滤请求转发的第一节地址,即 client。最终地址为: lb://openfeign-client/**
            - AddRequestParameter=age,30 # 在请求中自动增加一个请求参数,参数名为 age,参数值为 30。可以用于提供固定参数。
            - AddRequestParameter=name,TeacherWu # 每个 AddRequestParameter 过滤器,只能提供一个请求参数,提供多请求参数,需要定义多个过滤器
            - AddRequestParameter=token,123
            - AddRequestHeader=myHeader,myHeaderValue e # 在请求中自动增加 一个请求头参数,参数名为 my-header,参数值为 test-header-value。
            - Authentication=token
            - name: Hystrix  #开器Hystrix过滤器
              args:
                 name: fallbackcmd
                 fallbackUri: forward:/fallback  #设置Hystrix回调方法的请求路径

        - id: service02
          uri: lb://service02
          predicates:
            - Path=/bbb/**
          filters:
            - StripPrefix=1
#设置注册中心连接信息
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8080/eureka
#hystrix服务降级
hystrix:
  command:
    default:
      execution:
        timeout:
          # 如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为容错根据
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 1000 # 超时时间,默认1000ms

2 自定义过滤器 

2.1 自定义 GatewayFilter - 网关过滤器

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

/**
 * 登录校验过滤器工厂
 * 泛型是此工厂构造时自动注入的配置对象。此配置对象由Spring容器提供。
 * 根据配置文件中提供的后置配置内容,自动进行配置。
 * 如: 当前类型中定义Config有一个属性token,此属性为字符串类型。那么对应的配置是, Authentication=xxx,xxx就是要传递的token属性值。
 * 在当前实现中,Config中的token属性即是请求参数中用于标明登录标记的请求参数名。
 */

@Component
public class AuthenticationGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthenticationGatewayFilterFactory.Config> {
    public AuthenticationGatewayFilterFactory() {
        super(AuthenticationGatewayFilterFactory.Config.class);
    }

    /**
     * Spring构造Config对象时,读取的配置文件数据对应Config对象中的哪一个属性,即property命名。
     * @return
     */

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("tokenName");
    }

    //完成核心过滤业务逻辑
    @Override
    public GatewayFilter apply(Config config) {
        return new GatewayFilter() {
            //ServerWebExchange命名为服务网络交换器,存放着重要的请求-响应属性、请求实例和响应实例等等
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                String token = exchange.getRequest().getQueryParams().getFirst(config.getTokenName());
                //请求头中不存在token,用户未登录,返回登录。
                if(token == null || token.isEmpty()){
                    exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                    return exchange.getResponse().setComplete();

                }
                // 用户已登录,进入后续执行流程
                return chain.filter(exchange);
            }
        };
    }

    public static  class Config{
        private String tokenName;

        public String getTokenName() {
            return tokenName;
        }

        public void setTokenName(String tokenName) {
            this.tokenName = tokenName;
        }
    }
}

 2.2 自定义 GlobalFilter - 全局过滤器

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 日志全局过滤器
 */
@Component
public class LoggerGlobalFilter implements GlobalFilter {
    private Logger logger = LoggerFactory.getLogger(LoggerGlobalFilter.class);
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        logger.info("logger日志输出!");
        return chain.filter(exchange);
    }
}

 四、 使用 Spring Cloud Gateway 实现熔断功能

Spring Cloud Gateway 也可以利用 Hystrix 的熔断特性,在流量过大时进行服务降级。

1 POM 依赖

同上 

2 熔断处理代码 

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

@RestController
public class FallbackController {
    @GetMapping("/fallback")
    public String fallback(){
        return "服务降级fallcack方法执行!";
    }
}

3 配置文件

#设置端口号
server:
  port: 8081
#设置应用名称
spring:
  application:
    name: cloud-gateway

  cloud:
    gateway:
      discovery:
        locator:
          enabled: false #关闭Gateway服务注册和发现的功能
          lower-case-service-id: true #将请求路径上的服务名配置为小写
      #手工绑定路由规则
      routes:
        - id: service01 #唯一命名
          uri: lb://service01  # 转发路径,lb 代表 loadbalance,即从 Eureka 中获取的服务列表负载均衡器。
                               #openfeign-client 即服务名称,相当于openfeign-client 即服务名称,相当于 http://localhost:8081/
          predicates:  # 定义映射
            - Path=/aaa/**  # 发送到 Gateway 网关上的请求路径映射,此映射匹 配的路径都会转发到 uri 上。
                            #具体地址为: lb://openfeign-client/client/**
          filters:
            - StripPrefix=1 # 请求转发时,会自动过滤请求转发的第一节地址,即 client。最终地址为: lb://openfeign-client/**
            - AddRequestParameter=age,30 # 在请求中自动增加一个请求参数,参数名为 age,参数值为 30。可以用于提供固定参数。
            - AddRequestParameter=name,TeacherWu # 每个 AddRequestParameter 过滤器,只能提供一个请求参数,提供多请求参数,需要定义多个过滤器
            - AddRequestParameter=token,123
            - AddRequestHeader=myHeader,myHeaderValue e # 在请求中自动增加 一个请求头参数,参数名为 my-header,参数值为 test-header-value。
            - Authentication=token
      
            - name: Hystrix  #开器Hystrix过滤器
              args:
                 name: fallbackcmd
                 fallbackUri: forward:/fallback  #设置Hystrix回调方法的请求路径

        - id: service02
          uri: lb://service02
          predicates:
            - Path=/bbb/**
          filters:
            - StripPrefix=1
#设置注册中心连接信息
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8080/eureka
#hystrix服务降级
hystrix:
  command:
    default:
      execution:
        timeout:
          # 如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为容错根据
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 1000 # 超时时间,默认1000ms

4 启动类  

同上

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值