系列学习 Gateway 之第 1 篇 —— SpringCloud Gateway 简介,Gateway 入门实例

 

SpringCloud Gateway 官网地址:https://spring.io/projects/spring-cloud-gateway

OK,这一期课程我们来学习 SpringCloud 的另外一个组件:Gateway。

之前我们学习网关服务,主要是 Zuul。Gateway 比 Zuul 的功能更强大,Zuul 2.0 从2019年5月份才推出,目前基本被Gateway 替代了。想了解 Zuul 可以查看博客:https://blog.csdn.net/BiandanLoveyou/article/details/102765142

什么是 Gateway?

SpringCloud Gateway 是 Spring Cloud 官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。这样 REST API 接口服务就被 API 网关保护起来,对所有的调用者透明。因此,隐藏在 API 网关后面的业务系统就可以专注于创建和管理服务,而不用去处理这些策略性的基础设施。

 

Gateway 功能

1、请求接入。能够匹配任何请求属性上的路由,是所有 API 请求的接入点。

2、业务聚合。作为所有后端业务的聚合点。

3、中介策略。可实现路由转发、权限校验、限流控制等。

 

Gateway 几个重要概念

1、路由 Route。这是网关的基本构建内容,它由一个 ID,一个目标 URI,一组断言和一组过滤器构成。如果断言为真,则匹配路由。

2、断言 Predicate(也叫谓词)。输入类型是一个 ServerWebExchange,我们可以使用它来匹配 HTTP 请求的任何内容,比如 Headers 参数等。

3、过滤器 Filter。Gateway 中的过滤器 Filter 分为2种:Gateway Filter 和 Global Filter。过滤器 Filter 将会对请求和响应进行修改处理。

 

Gateway 工作流程

Gateway工作原理:客户端向 Spring Cloud Gateway发出请求。 如果 Gateway Handler Mapping 确定请求与路由匹配(这个时候就用到 predicate),则将其发送到 Gateway Web Handler 处理。Gateway Web Handler 处理请求时会经过一系列的过滤器链。 过滤器链被虚线划分的原因是过滤器链可以在发送代理请求之前或之后执行过滤逻辑。 先执行所有“pre”过滤器逻辑,然后进行代理请求。 在发出代理请求之后,收到代理服务的响应之后执行“post”过滤器逻辑。这跟 zuul 的处理过程很类似。在执行所有“pre”过滤器逻辑时,往往进行了鉴权、限流、日志输出等功能,以及请求头的更改、协议的转换;转发之后收到响应之后,会执行所有“post”过滤器的逻辑,在这里可以响应数据进行了修改,比如响应头、协议的转换等。

 

Gateway 入门实例

为了演示如何使用 Gateway,我们先提前搭建好项目的脚手架。下载代码:https://pan.baidu.com/s/1cIRe7hwJ5eCMycGg44jUCw  提取码:qux4

例子中,使用的 SpringCloud 版本是 Hoxton.SR2,SpringBoot 版本是 2.2.2.RELEASE。使用其它版本会有兼容性问题!!需要注意的是:我们把 spring-boot-starter-web 依赖放入到产品微服务的 pom 和订单微服务的 pom 中,避免启动 Gateway 的时候报错:

**********************************************************

Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway at this time. Please remove spring-boot-starter-web dependency.

**********************************************************

原因是:Gateway 构建于 Spring 5+,基于 Spring Boot 2.x 响应式的、非阻塞式的 API。同时,它支持 websockets,和 Spring 框架紧密集成。报错原因:启动时默认使用了 spring-boot-starter-web 的内置容器,不支持非阻塞,就会产生冲突。

 

下载好的代码结构图,其中 gateway-server 的代码还是空的,我们搭建了注册中心 eureka-server、订单服务 order-server、产品服务 product-server:

需要说明的是,订单服务使用声明式服务调用 FeignClient 来调用产品服务,为了测试简便,代码里写固定产品信息。

依次启动注册中心(端口号 8080)、产品服务(端口号 9090)和订单服务(端口号 9091),然后测试。

进入注册中心查看已注册的微服务:http://127.0.0.1:8080/

然后测试产品服务,浏览器地址输入:http://127.0.0.1:9090/product/1

测试订单服务,浏览器地址输入:http://127.0.0.1:9091/order/1

OK,我们的脚手架已经搭建好,现在开始开发 Gateway 服务。结构图:

首先在 gateway-server 的 pom.xml 配置文件增加 gateway 的依赖,完整配置如下(注意这里的 gateway 是作为本例子的一个模块,父级的依赖已经有了 SpringCloud 的依赖了):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>study</artifactId>
        <groupId>com.study</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>gateway-server</artifactId>

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

</project>

然后新增启动类:GatewayApplication

package com.study;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * @author biandan
 * @description
 * @signature 让天下没有难写的代码
 * @create 2021-05-27 下午 8:36
 */
@EnableEurekaClient
@SpringBootApplication
public class GatewayApplication {

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

在 resources 目录下新增配置文件 application.yml ,我们增加产品微服务的路由和订单微服务的路由。

server:
  port: 9999

eureka:
  instance:
    hostname: 127.0.0.1
  client:
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:8080/eureka/


spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      routes:
        # 路由的 ID,没有固定规则但要求唯一,建议配合服务名
        # 产品微服务路由
      - id: product-server
        # 匹配后提供服务的路由地址
        uri: http://${eureka.instance.hostname}:9090/
        # 断言,路径相匹配的进行路由,配置服务端的方法路径
        predicates:
          - Path=/product/**

        # 订单微服务路由
      - id: order-server
        # 匹配后提供服务的路由地址
        uri: http://${eureka.instance.hostname}:9091/
        predicates:
          - Path=/order/**
          

OK,启动 Gateway 微服务,浏览器地址访问:http://127.0.0.1:9999/product/1  

说明网关帮我们转发到了产品微服务上。

浏览器地址访问:http://127.0.0.1:9999/order/1

说明网关帮我们转到了订单微服务上。

原理:Gateway 根据路由 ID,且断言为真,就去匹配对应的 URI,将请求转发到:http://127.0.0.1:9090/product/1 上,实际上跟我们直接访问产品微服务的效果是一样的。

 

本例子代码:https://pan.baidu.com/s/1GZQdFz_tII_lBf2ANbnuQw  提取码:h8qq

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值