Go 的故障容错与弹性模式
容错库与模式
- 链接中的 Go 库被视为现有思想的移植:来自同一项目更成熟的 Java 版本,并且与 .NET Polly 库非常相似。
- 有人称赞在 Go 中拥有这些弹性模式(重试、断路器等);也有人警告它们常被误用,反而导致更多故障(例如内部服务中过于激进的断路器)。
- 一位评论者指出该库仅在内存中工作;真正的“fail-safe”行为通常需要持久队列或日志,不过并非所有系统都能承受那样的延迟或复杂度。
Go 的设计目标与不断演进的功能集
- 争论集中在 Go 是否有意为大型公司的相对缺乏经验的工程师设计,强调简单性和快速上手。
- 一些人认为加入更多功能(泛型、更好的枚举、可空性)会让 Go 变成一个更糟糕的 Java;另一些人则表示语言必须演进才能保持有用。
- 泛型来得很晚(约 12 到 13 年后)被同时解读为一种优点(保守、理论基础扎实的设计)和一种错失机会,因为其他语言更早支持了泛型。
Nil、可空类型与错误处理
- 频繁的 nil 指针 panic 被描述为一个真实的痛点;有人认为缺少非空类型是设计缺陷。
- 也有人反驳说,指针本身就已经充当了可空类型,而 nil 问题通常说明的是架构或纪律问题。
- 建议的模式包括:工厂函数、严格检查错误(
errcheck)、当存在错误时绝不使用该值。 - 有几个人认为这种手动风格其实是在用一种冗长的方式隐式重现异常;也有人回应说,错误很容易一路向上传播(异常),反而会鼓励把真正的处理推迟到后面。
- 对 C#、Rust(
Option)以及 NilAway 之类工具的引用,展示了其他关于空安全的做法。
枚举、类型系统与“Go 风格”
- 关于 Go 基于
iota的常量是否算“真正的”枚举存在分歧;批评者说它们与经典枚举构造或和类型相比太弱。 - 更广泛的观点是:许多现代语言更偏好和类型而不是传统枚举;Go 则有意保留一种“古早”的感觉。
OTP、Erlang/Elixir 与 Kubernetes
- 许多人注意到,Go 的库和云工具(例如弹性模式、微服务、Kubernetes)与 Erlang/Elixir 的 OTP 中早已存在的概念很相似。
- 有些人认为 K8s 是一种语言无关的替代方案,“把 OTP 做得更好”;另一些人则称它是“穷人版 OTP”。
- OTP/BEAM 尽管有优势,却没有更广泛使用的原因包括:动态类型、不同寻常的语法、某些工作负载下性能较弱、生态较小,以及招聘/学习门槛。
- 另一种观点是:一些团队在生产中成功使用了 Erlang/Elixir,但也承认与 Go、Java 等相比,生态仍有缺口且采用率有限。
对 failsafe-go API 设计的批评
- 少数评论者觉得该库大量使用泛型和许多小包“没有 Go 的感觉”,而且过度设计了。
- 作者为这一设计辩护,认为它能实现强类型安全和可组合性;另一位评论者则把它与一种更简单的状态机方案作了比较。