Spring Cloud Alibaba 网关 Gateway 集成(7)

项目的源码地址
Spring Cloud Alibaba 工程搭建(1)
Spring Cloud Alibaba 工程搭建连接数据库(2)
Spring Cloud Alibaba 集成 nacos 以及整合 Ribbon 与 Feign 实现负载调用(3)
Spring Cloud Alibaba Ribbon 负载调用说明(4)
Spring Cloud Alibaba 核心理论 CAP与BASE理论简单理解(5)
Spring Cloud Alibaba Sentinel 集成与限流实战(6)
目录

什么是网关

我们从下面几个点来说明吧:

  1. API Gateway,是系统的唯⼀对外的⼊⼝,介于客户端和服务器端之间的中间层,处理⾮业务功能,提供路由请求、鉴权、监控、缓存、限流等功能。
  2. 统一接入,可以做智能路由,负载均衡,容灾处理,日志埋点等等
  3. 流量监控,限流处理与服务降级
  4. 安全防护,统一的鉴权处理,监控,机器网络隔离
    Api Gateway
    主流的网关有哪些呢?
  • zuul: 是Netflix开源的微服务网关,和 Eureka,Ribbon,Hystrix 等组件配合使用,依赖组件比较多,性能教差(这个是我百度之后搬过来的,我还没有用过这个 zuul)。
  • nginx+lua:是⼀个⾼性能的HTTP和反向代理服务器,lua 是脚本语⾔,让Nginx执⾏Lua脚本,并且⾼并发、⾮阻塞的处理各种请求
  • SpringCloud Gateway: Spring公司专⻔开发的⽹关,替代 zuul。

AlibabaCloud 全家桶还没对应的⽹关,我们就⽤ SpringCloud官⽅推荐的 Gateway。

Spring Cloud Gateway

spring 官方的说明文档,点击这里看看,官网上面有一句话,是说 Spring Cloud Gateway 是基于 Spring Boot 2.x,Spring WebFlux 和 Project Reactor 构建。

这里引用官方上面的两段文字,是需要我们引起注意的地方

Spring Cloud Gateway 是建立在 Spring Boot 2.x、 Spring WebFlux 和 Project Reactor之上。因此,你所熟悉的许多同步库(例如Spring Data和Spring Security)和模式在你使用Spring Cloud Gateway时可能不适用。如果你不熟悉这些项目,我们建议你在使用Spring Cloud Gateway之前,先阅读它们的文档,熟悉一些新概念。

Spring Cloud Gateway 需要 Spring Boot 和 Spring Webflux 提供的 Netty 运行时。它不能在传统的Servlet容器中工作,也不能以WAR的形式构建。

三个核心的术语

  • Route(路由): 网关的基本构件。它由一个ID、一个目的地URI、一个谓词(Predicate)集合和一个过滤器(Filter)集合定义。如果集合谓词为真,则路由被匹配。

  • Predicate(谓词): 这是一个 Java 8 Function Predicate。输入类型是 Spring Framework ServerWebExchange。这让你可以在HTTP请求中的任何内容上进行匹配,比如header或查询参数。

  • Filter(过滤器): 这些是 GatewayFilter 的实例,已经用特定工厂构建。在这里,你可以在发送下游请求之前或之后修改请求和响应。

这里我们先有一个眼熟,后面我们再具体操作。

工程搭建

新增 api-gateway 模块

这里我们按照之前搭建工程的方式创建一个 demo-api-gateway 的模块出来,具体的搭建方式看这里,搭建的方式是一样的,其实就是新建一个 module,这里就不赘述了。最后搭建完了之后,是这样子的结构:
增加 api-gateway

增加模块内容

pom 文件依赖引入

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

启动类

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

配置文件
这个 routes 节点是一个数组,是可以写多个的

server:
  port: 8888

