每日Java面试场景题知识点之-微服务中的网关架构
每日Java面试场景题知识点之-微服务中的网关架构
一、为什么微服务需要网关?
在微服务架构中,系统被拆分为多个独立服务,每个服务都有独立的网络地址和端口。如果客户端直接与各个微服务通信,会面临以下问题:
- 客户端需要知道每个服务的地址,耦合度极高
- 每个服务都需要独立处理跨域、鉴权、限流等公共逻辑,代码冗余严重
- 内部服务地址直接暴露,存在安全隐患
- 服务拆分或扩缩容时,客户端需要同步修改,运维成本极高
网关(API Gateway)作为微服务架构中的统一入口,完美解决了上述痛点。它是所有客户端请求的"前门",负责将请求路由到对应的微服务,同时承载了众多非业务性的横切关注点。
二、网关的核心功能
2.1 动态路由
路由是网关最基础的功能。它根据请求的URL、Header、参数等条件,将请求转发到对应的下游服务。
Spring Cloud Gateway中的路由配置示例:
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
关键点解析:
- id:路由唯一标识
- uri:目标服务地址,
lb://表示基于注册中心的负载均衡 - predicates:路由断言,匹配条件
- filters:路由过滤器,对请求/响应进行处理
结合Nacos等注册中心,路由可实现动态感知——服务实例上下线时,网关自动更新路由表,无需重启。
2.2 统一鉴权
网关是做统一鉴权的最佳位置,避免每个微服务都重复实现鉴权逻辑。
常见鉴权流程:
- 客户端携带Token请求网关
- 网关全局过滤器拦截请求,解析并验证Token
- 验证通过后,将用户信息放入请求Header传递给下游服务
- 验证失败,直接返回401 Unauthorized
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
if (StringUtils.isBlank(token) || !validateToken(token)) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// 解析用户信息,放入Header透传给下游服务
String userId = parseUserId(token);
ServerHttpRequest request = exchange.getRequest().mutate()
.header("X-User-Id", userId)
.build();
return chain.filter(exchange.mutate().request(request).build());
}
@Override
public int getOrder() {
return -1; // 优先级最高
}
}
2.3 限流熔断
限流 protects系统在高并发下不被冲垮,熔断 则防止下游服务故障引发级联崩溃。
限流实现(基于Redis + Lua脚本)
Spring Cloud Gateway内置了RequestRateLimiter过滤器,基于Redis实现令牌桶限流:
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100 # 每秒填充令牌数
redis-rate-limiter.burstCapacity: 200 # 令牌桶容量
key-resolver: "#{@userKeyResolver}" # 限流维度
@Bean
public KeyResolver userKeyResolver() {
// 按用户ID限流
return exchange -> Mono.just(
exchange.getRequest().getHeaders().getFirst("X-User-Id")
);
}
熔断降级(结合Sentinel)
Alibaba Sentinel与Spring Cloud Gateway的集成是目前主流的熔断方案:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
scg:
fallback:
mode: response
response-status: 200
response-body: '{"code":503,"message":"服务降级"}'
Sentinel支持按路由ID或API分组配置流控规则,实现精细化熔断策略。
2.4 请求日志与监控
网关作为流量入口,是采集请求日志和监控指标的天然节点:
- 访问日志:记录每个请求的路径、耗时、状态码
- 链路追踪:生成TraceId,注入请求Header,实现分布式链路追踪
- 指标采集:QPS、响应时间、错误率等,对接Prometheus + Grafana
@Component
public class LoggingGlobalFilter implements GlobalFilter, Ordered {
private static final Logger log = LoggerFactory.getLogger(LoggingGlobalFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String traceId = UUID.randomUUID().toString();
ServerHttpRequest request = exchange.getRequest().mutate()
.header("X-Trace-Id", traceId)
.build();
long startTime = System.currentTimeMillis();
return chain.filter(exchange.mutate().request(request).build())
.doFinally(signalType -> {
long duration = System.currentTimeMillis() - startTime;
log.info("TraceId:{}, Path:{}, Status:{}, Duration:{}ms",
traceId,
request.getPath(),
exchange.getResponse().getStatusCode(),
duration);
});
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
三、主流网关方案对比
Spring Cloud Gateway
- 技术栈:基于Spring WebFlux + Netty,非阻塞异步模型
- 优势:与Spring Cloud生态深度融合,编程模型友好,社区活跃
- 适用场景:Spring Cloud技术栈项目,中小到中大规模
- 注意:基于WebFlux,不支持传统的Servlet API
Kong
- 技术栈:基于OpenResty(Nginx + Lua),性能极致
- 优势:高性能、插件生态丰富、支持多语言插件
- 适用场景:超大规模流量、多语言微服务架构
- 注意:学习曲线较陡,运维复杂度较高
APISIX
- 技术栈:基于Nginx + etcd,Apache顶级项目
- 优势:高性能、动态配置热更新、插件热加载、多协议支持
- 适用场景:云原生环境、Kubernetes Ingress、需要极致动态能力
- 注意:相对较新,企业级案例在积累中
四、网关架构设计要点(面试高频)
4.1 网关高可用设计
网关是整个系统的咽喉,必须保证高可用:
- 多实例部署:网关无状态设计,水平扩展
- 前置负载均衡:Nginx/SLB做网关的负载均衡
- 健康检查:自动剔除异常实例
- 同城双活/异地多活:跨机房容灾部署
4.2 网关性能优化
- Reactor模型:Spring Cloud Gateway基于Netty的Reactor线程模型,天然支持高并发
- 连接池优化:调整Netty的连接池参数,如最大连接数、连接超时
- 缓存策略:对不常变化的接口响应做网关层缓存
- 异步化:过滤器逻辑尽量异步非阻塞,避免阻塞Reactor线程
4.3 网关安全防护
- HTTPS双向认证:保证传输层安全
- 防重放攻击:请求加时间戳+签名,网关校验
- IP黑白名单:基于远程地址过滤器
- SQL/XSS注入检测:对请求参数做安全过滤
- 接口签名验证:防止参数篡改
4.4 灰度发布
网关是实现灰度发布的利器,常见策略:
- 基于权重:新版本分配10%流量,老版本90%
- 基于Header/Cookie:特定标识的请求路由到新版本
- 基于用户标签:白名单用户优先体验新功能
spring:
cloud:
gateway:
routes:
- id: user-service-v1
uri: lb://user-service-v1
predicates:
- Path=/api/user/**
- Weight=group1, 90
- id: user-service-v2
uri: lb://user-service-v2
predicates:
- Path=/api/user/**
- Weight=group1, 10
五、面试高频问题
Q1:网关和服务注册中心的关系?
网关通过注册中心(如Nacos、Eureka)动态发现服务实例,实现路由的自动更新。网关本身也是微服务,也需要注册到注册中心。当服务实例上下线时,注册中心通知网关更新路由表,实现动态路由。
Q2:网关过滤器与微服务内部拦截器的区别?
- 网关过滤器作用于所有经过网关的请求,是全局性的横切逻辑
- 微服务拦截器作用于单个服务内部,处理服务特定的业务逻辑
- 建议将鉴权、限流、日志等公共逻辑放在网关,业务相关的校验放在服务内部
Q3:Spring Cloud Gateway为什么选择WebFlux而不是传统的Spring MVC?
Spring MVC基于Servlet容器,采用线程池模型——每个请求占用一个线程,高并发时线程资源消耗大。WebFlux基于Reactor + Netty,采用事件驱动和非阻塞I/O模型,少量线程即可处理大量并发连接,更适合网关这种高并发、I/O密集型的场景。
Q4:网关如何处理跨域?
网关统一配置CORS,避免每个服务单独处理:
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowed-origins: "*"
allowed-methods: "*"
allowed-headers: "*"
max-age: 3600
六、总结
微服务网关是架构设计中不可或缺的一环,其核心价值在于统一入口、解耦客户端与服务、收敛横切关注点。在实际选型时:
- Spring Cloud体系 → 优先选Spring Cloud Gateway
- 极致性能需求 → 考虑Kong或APISIX
- 云原生/K8s环境 → APISIX是热门选择
掌握网关的路由、鉴权、限流、熔断四大核心功能,以及高可用和性能优化的设计要点,是Java面试中微服务模块的高频加分项。
感谢读者观看
更多推荐


所有评论(0)