Spring之Gateway网关

news2025/1/15 17:25:51

前言

        什么是网关?简单理解就是我们所有服务的入口,当我们使用了微服务以后,每个服务都会有一个对应的接口,比如我们有用户服务,订单服务等等,如果没有网关的话,那么前端是这样调用的

        很明显app和h5需要知道所有微服务的地址,显然会让前端变得很复杂,同时也不太安全,那如果有网关后是怎么样的呢?如下

这样一来,所有流量就会从网关进来了,当然了网关会存在单点故障问题,这个可以通过负载均衡就可以解决了

网关核心概念 

        路由:路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。通过ID使用微服务名称,因为微服务一般就是全局统一的

        断言:简单了解就是对参数、请求头,URI等的判断

        Filter:拦截器,对请求进行拦截处理等,跟mvc的拦截器差不多

网关工作原理

网关的使用 

spring网关的官方api文档:spring gateway

        网关的使用其实非常简单,只需要做以下的两步即可

1. 引入maven依赖

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

<!-- nacos服务注册与发现 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

       2. 配置yml文件

server:
  port: 9999
spring:
  application:
    name: gateway
  #配置nacos注册中心地址
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

    gateway:
      #设置路由:路由id、路由到微服务的uri、断言
      routes:
        - id: user_route   #路由ID,全局唯一,建议配置服务名
          uri: lb://user  #lb 整合负载均衡器ribbon,loadbalancer
          predicates:
            - Path=/user/**   # 断言,路径相匹配的进行路由

 3. 定义springBoot配置类启动即可使用了

网关使用遇到的问题

 首先,你在使用网关的时候需要排除webmvc,因为网关是基于webflux实现的,所以必须排除这个,否则启动不了

<!-- gateway网关 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </exclusion>
    </exclusions>
</dependency>

 其次,不知道为啥我启动的时候报下面的错

***************************
APPLICATION FAILED TO START
***************************

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    org.springframework.cloud.gateway.config.GatewayAutoConfiguration$NettyConfiguration.buildConnectionProvider(GatewayAutoConfiguration.java:798)

The following method did not exist:

    reactor.netty.resources.ConnectionProvider$Builder.evictInBackground(Ljava/time/Duration;)Lreactor/netty/resources/ConnectionProvider$ConnectionPoolSpec;

The method's class, reactor.netty.resources.ConnectionProvider$Builder, is available from the following locations:

    jar:file:/E:/javaEvn/mvn-need/io/projectreactor/netty/reactor-netty/0.9.10.RELEASE/reactor-netty-0.9.10.RELEASE.jar!/reactor/netty/resources/ConnectionProvider$Builder.class

The class hierarchy was loaded from the following locations:

    reactor.netty.resources.ConnectionProvider.Builder: file:/E:/javaEvn/mvn-need/io/projectreactor/netty/reactor-netty/0.9.10.RELEASE/reactor-netty-0.9.10.RELEASE.jar
    reactor.netty.resources.ConnectionProvider.ConnectionPoolSpec: file:/E:/javaEvn/mvn-need/io/projectreactor/netty/reactor-netty/0.9.10.RELEASE/reactor-netty-0.9.10.RELEASE.jar


Action:

Correct the classpath of your application so that it contains a single, compatible version of reactor.netty.resources.ConnectionProvider$Builder


Process finished with exit code 1

看报错信息就是说找不到类之类的,所以尝试了几个解决方案

  1. 删除maven对应的依赖,因为有时可能因为网络问题引起jar包有问题,但是无法解决
  2. 看网上说可能是版本不匹配的问题,官网的推荐是版本说明 · alibaba/spring-cloud-alibaba Wiki · GitHub,
  3. 但是我的版本也是没问题,都是匹配的

<spring-cloud.version>Hoxton.SR12</spring-cloud.version>
<spring-cloud-alibaba.version>2.2.8.RELEASE</spring-cloud-alibaba.version>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>

最后实在没办法了,找到了网关启动类GatewayAutoConfiguration,里面有个方法叫org.springframework.cloud.gateway.config.GatewayAutoConfiguration.NettyConfiguration#buildConnectionProvider的builder.evictInBackground(pool.getEvictionInterval());报错了,这也是上面报错的原因,所以就尝试了一下对reactor.netty.resources.ConnectionProvider依赖进行了升级,如下

<dependency>
    <groupId>io.projectreactor.netty</groupId>
    <artifactId>reactor-netty</artifactId>
    <version>0.9.25.RELEASE</version>
</dependency>

这样一来,就可以解决了,但是官网推荐的版本匹配岂不是有问题吗,这个有待于后续的研究

这个问题解决以后,gateway就可以正常启动了

断言工具

        我们常用的是Path断言,断言就是个判断

predicates:
  - Path=/user/**   # 断言,路径相匹配的进行路由

其他更多的可以查看官网:spring 断言类

如果提供的不够还可以进行自定义,找一个参考就行了,命令也是要按照规范来即可

GatewayFilter拦截链

网关提供了GatewayFilter接口,默认提供了很多实现,当然我们也可以自己进行实现,然后放到容器中,他就会走我们的逻辑了,比如我定义了一个拦截器的实现,如下

@Component
public class ZxcGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {

    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange,
                                     GatewayFilterChain chain) {
                String name = config.getName();
                String value = config.getValue();
                System.out.println(name);
                System.out.println(value);

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

注意:名字要规范ZxcGatewayFilterFactory,Zxc为你使用的名字,后面的格式是固定的,然后放到ioc容器中就可以了,然后是在yml配置中进行配置,如下

gateway:
  #设置路由:路由id、路由到微服务的uri、断言
  routes:
    - id: user_route   #路由ID,全局唯一,建议配置服务名
      uri: lb://user  #lb 整合负载均衡器ribbon,loadbalancer
      filters:
        - Zxc=zxc,ttt
      predicates:
        - Path=/user/**   # 断言,路径相匹配的进行路由

spring提供了多个GatewayFilterFactory,地址:Spring GatewayFilterFactory

配置比较简单,不过这种是局部配置的,我们一般会使用全局的,如下

GlobalFilter

这个是全局的,spring一样提供了很多,地址:Spring GlobalFilter

如果这些还不够,我们可以自己再提供一些实现,如下面定义了校验权限和校验白名单的类

@Component
public class AuthGlobalFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        String token = exchange.getRequest().getQueryParams().getFirst("token");
        ServerHttpResponse response = exchange.getResponse();
        if(token == null) {
            return response.writeWith(Mono.just(response.bufferFactory().wrap("没有权限".getBytes())));
        }

        return chain.filter(exchange);
    }
}
package com.zxc.gateway.filter;

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 WhiteGlobalFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

       //todo 校验白名单逻辑

        return chain.filter(exchange);
    }
}

然后只要把实现类放到ioc容器中即可,以上都是网关提供的一些扩展点

网关限流整合

官网提供的

基于redis+lua脚本方式采用令牌桶算法实现了限流

具体文档为:gateway基于 redis+lua 限流

整合sentinel限流

参考地址

网关限流 · alibaba/Sentinel Wiki · GitHub

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Design a TinyURL

title: Notes of System Design No.02 — Design a TinyURL date: 2022-05-05 13:23:57 tags: 系统设计 categories: 系统设计 description: " Design a TinyURL" 1.Functional Requirements 1.长链接->短链接(写) 2.短链接->长链接(读) 3.可以设置超时时间…

unittest框架

unittest框架1.通过unittest框架创建测试2.通过unittest框架添加断言3.自动化用例管理TestLoader类的用法4.unittest智能封装等待1.通过unittest框架创建测试 1.必须继承于unittest.TestCase类 2.可以定义setUp和tearDown方法进行初始化&#xff0c;每条测试用例开始或结束会执…

谷歌浏览器-chrome浏览器占用电脑CPU过高、容易崩溃的解决办法

一、问题背景 最近特别难受的一点——谷歌浏览器总是莫名其妙崩溃&#xff0c;而且明明是只开了两三个标签页的情况下。 不管是谷歌自己的任务管理器&#xff0c;还是win10自带的任务管理器&#xff1b;在崩溃情况下&#xff0c;谷歌浏览器的电脑cpu占用率高达80以上。 网上…

Java01-JDK1.8下载安装教程(win11版)

文章导航JDK 1.8 官网下载&#xff08;下载慢&#xff09;百度网盘下载&#xff08;下载快&#xff09;安装过程JDK环境配置教程验证JDK是否安装成功使用JDK1.8的原因当下互联网行情以及个人建议JDK 1.8 官网下载&#xff08;下载慢&#xff09; 点击跳转至JDK1.8官方网址 32…

暴雪和网易分手百万玩家何去何从

暴雪和网易分手百万玩家何去何从 这两天看到很多报道说网易与暴雪分手的消息&#xff0c;作为一个游戏玩家我甚是感到很意外。 看了不少相关的报道消息才有了今天的这篇文章 暴雪和其旗下《魔兽世界》等游戏陪伴了我们这一代人成长&#xff0c;或许终究不属于这个时代。看到暴…

智慧路灯解决方案-最新全套文件

智慧路灯解决方案-最新全套文件一、建设背景二、思路架构三、建设方案四、获取 - 智慧路灯全套最新解决方案合集一、建设背景 智慧城市是利用信息通信技术感知、分析、整合城市运行核心系统的各种关键信息&#xff0c;从而改善民生、环保、公共安全、城市服务、智能响应包括工…

【Java八股文总结】之反射

文章目录Java反射一、泛型1、何为泛型&#xff1f;2、泛型通配符Q&#xff1a;泛型擦除是什么&#xff1f;3、泛型上限和下限二、反射1、何为反射&#xff1f;2、反射有什么用&#xff1f;3、反射应用场景有哪些&#xff1f;Q&#xff1a;反射的优缺点&#xff1f;4、反射获取C…

三极管集电极电阻的作用

放大状态&#xff1a;电流信号转变为电压信号 饱和状态 ;发射极正偏&#xff0c;集电极反偏 当有无电阻的作用。当集电极有电阻时&#xff0c;可以得到随IC电流变化的电压信号&#xff0c;当工作在饱和状态。集电阻电阻越大。越容易进入饱和状态.当Ib有个小电流,Ic会出现大的…

Dubbo的SPI机制

目录 什么是 SPI Java SPI 示例 Java SPI 源码分析 想一下 Java SPI 哪里不好 Dubbo SPI Dubbo SPI 简单实例 Dubbo 源码分析 getExtensionClasses Adaptive 注解 - 自适应扩展 Adaptive 注解在类上 Adaptive 注解在方法上 WrapperClass - AOP injectExtension - …

webpack 官方文档解读一(详细使用教程) 起步

什么是webpack 就是个打包工具。通过一系列插件帮你优化项目&#xff0c;压缩&#xff0c;混淆等。总之什么脏活累活都能干。 入门案例 创建一个目录&#xff0c;并安装webpack和webpack-cli这两个包。webpack包是webpack本体&#xff0c;webpack-cli是他提供的工具包。 mk…

RTL8380M/RTL8382M管理型交换机系统软件操作指南二:转发表

前面介绍了端口配置,这次对转发表进行详细的描述&#xff0c;主要包括以下三方面内容&#xff1a;基础配置、转发表、删除1.1 基础配置 1.1.1 老化时间 老化时间是一个影响交换机学习进程的参数。从一个地址记录加入地址表以后开始计时&#xff0c;如果在老化时间内各端口未收…

ResNet网络详解

ResNet ResNet在2015年由微软实验室提出&#xff0c;斩获当年lmageNet竞赛中分类任务第一名&#xff0c;目标检测第一名。获得coco数据集中目标检测第一名&#xff0c;图像分割第一名。 ResNet亮点 1.超深的网络结构(突破1000层) 2.提出residual模块 3.使用Batch Normalizat…

java项目-第147期ssm社区生活超市管理系统_(spring+springmvc+mybatis+jsp)_java毕业设计_计算机毕业设计

java项目-第147期ssm社区生活超市管理系统_(springspringmvcmybatisjsp)_java毕业设计_计算机毕业设计 【源码请到资源专栏下载】 今天分享的项目是《ssm社区生活超市管理系统》 该项目分为3个角色&#xff0c;管理员、用户、供应商角色。 用户可以浏览前台商品&#xff0c;进行…

[附源码]java毕业设计软件项目过程管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

牛客小白月赛 61 E 排队

题目大意&#xff1a; n个数&#xff0c;共有n&#xff01;种排列方式&#xff0c;记Pi(a)表示序列a的第i种排队方式&#xff0c;cnt(Pi(a))表示P(i)的逆序对个数&#xff0c;PLMM想知道这n&#xff01;种排列方式共有多少对逆序对 给定一个 nnn 个数&#xff0c;在所有排列顺序…

Windows 11 Insider Preview Build 25247.1000(rs_prerelease)更新内容

微软于今日推出了新的Dev预览版25247.1000&#xff0c;引入了电源设置的新能源建议&#xff0c;“帐户”页面现在会在 OneDrive 存储空间不足时显示警告。下面就和小编一起来看看详细的更新内容吧。 更新内容 此版本包括一些新功能&#xff0c;包括能源建议、任务管理器的一些改…

MySQL8.0优化 - 锁 - 从数据操作的类型划分:读锁、写锁

文章目录学习资料锁的不同角度分类锁的分类图如下从数据操作的类型划分&#xff1a;读锁、写锁读锁写锁锁定读MySQL8.0新特性写操作学习资料 【MySQL数据库教程天花板&#xff0c;mysql安装到mysql高级&#xff0c;强&#xff01;硬&#xff01;-哔哩哔哩】 【阿里巴巴Java开…

【21-业务开发-基础业务-商品模块-分类管理-商品系统三级分类的新增类别前后端代码实现-商品系统三级分类的更新类别前后端代码实现-之前错误的Bug修正】

一.知识回顾 【0.三高商城系统的专题专栏都帮你整理好了&#xff0c;请点击这里&#xff01;】 【1-系统架构演进过程】 【2-微服务系统架构需求】 【3-高性能、高并发、高可用的三高商城系统项目介绍】 【4-Linux云服务器上安装Docker】 【5-Docker安装部署MySQL和Redis服务】…

2022 全网最全最新 Java 面试题 - 独家内部教材

怎样才能拿到大厂的 offer&#xff0c;没有掌握绝对的技术&#xff0c;那么就要不断的学习 从疫情破局而出&#xff0c;又在毕业季一路过关斩将&#xff0c;我是如何笑面试官&#xff0c;拿到阿里&#xff0c;腾讯等八家大厂的 offer 的呢&#xff0c;在这里分享我的秘密武器&…

kubernetes(K8S)学习笔记P3:集群 YAML 文件(部署)

集群 YAML 文件&#xff08;部署&#xff09;4.集群 YAML 文件&#xff08;部署&#xff09;4.1 YAML 文件概述4.2YAML 文件书写格式4.2.1YAML 介绍4.2.2YAML 基本语法4.2.3YAML 支持的数据结构4.3资源清单描述方法4.3.1常用字段4.3.2字段解释4.4快速编写yml-->kubdectl cre…