一、什么是微服务网关(API Gateway)
定义:微服务网关是整个系统请求的统一入口,负责请求转发、过滤处理、安全校验等。
作用:
请求路由
日志记录
权限控制
参数校验
解决跨域问题
黑白名单控制
限流、熔断、降级
统一前后端接口调用
二、过滤器与网关的区别
对比项 过滤器(Filter) 网关(Gateway) 作用范围 单个微服务内部 整个微服务系统 实现方式 @WebFilter、OncePerRequestFilter Spring Cloud Gateway 适用场景 局部处理、日志、拦截器 全局处理、统一入口、鉴权
三、Zuul vs Gateway
对比项 Zuul(1代网关) Gateway(2代网关) 所属公司 Netflix Spring 官方 技术架构 Servlet、阻塞式 WebFlux、非阻塞响应式 性能 较差 高性能、支持长连接 生态整合 较弱 完美整合 Spring 生态 适合场景 兼容性要求高的旧项目 新项目优选、高并发场景
四、快速构建 Gateway 项目
Maven 依赖
//注意:会和spring-webmvc的依赖冲突,需要排除spring-webmvc <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
在使用
spring-cloud-starter-gateway
时,不能再同时使用spring-boot-starter-web
,否则会产生冲突或运行时报错。
✅ 原因详解
🔧
spring-cloud-starter-gateway
是基于 Spring WebFlux(响应式编程)
内部依赖的是
spring-boot-starter-webflux
使用响应式的非阻塞式 Netty 服务器(不是 Tomcat)
框架核心类如:
WebHandler
、ServerWebExchange
、Mono
、Flux
❌
spring-boot-starter-web
是基于 Spring MVC(Servlet 阻塞式编程)
内部使用的是
spring-web + spring-webmvc
默认使用嵌入式 Tomcat
与 WebFlux 核心机制不兼容
application.yml 配置
server: port: 80 spring: application: name: gateway-service cloud: gateway: discovery: //二选一 locator: enabled: true # 开启服务注册自动路由 routes: //二选一 - id: example-route uri: http://www.example.com/ predicates: - Path=/example/**
✅
discovery.locator.enabled: true
(自动路由)
会自动将注册中心的服务映射成路由,无需手动配置。
访问格式:
http://网关地址/服务名/**
适合:快速开发、测试环境。
不灵活:路径固定为服务名,不能自定义。
✅ 手动配置
routes
你手动指定路由规则(路径、服务名、过滤器等)。
更灵活:可以自定义路径、加过滤器、权限控制等。
适合:生产环境。
✅ 是否二选一?
一般只用一个即可。
正式环境推荐:关闭
discovery.locator.enabled
,手动写routes
。
五、整合 Nacos 实现服务注册与发现
添加依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
application.yml 示例
spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 gateway: discovery: locator: enabled: true routes: - id: member uri: lb://member-service predicates: - Path=/member/** filters: - StripPrefix=1
✅ 两种
uri
写法的区别🟩 第一种:
routes: - id: user-service uri: lb://user-service predicates: - Path=/user/**
解释:
uri: lb://user-service
表示使用服务发现 + 负载均衡。
lb://
前缀 = load balancer,Spring Cloud Gateway 会去注册中心(如 Nacos)里找名为user-service
的服务,并自动负载均衡调用。这个写法 必须依赖 Nacos 或其他服务注册中心,否则会报错:服务找不到。
🟩 第二种:
routes: - id: example-route uri: http://www.example.com/ predicates: - Path=/example/**
解释:
uri: http://...
表示直接转发到固定的 HTTP 地址。不需要注册中心,Gateway 会将请求直接转发到
www.example.com
。不需要 Nacos 等服务发现组件。
✅ 总结对比表
配置方式 是否需要注册中心(如 Nacos) 说明 uri: lb://user-service
✅ 需要 从注册中心获取服务实例,负载均衡 uri: http://www.example.com/
❌ 不需要 直接转发到固定地址
✅ 最常用的判断逻辑
是否用到了
lb://
?如果用到了,就需要服务注册中心(Nacos)。否则不需要。
六、Nginx 与 Gateway 的区别
项目 Nginx Spring Cloud Gateway 编程语言 C语言 Java 扩展性 靠 Lua 二次开发 基于 Java/Spring 插件式开发 所属层级 网络层(L7)反向代理 微服务层 适合 高性能网络转发 服务间通信、认证授权、动态路由
七、自定义全局过滤器(如 Token 拦截)
@Component public class TokenFilter implements GlobalFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String token = exchange.getRequest().getQueryParams().getFirst("token"); if (token == null || token.isEmpty()) { ServerHttpResponse response = exchange.getResponse(); response.setStatusCode(HttpStatus.BAD_REQUEST); DataBuffer buffer = response.bufferFactory().wrap("token not is null".getBytes()); return response.writeWith(Mono.just(buffer)); } return chain.filter(exchange); } }
八、接口安全措施总结
幂等性控制:使用 token 防重复提交
HTTPS 加密传输
MD5 签名防篡改
API 权限控制(白名单、黑名单、OAuth2)
熔断、降级、隔离防止雪崩
Swagger 文档统一管理
九、网关高可用架构
使用 Nginx / LVS + Gateway 实现高可用网关
网关本身无状态,可水平扩展
示例 Nginx 配置:
upstream gateway_cluster { server 127.0.0.1:8081; server 127.0.0.1:8082; } server { listen 80; server_name gateway.example.com; location / { proxy_pass http://gateway_cluster; } }
🔁 十、动态路由实现(基于数据库)
表结构
CREATE TABLE boyatop_gateway ( id INT AUTO_INCREMENT PRIMARY KEY, route_id VARCHAR(50), route_name VARCHAR(255), route_pattern VARCHAR(255), route_type VARCHAR(10), route_url VARCHAR(255) );
核心代码
public void loadRoute(GateWayEntity gateway) { RouteDefinition definition = new RouteDefinition(); definition.setId(gateway.getRouteId()); PredicateDefinition predicate = new PredicateDefinition(); predicate.setName("Path"); predicate.addArg("pattern", gateway.getRoutePattern()); FilterDefinition filter = new FilterDefinition(); filter.setName("StripPrefix"); filter.addArg("_genkey_0", "1"); URI uri = gateway.getRouteType().equals("0") ? UriComponentsBuilder.fromUriString("lb://" + gateway.getRouteUrl()).build().toUri() : UriComponentsBuilder.fromHttpUrl(gateway.getRouteUrl()).build().toUri(); definition.setUri(uri); definition.setPredicates(List.of(predicate)); definition.setFilters(List.of(filter)); routeDefinitionWriter.save(Mono.just(definition)).subscribe(); publisher.publishEvent(new RefreshRoutesEvent(this)); }
🔄 十一、谓词与过滤器
谓词(Predicates):判断是否匹配请求
Path=/xxx/**
After=时间
Host=xxx.example.com
Method=GET
Header=X-Request-Id, \d+
Weight=group1, 2
过滤器(Filters):处理请求前/后逻辑
StripPrefix=1
AddRequestHeader=X-Name, value
RewritePath=/old/(?<segment>.*), /new/${segment}
Retry、CircuitBreaker
🌍 十二、解决跨域问题(CORS)
全局跨域过滤器实现
@Component public class CorsFilter implements GlobalFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpResponse response = exchange.getResponse(); HttpHeaders headers = response.getHeaders(); headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*"); headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "*"); headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*"); headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*"); return chain.filter(exchange); } }
🔬 十三、源码启动流程(核心组件)
GatewayClassPathWarningAutoConfiguration:校验是否依赖 webflux
GatewayAutoConfiguration:加载所有核心 Bean(如 RouteDefinitionLocator)
RoutePredicateHandlerMapping:路由匹配
FilteringWebHandler:执行过滤器链
GatewayFilterChain:按顺序执行自定义/内置过滤器
GatewayLoadBalancerClientAutoConfiguration:整合负载均衡器
GatewayRedisAutoConfiguration:限流配置
GatewayDiscoveryClientAutoConfiguration:注册中心服务发现
🧠 十四、常见错误总结
错误:
required a bean of type 'org.springframework.http.codec.ServerCodecConfigurer'
原因:Spring Cloud Gateway 使用 webflux,请删除 spring-boot-starter-web 依赖,使用
spring-boot-starter-webflux
📚 十五、关键词汇速查表
名称 说明 Route 路由配置(包含 id、uri、predicates、filters) Predicate 请求匹配规则(Path、Method、Header、Host) Filter 请求过滤器,可修改请求/响应 lb:// 使用服务名转发(注册中心) StripPrefix 去除路径前缀 RefreshRoutesEvent 动态刷新路由事件
📎 官方参考文档