如何设计一个高可用的微服务网关?你会如何考虑这道面试题?
作者:一个写了 8 年 Java、踩坑无数的后端程序员
🧠 前言:只要你写微服务,早晚得面对网关这事
微服务架构大行其道,系统从"巨无霸单体"切成了"满地小碎片",这时候一个统一的 "门面" ------ 微服务网关(API Gateway)就成了必不可少的角色。
而在面试中, "如何设计一个高可用的微服务网关?" 是一道出场率极高的系统设计题。
今天就从一个 Java 开发老兵的角度,带你一步步拆解这道题,不仅会写,还要写得让面试官拍大腿!
🧩 一、业务场景分析:为啥需要网关?
先别急着撸代码,面试第一步永远是:你为啥要这么设计?
✅ 为什么需要微服务网关?
- 统一入口:对外暴露一个 API 地址,隐藏后端服务细节。
- 服务路由:根据请求路径/参数把请求转发到不同微服务。
- 权限控制:统一做登录校验、权限校验、Token 验证。
- 限流降级:防止请求打爆后端服务。
- 日志监控:记录访问日志、调试日志、链路追踪。
- 灰度发布:根据用户/IP/参数实现 A/B 测试或灰度上线。
🧱 场景举例:
你有以下服务:
order-service
:订单服务user-service
:用户服务product-service
:商品服务
前端只需要访问一个地址,比如 https://api.xxx.com/
,然后由网关转发到对应服务。
🧩 二、技术选型:选轮子,还是造轮子?
作为 Java 程序员,我们当然首选 Spring 全家桶,尤其是:
✅ 常见网关技术选型
技术 | 特点 |
---|---|
Spring Cloud Gateway | 基于 WebFlux,响应式、支持路由、限流、过滤器、熔断、动态配置等,Spring 官方推荐 |
Zuul | Netflix 出品,Spring Cloud 的旧宠,现在基本被 Gateway 替代 |
Nginx + Lua | 更偏向运维层面的 API 网关,支持高并发但扩展性差 |
Kong / APISIX | 开源网关,支持插件,适合大公司 DevOps 场景 |
面试时建议主推 Spring Cloud Gateway,Java 系栈原生,生态完整,功能足够。
🧠 三、高可用网关设计核心要点
如果你只会说"我用过 Gateway",那只是个使用者。但面试要你设计一个高可用网关,你得从以下几个维度考虑:
1. 高可用部署架构
- 多实例部署,配合 Nginx、Keepalived 做负载均衡
- 无状态设计,配合注册中心(如 Nacos、Eureka)实现服务发现
- 支持健康检查 + 自动下线机制
📌 图示结构:
csharp
客户端
↓
[Nginx/SLB]
↓
[Gateway 节点1] ←→ 注册中心 ←→ 微服务
[Gateway 节点2]
2. 服务路由与注册发现
- 静态路由:写死配置
- 动态路由:从注册中心动态拉取服务列表(推荐)
yaml
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
3. 限流与熔断
- 限流:防止接口被刷爆(基于令牌桶、漏斗算法)
- 熔断:服务故障时快速失败,避免级联故障
yaml
spring:
cloud:
gateway:
routes:
- id: user_route
uri: lb://user-service
predicates:
- Path=/user/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
4. 认证鉴权
- Token 验证(JWT)
- 权限过滤器(自定义 GlobalFilter)
- 支持白名单、黑名单、角色权限控制
5. 灰度发布
- 自定义路由规则:根据用户 ID、版本号、IP 地址等
- 配合 Nacos 动态配置,实现按比例转发
6. 可 observability(可观测性)
- 接入 ELK / Prometheus / Zipkin 实现日志、指标、链路追踪
- 请求日志、错误日志、慢接口统计
💻 四、核心代码示例(Spring Cloud Gateway)
我们用 Spring Boot + Spring Cloud Gateway 构建一个简单的网关服务。
1. 引入依赖
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-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
2. 配置 application.yml
yaml
server:
port: 8080
spring:
application:
name: gateway-service
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/user/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 5
redis-rate-limiter.burstCapacity: 10
redis:
host: localhost
port: 6379
3. 自定义过滤器(认证)
kotlin
@Component
public class AuthFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// 解析 JWT,校验逻辑略
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1;
}
}
🧾 五、面试场景如何回答?
面试官问: "你如何设计一个高可用的微服务网关?"
你可以这样回答:
我会基于 Spring Cloud Gateway 实现 API 网关,考虑高可用从以下几个方面入手:
- 多实例部署,配合 Nginx 做负载均衡,支持注册中心服务发现
- 实现动态路由、Token 鉴权、自定义过滤器
- 配置限流和熔断机制,保护后端服务
- 接入链路追踪、监控、日志系统
- 支持灰度发布和动态配置
在代码层面,我会使用配置文件定义路由规则,使用自定义 GlobalFilter 实现身份校验,使用 Redis 做限流。
✅ 总结:高可用,不只是"不宕机"
设计一个高可用的微服务网关,不只是代码写得好,更是系统设计能力的综合体现。
高可用 = 架构 + 容错 + 自动化 + 监控 + 实践
希望这篇文章能帮你在面试中自信回答"这题我会",也能在实际开发中把网关设计得更坚固、更稳定。