spring:
  application:
    name: api-gateway

  cloud:
    gateway:
      routes: #数组形式
        - id: demo-order  #路由唯一标识
          uri: http://127.0.0.1:9000  #想要转发到的地址
          order: 1 #优先级,数字越小优先级越高
          predicates: #断言 配置哪个路径才转发
            - Path=/demo-order/**
          filters: #过滤器,请求在传递过程中通过过滤器修改
            - StripPrefix=1  #去掉第一层前缀

这里先初步说明下配置的意思:

  • 我们请求的地址如果是: http://localhost:8888/demo-order/api/v1/video_order/list ,这个是我们网关的地址,
  • 访问网关之后,会转发到 这个地址上面去 http://localhost:9000/demo-order/api/v1/video_order/list 访问我们订单服务。
    请求的过程

测试下

访问下:http://localhost:8888/demo-order/api/v1/video_order/list
请求
然后我们再访问下:http://localhost:9000/api/v1/video_order/list
请求
OK了,我们初步的测试就算通过了,那么我们就接着向下看把,

连接Nacos

在 pom 文件中增加 nacos 依赖

 <!--添加 nacos 客户端-->
 <dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
 </dependency>

增加启动类开启支持

@EnableDiscoveryClient

修改配置文件

注意看下下面增加的部分

  • nacos.discovery.server-addr
  • gateway.routes.id.uri:这里使用了 lb://demo-order 负载的调用方式
  • gateway.locator.enabled: 开启网关拉取 nacos 服务
server:
  port: 8888

spring:
  application:
    name: api-gateway

  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

    gateway:
      routes: #数组形式
        - id: order-service  #路由唯一标识
          #uri: http://127.0.0.1:8000  #想要转发到的地址

          uri: lb://demo-order  #从nocas进行转发

          order: 1 #优先级,数字越小优先级越高
          predicates: #断言 配置哪个路径才转发
            - Path=/order-server/**
          filters: #过滤器,请求在传递过程中通过过滤器修改
            - StripPrefix=1  #去掉第一层前缀

      discovery:
        locator:
          enabled: true  #开启网关拉取nacos的服务

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

我们去订单服务里面增加一个接口,方便于测试

@RequestMapping("gateway")
private Map gateway(HttpServletRequest httpRequest) {
    String serverInfo = httpRequest.getServerName() + ":"+ httpRequest.getServerPort();
    return Map.of("title", "测试返回数据", "name", "返回名称", "serverInfo", serverInfo);
}

增加接口
测试下

首先我们启动两个订单服务
启动服务列表
然后我们看下 nacos 的面板,可以看到相关的服务都在上面了
在这里插入图片描述
开始请求:http://localhost:8888/order-server/api/v1/video_order/gateway
请求
再次请求下:http://localhost:8888/order-server/api/v1/video_order/gateway
请求

断言、过滤器实战

网关的配置项回顾

路由:是网关的基本单元,由ID、URI、一组Predicate、一组Filter组成,根据Predicate进行匹配转发

route组成部分

id:路由的ID
uri:匹配路由的转发地址
predicates:配置该路由的断言,通过 PredicateDefinition 类进行接收配置。
order:路由的优先级,数字越小,优先级越高。

交互流程

  • 客户端向Spring Cloud Gateway发出请求
  • 如果网关处理程序映射确定请求与路由匹配
  • 则将其发送到网关Web处理程序
  • 通过特定过滤器链运行,前置处理-后置处理
    请求流程

断言

什么是Gateway路由断言 ?

  • Predicate 来源于Java8,接受输入参数,返回一个布尔值结果
  • Spring Cloud Gateway 中 Spring 利用 Predicate 的特性实现了各种路由匹配规则
  • 转发的判断条件,SpringCloud Gateway支持多种方式,常见如:Path、Query、Method、Header等
  • 支持多个Predicate请求的转发是必须满足所有的Predicate后才可以进行路由转发

内置路由断言都是 RoutePredicateFactory 接口实现类,我们一起看下:
具体的实现类
我们可以去访问下这里,具体的说明这里也有Route Predicate(路由谓词)工厂,我们这里就选几个出来看看

Before

比如,我们现在有一个需求接口需要在指定时间进行下线,过后不可以在被访问。那么我们可以使用 Before Gateway 内置的路由接口定时下线实战。

Before 路由谓词工厂只需要一个参数,即 datetime(这是一个java ZonedDateTime)。这个谓词匹配发生在指定 datetime 之前的请求。

predicates:
  - Before=2024-05-11T01:01:01.000+08:00

那么修改下把:
修改

测试访问下,现在是可以访问的:
测试访问
然后我们再修改下:

Before=2024-05-09T01:01:01.000+08:00

访问不了

Query

query 参数表示再请求的时候一定要带上的字段,如果没有这个字段就是非法请求
query参数

访问请求
http://localhost:8888/order-server/api/v1/video_order/gateway
请求报错
http://localhost:8888/order-server/api/v1/video_order/gateway?source=alipay
带上参数

Filter 过滤器

这里我们再看下这个图,可以看到我们的 Filter,是一层层的过滤然后访问到 proxied service ,然后再一层层的经过 filter 返回
请求流程

过滤器生命周期

PRE: 这种过滤器在请求被路由之前调用,一般用于鉴权、限流等
POST:这种过滤器在路由到微服务以后执行,一般用于修改响应结果,比如增加header信息、打点结果日志

网关过滤器分类

  • 局部过滤器GatewayFilter:应用在某个路由上,每个过滤器工厂都对应一个实现类,并且这些类的名称必须以GatewayFilterFactory 结尾

  • 全局过滤器:作用全部路由上

局部过滤器

内置很多局部过滤器,顶级接口 GatewayFilterFactory
GatewayFilterFactory
全局过滤器

内置很多全局过滤器,顶级接⼝ GlobalFilter
全局过滤器

自定义网关过滤器

第一步:先增加一个自定义的过滤器
新增代码

import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;


@Component
public class UserGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //写业务逻辑
        String token = exchange.getRequest().getHeaders().getFirst("token");

        //TODO 根据业务开发对应的鉴权规则, JWT

        if(StringUtils.isBlank(token)){
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }


        //继续往下执行
        return chain.filter(exchange);
    }

    //数字越小,优先级越高
    @Override
    public int getOrder() {
        return 0;
    }
}

第二步: 接着重启服务

访问测试下:http://localhost:8888/order-server/api/v1/video_order/gateway?source=alipay
报错访问通过 postMan 访问,可以请求到数据
PostMan访问
好了,我们总算是搞定了这个 Gateway 了,其实这个更多的就是配置,没有啥其他代码部分的东西。先理解配置部分东西,方便与工作中使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/613084.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Web】CTFSHOW 月饼杯 题解(全)

目录 web1_此夜圆 web2_故人心 web3_莫负婵娟 web1_此夜圆 拿到源码&#xff0c;一眼字符串逃逸 本地测一测&#xff0c;成功弹出计算器 <?phpclass a {public $uname;public $password;public function __wakeup(){system(calc);} }function filter($string){retur…

【北京迅为】《iTOP-3588从零搭建ubuntu环境手册》-第5章 安装SSH

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…

【深度学习Labelme】使用Segment Anything Model (SAM)快速打标,labelme多边形转yolo txt框看看对不对

文章目录 windows安装环境打开labelme自动保存勾选上&#xff0c;保存图片数据不要勾选选SAM精准模型&#xff0c;然后打开图片路径&#xff0c;然后点击创建AI多边形&#xff1a;鼠标点击确认物体控制点&#xff0c;确认完成后&#xff0c;双击鼠标完成选取&#xff0c;并给上…

Django 静态文件管理与部署指南

title: Django 静态文件管理与部署指南 date: 2024/5/10 17:38:36 updated: 2024/5/10 17:38:36 categories: 后端开发 tags: WebOptCDN加速DjangoCompressWebpackStaticDeployCICD-ToolsSecStatic 第一章&#xff1a;介绍 Django 静态文件的概念和重要性 在 Web 开发中&a…

解读计数器算法:原理、Java实现与优劣分析

计数器算法的介绍 计数器算法的基本原理是通过一个计数器来记录事件的发生次数。每当一个特定的事件发生时&#xff0c;计数器的值就会增加一。当需要检查这个事件发生的次数时&#xff0c;只需要查看计数器的当前值即可。这种方法简单直观&#xff0c;易于理解和实现。 想象…

Docker + Django跨域解决方案

什么是Django Django 是一个开源的高级 Python Web 框架&#xff0c;它鼓励快速开发并遵循可重用和可维护的实践。Django 是在 MTV&#xff08;模型-模板-视图&#xff09;模式的基础上设计的&#xff0c;这个模式类似于但不同于 MVC&#xff08;模型-视图-控制器&#xff09;模…

雷森托尔环保科技有限公司见证2024杭州数字供应链装备展潮流

参展企业介绍 青岛雷森托尔环保科技有限公司创建于2018年&#xff0c;位于山东青岛&#xff0c;现注册资本3000万。公司主营生产模压木托盘、化工木托盘、大型设备木包装、出口木托盘、酒柜木酒架等&#xff0c;公司拥有技术人员6人&#xff0c;均为包装设计专业毕业&#xff0…

智慧公厕管理系统的四层架构:感知层、传输层、平台层和应用层

智慧公厕管理系统是一种利用先进技术实现智能化管理和优化厕所体验的创新解决方案。该系统采用复杂的架构&#xff0c;涵盖了多个应用子系统&#xff0c;致力于提高公厕的卫生状况、资源利用效率、安全性以及用户体验。本文将以智慧公厕源头实力厂家广州中期科技有限公司&#…

element el-date-picker组件 输入输出格式为时间戳

<!-- 时间戳 --><el-date-pickerv-model"time"value-format"timestamp"type"date"placeholder"选择日期"/>// 把 value-format"timestamp" 加入 就可以实现时间戳格式

【数学】泰勒公式

目录 引言 一、泰勒公式 1.泰勒公式及推导 &#xff08;1&#xff09;推导 &#xff08;2&#xff09;公式 2.泰勒中值定理 &#xff08;1&#xff09;定理1&#xff08;佩亚诺余项&#xff09; &#xff08;2&#xff09;定理2&#xff08;拉格朗日余项&#xff09; …

前端动画requestAnimationFrame

window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画&#xff0c;并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数&#xff0c;该回调函数会在浏览器下一次重绘之前执行。 备注&#xff1a; 若你想在浏览器下次重绘…

GRU模块:nn.GRU层

摘要&#xff1a; 如果需要深入理解GRU的话&#xff0c;内部实现的详细代码和计算公式就比较重要&#xff0c;中间的一些过程及中间变量的意义需要详细关注。只有这样&#xff0c;才能准备把握这个模块的内涵和意义&#xff0c;设计初衷和使用方式等等。所以&#xff0c;仔细研…

实现流程化办公,可了解一下可视化报表开源

当前&#xff0c;实现流程化办公早已成为众多中小企业的发展目标和趋势。可以借助什么样的软件平台实现这一目标&#xff1f;低代码技术平台拥有可视化操作界面、够灵活、易维护等优势特点&#xff0c;在助力企业实现流程化办公、数字化转型方面具有重要的应用价值和推动作用。…

Selenium定位方法汇总及举例

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

arp icmp 等报文格式

ARP报文格式 ARP是一个独立的三层协议&#xff0c;所以ARP报文在向数据链路层传输时不需要经过IP协议的封装&#xff0c;而是直接生成自己的报文&#xff0c;其中包括ARP报头&#xff0c;到数据链路层后再由对应的数据链路层协议&#xff08;如以太网协议&#xff09;进行封装…

2022 年全国职业院校技能大赛高职组云计算赛项试卷(容器云)

#需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包…

C#上位机1ms级高精度定时任务

precisiontimer 安装扩展包 添加引用 完整代码 using PrecisionTiming;using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; us…

Android虚拟机机制

目录 一、Android 虚拟机 dalvik/art&#xff08;6版本后&#xff09;二、Android dex、odex、oat、vdex、art区别 一、Android 虚拟机 dalvik/art&#xff08;6版本后&#xff09; 每个应用都在其自己的进程中运行&#xff0c;都有自己的虚拟机实例。ART通过执行DEX文件可在设…

C——单链表

一.前言 我们在前面已经了解了链表中的双向链表&#xff0c;而我们在介绍链表分类的时候就说过常用的链表只有两种——双向带头循环链表和单向不带头不循环链表。下来我来介绍另一种常用的链表——单向不带头不循环链表也叫做单链表。不清楚链表分类的以及不了解双向链表的可以…

react18【系列实用教程】JSX (2024最新版)

为什么要用 JSX&#xff1f; JSX 给 HTML 赋予了 JS 的编程能力 JSX 的本质 JSX 是 JavaScript 的语法扩展&#xff0c;浏览器本身不能识别&#xff0c;需要通过解析工具&#xff08;如babel&#xff09;解析之后才能在浏览器中运行。 bable 官网可以查看解析过程 JSX 的语法 …