第五次课:微服务网关之SpringcludGateway

飞一样的编程
飞一样的编程
擅长邻域:Java,MySQL,Linux,nginx,springboot,mongodb,微信小程序,vue

分类: Java springboot 专栏: 分布式学习 标签: 微服务网关

2023-06-16 23:28:34 665浏览

微服务网关之SpringcludGateway

前言

优化下之前的版本依赖管理。写了很多的version.很不方便。可以把nacos的版本和springcloud的版本管理依赖写到父级pom里

 <dependencyManagement>
      <dependencies>

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

          <!--nacos的管理依赖-->
          <dependency>
              <groupId>com.alibaba.cloud</groupId>
              <artifactId>spring-cloud-alibaba-dependencies</artifactId>
              <version>2.2.1.RELEASE</version>
              <type>pom</type>
              <scope>import</scope>
          </dependency>
    </dependencies>
</dependencyManagement>

什么是网关

SpringCloud Gateway是Spring Cloud的一一个全新项目,基于Spring 5.0+Spring Boot 2.0和Project Reactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的统的API路由管理方式。

SpringCloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 1.x非Reactor模式的老版本。 而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。Spring Cloud Gateway的目标提供统一的路由方式且基于Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。

网关的功能

  • 身份认证和权限校验
  • 服务路由反向代理、负载均衡
  • 请求限流
  • 日志监控

springcloud-gateway使用

依赖

gateway-service 的依赖

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

父级pom——最主要的就是springcloud的管理依赖和nacos管理依赖and nacos的注册中心和配置中心

    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.3.7.RELEASE</version>
    </parent>

    <properties>
        <mybatis-plus.version>3.4.2</mybatis-plus.version>
        <lombok.version>1.18.2</lombok.version>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
    </properties>

    <dependencyManagement>
        <dependencies>

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

            <!--nacos的管理依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>



        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>

        <!--nacos注册中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--nacos配置中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
    </dependencies>

配置文件application.yaml

server:
  port: 9527
spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      server-addr: localhost:8848
    gateway:
      routes: # 网关路由规则
        - id: user-service #路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 #路由的目标地址http 就是固定地址
          uri: lb://user-service #路由的目标地址Lb就是负载均衡,后面跟服务名称
          predicates: #路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** #这个是按照路径匹配,只要以/user/开头就符合要求
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**


路由配置包括:

1. 路由id:路由的唯一标示

2.路由目标 (uri) :路由的目标地址, http代表固定地址, lb代表据服务名负载均衡

3.路由断言 ( predicates) :判断路由的规则,

4.路由过滤器(filters) :对请求或响应做处理

