关键要点
- 保持领域和事务边界的显式性。
- 对易出错的外部工作使用幂等性和持久化任务。
- 为混合版本部署和真实数据量设计迁移。
- 优先选择可观测、可逆的操作,而非精巧的抽象。
运维软件的高效默认组合
Go 提供简洁的并发模型、静态二进制文件、强大的工具链和显式的错误处理。PostgreSQL 结合了事务、关系约束、索引、JSON、全文搜索、地理空间扩展和成熟的运维能力。
其价值不在于基准测试的新颖性,而在于能够清晰地建模重要的业务不变量,并以相对小的运维面部署服务。
将不变量放在事务边界内
服务方法应明确哪些读写必须一起成功。使用数据库约束来保证唯一性、引用、有效性和并发保证,无论应用路径如何都必须成立。
避免包含缓慢网络调用的事务。提交持久化意图,然后通过发件箱或任务队列以幂等处理器分派外部工作。
在故障发生前设计重试
客户端、代理和工作进程都会重试。没有幂等性,一次超时即使每个组件都正常运行也可能产生重复的订阅、通知、付款或导出。
使用操作特定的幂等键,以事务方式存储结果状态,并定义冲突时返回原始结果还是拒绝变更的输入。工作进程应记录尝试次数、错误类别、下次重试时间和终态失败。
迁移是分布式系统变更
在部署期间,新旧应用版本可能同时运行在同一数据库上。优先采用扩展-收缩变更:添加兼容结构,部署能处理两种模式的代码,安全地回填数据,切换读取,然后再移除旧结构。
针对生产级数据量测试锁和运行时。一个语法上简单的默认值、索引或类型变更可能在大型活跃表上造成不可接受的争用。
对领域操作而非仅 HTTP 请求进行插桩
请求延迟很重要,但运维人员还需要队列积压时间、任务失败类别、事务冲突、Webhook 投递、导出持续时间、租户限流和迁移进度。
好的服务暴露健康状态而不隐藏部分故障。结构化日志、追踪、指标和审计事件应共享关联标识和租户安全的身份,以便端到端地重建事件。