1. 为什么微服务一定要有统一网关服务拆得越细调用方要记的地址就越多。订单服务一个端口、库存服务一个端口、用户服务又一个端口前端同学每次联调都要问一圈“这个接口现在走哪个 IP”。更麻烦的是认证、限流、跨域这些公共逻辑如果每个服务各写一遍改一次规则要动十几个仓库。Gateway 就是来解决这件事的。它是 Spring Cloud 官方推出的第二代网关基于 Netty 异步非阻塞模型和第一代 Zuul 的 Servlet 阻塞模型相比长连接和高并发场景下表现更稳。它的核心只有两件事路由转发和过滤器。所有外部请求先到网关网关根据断言Predicate判断该走哪条路由再通过过滤器做鉴权、限流、熔断、跨域处理最后转发到真正的微服务。配合 Nacos 做服务发现后网关不再需要写死http://localhost:8003这种地址而是用lb://服务名的方式从注册中心动态拿实例列表服务扩容、缩容、换端口网关自动感知。这篇文章就带你从零把 Gateway Nacos 动态路由跑通包含可复制的配置、启动验证动作以及我实际踩过的几个坑。适合谁看已经用 Spring Cloud Alibaba 拆了微服务、正在找统一入口方案的后端同学或者网关配置写完但一直 404、负载均衡不生效的排查者。2. 前置准备Nacos 与 TaoToken 接入信息动手前先确认两件事Nacos 已经跑起来并且你的业务服务能正常注册进去。Nacos 默认地址是127.0.0.1:8848控制台能打开、服务列表能看到实例这一步没问题再往下走。如果你在本地调试模型能力、或者想让网关后面挂一些 AI 相关的服务做联调可以用 TaoToken 作为统一入口来管理密钥和调用。它的 API 地址是https://taotoken.net/api控制台和密钥管理在下面这些入口模型对话体验https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel_chat接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdocAPI Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi_keys控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentconsole官网首页是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。这些入口在后面做网关转发验证时会用到先把 Key 准备好避免配置到一半又去翻页面。依赖版本上建议 Spring Cloud Alibaba 用 2021.x 或 2022.x 对应 Spring Boot 2.6 / 3.xGateway 用spring-cloud-starter-gatewayNacos 发现用spring-cloud-starter-alibaba-nacos-discovery。版本对齐是后面少报错的关键。3. 可复制配置Gateway 模块与 Nacos 动态路由3.1 新建网关子模块并引入依赖网关建议单独建一个模块比如smartcar-gateway不要和业务服务混在一起。pom.xml里关键依赖如下parent groupIdcom.smart.car.root/groupId artifactIdsmartcar-project/artifactId version0.0.1-SNAPSHOT/version /parent dependencies !-- Gateway 核心注意它基于 WebFlux不能和 spring-web 共存 -- dependency groupIdorg.springframework.cloud/groupId artifactIdspring-cloud-starter-gateway/artifactId /dependency !-- Nacos 服务发现 -- dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId /dependency /dependencies这里有个高频坑如果你的公共模块common里带了spring-boot-starter-web或tomcat-embed-core一定要排除掉。Gateway 跑在 Netty 上和 Servlet 容器不兼容两个同时存在启动会直接失败。dependency groupIdcom.smart.car.common/groupId artifactIdsmartcar-common/artifactId version0.0.1-SNAPSHOT/version exclusions exclusion groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /exclusion exclusion groupIdorg.apache.tomcat.embed/groupId artifactIdtomcat-embed-core/artifactId /exclusion /exclusions /dependency3.2 启动类开启服务发现EnableDiscoveryClient SpringBootApplication(exclude {DataSourceAutoConfiguration.class}) public class SmartGatewayApplication { public static void main(String[] args) { SpringApplication.run(SmartGatewayApplication.class, args); } }exclude DataSourceAutoConfiguration.class是因为 common 里可能带了 MySQL 依赖但网关本身不连库不排除会报Failed to configure a DataSource。3.3 application.yml 配置动态路由把application.properties改成application.yml核心配置如下server: port: 8008 spring: application: name: smartcar-gateway cloud: nacos: discovery: server-addr: 127.0.0.1:8848 register-enabled: true gateway: discovery: locator: enabled: true # 开启基于服务发现的自动路由 lower-case-service-id: true # 服务名转小写避免大小写不匹配 routes: - id: member-service uri: lb://smartcar-member # lb 表示从注册中心负载均衡取实例 predicates: - Path/member/** filters: - StripPrefix1 # 转发前去掉第一段路径 - id: points-service uri: lb://smartcar-points predicates: - Path/points/** filters: - StripPrefix1几个参数必须说清楚uri: lb://smartcar-member里的lb是 load balance 的缩写后面跟的是服务在 Nacos 上的spring.application.name。用lb方式时服务名有命名限制只允许字母、数字、加号、点、减号下划线不识别。如果你写成smartcar_member启动会抛Invalid host: lb://smartcar_member。StripPrefix1表示去掉路径的第一段。比如请求/member/list去掉member后转发给服务的是/list。如果你的 Controller 本身映射就是/member/list那这个过滤器要去掉否则会 404。这是新手最容易踩的坑。discovery.locator.enabled: true开启后即使不写 routes网关也会自动按服务名生成路由但生产环境建议显式写 routes可控性更强。4. 启动验证请求怎么走、结果怎么看配置写完先启动 Nacos再启动两个业务服务比如 member 起两个实例端口 8003 和 8004最后启动网关 8008。第一步打开 Nacos 控制台的服务列表确认smartcar-member下面有两个健康实例smartcar-gateway也注册成功。第二步直接通过网关访问curl http://localhost:8008/member/list如果返回的是业务数据说明路由通了。连续请求几次观察 member 两个实例的日志会发现请求在 8003 和 8004 之间轮询这就是lb配合 Nacos 做的负载均衡。第三步验证动态性。把 member 的 8004 实例停掉等大约 5 秒再请求。前几秒可能还会打到已停实例上因为 Nacos 心跳默认 5 秒检测一次之后网关拿到的实例列表就只剩 8003请求恢复正常。这个延迟是正常的不是配置错误。如果你在网关后面挂了模型调用类服务做联调可以用 TaoToken 的模型对话入口先验证 Key 是否可用https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel_chat 确认没问题再走网关转发能少排查一层。5. 本篇常见错误排查报错一Failed to configure a DataSource: url attribute is not specified原因common 模块带了 MySQL 依赖网关没配数据源。解决启动类加exclude {DataSourceAutoConfiguration.class}或者把 common 里的数据源依赖排除。报错二Invalid host: lb://smartcar_member原因服务名里用了下划线。Gateway 的 lb 前缀对 host 有正则限制只认[a-zA-Z]([a-zA-Z]|\d|\|\\.|-)*。解决把服务名改成中划线或纯字母比如smartcar-member。报错三访问网关一直 404先查StripPrefix。请求/member/list如果服务端接口是/member/list那StripPrefix1会把member去掉变成/list自然 404。把该过滤器删掉再试。再查Path断言是否写对/member/**和/member/*匹配范围不同前者匹配多级路径。报错四负载均衡不生效总是打同一个实例确认uri用的是lb://而不是写死的http://。写死地址就没有负载均衡可言。另外确认多个实例注册在同一个 Nacos 命名空间和分组下。报错五跨域请求被拦前后端分离时浏览器会报 CORS 错误。在网关层统一处理application.yml加spring: cloud: gateway: globalcors: cors-configurations: [/**]: allowedHeaders: * allowedOrigins: * allowedMethods: - GET - POST - PUT - DELETE - OPTIONS注意网关处理了跨域后面的业务服务就不要再配一遍重复配置会导致跨域失效。另外allowedOrigins(*)不能和allowCredentials(true)同时使用。6. 继续往下走熔断、限流与长期编码路由通了只是第一步。生产环境还要考虑服务宕机时请求堆积在网关的问题这时候需要熔断降级还要考虑突发流量打垮后端需要限流。这两块可以分别用 Hystrix 和 Sentinel 来做Sentinel 还支持把限流规则持久化到 Nacos重启不丢规则。如果你正在做长期的微服务开发或 Agent 类项目需要稳定的模型调用通道可以了解 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding_plan 。接入细节和参数说明都在文档里https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc Key 在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi_keys 管理。网关这层配好之后前端只需要记住一个 8008 端口后面服务怎么拆、怎么扩、怎么换端口对调用方都是透明的。这才是统一入口真正的价值。
阅读完成 · 觉得有帮助?