用 Golang 从零实现的简易负载均衡器

发布: (2026年2月8日 GMT+8 18:56)
9 分钟阅读
原文: Dev.to

Source: Dev.to

(未提供需要翻译的正文内容。如需翻译,请提供完整的文本。)

负载均衡基础

类型描述
L7 (应用层)HTTP / gRPC在应用层运行。
L4 (传输层)TCP / UDP在传输层运行。

核心职责

  1. 接收来自客户端的请求。
  2. 将请求转发给后端服务器池中的一台服务器。
  3. 将后端的响应返回给客户端。

其他关注点(本简易项目未涉及)

  • 同步响应 vs. 流式响应
  • 后端选择算法
  • 错误处理
  • 会话亲和性 / 粘性会话
  • 监控与可观测性

生产就绪的替代方案

Solution / ServiceType / RoleOSI LayerNotes
NGINX反向代理、Web 服务器、负载均衡L7路径路由通过 location 块。
EnvoyL7 代理 / 服务代理L7核心模型:Listener → Route → Cluster。
AWS Application Load Balancer托管的应用层负载均衡L7支持基于路径和主机的路由规则。
AWS Network Load Balancer托管的网络层负载均衡L4仅 TCP/UDP;不具备 HTTP 感知。
GCP HTTP(S) Load Balancer托管的全球应用层负载均衡L7全局主机和路径路由。
GCP TCP/UDP Load Balancer托管的网络层负载均衡L4无第 7 层检查。
Azure Application Gateway托管的应用层负载均衡L7主机/路径路由 + WAF 集成。
Azure Load Balancer托管的网络层负载均衡L4仅基本的 TCP/UDP 分发。

本项目特性

  • Traffic Proxying – HTTP 请求代理,支持多种负载均衡策略。
  • Load‑Balancing Strategies
    • Round Robin – 循环分配。
    • Weighted Round Robin – 根据服务器权重进行分配。
    • Least Connections – 将请求发送到活动连接最少的服务器。
    • Random – 随机选择。
  • Health Checks – 定期进行 TCP 拨号检查;不健康的后端会被暂时移除。
  • Request Retry – 失败时,请求会在不同的后端重新尝试。
  • Configuration – 使用 JSON 文件(config.json)或命令行标志进行配置。可配置项包括:
    • 负载均衡器端口
    • 请求超时时间
    • 健康检查间隔
    • 负载均衡策略
    • 后端服务器列表

架构 模块化、可测试且易于理解,遵循 关注点分离 原则。每个组件只有单一且明确的职责,使代码简洁,并且与生产系统中使用的模式相吻合。

高层流程

+-------------------+        +-------------------+        +-------------------+
|   LoadBalancer    |  -->   |   Strategy (SB)   |  -->   |   Backend (RB)    |
| (receives request)|        | (chooses backend) |        | (reverse proxy)   |
+-------------------+        +-------------------+        +-------------------+
  1. LoadBalancer 接收请求。
  2. 它请求当前的 Strategy 从池中选择一个后端。
  3. LoadBalancer 使用所选 Backend 的反向代理转发请求。

组件详情

strategy 模块 – 大脑

后端选择逻辑通过接口定义——经典的 Strategy Design Pattern(策略设计模式)。

type LoadBalancingStrategy interface {
    // SelectBackend returns the backend that should handle the request.
    SelectBackend(pool []*Backend) *Backend
}

LoadBalancer 持有该接口类型的变量,使得可以在不修改核心负载均衡器代码的情况下,随意切换各种策略(轮询、最少连接等)。

backend 模块 – 工作者

后端是一个有状态的对象,而不仅仅是一个 URL 字符串。

type Backend struct {
    Url                url.URL
    proxy              *httputil.ReverseProxy
    isHealthy          bool
    activeConnections  int64
    // ... other fields ...
    mu                 sync.RWMutex
}
  • 跟踪健康状态、活动连接数和权重。
  • 持有执行请求转发的 httputil.ReverseProxy
  • 使用互斥锁在并发请求和健康检查之间安全地读写状态。

loadbalancer 模块 – 协调者

将所有部分连接在一起的核心组件。

type LoadBalancer struct {
    pool                []*Backend
    strategy            LoadBalancingStrategy
    // ... other fields (e.g., health‑check ticker, retry config) ...
}

职责

  • 管理 Backend 对象池。
  • 处理传入的 HTTP 流量,并使用当前的 Strategy 选择后端。
  • 对所有后端执行定期健康检查。
  • 在请求选定后端失败时实现重试逻辑。

config 模块 – 蓝图

一个简单但重要的模块,负责从 JSON 文件或命令行标志加载配置。它会填充以下字段:

  • 监听端口
  • 请求超时
  • 健康检查间隔
  • 选定的负载均衡策略
  • 后端服务器定义(URL、权重等)

结束语

通过将逻辑隔离——例如,将后端选择与请求代理分离——我们可以 对每个部分进行独立的单元测试,并以最小的副作用添加新功能。该项目是一个扎实的学习练习,也是构建更复杂、生产级负载均衡器的基础。

加载和解析配置

应用程序从 config.json 文件加载其配置。这将负载均衡器的逻辑与硬编码设置解耦,使您能够在不更改代码的情况下重新配置它。

我们构建的

在本文中,我们从头开始使用 Go 语言构建了一个简单而实用的 HTTP 负载均衡器,并逐步演示了整个过程。我们实现了多个核心功能,包括:

  • 多种负载均衡策略
  • 定期健康检查
  • 动态配置

最终得到一个可运行的应用程序,展示了流量管理的基本原理。

设计模式实战

更重要的是,这个项目是对关键软件设计模式的实际探索。通过为我们的平衡算法使用 interface策略模式),我们创建了一个:

  • 灵活的
  • 易于扩展的

对模块化和关注点分离的强调,使代码库保持清晰、可测试,并且更易于理解。

未来改进

虽然我们的负载均衡器很简单,但它提供了坚实的基础,可在许多方面进行扩展。可能的增强包括:

  • 更高级的策略 – 实现 IP 哈希以进行会话亲和(粘性会话)。
  • 增强可观测性 – 添加 Prometheus 指标,以监控请求延迟、错误率和活动连接数。
  • HTTPS 支持 – 添加 TLS 终止以实现安全通信。
  • 动态配置 – 实现配置文件的热加载,无需重启服务。

结束语

我希望本文能让您深入了解负载均衡器的内部工作原理,并激发您自行构建的兴趣。欢迎在 GitHub 上查看完整源码,亲自尝试,甚至贡献自己的想法!

0 浏览
Back to Blog

相关文章

阅读更多 »

Go 模板

什么是 Go 模板?Go 模板是一种在 Go 中通过将数据与纯文本或 HTML 文件混合来创建动态内容的方式。它们允许您替换占位符……