一致性事务:从 2PC 到 Outbox pattern
如果你做过一点微服务开发,大概率都遇到过这种场景:用户下单 → 扣库存 → 扣余额 → 更新积分。这听上去很简单,按顺序写几行逻辑就好,但问题是——这些操作分散在不同的服务、不同的数据库里。于是问题来了:如果中间有一步失败了,整个流程该怎么办?订单创建了,但库存没扣?库存扣了,但支付失败?消息没发出去,用户看不到状态…
如果你做过一点微服务开发,大概率都遇到过这种场景:用户下单 → 扣库存 → 扣余额 → 更新积分。这听上去很简单,按顺序写几行逻辑就好,但问题是——这些操作分散在不同的服务、不同的数据库里。于是问题来了:如果中间有一步失败了,整个流程该怎么办?订单创建了,但库存没扣?库存扣了,但支付失败?消息没发出去,用户看不到状态…
在做移动应用开发时,不管是 Android 还是 iOS,我们都绕不开“签名”这件事。最近我们项目在筹备适配 HarmonyOS NEXT(鸿蒙 Next) 的 SDK,也顺势把鸿蒙的签名机制研究了一遍。这篇文章来分享下。
在我们的后端架构中,我们采用了以游戏为租户单位的多租户数据库设计。所有游戏共享同一套数据库 schema,每张表通过 game_id 字段进行逻辑隔离。这种设计在初期带来了显著的开发与维护效率,支持我们快速迭代、快速上线多个游戏项目。然而,随着接入的游戏数量增加、业务数据持续增长,这种“共享单表”的设计逐渐暴露出一些架…
在 Golang 网络请求中,我们经常会遇到两种常见的错误:EOF 和 read: connection reset by peer。这两个错误虽然看似相似,但实际上有着本质的区别。这篇文章将深入探讨这两种错误的原因、区别以及如何优雅的处理它们。
在 Go 语言中,context 包提供了一种跨 API 和进程边界传递请求作用域值、取消信号以及超时信号的方式。使用 context 可以帮助我们更好地控制 goroutine,避免 goroutine 泄漏等问题。出现 "context deadline exceeded" 错误通常是因为在请求上下文中设置了超时时…
我们团队负责的防沉迷上报服务突然在某一天遭遇了内存溢出(OOM)的情况。通过查看 Prometheus 监控数据,我们发现 Goroutines 的数量在中午十二点之后呈现出线性增长趋势,直至晚上十点 OOM 发生,Goroutines 数量骤降为零。
在使用 gorm 处理数据库操作时,尤其是针对 MySQL,有时我们会遇到 golang 标准库errors.Is函数无法直接识别特定的 gorm 错误类型的情况,如主键冲突错误。尽管 gorm 提供了gorm.ErrDuplicatedKey来表示此类错误,但在原始错误返回中并不能直接通过errors.Is(err…
在现代 Web 应用中,服务端与客户端之间的高效通信至关重要。本文探讨了四种主流的服务端通信方法:短轮询、WebSocket、SSE(Server-Sent Events)和长轮询,分析它们的工作原理、适用场景及优缺点。
在谈论 API 设计和开发时,有时,一个属性可以是多种类型中的一个,但不能同时是多种类型。比如支付接口的回调处理,常常为了兼容不同平台的参数,会使用以下方式中的一种来进行接收,在程序开发中,我们往往会采用主流的 HTTP 协议和 gRPC 协议进行通信,两种技术都为开发者提供了强大的工具来描述、验证和生成 API,但它…
随着现代软件开发的持续迭代,团队间的协作变得越来越重要。为了确保整个团队在编码、构建和部署过程中的效率和质量,引入一些特定的配置文件和标准工作流程显得尤为关键。以下就是一些在团队开发中常见而又重要的文件,我总结了它们的一些作用和优点。
GORM 中SQL、慢SQL打印日志传递 trace ID, 重写GORM日志实现,SQL日志、慢日志请求追踪
使用kratos这个框架有近一年了,最近了解了一下kratos关于程序优雅退出的具体实现。
在程序进行重启等操作时,我们需要让程序完成一些重要的任务之后,优雅地退出,Golang为我们提供了signal包,实现信号处理机制,允许Go 程序与传入的信号进行交互。
在我最近使用Gorm进行字段更新的过程中,我遇到了一个问题。当我尝试更新status字段时,即使该字段的值没有发生变化,Gorm还是提示我“Duplicate entry 'xxxx' for key 'PRIMARY'”。