大家好,我是小悟。
一、API Gateway概述
什么是API Gateway?
API Gateway(API网关)是一个服务器端组件,作为客户端与后端微服务之间的单一入口点。它负责请求路由、组合、协议转换以及跨领域功能处理。
主要功能:
- 请求路由:将客户端请求路由到对应的后端服务
- 负载均衡:在多个服务实例间分发请求
- 身份验证和授权:统一处理安全认证
- 限流和熔断:防止服务过载
- 监控和日志:集中收集请求指标
- 协议转换:处理不同协议间的转换
- 缓存:缓存响应以提升性能
二、Spring Cloud Gateway整合步骤
环境要求
- JDK 11+
- Spring Boot 2.7+
- Maven 3.6+
步骤1:创建父工程
<!-- pom.xml -->
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>gateway-demo</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.14</version>
<relativePath/>
</parent>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.8</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>api-gateway</module>
</modules>
</project>
步骤2:创建Gateway服务
<!-- api-gateway/pom.xml -->
<?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>gateway-demo</artifactId>
<groupId>com.example</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>api-gateway</artifactId>
<dependencies>
<!-- Spring Cloud Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 服务发现 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 配置中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- 监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 安全 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
</project>
步骤3:主启动类
// ApiGatewayApplication.java
package com.example.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
步骤4:基础配置
# application.yml
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 启用服务发现
lower-case-service-id: true
routes:
# 用户服务路由
- id: user-service
uri: lb://USER-SERVICE
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: userService
fallbackUri: forward:/fallback/user
# 商品服务路由
- id: product-service
uri: lb://PRODUCT-SERVICE
predicates:
- Path=/api/products/**
filters:
- StripPrefix=1
- AddRequestHeader=X-Request-From, gateway
# 订单服务路由
- id: order-service
uri: lb://ORDER-SERVICE
predicates:
- Path=/api/orders/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10 # 每秒10个请求
redis-rate-limiter.burstCapacity: 20 # 最大突发容量20
key-resolver: "#{@userKeyResolver}"
# 直接路由示例
- id: baidu-route
uri: https://www.baidu.com
predicates:
- Path=/baidu/**
# 全局过滤器配置
default-filters:
- AddResponseHeader=X-Response-Time, ${spring.application.name}
# 负载均衡配置
loadbalancer:
retry:
enabled: true
# 熔断器配置
resilience4j:
circuitbreaker:
instances:
userService:
slidingWindowSize: 10
failureRateThreshold: 50
waitDurationInOpenState: 10000
# 监控端点
management:
endpoints:
web:
exposure:
include: health,info,gateway
endpoint:
gateway:
enabled: true
步骤5:自定义过滤器
// JwtAuthenticationFilter.java
package com.example.gateway.filter;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
@Component
public class JwtAuthenticationFilter extends AbstractGatewayFilterFactory<JwtAuthenticationFilter.Config> {
@Value("${jwt.secret}")
private String jwtSecret;
public JwtAuthenticationFilter() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
String path = exchange.getRequest().getURI().getPath();
// 跳过认证的路径
if (config.getWhiteList().stream().anyMatch(path::startsWith)) {
return chain.filter(exchange);
}
// 获取token
String token = exchange.getRequest()
.getHeaders()
.getFirst(HttpHeaders.AUTHORIZATION);
if (token == null || !token.startsWith("Bearer ")) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
try {
// 验证JWT
Claims claims = Jwts.parser()
.setSigningKey(jwtSecret)
.parseClaimsJws(token.substring(7))
.getBody();
// 添加用户信息到header
exchange.getRequest().mutate()
.header("X-User-Id", claims.getSubject())
.header("X-User-Roles", claims.get("roles", String.class))
.build();
} catch (Exception e) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
};
}
public static class Config {
private java.util.List<String> whiteList = new java.util.ArrayList<>();
public java.util.List<String> getWhiteList() {
return whiteList;
}
public void setWhiteList(java.util.List<String> whiteList) {
this.whiteList = whiteList;
}
}
}
步骤6:全局过滤器
// GlobalLoggingFilter.java
package com.example.gateway.filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class GlobalLoggingFilter implements GlobalFilter, Ordered {
private static final Logger logger = LoggerFactory.getLogger(GlobalLoggingFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
long startTime = System.currentTimeMillis();
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
long duration = System.currentTimeMillis() - startTime;
logger.info("Request: {} {} - Status: {} - Time: {}ms",
exchange.getRequest().getMethod(),
exchange.getRequest().getURI().getPath(),
exchange.getResponse().getStatusCode(),
duration);
}));
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
步骤7:限流配置
// RateLimiterConfig.java
package com.example.gateway.config;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;
@Configuration
public class RateLimiterConfig {
@Bean
public KeyResolver userKeyResolver() {
return exchange -> {
// 根据用户限流
String userId = exchange.getRequest()
.getHeaders()
.getFirst("X-User-Id");
if (userId != null) {
return Mono.just(userId);
}
// 根据IP限流
String ip = exchange.getRequest()
.getRemoteAddress()
.getAddress()
.getHostAddress();
return Mono.just(ip);
};
}
@Bean
public KeyResolver apiKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getURI().getPath()
);
}
}
步骤8:熔断降级处理
// FallbackController.java
package com.example.gateway.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Map;
@RestController
public class FallbackController {
@GetMapping("/fallback/user")
public Mono<ResponseEntity<Map<String, Object>>> userServiceFallback() {
return Mono.just(ResponseEntity
.status(HttpStatus.SERVICE_UNAVAILABLE)
.body(createFallbackResponse("User service is temporarily unavailable")));
}
@GetMapping("/fallback/product")
public Mono<ResponseEntity<Map<String, Object>>> productServiceFallback() {
return Mono.just(ResponseEntity
.status(HttpStatus.SERVICE_UNAVAILABLE)
.body(createFallbackResponse("Product service is temporarily unavailable")));
}
private Map<String, Object> createFallbackResponse(String message) {
Map<String, Object> response = new HashMap<>();
response.put("success", false);
response.put("message", message);
response.put("timestamp", System.currentTimeMillis());
response.put("code", 503);
return response;
}
}
步骤9:安全配置
// SecurityConfig.java
package com.example.gateway.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http
.csrf().disable()
.authorizeExchange()
.pathMatchers("/actuator/**", "/fallback/**").permitAll()
.pathMatchers("/api/auth/**").permitAll()
.pathMatchers("/api/public/**").permitAll()
.anyExchange().authenticated()
.and()
.httpBasic().disable()
.formLogin().disable()
.build();
}
}
步骤10:健康检查配置
// HealthCheckConfig.java
package com.example.gateway.config;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
@Component
public class HealthCheckConfig implements ReactiveHealthIndicator {
@Override
public Mono<Health> health() {
return checkDownstreamServiceHealth()
.onErrorResume(ex -> Mono.just(
Health.down().withException(ex).build())
);
}
private Mono<Health> checkDownstreamServiceHealth() {
// 检查下游服务健康状态
return Mono.just(Health.up().build());
}
}
步骤11:动态路由配置(基于数据库)
// DynamicRouteService.java
package com.example.gateway.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
import java.util.List;
@Service
public class DynamicRouteService {
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
@Autowired
private ApplicationEventPublisher publisher;
@PostConstruct
public void initRoutes() {
// 从数据库加载路由配置
loadRoutesFromDatabase();
}
private void loadRoutesFromDatabase() {
// 实现从数据库加载路由的逻辑
}
public void addRoute(RouteDefinition definition) {
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
refreshRoutes();
}
public void updateRoute(RouteDefinition definition) {
deleteRoute(definition.getId());
addRoute(definition);
}
public void deleteRoute(String routeId) {
routeDefinitionWriter.delete(Mono.just(routeId)).subscribe();
refreshRoutes();
}
private void refreshRoutes() {
publisher.publishEvent(new RefreshRoutesEvent(this));
}
}
三、测试验证
创建测试配置
# application-test.yml
spring:
cloud:
gateway:
routes:
- id: test-route
uri: http://httpbin.org:80
predicates:
- Path=/get/**
filters:
- AddRequestHeader=Hello, World
logging:
level:
org.springframework.cloud.gateway: DEBUG
com.example.gateway: DEBUG
编写测试用例
// GatewayTest.java
package com.example.gateway;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
import org.springframework.test.web.reactive.server.WebTestClient;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureWireMock(port = 8081)
class GatewayTest {
@Autowired
private WebTestClient webClient;
@Test
void testRoute() {
stubFor(get(urlEqualTo("/test"))
.willReturn(aResponse()
.withBody("test")
.withHeader("Content-Type", "text/plain")));
webClient.get()
.uri("/test")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("test");
}
}
四、部署配置
Docker部署配置
# Dockerfile
FROM openjdk:11-jre-slim
VOLUME /tmp
COPY target/api-gateway-*.jar app.jar
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"]
EXPOSE 8080
Kubernetes配置
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-gateway
spec:
replicas: 3
selector:
matchLabels:
app: api-gateway
template:
metadata:
labels:
app: api-gateway
spec:
containers:
- name: api-gateway
image: api-gateway:latest
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 30
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 15
五、总结
优势特点:
- 性能优秀:基于WebFlux响应式编程,非阻塞IO,高并发能力强
- 功能全面:内置路由、过滤、熔断、限流等核心功能
- 易于扩展:支持自定义过滤器和全局过滤器
- 云原生友好:完美整合Spring Cloud生态
- 配置灵活:支持YAML配置、Java配置和动态配置
最佳实践:
- 路由设计:合理规划API路径,遵循RESTful规范
- 安全防护:统一认证授权,实施请求验证
- 性能监控:集成监控系统,实时收集指标
- 容错处理:配置熔断降级,确保系统可用性
- 版本管理:支持API版本控制,平滑升级
注意事项:
- 网关应保持轻量级,避免复杂业务逻辑
- 合理配置超时时间和重试机制
- 实施灰度发布和蓝绿部署
- 定期更新和维护路由规则
- 监控网关性能,及时扩容
通过Spring Cloud Gateway,我们可以构建一个高性能、可扩展、安全的API网关,有效管理和保护微服务架构中的API接口,提升系统的整体稳定性和可维护性。

谢谢你看我的文章,既然看到这里了,如果觉得不错,随手点个赞、转发、在看三连吧,感谢感谢。那我们,下次再见。
您的一键三连,是我更新的最大动力,谢谢
山水有相逢,来日皆可期,谢谢阅读,我们再会
我手中的金箍棒,上能通天,下能探海