Spring之Gateway网关

这篇具有很好参考价值的文章主要介绍了Spring之Gateway网关。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

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

Spring之Gateway网关

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

Spring之Gateway网关

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

网关核心概念 

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

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

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

网关工作原理

Spring之Gateway网关

网关的使用 

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容器中即可,以上都是网关提供的一些扩展点

适配器模式

        网关提供的Filter过滤器包含了两种,一种是局部的GatewayFilter,一种是全局的GlobalFilter,先看看下面的两种接口的定义

public interface GatewayFilter extends ShortcutConfigurable {

	/**
	 * Name key.
	 */
	String NAME_KEY = "name";

	/**
	 * Value key.
	 */
	String VALUE_KEY = "value";

	/**
	 * Process the Web request and (optionally) delegate to the next {@code WebFilter}
	 * through the given {@link GatewayFilterChain}.
	 * @param exchange the current server exchange
	 * @param chain provides a way to delegate to the next filter
	 * @return {@code Mono<Void>} to indicate when request processing is complete
	 */
	Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);

}
public interface GlobalFilter {

	/**
	 * Process the Web request and (optionally) delegate to the next {@code WebFilter}
	 * through the given {@link GatewayFilterChain}.
	 * @param exchange the current server exchange
	 * @param chain provides a way to delegate to the next filter
	 * @return {@code Mono<Void>} to indicate when request processing is complete
	 */
	Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);

}

现在有个问题是说,比如我需要把两种拦截器都放在一个列表里,但是他们是不同接口类型的,那么我可以怎么做?这时候就可以使用适配器了,这是个很巧妙的设计,在源码中有这么一个适配器的类,如下

private static class GatewayFilterAdapter implements GatewayFilter {

		private final GlobalFilter delegate;

		GatewayFilterAdapter(GlobalFilter delegate) {
			this.delegate = delegate;
		}

		@Override
		public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
			return this.delegate.filter(exchange, chain);
		}

		@Override
		public String toString() {
			final StringBuilder sb = new StringBuilder("GatewayFilterAdapter{");
			sb.append("delegate=").append(delegate);
			sb.append('}');
			return sb.toString();
		}

	}

是不是很巧妙,把GlobalFilter通过GatewayFilterAdapter包装一下,就可以变成了GatewayFilter类型的,这样一来两种Filter就可以放在同一个list里面的,设计核心点:

1.  GatewayFilterAdapter包含了一个GlobalFilter的对象

2.  GlobalFilter实现了GatewayFilter接口

3. 在GatewayFilterAdapter实现GatewayFilter的接口使用内部的GlobalFilter来进行实现

通过以上的设计,就间接把GlobalFilter和GatewayFilter整合在一起了,很值得我们去学习

网关限流整合

官网提供的

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

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

整合sentinel限流

参考地址

网关限流 · alibaba/Sentinel Wiki · GitHub文章来源地址https://www.toymoban.com/news/detail-493526.html

到了这里,关于Spring之Gateway网关的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring cloud教程Gateway服务网关

    写在前面的话: 本笔记在参考网上视频以及博客的基础上,只做个人学习笔记,如有侵权,请联系删除,谢谢! Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关,它旨在为微服务架构提

    2024年02月08日
    浏览(45)
  • Spring Cloud之API网关(Gateway)

    目录 API网关 好处 解决方案 Gateway 简介 特征 核心概念 Route(路由) Predicate(断言) Filter(过滤器) 工作流程 Route(路由) 路由配置方式 1.yml配置文件路由 2.bean进行配置 3.动态路由 动态路由 Predicate(断言) 特点 常见断言 示例 Filter(过滤器) filter分类 Pre 类型 Post 类型 网关过滤器 格式

    2024年02月08日
    浏览(52)
  • spring cloud gateway网关和链路监控

    文章目录 目录 文章目录 前言 一、网关 1.1 gateway介绍 1.2 如何使用gateway  1.3 网关优化 1.4自定义断言和过滤器 1.4.1 自定义断言 二、Sleuth--链路追踪 2.1 链路追踪介绍 2.2 Sleuth介绍 2.3 使用 2.4 Zipkin的集成  2.5 使用可视化zipkin来监控微服务 总结 所谓的API网关,就是指系统的 统

    2024年02月02日
    浏览(39)
  • Spring Cloud第二季--服务网关Gateway

    Spring Cloud Gateway是在Spring生态系统之上构建的API网关服务,基于Spring 5,Spring Boot 2和 Project Reactor等技术。 Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了 Netty 通讯框架。Spring Cloud Gateway能干嘛呢? Gateway是原zuul1.x版的替代。 Spring Cloud Gateway 与 Zuul的区别: Zuu

    2024年02月03日
    浏览(52)
  • Gateway网关组件(在Spring Cloud整合Gateway(idea19版本))

            Spring Cloud Gateway官网:Spring Cloud Gateway         局域网中就有网关这个概念,局域网接收数据或发送数据都要通过网关,比如使用VMware虚拟机软件搭建虚拟机集群的时候,往往我们需要选择IP段中的⼀个IP作为网关地址,网关可以对请求进行控制,提升我们系统的安

    2024年02月16日
    浏览(45)
  • Spring Colud gateway 网关引入转发无效 (404)

    跟着大佬们的文章,想玩一下gateway api网关。经过一系列ctrl+c和ctrl+v的操作,项目的基本就搭建好了; 1.引入依赖 pom.xml 2.创建启动类 前期没有配置spieng.cloud.gateway.enabled=true,测试网关一直到报404,看了很多大佬debug,不明所以,最后发现是这边配置没有加,而是配置一个spie

    2024年02月16日
    浏览(40)
  • Spring Cloud GateWay 网关的相关面试题

    Spring Cloud GateWay如何实现限流? 1.Spring Cloud GateWay使用令牌桶算法实现限流(Nginx使用漏桶算法实现限流 ) 2.Spring Cloud GateWay默认使用Redis 的RateLimter限流算法来实现,所以需要引入Redis依赖 3.使用的过程中,主要配置 令牌桶填充的速率,令牌桶容量,指定限流的key 4.限流的Ke

    2024年02月13日
    浏览(56)
  • Spring Cloud Alibaba 系列之 Gateway(网关)

    网关作为流量的入口,常用的功能包括路由转发,权限校验,限流等。 Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关框架,定位于取代 Netflix Zuul1.0。相比 Zuul 来说,Spring Cloud  Gateway 提供更优秀的性能,更强大的有功能。 Spring Cloud Gateway 是由 WebFlux + Netty + Reactor 实现的

    2024年02月10日
    浏览(47)
  • Spring Cloud Gateway 网关实现白名单功能

    1 摘要 对于微服务后台而言,网关层作为所有网络请求的入口。一般基于安全考虑,会在网关层做权限认证,但是对于一些例如登录、注册等接口以及一些资源数据,这些是不需要有认证信息,因此需要在网关层设计一个白名单的功能。本文将基于 Spring Cloud Gateway 2.X 实现白

    2023年04月08日
    浏览(44)
  • 【Spring Cloud Alibaba】8.路由网关(Gateway)

    接下来对服务消费者添加路由网关来实现统一访问接口,本操作先要完成之前的步骤,详情请参照【Spring Cloud Alibaba】Spring Cloud Alibaba 搭建教程 Spring Cloud Gateway 是 Spring 官方基于 Spring 5.0 , Spring Boot 2.0 和 Project Reactor 等技术开发的网关,该项目提供了一个库,用于在 Spring W

    2023年04月24日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包