外卖API对接实战:Spring Cloud Gateway在霸王餐接口网关中的配置与限流
·
外卖API对接实战:Spring Cloud Gateway在霸王餐接口网关中的配置与限流
在外卖平台对接“霸王餐”营销能力的架构中,为统一鉴权、路由转发、安全防护与流量控制,我们采用Spring Cloud Gateway作为API网关。本文以baodanbao-gateway项目为例,详解路由配置、自定义过滤器、Redis+RequestRateLimiter限流等核心实践。
基础路由配置
在application.yml中定义路径匹配与服务转发:
spring:
cloud:
gateway:
routes:
- id: baodanbao-api
uri: lb://baodanbao-api-service
predicates:
- Path=/api/baodanbao/**
filters:
- StripPrefix=1
所有/api/baodanbao/**请求将被转发至baodanbao-api-service微服务,并去除第一级路径前缀。
自定义全局鉴权过滤器
实现基于appId和签名的请求合法性校验:
// baodanbao.com.cn.gateway.filter.AuthGlobalFilter.java
package baodanbao.com.cn.gateway.filter;
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.Arrays;
import java.util.List;
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
private static final List<String> ALLOWED_APP_IDS = Arrays.asList("waimai_1001", "meituan_2002");
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String appId = exchange.getRequest().getHeaders().getFirst("X-App-Id");
String sign = exchange.getRequest().getHeaders().getFirst("X-Sign");
if (appId == null || sign == null || !ALLOWED_APP_IDS.contains(appId)) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// 简化:实际应校验sign是否由appId+body+timestamp生成
if (!isValidSignature(appId, sign)) {
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
private boolean isValidSignature(String appId, String sign) {
// 此处应调用baodanbao.com.cn.common.SecurityUtils.verify()
return sign.equals("mock_sign_for_" + appId);
}
@Override
public int getOrder() {
return -100; // 高优先级
}
}

基于Redis的令牌桶限流
使用RequestRateLimiter结合Redis实现分布式限流:
spring:
cloud:
gateway:
routes:
- id: baodanbao-api
uri: lb://baodanbao-api-service
predicates:
- Path=/api/baodanbao/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10 # 每秒生成10个令牌
redis-rate-limiter.burstCapacity: 20 # 最大突发20
key-resolver: "#{@remoteAddrKeyResolver}"
定义KeyResolver按客户端IP限流:
// baodanbao.com.cn.gateway.config.KeyResolverConfig.java
package baodanbao.com.cn.gateway.config;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Configuration
public class KeyResolverConfig {
@Bean
public KeyResolver remoteAddrKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}
}
添加Redis依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
确保Redis连接配置:
spring:
redis:
host: redis.baodanbao.com.cn
port: 6379
异常处理与统一响应
自定义ErrorWebExceptionHandler返回标准格式:
// baodanbao.com.cn.gateway.handler.GlobalErrorWebExceptionHandler.java
@Component
@Order(-2)
public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {
public GlobalErrorWebExceptionHandler(ErrorAttributes errorAttributes,
Resources resources,
ApplicationContext applicationContext) {
super(errorAttributes, resources, applicationContext);
}
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
}
private Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
Throwable error = getError(request);
String message = "系统繁忙";
if (error instanceof ResponseStatusException) {
message = error.getMessage();
}
return ServerResponse.status(HttpStatus.OK)
.bodyValue(Map.of("code", "GATEWAY_ERROR", "message", message));
}
}
健康检查与可观测性
暴露Actuator端点供监控:
management:
endpoints:
web:
exposure:
include: health,gateway,routes
endpoint:
health:
show-details: always
通过/actuator/gateway/routes可实时查看路由状态。
通过上述配置,Spring Cloud Gateway为“霸王餐”API提供了安全、稳定、可控的入口层,有效隔离外部风险并保障核心服务稳定性。
本文著作权归 俱美开放平台 ,转载请注明出处!
更多推荐




所有评论(0)