【微服务之服务调用Gateway】Gateway应用示例
一 Gateway介绍
Spring Cloud Gateway 是基于 Spring WebFlux 和 Project Reactor 构建的新一代 API 网关,是 Spring Cloud 官方推荐替代 Zuul 的轻量级、高性能网关。API网关就是指系统的统一入口,提供内部服务的路由中转,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、路由转发等。
网关作用定位:

核心功能:
- 动态路由:支持基于 Predicate(断言)+ Filter 链式匹配,支持路径、主机、方法、Header、参数、Host、Cookie 等多种匹配条件
- 全局/路由级 Filter:提供请求前置、后置处理,支持鉴权、限流、熔断、日志、跨域、请求头添加/移除等
- 内置强大 Route Predicate Factories 和 Route Filter Factories(如 Retry、CircuitBreaker、RequestRateLimiter)
- 与 Spring Cloud LoadBalancer、DiscoveryClient 无缝集成,支持服务发现自动路由(Nacos、Eureka、Consul 等)
- 支持 WebSocket 路由、TLS/SSL 终结
- 深度集成 Resilience4j(限流、熔断、超时)、Sentinel、Spring Cloud CircuitBreaker
典型应用场景:
- 微服务统一入口与流量聚合
- 动态路由与灰度发布、金丝雀发布
- 统一认证鉴权(GatewayFilter + OAuth2/JWT)
- 跨域处理、请求响应改造
- 结合 Hystrix/Resilience4j 实现服务熔断降级
- 前后端分离项目、移动端网关、BFF(Backend For Frontend)模式
二 调用组件SpringCloud Gateway示例
1. 引入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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
2. 在启动类开启@EnableDiscoveryClient注解
@EnableDiscoveryClient
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class,args);
}
}
3. 编写Gateway配置项
spring:
cloud:
gateway:
routes:
- id : order-route
uri: lb://order-service
predicates:
- Path=/api/order/**
order: 1
- id : user-route
uri: lb://user-service
predicates:
- Path=/api/user/**
order: 2
4. Gateway调用流程

三 Gateway路由断言Predicate
SpringCloud Gateway 的断言(Predicates)是路由匹配的核心规则,用于根据请求属性动态决策路由路径。Gateway 内置很多路由断言,部分展示如下所示。

1. Query断言
例如Query 断言,
spring:
cloud:
gateway:
routes:
- id: bingying-route
uri: https://www.bing.com
predicates:
- Path=/search
- name: Query
args:
param: q
regexp: abc
工作原理:
- 提取URL中的查询参数部分(?后面的内容)
- 检查是否存在名为param的参数
- 将参数值与regexp进行正则匹配
- 都满足返回true
请求 你的IP/search?q=abc, 跳转必应搜索页面:

2. 自定义断言
内置的断言可能无法满足业务需求,你有需要满足一定条件才能访问功能的要求。
实现自定义断言,需继承AbstractRoutePredicateFactory,命名规则:XxxRoutePredicateFactory。
// 自定义Role 的断言工厂
@Component
public class RoleRoutePredicateFactory extends AbstractRoutePredicateFactory<RoleRoutePredicateFactory.Config> {
public RoleRoutePredicateFactory(){
super(Config.class);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange serverWebExchange) {
ServerHttpRequest request = serverWebExchange.getRequest();
String first = request.getQueryParams().getFirst(config.param);
return StringUtils.hasText(first)&&first.equals(config.value);
}
};
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("param", "value");
}
@Validated
public static class Config {
@NotEmpty
private String param;
@NotEmpty
private String value;
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
}
添加配置
spring:
cloud:
gateway:
routes:
- id: bingying-route
uri: https://www.bing.com
predicates:
- Path=/search
- name: Query
args:
param: q
regexp: abc
- Role=user,admin
3. 过滤器
在 Gateway 的过滤器中又可以分为 局部过滤器和全局过滤器。局部是用于某一个路由上的,全局是用于所有路由上的。Gateway 内置很多过滤器,部分展示如下所示。

在配置添加内置过滤器。
spring:
cloud:
gateway:
routes:
- id : order-route
uri: lb://order-service
predicates:
- Path=/api/order/**
order: 1
- id : user-route
uri: lb://user-service
predicates:
- Path=/api/user/**
order: 2
- id: bingying-route
uri: https://www.bing.com
predicates:
- Path=/search
- name: Query
args:
param: q
regexp: abc
# 默认filter
default-filters:
- AddResponseHeader=X-Response-Red,111
Gateway支持自定义全局过滤器。
实现自定义全局过滤器,需继承GlobalFilter, Ordered。
// 全局过滤器
@Component
@Slf4j
public class RtGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request= exchange.getRequest();
ServerHttpResponse response=exchange.getResponse();
String uri=request.getURI().toString();
long start=System.currentTimeMillis();
log.info("请求【{}】开始时间:{}",uri,start);
// 后置逻辑
Mono<Void> filter = chain.filter(exchange).doFinally(
(result)->{
long end = System.currentTimeMillis();
log.info("请求【{}】结束时间:{},耗时:{}ms",uri,end,end-start);
}
);
return filter;
}
@Override
public int getOrder() {
return 0;
}
}
Gateway支持自定义过滤器工厂。
实现自定义局部过滤器,可继承AbstractNameValueGatewayFilterFactory。
@Component
public class OnceTokenGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 每次响应之前,添加一次性令牌
return chain.filter(exchange).then(Mono.fromRunnable(()->{
ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = response.getHeaders();
String value = config.getValue();
//UUID 方式
if("uuid".equalsIgnoreCase(value)){
value= UUID.randomUUID().toString();
}
headers.add(config.getName(),value);
}));
}
};
}
}
在所需服务添加配置OnceToken过滤器。
spring:
cloud:
gateway:
routes:
- id : order-route
uri: lb://order-service
predicates:
- Path=/api/order/**
# 配置自定义过滤器工厂
filters:
- OnceToken=X-Response-Token,uuid
order: 1
- id : user-route
uri: lb://user-service
predicates:
- Path=/api/user/**
order: 2
- id: bingying-route
uri: https://www.bing.com
predicates:
- Path=/search
- name: Query
args:
param: q
regexp: abc
# 默认filter
default-filters:
- AddResponseHeader=X-Response-Red,111
4. 网关跨域设置
当一个浏览器请求url的协议、域名、端口三者之间的任意一个与当前页面url不同即为跨域。浏览器在访问网关的时候存在跨域,而网关访问服务是不存在跨域的,因为跨域问题是浏览器与服务之间的问题。
在yml配置文件添加配置。
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowed-origin-patterns: '*'
allowed-headers: '*'
allowed-methods: '*'
routes:
- id : order-route
uri: lb://order-service
predicates:
- Path=/api/order/**
filters:
- OnceToken=X-Response-Token,uuid
order: 1
- id : user-route
uri: lb://user-service
predicates:
- Path=/api/user/**
order: 2
- id: bingying-route
uri: https://www.bing.com
predicates:
- Path=/search
- name: Query
args:
param: q
regexp: abc
# 默认filter
default-filters:
- AddResponseHeader=X-Response-Red,111
也可以采用注入配置类的方式设置。
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", buildConfig());
return new CorsWebFilter(source);
}
private CorsConfiguration buildConfig(){
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("content-type");
corsConfiguration.addAllowedMethod("POST,GET,OPTIONS,DELETE,PUT");
corsConfiguration.setMaxAge(3628800L);
return corsConfiguration;
}
}
更多推荐
所有评论(0)