路由断言工厂

  • 我们在配置文件中写的断言规则只是字符串, 这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件
  • 例如Path=/oreder/**是按照路径匹配, 这个规则是由org. springframework cloud.gateway.handler.predicate PathRoutePredicateFactory类来处理的

Spring提供了11种基本的Predicate工厂

名称

说明

示例

After

是某个时间点后的请求

-After=2023-06-16T17:42:47.789-07:00[America/Denver]

Before

是某个时间点之前的请求

- Before=2017-01-20T17:42:47.789-07:00[America/Denver]

Between

是某两个时间点之间的请求

- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

Cookie

请求必须包含cookie

- Cookie=chocolate, ch.p

Header

请求必须包含某些header

- Header=X-Request-Id, \d+

Host

请求必须是某个host(域名)

- Host=**.jf3q.com,**.jf3q.cn

Method

请求方式必须是指定方式

- Method=GET,POST

Path

请求路径必须符合规则

- Path=/red/{segment},/blue/{segment}

Query

请求参数必须包含指定参数

- Query=green

RemoteAddr

请求者ip必须是指定范围

- RemoteAddr=192.168.1.1/24

Weight

权重处理

- Weight=group1, 2

其他可以查看spring官网

路由过滤器

针对某个路由

Spring提供了31种不同的路由过滤器工厂。例如:

名称

说明

AddRequestHeader

给当前请求添加一个请求头

RemoveRequestHeader

移除请求中的一个请求头

AddResponseHeader

给响应结果中添加一个响应头

RemoveResponseHeader

从响应结果中移除有一个响应头

RequestRateLimiter

限制请求的流量

gateway:
      routes: # 网关路由规则
        - id: user-service #路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 #路由的目标地址http 就是固定地址
          uri: lb://user-service #路由的目标地址Lb就是负载均衡,后面跟服务名称
          predicates: #路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** #这个是按照路径匹配,只要以/user/开头就符合要求
          filters:
            - AddRequestHeader=notice,my team is jf3q
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**

默认过滤器

针对全部路由

gateway:
      routes: # 网关路由规则
        - id: user-service #路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 #路由的目标地址http 就是固定地址
          uri: lb://user-service #路由的目标地址Lb就是负载均衡,后面跟服务名称
          predicates: #路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** #这个是按照路径匹配,只要以/user/开头就符合要求
          filters:
            - AddRequestHeader=notice,my team is jf3q
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**
      default-filters:
        - AddRequestHeader=notice,my team is jfit

全局过滤器

通过自定义编码的方式实现处理一切进入网关的请求和微服务的响应,而不是上面那种配置的方式(不方便,不灵活)。

  • 小案例:定义全局过滤器,拦截并判断用户角色

需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面的条件

参数中是否有role且是否是admin,是则放行,否则拦截。

@Order(1)//越小越靠前
@Component
public class AuthFilter implements GlobalFilter{
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> params = request.getQueryParams();
        // 2.获取参数中的 role 参数
        String auth = params.getFirst("role");
        // 3.判断参数值是否等于 admin
        if ("admin".equals(auth)) {
            // 4.是,放行
            return chain.filter(exchange);
        }
        // 5.否,拦截
        // 5.1.设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        // 5.2.拦截请求
        return exchange.getResponse().setComplete();
    }
}

过滤器执行顺序

跨域问题

 gateway:
      # ...
      globalcors: #全局的跨城处理
        add-to-simple-url-handLer-mapping: true #解决options 请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: #允许哪些网站的跨城请求
              - "http://localhost:8080"
              - "http://www.jf3q.com"
            allowedMethods: #允许的跨城ojax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" #允许在请求中携带的头信息
            allowCredentials: true #是否允许携带cookie
            maxAge: 360000 #这次跨域检测的有效期

三大核心概念

Router(路由)

路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由

Predicate(断言)

开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由

Filter(过滤)

指的是Spring框架中GatewayFilter的实例, 使用过滤器,可以在请求被路由前或者之后对请求进行修改。

总结

web请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制。

predicate就是我们的匹配条件;而filter,就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标uri,就可以实现个具体的路由了

思考:

gateway整合springsecurity

Nginx和gateway的区别

好博客就要一起分享哦!分享海报

此处可发布评论

评论(7展开评论

蓝色妖姬 能力:10

2023-06-27 17:03:43

温习中
就一傻蛋 能力:10

2023-06-20 15:15:02

baby
周杰伦 能力:10

2023-06-17 15:45:53

大家好,我是歌手周杰伦;今天正式入驻杰凡IT,哎呦,这个网站不错哦!
蓝色的妖姬 能力:10

2023-06-17 14:29:12

大家好,我是歌手薛之谦;今天正式入驻杰凡IT,希望大家多多评论,为我加油!我的新歌 崇拜 已经上线,希望大家支持我
蓝色妖姬 能力:10

2023-06-17 11:31:04

学习中
绿你奇迹 能力:10

2023-06-17 11:23:55

学习中
少奇 能力:10

2023-06-17 10:42:47

正在学习中
点击查看更多评论

展开评论

您可能感兴趣的博客

客服QQ 1913284695