Spring Cloud Gateway学习(1)—— Gateway 的基本概念 & 引入依赖需要注意的事项 +解决方案 & 全局网关的入门使用案例

前言

Spring Cloud Gateway 基于 Spring Boot 2,是 Spring Cloud 的全新项目。Gateway 旨在提供一种简单而有效的途径来转发请求,并为它们提供横切关注点。

gateway相当于所有服务的门户,将客户端请求与服务端应用相分离,客户端请求通过gateway后由定义的路由和断言进行转发,路由代表需要转发请求的地址,断言相当于请求这些地址时所满足的条件,只有同时符合路由和断言才给予转发。

本篇博客介绍Spring Cloud Gateway 的基本概念,引入依赖需要注意的事项,以及解决方案;还有全局网关的入门使用案例。

在这里插入图片描述

引出


1.Spring Cloud Gateway 的基本概念;
2.引入依赖需要注意的事项,以及解决方案;
3.全局网关的入门使用案例;

在这里插入图片描述

网关gateway

网关是啥

API 网关是一个服务,是系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。API 网关封装了系统内部架构,为每个客户端提供一个定制的 API 。它可能还具有其它职责,如身份验证、监控、负载均衡、限流、降级与应用检测。

Spring Cloud Gateway 基于 Spring Boot 2,是 Spring Cloud 的全新项目。Gateway 旨在提供一种简单而有效的途径来转发请求,并为它们提供横切关注点。
Spring Cloud Gateway 中最重要的几个概念:

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

  • 断言 Predicate:Java 8 中的断言函数。Spring Cloud Gateway 中的断言函数输入类型是 Spring5.0 框架中的 ServerWebExchange 。Spring Cloud Gateway 中的断言函数允许开发者去定义匹配来自 Http Request 中的任何信息,比如请求头和参数等。

  • 过滤器 Filter:一个标准的 Spring Web Filter。Spring Cloud Gateway 中的 Filter 分为两种类型:Gateway Filter 和 Global Filter。过滤器 Filter 将会对请求和响应进行修改处理。

在这里插入图片描述

zuul---->SpringCloud,gateway---->zuul2.0

过去做法:Eureak + zuul2.0 + config

现在做法:SpringCloud-nacos + gateway,rocketMQ/RabbitMQ/ActiveMQ

引入依赖和基本运作模式

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

在这里插入图片描述

配置文件访问流程的分析

在这里插入图片描述

参数解释

在这里插入图片描述

如果用springmvc需要设置一下

方式一:配置文件

在这里插入图片描述

<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.tianju</groupId>
        <artifactId>spring-cloud-move</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.tianju.gateway</groupId>
    <artifactId>movie-gateway</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

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

<!--        如果需要用web,则需要排除一下tomcat-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
<!--            打包成可运行的jar包-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

配置文件的解决方案

在这里插入图片描述

spring:
  cloud:
    # nacos的部分
    nacos:
      discovery: # 注册中心
        server-addr: http://192.168.111.130:8848/
        register-enabled: true

    # 网关部分
    gateway:
      discovery:
        locator:
          enabled: true # 允许定位
      routes: # 路由
        - id: my-hello-id # id要唯一
          uri: lb://movie-cinema/api # 在nacos里根据服务名称找
          predicates:
          # http://localhost:18888/hello-wx/api/cinema/checkGenreInThisCinema
           - Path=/hello-wx/** # 比如输了 ip+端口/hello-wx/** 然后在nacos找真的路径
          filters:
            - StripPrefix=1 # 替换第一个,内置的filter过滤器

        - id: my-hello-baidu # id要唯一
          uri: https://www.sohu.com
          predicates:
          # http://localhost:18888/hello-ly
           - Path=/hello-ly/**

  # 如要要用spring web,则把tomcat排除一下
  main:
    web-application-type: reactive


启动的是tomcat

在这里插入图片描述

方式二:排除tomcat

在这里插入图片描述

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

全局网关

在这里插入图片描述

package com.tianju.gateway.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
@Slf4j
public class AuthGateway implements GlobalFilter, Ordered {
    
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
    
        log.debug("我是全局过滤器>>>>>>>>>>");
        return null;
    }

    @Override
    public int getOrder() {
    
    
        return 0;
    }
}

在这里插入图片描述

package com.tianju.gateway.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
@Slf4j
public class AuthGateway implements GlobalFilter, Ordered {
    
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
    
        log.debug("我是全局过滤器>>>>>>>>>>");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
    
    
        return 0;
    }
}

在这里插入图片描述

网关的相关代码

在这里插入图片描述

1.导入依赖

<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.tianju</groupId>
        <artifactId>spring-cloud-move</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.tianju.gateway</groupId>
    <artifactId>movie-gateway</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

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

<!--        如果需要用web,则需要排除一下tomcat-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.tianju.common</groupId>
            <artifactId>movie-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
<!--            打包成可运行的jar包-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

2.配置config

bootstrap.yml文件

spring:
  cloud:
    # nacos的部分
    nacos:
      discovery: # 注册中心
        server-addr: http://192.168.111.130:8848/
        register-enabled: true

    # 网关部分
    gateway:
      discovery:
        locator:
          enabled: true # 允许定位
      routes: # 路由
        - id: my-hello-id # id要唯一
          uri: lb://movie-cinema/api # 在nacos里根据服务名称找
          predicates:
          # http://localhost:18888/hello-wx/api/cinema/checkGenreInThisCinema
           - Path=/hello-wx/** # 比如输了 ip+端口/hello-wx/** 然后在nacos找真的路径
          filters:
            - StripPrefix=1 # 替换第一个,内置的filter过滤器

        - id: my-hello-baidu # id要唯一
          uri: https://www.sohu.com
          predicates:
          # http://localhost:18888/hello-ly
           - Path=/hello-ly/**

  # 如要要用spring web,则把tomcat排除一下
  main:
    web-application-type: reactive


application.yml

server:
  port: 18888
spring:
  application:
    name: movie-gateway

logging:
  level:
    com.tianju.gateway: debug

3.网关AuthGateway

package com.tianju.gateway.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.tianju.common.result.HttpResp;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;

@Component
@Slf4j

// http://localhost:18888/hello-wx/api/cinema/checkGenreInThisCinema
public class AuthGateway implements GlobalFilter, Ordered {
    
    

    @Override
    @SneakyThrows
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
    
        log.debug("我是全局过滤器>>>>>>>>>>");
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        // 请求request 的URL:http://localhost:18888/hello-wx/api/cinema/checkGenreInThisCinema
        log.debug("请求request 的URL:"+request.getURI());
        log.debug("请求request 数据"+request.getHeaders().get("jwt"));
//        String jwt = "请求request 数据" + request.getHeaders().get("jwt").get(0);

        if (Objects.isNull(request.getHeaders().get("jwt"))){
    
     // 如果没有携带token
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            ObjectMapper objectMapper = new ObjectMapper();
            DataBuffer buffer = response.bufferFactory()
                    .wrap(objectMapper.writeValueAsString(HttpResp.failed("没有jwt"))
                            .getBytes(StandardCharsets.UTF_8));

            return response.writeWith(Mono.just(buffer));

        }else {
    
    
            return chain.filter(exchange);
        }
    }

    @Override
    public int getOrder() {
    
    
        return 0;
    }
}

4.主启动类

package com.tianju.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApp {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(GatewayApp.class);
    }
}


总结

1.Spring Cloud Gateway 的基本概念;
2.引入依赖需要注意的事项,以及解决方案;
3.全局网关的入门使用案例;

猜你喜欢

转载自blog.csdn.net/Pireley/article/details/133443521