SpringCloud学习(七)——统一网关Gateway

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

1. 网关介绍

到现在,我们可以使用Nacos对不同的微服务进行注册并管理配置文件,也可以使用 Feign 对不同的微服务进行访问,但是,这种访问是任何人都可以访问的,这是不行的,访问之间应该有某种权限的控制,而且,如果所有允许的访问都可以进入,那么如果有一个时间访问量太过巨大则会引起服务器出现问题,这就需要使得请求限流了,所以,我们需要使用一些工具来达到这些目的,这就是网关Gateway。
SpringCloud学习(七)——统一网关Gateway
网关具体需要实现的功能包括:

  1. 对用户请求做身份认证、权限校验
  2. 将用户请求路由到微服务,并实现负载均衡
  3. 对用户请求做限流

SpringCloud中网关的实现有两种:

  • gateway
  • zuul

zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能,所以我们接下来使用Gateway来对网关进行实现。

2. 网关搭建

接下来我们就试着为userserviceorderservice 搭建网关。

2.1 引入依赖

首先初始化一个新的Module,将其初始化为空的Maven,统一网关实际上也是一个微服务,所以也需要在Nacos上进行注册发现,故添加如下依赖:

<dependencies>
    <!--    nacos服务发现注册依赖    -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--    网关gateway依赖    -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
</dependencies>

2.2 创建启动类

创建一个 GatewayApplication 的文件,将其当做启动类,该文件的内容如下:

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

2.3 编写配置

在网关这里,需要在 application.yml 配置中编写路由配置以及nacos的地址等配置信息,配置文件中的配置信息如下所示:

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由标示,必须唯一
          uri: lb://userservice # 路由的目标地址,lb是负载均衡,后面跟服务名称
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**

从配置信息可以看到,网关实现了负载均衡以及路径的断言,让访问变得更加的轻松方便。

2.4 测试

接下来我们将 userservice, orderservice, gateway 三个服务都启动,然后输入网址 http://localhost:10010/user/1 可以看到用户信息能够顺利显示出来。
SpringCloud学习(七)——统一网关Gateway
再输入网址 http://localhost:10010/order/101 ,能够正确的显示相关的信息,
SpringCloud学习(七)——统一网关Gateway
这说明我们的网关构建时成功的。

3. 路由断言工厂

我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理
转变为路由判断的条件。

