微服务网关统一鉴权、限流、日志实战

作者:洛水石
> 标签:微服务网关、Spring Cloud Gateway、鉴权、限流、日志


一、为什么需要微服务网关

1.1 单体应用 vs 微服务架构

在单体应用中,所有功能模块共享一个入口:

``_INLINE

客户端 → Nginx → 单体应用(用户/订单/支付模块)

__`_INLINE

微服务架构下,服务数量爆炸式增长:

__`_INLINE

客户端 → 用户服务:8081

→ 订单服务:8082

→ 支付服务:8083

→ 库存服务:8084

→ 物流服务:8085

→ ...

__`_INLINE

没有网关的问题

  • 客户端需要维护多个服务地址

  • 每个服务都要实现鉴权、限流、日志

  • 跨域问题需要在每个服务处理

  • 服务升级时客户端需要同步修改

1.2 网关的核心价值

__`_INLINE

┌─────────────────────────────────────────────┐

│ 微服务网关 │

│ ┌─────────┬─────────┬─────────┬─────────┐ │

│ │ 路由 │ 鉴权 │ 限流 │ 日志 │ │

│ │ Routing │ Auth │ Rate │ Log │ │

│ │ │ │ Limit │ │ │

│ └─────────┴─────────┴─────────┴─────────┘ │

└─────────────────────────────────────────────┘

│ │ │

用户服务 订单服务 支付服务 库存服务

__`_INLINE

网关统一处理

  • 路由转发 :/api/users → 用户服务

  • 统一鉴权 :JWT Token 校验

  • 限流熔断 :保护后端服务

  • 日志追踪 :请求全链路记录


二、Spring Cloud Gateway 快速入门

2.1 核心概念

|-----------|------|-------------------------------------|
| 概念 | 说明 | 示例 |
| Route | 路由规则 | /api/users/** → lb://user-service |
| Predicate | 断言条件 | Path、Method、Header |
| Filter | 过滤器 | 鉴权、限流、日志 |

2.2 基础配置

pom.xml 依赖

__`__INLINE_xml

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-gateway</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-loadbalancer</artifactId>

</dependency>

</dependencies>

__`_INLINE

application.yml 基础路由

__`__INLINE_yaml

server:

port: 8080

spring:

application:

name: gateway-service

cloud:

gateway:

routes:

用户服务路由

  • id: user-service

uri: lb://user-service

