API 网关如何通过服务发现实现动态路由,自动把请求转发到正确的微服务?

这是微服务架构中“API 网关 + 服务发现”最核心的协作机制。我在项目中使用的API网关是Kong,服务注册中心是Consul,这里就拿他们讲解。

我们来一步步、用通俗易懂的方式详细讲解这个过程,结合微服务项目场景来说明。

 一、目标是什么?

想实现的效果是:

用户访问 /goods/list → 请求被 Kong 接收 → Kong 自动知道这个请求应该转发给 商品服务(goods-srv) → 并且能自动负载均衡到多个 goods-srv 实例上。

而且:

  • 不用手动写死 IP 地址
  • 商品服务扩容/缩容(实例增减)时,Kong 能自动感知
  • 新增一个服务(比如 order-srv),只需注册进 Consul,Kong 就能路由过去

这就叫:动态路由 + 动态服务发现


 二、Kong 和 Consul 分别做什么?

组件角色
KongAPI 网关,负责接收所有外部请求,决定“这个请求该转发给谁”
Consul服务注册中心,记录“每个服务叫什么名字、有哪些实例(IP+端口)、健康吗?”

它们配合起来,就像“快递分拣中心(Kong)”和“公司员工花名册(Consul)”。


 三、核心机制:Kong 如何知道服务在哪?——“服务(Service)”的概念

Kong 内部有两个关键抽象:

1. Service(服务)

  • 表示一个后端微服务(如 goods-srv
  • 它不直接写死 IP,而是告诉 Kong:“你要找的商品服务,在 Consul 里叫 mxshop-goods-srv
  • 配置示例:
    curl -X POST http://kong:8001/services \
      -d "name=goods-service" \
      -d "url=consul://consul:8500/mxshop-goods-srv"
    • name=goods-service:这是 Kong 内部给这个后端服务起的名字。
    • url=consul://...:这是重点!它不是 http://192.168.1.10:8001 这种固定地址,而是指向 Consul 中注册的服务名 mxshop-goods-srv

✅ 所以,Kong 的 “Service” 是一个逻辑概念,它通过 Consul 动态获取真实地址。


2. Route(路由)

  • 表示“什么样的请求应该交给哪个 Service 处理”
  • 通常是基于 URL 路径或 Host 匹配
  • 配置示例:
    curl -X POST http://kong:8001/services/goods-service/routes \
      -d "paths[]=/goods" \
      -d "methods[]=GET" \
      -d "methods[]=POST"
    • 意思是:所有以 /goods 开头的请求(如 /goods/list/goods/detail),都交给 goods-service 这个 Service 处理。

 四、完整请求流转过程(以 /goods/list 为例)

我们来走一遍用户请求的完整路径:

步骤 1️⃣:用户发起请求

GET http://api.example.com/goods/list

步骤 2️⃣:Kong 接收到请求

Kong 检查所有 Route,发现 /goods 路径匹配 goods-service 这个 Service。

步骤 3️⃣:Kong 查询 Consul 获取真实地址

Kong 看到 goods-serviceurl=consul://.../mxshop-goods-srv,于是:

  • 向 Consul 发起查询:"mxshop-goods-srv" 这个服务现在有哪些健康的实例?"
  • Consul 返回:
    [
      {"Address": "192.168.1.10", "Port": 50051},
      {"Address": "192.168.1.11", "Port": 50051},
      {"Address": "192.168.1.12", "Port": 50051}
    ]

步骤 4️⃣:Kong 选择一个实例并转发

Kong 从这三个地址中按负载均衡策略(如轮询)选一个,比如 192.168.1.11:50051,然后把请求转发过去:

GET http://192.168.1.11:50051/goods/list

✅ 最终结果

用户无感知地访问到了商品服务,而 Kong 完全不知道具体 IP,它只认“服务名”。


 五、动态性体现在哪里?——服务扩缩容自动适配

假设你现在把商品服务从 3 个实例扩容到 5 个:

  1. 新的 goods-srv 实例启动 → 自动向 Consul 注册自己(服务名仍是 mxshop-goods-srv
  2. Consul 更新服务列表,新增两个实例
  3. Kong 通过 Consul 插件(定期轮询或监听事件)自动获取最新实例列表
  4. 下次请求来时,Kong 就可能把流量分发到新实例上

👉 整个过程不需要你手动改 Kong 配置!


 六、新增一个服务(如 order-srv)怎么办?

  1. order-srv 启动 → 向 Consul 注册为 mxshop-order-srv
  2. 在 Kong 中创建新 Service:
    curl -X POST http://kong:8001/services \
      -d "name=order-service" \
      -d "url=consul://consul:8500/mxshop-order-srv"
  3. 创建对应路由:
    curl -X POST http://kong:8001/services/order-service/routes \
      -d "paths[]=/order"
  4. 用户访问 /order/create → 自动转发到 order-srv

✅ 只要服务在 Consul 注册了,Kong 就能通过服务名找到它。


 七、总结:Kong + Consul 动态路由的本质

层级配置项作用是否需要手动配置
1. 路由层Route (/goods)匹配 URL 路径✅ 需要(一次)
2. 服务层Service (goods-service)指向 Consul 中的服务名✅ 需要(一次)
3. 发现层Consul (mxshop-goods-srv)存储真实 IP 列表❌ 自动注册/更新

优势总结:

  • 解耦:Kong 不关心 IP,只关心“服务名”
  • 动态:实例增减,自动感知
  • 可维护:新增服务只需加 Route + Service,无需改代码
  • 高可用:结合健康检查,自动剔除不健康实例

 Kong 的 Consul 插件是如何工作的?

Kong 通过内置的 consul 协议支持,或使用 kong-plugin-consul-discovery 插件,实现以下功能:

  • 定期向 Consul 查询服务实例列表(默认每 5~10 秒)
  • 支持长轮询(Watch)模式,变更更实时
  • 支持健康检查过滤,只返回健康实例
  • 支持负载均衡(Kong 内置轮询、哈希等策略)

你现在完全可以这样理解:

API网关 是“指挥官”,它不亲自打仗(处理业务),而是根据“花名册”(服务注册中心Consul)上的名单,把任务(请求)分配给正确的“士兵”(微服务实例)。名单变了,指挥官自动调整,无需重新训练。

这就是项目中实现的“动态路由”的精髓!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值