Spring Gateway基本使用
Spring Gateway基本使用
spring gateway官方文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/
Springcloud Gateway使用了Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架,具有以下特性:
- 基于Spring Framework 5,Project Reactor和Spring Boot2.0进行构建
- 动态路由,能够匹配任何请求属性
- 可以对路由指定Predicate(断言)和Filter(过滤器)
- 集成Hystrix的断路器功能
- 集成Spring Cloud服务发现功能
- 易于编写的Predicate(断言)和Filter(过滤器)
- 请求限流功能
- 支持路径重写
spring gateway的三个重要概念
- Route(路由)
路由时构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
- Predicate(断言)
返回布尔值,判断匹配条件是否符合要求
- Filter(过滤)
指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改
代码实战
导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
注意:spring gateway的webflux模块和web模块冲突,不能导入以下两个依赖,不然启动会报错
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
编写配置文件
server:
port: 9527
spring:
application:
name: gateway
cloud:
gateway:
routes:
# 路由的ID,没有固定规则但要求唯一,建议配合服务名
- id: payment-routh1
# 匹配后提供服务的路由地址
uri: http://localhost:8001
# 断言,路径相匹配的进行路由
predicates:
- Path=/payment/get/**
- id: payment_routh2
uri: http://localhost:8001
predicates:
- Path=/payment/query/**
eureka:
instance:
hostname: gateway-9527
client:
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://127.0.0.1:7001/eureka
访问:http://localhost:9527/payment/get/** 自动转发到地址: http://localhost:8001/payment/get/**
访问:http://localhost:9527/payment/query/** 自动转发到地址: http://localhost:8001/payment/query/**
编码方式配置路由
上面通过配置文件配置了路由相关设置,通过编码方式也可以实现路由配置
编写配置类
package com.yl.gateway.config;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 路由配置
*
* @auther Y-wee
*/
@Configuration
public class GateWayConfig {
/**
* 配置一个id为service_route的路由:
* 当访问地址http://localhost:9527/guonei时自动转发到地址:http://news.baidu.com/guonei
* 当访问地址http://localhost:9527/guonji时自动转发到地址:http://news.baidu.com/guonji
*
* @param routeLocatorBuilder
* @return
*/
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
// 路由构建对象
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
// 配置路由
routes.route("service_route1",
r -> r.path("/guonei")
.uri("http://news.baidu.com/guonei")).build();
routes.route("service_route2",
r -> r.path("/guoji")
.uri("http://news.baidu.com/guoji")).build();
return routes.build();
}
}
配置动态路由
默认情况下Gateway会根据注册中心注册的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能
修改配置文件
server:
port: 9527
spring:
application:
name: gateway
cloud:
gateway:
discovery:
locator:
# 开启从注册中心动态创建路由的功能,利用微服务名进行路由
enabled: true
routes:
- id: payment-routh1
# 匹配后提供服务的路由地址(lb相当于@LoadBalanced,PAYMENT是被调用的服务名)
uri: lb://PAYMENT
predicates:
- Path=/payment/get/**
- id: payment_routh2
uri: lb://PAYMENT
predicates:
- Path=/payment/query/**
eureka:
instance:
hostname: gateway-9527
client:
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://127.0.0.1:7001/eureka
自定义全局过滤器
实现GlobalFilter,Ordered接口
package com.yl.gateway.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Date;
/**
* 自定义全局过滤器
*
* @auther Y-wee
*/
@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
/**
* 自定义过滤逻辑
*
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("come in MyLogGateWayFilter: " + new Date());
String uname = exchange.getRequest().getQueryParams().getFirst("uname");
if (uname == null) {
log.info("用户名为null,非法用户,o(╥﹏╥)o");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
/**
* 此过滤器的优先级顺序,数值越低优先级越高
*
* @return
*/
@Override
public int getOrder() {
return 0;
}
}
记得快乐
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南