一、微服务网关核心功能与架构设计
本教程将使用Java技术栈构建一个企业级微服务API网关,具备路由转发、负载均衡、熔断限流等核心功能。
技术选型:
- 核心框架:Spring Cloud Gateway 3.x
- 服务发现:Nacos 2.x
- 限流熔断:Sentinel 1.8
- 性能监控:Micrometer + Prometheus
- 安全认证:JWT + OAuth2
网关核心功能:
- 动态路由配置
- 请求限流与熔断
- 统一认证授权
- 请求/响应改写
- 灰度发布支持
- 全链路监控
架构设计图:
客户端 → API网关 → [认证过滤器] → [限流过滤器] → [路由过滤器] → 微服务集群 ↑ ↑ ↑ │ │ │ 配置中心 监控系统 注册中心
二、项目初始化与基础配置
1. 创建Spring Boot项目
使用Spring Initializr创建项目,主要依赖:
- Spring Web Flux
- Spring Cloud Gateway
- Spring Cloud Alibaba Nacos Discovery
- Spring Cloud Alibaba Sentinel
2. 项目结构
gateway-service/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ ├── config/ # 配置类
│ │ │ ├── filter/ # 网关过滤器
│ │ │ ├── handler/ # 自定义处理器
│ │ │ ├── predicate/ # 自定义路由断言
│ │ │ └── GatewayApplication.java
│ │ └── resources/
│ │ ├── application.yml
│ │ └── application-dev.yml
│ └── test/ # 测试代码
├── pom.xml
└── Dockerfile
3. 基础配置(application.yml)
server:
port: 8080
spring:
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
gateway:
discovery:
locator:
enabled: true
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
management:
endpoints:
web:
exposure:
include: '*'
metrics:
tags:
application: ${spring.application.name}
三、核心功能实现
1. 动态路由配置
创建Nacos动态路由数据源:
@Configuration
public class DynamicRouteConfig {
@Bean
public RouteDefinitionLocator nacosRouteDefinitionLocator(
NacosConfigManager configManager) {
return new NacosRouteDefinitionLocator(
configManager,
new NacosConfigProperties());
}
}
public class NacosRouteDefinitionLocator implements RouteDefinitionLocator {
private final NacosConfigManager configManager;
private final NacosConfigProperties properties;
public NacosRouteDefinitionLocator(
NacosConfigManager configManager,
NacosConfigProperties properties) {
this.configManager = configManager;
this.properties = properties;
}
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
try {
String content = configManager.getConfigService()
.getConfig(
"gateway-routes",
properties.getGroup(),
3000);
List<RouteDefinition> routes = JSON.parseArray(content, RouteDefinition.class);
return Flux.fromIterable(routes);
} catch (NacosException e) {
return Flux.empty();
}
}
}
2. 自定义全局过滤器
实现认证与日志记录:
@Component
@Order(-1)
public class AuthGlobalFilter implements GlobalFilter {
private static final Logger log = LoggerFactory.getLogger(AuthGlobalFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getPath().value();
// 跳过认证的路径
if (path.startsWith("/auth/login") || path.startsWith("/public/")) {
return chain.filter(exchange);
}
// 获取token
String token = request.getHeaders().getFirst("Authorization");
if (StringUtils.isEmpty(token)) {
return unauthorized(exchange);
}
// 验证token
try {
Claims claims = JwtUtil.parseToken(token);
String userId = claims.getSubject();
// 将用户信息添加到请求头
ServerHttpRequest newRequest = request.mutate()
.header("X-User-Id", userId)
.build();
log.info("用户{}访问{}", userId, path);
return chain.filter(exchange.mutate().request(newRequest).build());
} catch (Exception e) {
return unauthorized(exchange);
}
}
private Mono<Void> unauthorized(ServerWebExchange exchange) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type", "application/json");
String body = "{"code": 401, "message": "未授权"}";
DataBuffer buffer = response.bufferFactory().wrap(body.getBytes());
return response.writeWith(Mono.just(buffer));
}
}
3. 集成Sentinel限流
配置Sentinel网关流控:
@Configuration
public class SentinelConfig {
@PostConstruct
public void init() {
// 初始化Sentinel配置
initGatewayRules();
initCustomizedApis();
}
private void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
// 针对特定路由的限流规则
rules.add(new GatewayFlowRule("user-service")
.setCount(100)
.setIntervalSec(1)
.setBurst(50)
.setGrade(RuleConstant.FLOW_GRADE_QPS));
// 全局默认规则
rules.add(new GatewayFlowRule("default")
.setCount(500)
.setIntervalSec(1)
.setBurst(1000)
.setGrade(RuleConstant.FLOW_GRADE_QPS));
GatewayRuleManager.loadRules(rules);
}
private void initCustomizedApis() {
Set<ApiDefinition> definitions = new HashSet<>();
ApiDefinition api1 = new ApiDefinition("user_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem().setPattern("/api/user/**"));
}});
definitions.add(api1);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
}
四、高级功能实现
1. 灰度发布支持
实现基于Header的灰度路由:
@Component
public class GrayRoutePredicateFactory
extends AbstractRoutePredicateFactory<GrayRoutePredicateFactory.Config> {
public GrayRoutePredicateFactory() {
super(Config.class);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
HttpHeaders headers = exchange.getRequest().getHeaders();
String version = headers.getFirst("X-Version");
// 如果请求头包含灰度版本,则路由到灰度服务
if (StringUtils.isNotEmpty(version)
&& version.equals(config.getVersion())) {
return true;
}
// 默认路由到稳定版本
return false;
};
}
public static class Config {
private String version;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
}
// 在路由配置中使用
spring:
cloud:
gateway:
routes:
- id: gray-user-service
uri: lb://user-service-gray
predicates:
- name: Gray
args:
version: v2
- Path=/api/user/**
2. 请求响应改写
实现响应数据统一封装:
@Component
public class ModifyResponseFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getPath().value();
// 只处理API请求
if (!path.startsWith("/api/")) {
return chain.filter(exchange);
}
// 获取原始响应
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
// 包装响应
BodyHandlerServerHttpResponseDecorator decoratedResponse =
new BodyHandlerServerHttpResponseDecorator(originalResponse);
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
class BodyHandlerServerHttpResponseDecorator extends ServerHttpResponseDecorator {
public BodyHandlerServerHttpResponseDecorator(ServerHttpResponse delegate) {
super(delegate);
}
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
// 合并所有buffer
DataBufferFactory dataBufferFactory = new NettyDataBufferFactory(
ByteBufAllocator.DEFAULT);
DataBuffer join = dataBufferFactory.join(dataBuffers);
byte[] content = new byte[join.readableByteCount()];
join.read(content);
DataBufferUtils.release(join);
// 解析原始响应
String originBody = new String(content, StandardCharsets.UTF_8);
Object originData = JSON.parse(originBody);
// 构建统一响应格式
Map<String, Object> result = new LinkedHashMap<>();
result.put("code", 0);
result.put("message", "success");
result.put("data", originData);
result.put("timestamp", System.currentTimeMillis());
// 返回新响应
byte[] newContent = JSON.toJSONString(result)
.getBytes(StandardCharsets.UTF_8);
return bufferFactory.wrap(newContent);
}));
}
return super.writeWith(body);
}
}
}
五、性能优化与监控
1. 网关性能优化
- 启用响应式编程:使用WebFlux非阻塞模型
- 连接池优化:配置HTTP客户端连接池
spring:
cloud:
gateway:
httpclient:
pool:
max-connections: 1000
max-idle-time: 30000
server:
compression:
enabled: true
mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
min-response-size: 1024
2. 监控与告警
集成Prometheus监控:
@Configuration
public class MetricsConfig {
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
return registry -> registry.config().commonTags(
"application", "gateway-service",
"region", System.getenv().getOrDefault("REGION", "unknown"));
}
}
// 自定义监控指标
@Component
public class GatewayMetrics {
private final Counter requestCounter;
private final Timer requestTimer;
public GatewayMetrics(MeterRegistry registry) {
this.requestCounter = Counter.builder("gateway.requests.total")
.description("Total number of gateway requests")
.tags("status", "all")
.register(registry);
this.requestTimer = Timer.builder("gateway.request.duration")
.description("Request processing time")
.register(registry);
}
public void recordRequest(String path, String method, long duration, boolean success) {
requestCounter.increment();
requestTimer.record(duration, TimeUnit.MILLISECONDS);
// 可以添加更多细分指标
}
}
六、容器化部署
1. Dockerfile配置
# 使用多阶段构建
FROM maven:3.8.4-jdk-11 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src /app/src
RUN mvn package -DskipTests
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=build /app/target/gateway-service-*.jar /app/gateway.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "gateway.jar"]
2. Kubernetes部署文件
# gateway-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gateway
spec:
replicas: 3
selector:
matchLabels:
app: gateway
template:
metadata:
labels:
app: gateway
spec:
containers:
- name: gateway
image: your-registry/gateway-service:1.0.0
ports:
- containerPort: 8080
resources:
limits:
cpu: "2"
memory: 2Gi
requests:
cpu: "1"
memory: 1Gi
env:
- name: SPRING_PROFILES_ACTIVE
value: prod
- name: JAVA_OPTS
value: "-Xmx1536m -Xms1536m"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
# gateway-service.yaml
apiVersion: v1
kind: Service
metadata:
name: gateway
spec:
selector:
app: gateway
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
七、总结与扩展方向
本教程详细介绍了如何使用Java构建企业级微服务网关:
- 基于Spring Cloud Gateway实现动态路由
- 集成Nacos实现服务发现与配置管理
- 使用Sentinel实现熔断限流
- 实现统一认证与灰度发布
- 优化网关性能与监控
进一步扩展方向:
- 支持GraphQL网关
- 实现API全生命周期管理
- 集成OpenAPI/Swagger文档
- 增加WebSocket支持
- 开发自定义管理控制台
完整项目代码已上传GitHub:https://github.com/example/java-api-gateway