一、Spring Cloud Gateway
1.1 概述
所谓的网关就是指系统的统一入口,它封装了运用程序的内部结构,为客户端提供统一的服务,一些与业务功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、路由转发等。
Spring Cloud Gateway
是Spring Cloud
推出的第二代网关,是由WebFlux
、Netty
、Reactor
实现的响应式的API
网关,需要 Spring Boot
和 Spring Webflux
提供的 Netty
环境运行,不能在传统的Servlet
容器中工作,也不能构建成War
包。
Spring Cloud Gateway
旨在为微服务提供一种简单且有效的API
路由的管理方式,并基于Filter
的方式提供网关的基本功能。
1.2 核心概念
- 路由(
Route
):
路由是网关中最重要的部分,路由信息包括一个ID
、一个目的URL
、一组断言工厂、一组Filter
组成。如果断言为真,则说明请求的URL
和配置的路由匹配。
- 断言(
Predicate
):
Java8
中的断言函数,输入类型是Spring FrameworkServerWebExchange
。断言函数运行开发者去定义匹配Http Request
中的任何信息,比如请求头和参数。
- 过滤器(
Filter
):
分为:Gateway Filter
和Global Filter
,Filter
可以对请求和响应进行处理。
1.3 工作流程
客户端向 Spring Cloud Gateway
发出请求。如果 Gateway Handler Mapping
确定请求与路由匹配,则将其发送到 Gateway Web Handler
。此处理程序通过特定于请求的过滤器链运行请求。过滤器被虚线分开的原因是过滤器可以在发送代理请求之前和之后运行逻辑处理。
- 请求前过滤器(
pre
):参数校验、权限校验、流量监控、日志输出、协议转换。 - 请求后过滤器(
post
):响应内容和响应头修改,日志输出,流量监控等
1.4 内置断言Predicates
二、准备条件
已完成SpringCloud初始项目的手脚架搭建,详情请见:Spring Cloud融合Nacos实现服务的注册与发现 | Spring Cloud 4
三、项目搭建
3.1 新建模块gateway
3.2 引入依赖
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
若集成nacos
实现服务配置中心,还需引入:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
spring cloud alibaba 2021.0.1.0
版本后,spring-cloud-starter-alibaba-nacos-config
模块移除了spring-cloud-starter-bootstrap
依赖
3.3 编写配置文件
bootstrap.yml
server:
port: 9999
spring:
application:
name: @artifactId@
cloud:
nacos:
username: @nacos.username@
password: @nacos.password@
discovery:
enabled: true
register-enabled: true
server-addr: 192.168.0.31:8848
config:
server-addr: 192.168.0.31:8848
group: DEFAULT_GROUP
file-extension: yaml
# 网关gateway配置
gateway:
# 路由配置
routes:
- id: http-provider-route # 路由的唯一标识;http-provider-route
uri: http://localhost:4000 # 需要转发的地址
# 断言规则,用于路由规则的匹配
predicates:
# 因为是字符串所以可以这样写,自动映射
# http://localhost:9999/provider/sayHello?world=hello 路由到↓
# http://localhost:4000/provider/sayHello?world=hello
- Path=/provider/**
# 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
filters:
# 转发之前去掉1层路径(内置的一种过滤器)
# /provider/sayHello?world=hello 路由到↓
# /sayHello?world=hello
# 最终变成http://localhost:4000/sayHello?world=hello
- StripPrefix=1
- id: nacos-discovery-http-provider-route # 路由的唯一标识;nacos-discovery-http-provider-route
# 需要转发的地址 lb:使用nacos中本地的负载均衡策略 nacos-discovery-http-provider 服务名
# 需maven引入spring-cloud-starter-loadbalancer,其可切换负载均衡策略
uri: lb://nacos-discovery-http-provider
# 断言规则,用于路由规则的匹配
predicates:
# 因为是字符串所以可以这样写,自动映射
# http://localhost:9999/lb/sayHello?world=hello 路由到↓ nacos-discovery-http-provider集群中的一个
# http://localhost:4000/provider/sayHello?world=hello
- Path=/lb/**
# 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
filters:
# 转发之前去掉1层路径(内置的一种过滤器)
# /lb/sayHello?world=hello 路由到↓ nacos-discovery-http-provider集群中的一个
# /sayHello?world=hello
# 最终变成http://localhost:4000/sayHello?world=hello
- StripPrefix=1