Go 语言 API 网关:您微服务管弦乐队的私人指挥

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么您的 Go 项目需要一位指挥

\n\n

想象一个交响乐团。您有小提琴(用户服务)、管乐器(订单服务)、打击乐器(支付服务)。每件乐器本身都很出色,但没有指挥,它们就会各吹各的调。在 Go 微服务世界中,API 网关就是那位指挥。

\n\n

当您使用 Go 编程时,您已经习惯了高性能、简洁和优雅。但一旦服务数量超过 3-4 个,混乱就开始了:客户端不知道该访问哪个地址,身份验证在每个服务中重复,监控变成了令人头疼的问题。面向 Go 服务的 API 网关可以一次性解决这些问题。

\n\n

在本文中,我们不仅会讨论理论。我们将使用 Go、标准库以及几个流行的包,来构建我们自己的网关。准备好指挥了吗?我们开始吧!

\n\n

什么是 API 网关,为什么在 Go 中需要它?

\n\n

API 网关是所有客户端请求到您后端服务的单一入口点。假设您有以下服务:

\n\n
    \n
  • user-service:8081 — 注册和用户资料
  • \n
  • order-service:8082 — 购物车和订单
  • \n
  • payment-service:8083 — 交易
  • \n
\n\n

没有网关,客户端必须知道所有三个服务的地址。有了Go 语言 API 网关,客户端只需访问 api.example.com,网关自行决定将请求转发到何处。

\n\n

网关的主要功能

\n\n
    \n
  • 路由 — 将请求转发到相应的服务
  • \n
  • 身份验证和授权 — 在单一位置检查 JWT 令牌
  • \n
  • 速率限制 — 防御 DDoS 攻击和过载
  • \n
  • 数据聚合 — 将来自多个服务的响应合并为一个
  • \n
  • 负载均衡 — 在实例之间分配请求
  • \n
\n\n

Go 非常适合这个角色:它轻量、快速,并且能够在单核上每秒处理数千个请求。

\n\n

编写一个简单的 Go 语言 API 网关:从想法到代码

\n\n

让我们构建一个最小但可用的Go API 网关。我们将只使用标准库 net/http 和用于代理的 httputil.ReverseProxy 包。

\n\n

第 1 步:基本路由

\n\n

从简单的开始:根据路径将请求定向到不同的服务。

\n\n
package main\n\nimport (\n    "log"\n    "net/http"\n    "net/http/httputil"\n    "net/url"\n)\n\nfunc main() {\n    // 用户服务\n    userServiceURL, _ := url.Parse("http://localhost:8081")\n    userProxy := httputil.NewSingleHostReverseProxy(userServiceURL)\n\n    // 订单服务\n    orderServiceURL, _ := url.Parse("http://localhost:8082")\n    orderProxy := httputil.NewSingleHostReverseProxy(orderServiceURL)\n\n    http.HandleFunc("/api/users/", func(w http.ResponseWriter, r *http.Request) {\n        log.Printf("将请求转发到 user-service: %s", r.URL.Path)\n        userProxy.ServeHTTP(w, r)\n    })\n\n    http.HandleFunc("/api/orders/", func(w http.ResponseWriter, r *http.Request) {\n        log.Printf("将请求转发到 order-service: %s", r.URL.Path)\n        orderProxy.ServeHTTP(w, r)\n    })\n\n    log.Println("API 网关已启动,监听 :8080")\n    log.Fatal(http.ListenAndServe(":8080", nil))\n}\n
\n\n

这段代码已经完成了 80% 的工作:任何对 /api/users/ 的请求都会转到 user-service,而对 /api/orders/ 的请求则会转到 order-service。但是身份验证在哪里呢?

\n\n

第 2 步:添加 JWT 中间件

\n\n

Go 语言 API 网关的真正魔力发生在中间件中。让我们在代理之前添加 JWT 令牌验证。

\n\n
package main\n\nimport (\n    "context"\n    "log"\n    "net/http"\n    "net/http/httputil"\n    "net/url"\n)\n\nfunc main() {\n    // 用户服务\n    userServiceURL, _ := url.Parse("http://localhost:8081")\n    userProxy := httputil.NewSingleHostReverseProxy(userServiceURL)\n\n    // 订单服务\n    orderServiceURL, _ := url.Parse("http://localhost:8082")\n    orderProxy := httputil.NewSingleHostReverseProxy(orderServiceURL)\n\n    http.HandleFunc("/api/users/", func(w http.ResponseWriter, r *http.Request) {\n        log.Printf("将请求转发到 user-service: %s", r.URL.Path)\n        userProxy.ServeHTTP(w, r)\n    })\n\n    http.HandleFunc("/api/orders/", func(w http.ResponseWriter, r *http.Request) {\n        log.Printf("将请求转发到 order-service: %s", r.URL.Path)\n        orderProxy.ServeHTTP(w, r)\n    })\n\n    log.Println("API 网关已启动,监听 :8080")\n    log.Fatal(http.ListenAndServe(":8080", nil))\n}\n

博客

书籍推荐