predicates:

  • Path=/api/users/**

filters:

  • StripPrefix=1

订单服务路由

  • id: order-service

uri: lb://order-service

predicates:

  • Path=/api/orders/**

filters:

  • StripPrefix=1

支付服务路由

  • id: pay-service

uri: lb://pay-service

predicates:

  • Path=/api/pay/**

filters:

  • StripPrefix=1

__`_INLINE

路由说明

  • __lb://_INLINE:使用 LoadBalancer 负载均衡

  • _StripPrefix=1__INLINE:去掉第一个前缀 /api

  • 例如:__/api/users/info → /users/info__INLINE_


三、统一鉴权实战

3.1 JWT 鉴权方案

__`_INLINE

┌─────────┐ ┌─────────┐ ┌─────────┐

│ 客户端 │ ──────→ │ 网关 │ ──────→ │ 业务服务 │

└─────────┘ └─────────┘ └─────────┘

│ │

│ 1.登录获取Token │

│←─────────────────│

│ │

│ 2.请求携带Token │

│─────────────────→│ 3.校验Token

│ │

│ 4.返回数据 │ 5.转发请求

│←─────────────────│←───────────────│

__`_INLINE

3.2 全局鉴权过滤器

__`__INLINE_java

@Component

@Slf4j

public class AuthGlobalFilter implements GlobalFilter, Ordered {

@Autowired

private JwtTokenProvider tokenProvider;

// 白名单路径(不需要鉴权)

private static final List<String__QUOTE_1__

3.3 Token 刷新机制

__`__INLINE_java

@Component

public class TokenRefreshFilter implements GlobalFilter, Ordered {

@Autowired

private JwtTokenProvider tokenProvider;

@Override

public Mono<Void__QUOTE_2__

3.4 权限控制(RBAC)

__`__INLINE_java

@Component

public class RbacAuthFilter implements GlobalFilter, Ordered {

// URL-角色映射配置

private static final Map<String, List<String>QUOTE_3


四、网关限流实战

4.1 限流算法选择

|------|----------|-------|
| 算法 | 特点 | 适用场景 |
| 固定窗口 | 简单,但存在突刺 | 简单限流 |
| 滑动窗口 | 平滑,精度高 | 精确限流 |
| 令牌桶 | 允许突发,平滑 | API网关 |
| 漏桶 | 强制平滑输出 | 流量整形 |

网关推荐:令牌桶算法

4.2 Redis + Lua 分布式限流

__`__INLINE_java

@Component

public class RateLimitFilter implements GlobalFilter, Ordered {

@Autowired

private StringRedisTemplate redisTemplate;

// 限流配置:路径 -QUOTE_4

4.3 热点参数限流(Sentinel 集成)

__`__INLINE_java

@Configuration

public class SentinelGatewayConfig {

@PostConstruct

public void init() {

// 注册网关规则

GatewayRuleManager.loadRules(Arrays.asList(

// 用户API限流:100 QPS

new GatewayFlowRule("user-service")

.setCount(100)

.setIntervalSec(1),

// 订单API限流:50 QPS,热点参数限流

new GatewayFlowRule("order-service")

.setCount(50)

.setIntervalSec(1)

.setParamItem(new GatewayParamFlowItem()

.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)

.setFieldName("userId")

),

// 支付API严格限流:10 QPS

new GatewayFlowRule("pay-service")

.setCount(10)

.setIntervalSec(1)

.setGrade(RuleConstant.FLOW_GRADE_QPS)

));

}

}

__`_INLINE


五、全链路日志追踪

5.1 TraceID 传递

__`__INLINE_java

@Component

@Slf4j

public class TraceFilter implements GlobalFilter, Ordered {

public static final String TRACE_ID_HEADER = "X-Trace-Id";

public static final String SPAN_ID_HEADER = "X-Span-Id";

@Override

public Mono<Void__QUOTE_5__

5.2 异步日志收集

__`__INLINE_java

@Component

@Slf4j

public class AccessLogFilter implements GlobalFilter, Ordered {

@Autowired

private AccessLogProducer logProducer;

@Override

public Mono<Void__QUOTE_6__

5.3 ELK 日志查询

__`__INLINE_json

// Kibana 查询DSL

{

"query": {

"bool": {

"must": [

{ "match": { "traceId": "abc123def456" } },

{ "range": { "timestamp": { "gte": "now-1h" } } }

]

}

},

"sort": [{ "timestamp": "asc" }],

"aggs": {

"latency_percentiles": {

"percentiles": { "field": "duration", "percents": [50, 95, 99] }

}

}

}

__`_INLINE


六、完整配置示例

6.1 application.yml

__`__INLINE_yaml

spring:

cloud:

gateway:

默认过滤器(所有路由生效)

default-filters:

  • name: Retry

args:

retries: 3

statuses: BAD_GATEWAY,SERVICE_UNAVAILABLE

  • name: CircuitBreaker

args:

name: default

fallbackUri: forward:/fallback

全局跨域配置

globalcors:

cors-configurations:

'[/**]':

allowedOrigins: "*"

allowedMethods: GET,POST,PUT,DELETE,OPTIONS

allowedHeaders: "*"

allowCredentials: false

maxAge: 3600

路由配置

routes:

  • id: user-service

uri: lb://user-service

predicates:

  • Path=/api/users/**

  • Method=GET,POST,PUT,DELETE

filters:

  • StripPrefix=1

  • name: RequestRateLimiter

args:

redis-rate-limiter.replenishRate: 100

redis-rate-limiter.burstCapacity: 150

key-resolver: "#{@ipKeyResolver}"

  • name: Hystrix

args:

name: user-service

fallbackUri: forward:/fallback/user

  • id: order-service

uri: lb://order-service

predicates:

  • Path=/api/orders/**

filters:

  • StripPrefix=1

  • name: RequestRateLimiter

args:

redis-rate-limiter.replenishRate: 50

redis-rate-limiter.burstCapacity: 80

熔断器配置

hystrix:

command:

default:

execution:

isolation:

thread:

timeoutInMilliseconds: 5000

circuitBreaker:

requestVolumeThreshold: 10

sleepWindowInMilliseconds: 10000

errorThresholdPercentage: 50

__`_INLINE

6.2 网关启动类

__`__INLINE_java

@SpringBootApplication

@EnableDiscoveryClient

public class GatewayApplication {

public static void main(String[] args) {

SpringApplication.run(GatewayApplication.class, args);

}

@Bean

public KeyResolver ipKeyResolver() {

return exchange -QUOTE_7


七、性能优化建议

7.1 网关性能指标

|-----|-----|------|
| 指标 | 目标值 | 优化方案 |
| 吞吐量 | | |

7.2 生产环境配置

__`__INLINE_yaml

JVM 参数

-Xms2g -Xmx2g

-XX:+UseG1GC

-XX:MaxGCPauseMillis=100

-Dreactor.netty.ioWorkerCount=16

Netty 配置

spring:

cloud:

gateway:

httpclient:

connect-timeout: 2000

response-timeout: 5s

pool:

type: elastic

max-connections: 1000

max-idle-time: 10s

__``


总结

微服务网关三大核心能力:

|--------------|---------------|------------------|
| 能力 | 关键实现 | 注意事项 |
| **统一鉴权** | JWT + 全局过滤器 | Token刷新、RBAC权限控制 |
| **限流保护** | 令牌桶 + Redis | 分布式限流、热点参数限流 |
| **日志追踪** | TraceID + ELK | 异步收集、全链路追踪 |

作者:洛水石 | 架构进阶 | 微服务网关实战

作者:洛水石 | 架构进阶 | Java高并发实战

相关推荐
超级无敌葛大侠1 小时前
Redis主从复制
java·redis
殷紫川2 小时前
90% Java 开发都踩过坑的 @Resource 与 @Autowired
java
程序员老邢2 小时前
【产品底稿 12】工程架构最终定型:完整模块拆分、分包规范、层级依赖与开发规约全清单
微服务·架构·springboot·多模块·技术债务
kybs19912 小时前
springboot租车系统--附源码68701
java·hadoop·spring boot·python·django·asp.net·php
过期动态3 小时前
MySQL中的约束
android·java·数据库·spring boot·mysql
wxin_VXbishe3 小时前
springboot新能源车充电站管理系统小程序-计算机毕业设计源码29213
java·c++·spring boot·python·spring·django·php
程序员陆通3 小时前
月烧 400 刀到不到 20 刀:我是怎么把 OpenClaw 的 Token 账单砍掉 95% 的
java·前端·数据库
代码漫谈4 小时前
一文学习 SpringBoot 的 application.yml 配置,基于 Spring Boot 3.2.x
java·spring boot·spring·配置文件
SamDeepThinking4 小时前
程序员如何接受工作内容毫无意义?
java·后端·程序员