例如 Path=/user/** 是按照路径匹配,这个规则是由 org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory 类来处理的,像这样的断言工厂在SpringCloudGateway中还有十几个。

Spring提供了11中基本的路由断言工厂,11中工厂如下,

名称 说明
After 只处理某个时间点后的请求
Before 只处理某个时间点之前的请求
Between 只处理某两个时间点之前的请求
Cookie 请求必须包含某些cookie才处理
Header 请求必须包含某些header才处理
Host 请求必须是访问某个host(域名)才处理
Method 请求方式必须是指定方式才处理
Path 请求路径必须符合指定规则才处理
Query 请求参数必须包含指定参数才处理
RemoteAddr 请求者的ip必须是指定范围才处理
Weight 权重处理

所有这些断言工厂的实例都可以在Spring官网中找到。

比如我们需要只处理上海市2024年3月28日的orderservice请求,那么修改配置文件如下:

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由标示,必须唯一
          uri: lb://userservice # 路由的目标地址,lb是负载均衡,后面跟服务名称
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**
            - After=2024-03-28T17:42:47.789-07:00[Asia/Shanghai]

上面仅新增了最后一行,这样,因为现在是2023年,所以访问 http://localhost:10010/order/101 必定会失效。

4. 路由过滤器

Gateway不可能所有请求都进行响应,其会根据一些条件,将不符合的路径进行过滤,这也就是路由过滤器GatewayFilter的作用,对进行网关的请求和微服务返回的响应做出处理。
SpringCloud学习(七)——统一网关Gateway

4.1 过滤器配置

Spring中提供了30+种不同的路由过滤器工厂,这里就不一一列举出来了,所有的路由过滤器工厂都能在Spring官网进行查看。

比如这里,可以使用过滤器给userservice 添加一个请求头,添加如下:

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由标示,必须唯一
          uri: lb://userservice # 路由的目标地址,lb是负载均衡,后面跟服务名称
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
		  filters:
		    - AddRequestHeader=Truth,I am a really ikun!

则上面的代码会对所有的 userservice 服务添加一个请求头。

如果想要对所有的请求都添加一个请求头应该怎么做呢?
只需要定义 default-filters 即可,定义的过滤器如下:

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由标示,必须唯一
          uri: lb://userservice # 路由的目标地址,lb是负载均衡,后面跟服务名称
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
	  default-filters:
		- AddRequestHeader=Truth,I am a really ikun!

4.2 全局过滤器

全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与 default-filters 的作用一样区别在于 default-filters 通过配置定义,处理逻辑是固定的。而 GlobalFilter 的逻辑需要自己
写代码实现。

全局过滤器的实现步骤如下:

  • 实现 GlobalFilter 接口
  • 添加 @Order 注解或实现 Ordered 接口,目的是设置过滤的优先级
  • 编写处理逻辑

比如我们定义一个全局过滤器,拦截请求,判断请求的参数是或符合下面的条件:

  • 参数中是否有 authorization
  • authorization 参数值是否为 admin

如果同时满足,则对请求进行放行。

我们在 gateway 的Module中创新一个 AuthorizeFilter 的全局过滤文件,其文件内容如下;

// @Order 注解定义过滤器优先级,值越小,优先级越高,也可以通过Ordered接口实现
@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> params = request.getQueryParams();
        // 2.获取参数中的 authorization 参数
        String auth = params.getFirst("authorization");
        // 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();
    }
}

之后再使用 http://localhost:10010/order/101 ,则网页会报告我们所设置的状态码的错误,错误如下:
SpringCloud学习(七)——统一网关Gateway
而如果使用 http://localhost:10010/order/101?authorization=admin , 则网页能够正常访问。

4.3 过滤器执行顺序

请求进入网关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter
请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器,那么过滤器链的执行顺序是怎样的呢?

过滤器执行顺序如下:

  • 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。
  • GlobalFilter 通过实现 Ordered 接口,或者添加 @Order 注解来指定 order 值,由我们自己指定
  • 路由过滤器和 defaultFilterorder 由Spring指定,默认是按照声明顺序从1递增。即如果定义了多个过滤器配置,则其第一行优先级是1,第二行优先级是2,以此类推
  • 当过滤器的 order 值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter 的顺序执行。

5. 跨域问题处理

跨域问题指的是不同站点之间,使用 ajax 无法相互调用的问题。跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据,但这个保护机制也带来了新的问题,它的问题是给不同站点之间的正常调用,也带来的阻碍。简单来说就是浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题。

在请求时,如果出现了以下情况中的任意一种,那么它就是跨域请求:

  • 协议不同,如 httphttps
  • 域名不同;
  • 端口不同。

也就是说,即使域名相同,如果一个使用的是 http,另一个使用的是 https,那么它们也属于跨域访问。常见的跨域问题如下图所示:

当前页面 被请求页面 是否跨域
http://www.test.com/ http://www.test.com/index.html
http://www.test.com/ https://www.test.com/index.html 是,协议名不同(http,https)
http://www.test.com/ http://www.baidu.com/ 是,主域名不同(test,baidu)
http://www.test.com/ http://blog.test.com/ 是,子域名不同(www,blog)
http://www.test.com:8080/ http://www.test.com:8081/ 是,端口不同(8080,8081)

而解决跨域问题的方案就是 CORSCORS 是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing),允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。它通过服务器增加一个特殊的Header[Access-Control-Allow-Origin]来告诉客户端跨域的限制,如果浏览器支持CORS、并且判断Origin通过的话,就会允许XMLHttpRequest发起跨域请求。

网关处理跨域问题采用的方案同样是CORS方案,且只需要经行简单的配置即可,配置如下:

spring:
  cloud:
    gateway:
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        cors-configurations:
          '[/**]': # 对哪些网址进行配置,[/**] 指的是所有网址
            allowedOrigins: # 允许哪些网站的跨域请求
              - "http://localhost:8090"
              - "http://www.leyou.com"
            allowedMethods: # 允许的跨域AJAX请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求头中携带的头信息
            allowedCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期,有效期内无需再次检查请求

按照这种格式进行配置即可解决跨域问题。文章来源地址https://www.toymoban.com/news/detail-461051.html

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

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

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

相关文章

  • 【SpringCloud学习笔记】gateway网关

    【SpringCloud学习笔记】gateway网关

    核心概念: 路由(route):路由信息由id、目标url、一组断言和一组过滤器组成。如果断言路由为真,则说明请求的 URI 和配配 断言(predicate): Java8 中的断言函数,可以配置http请求的断言条件,断言成功会对匹配的路径进行路由 过滤器(filter):过滤器分为两种类型,分

    2024年02月11日
    浏览(9)
  • SpringCloud之网关组件Gateway学习

    SpringCloud之网关组件Gateway学习

    Spring Cloud Gateway是Spring Cloud的⼀个全新项目,目标是取代Netflix Zuul,它基于Spring5.0+SpringBoot2.0+WebFlux(基于高性能的Reactor模式响应式通信框架Netty,异步⾮阻塞模型)等技术开发,性能⾼于Zuul,官方测试,Gateway是Zuul的1.6倍,旨在为微服务架构提供种简单有效的统⼀的API路由管

    2024年03月24日
    浏览(11)
  • 微服务-统一网关Gateway

    微服务-统一网关Gateway

    对用户请求做身份认证、权限校验 将用户请求路由到微服务,并实现负载均衡 对用户请求做限流 创建新module,命名为Gateway,引入依赖(1.SpringCloudGateway依赖;2.Eureka客户端依赖或者nacos的服务发现依赖)。在本案例中使用的是Eureka。 配置Application.yml的网关服务 路由id:路由

    2024年02月08日
    浏览(14)
  • 【微服务】八. 统一网关gateway

    【微服务】八. 统一网关gateway

    网关功能: 身份认证和权限校验 服务路由、负载均衡 请求限流 网关的技术实现 在SpringCloud中网关的实现包括两种: gateway zuul Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。 网关的作用 对

    2024年02月07日
    浏览(13)
  • 微服务中间件--统一网关Gateway

    微服务中间件--统一网关Gateway

    网关功能: 身份认证和权限校验 服务路由、负载均衡 请求限流 网关的技术实现 在SpringCloud中网关的实现包括两种: gateway zuul Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。 搭建网关服务

    2024年02月11日
    浏览(10)
  • satoken+ gateway网关统一鉴权 初版

    satoken+ gateway网关统一鉴权 初版

    本博客内容 参考了satoken官网实现,satoken官网地址: https://sa-token.cc/doc.html#/micro/gateway-auth jinyi-gateway 网关服务 jinyi-user-service 用户服务 2.1 jinyi-user-api 2.2 jinyi-user-client 2.3 jinyi-user-provider jinyi-common 通用服务,定义了一些统一返回类,全局常量(R等) 项目层级关系截图: 3.1jinyi-

    2023年04月20日
    浏览(11)
  • springcloud~gateway网关

    springcloud~gateway网关

    有时间,我们在搭建微服务时,总希望拿一个比较单纯的,没有污染其它代码的项目来从头开始做,今天我们来建设一个最简单的,gateway项目,它被注册到nacos里,路由配置也存到nacos里,动态实现更新配置功能。 版本:com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:2021.0

    2024年02月06日
    浏览(10)
  • 【SpringCloud-5】gateway网关

    【SpringCloud-5】gateway网关

    网关是干啥用的就不用再说了。 sringcloud中的网关,第一代是zuul,但是性能比较差(1.x是阻塞式的,2.x是基于Netty的),然后有了第二代GateWay,基于Reactor模型 异步非阻塞。  springcloud网关就是一系列的filter,在请求到达真实服务的前后,进行拦截处理。   GateWay 核⼼逻辑:路

    2024年02月09日
    浏览(10)
  • SpringCloud:Gateway服务网关

    SpringCloud:Gateway服务网关

    网关(Gateway)是将两个使用不同协议的网络段连接在一起的设备。 网关的作用就是对两个网络段中的使用不同传输协议的数据进行互相的翻译转换。 创建服务 导入依赖 编写启动类 添加配置 Route Predicate Factories :: Spring Cloud Gateway 对所有路径都生效 全局过滤器的作用也是处理

    2024年02月01日
    浏览(17)
  • springcloud(gateway网关)

    springcloud(gateway网关)

    目录 1. gateway简介 1.1 是什么 1.2 作用 1.3 主要特征 1.4 与zuul的主要区别 1.5 主要组件 1.6 架构图 2. 开发示例 2.1 创建一个gateway模块 2.2 与nacos结合使用 2.2.1 默认规则 2.2.2 通过配置文件配置路由 2.2.3 动态路由 SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在

    2024年02月07日
    浏览(10)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包