从单体服务到 RPC 与微服务:Go 工程化下一步怎么走
当你把一个 Go HTTP 服务的基础工程化能力逐步补齐以后,通常会自然遇到下一个问题:如果业务继续增长,一个服务开始承担越来越多职责,或者系统之间需要更稳定地互相调用,后面应该怎么走?这时你会逐渐从...
当你把一个 Go HTTP 服务的基础工程化能力逐步补齐以后,通常会自然遇到下一个问题:如果业务继续增长,一个服务开始承担越来越多职责,或者系统之间需要更稳定地互相调用,后面应该怎么走?这时你会逐渐从...
很多 Go 项目在最开始都能很快跑起来:一个 main.go,一个 go.mod,再加几个包,功能就能开始迭代了。但只要项目继续长大,你很快会碰到另一类问题:构建命令每个人写得不一样,启动方式靠口头约...
很多人刚开始写后端服务时,对测试的态度往往是“先把功能写完再说”。结果到了后面,接口越来越多、逻辑越来越绕,每次改一点代码都担心牵出别的问题,但又没有足够信心去改。这个阶段最明显的感觉就是:项目能继续...
很多接口在开发阶段都能跑通,但一旦交给前端、测试或者别的服务方使用,问题就会很快暴露出来:参数规则不清楚、错误信息不稳定、同类接口返回结构不一致、不同异常时状态码和业务码含义混乱。表面上看,这些都不算...
很多服务在开发阶段都能正常运行,但一谈到上线,就会暴露出另一类问题:服务启动后能不能被探活、退出时会不会把正在处理的请求直接掐掉、依赖异常时外界能不能及时看出来、出了问题有没有基础观测信号。这些问题和...
很多后端项目刚开始都很简单,一个接口就是一个函数,参数解析、业务判断、数据库查询、响应拼装全写在一起,功能也确实能跑。但项目只要开始增长,代码很快就会变得越来越难维护。一个很典型的信号就是:改一个接口...
Go 最吸引人的特点之一,就是并发写起来相对直接。goroutine 很轻,channel 很方便,标准库也提供了不少同步原语。这些能力让很多人一开始就对 Go 的并发印象很好。但真正把它们放进后端服...
很多同学刚接触 Go Web 开发时,会把中间件理解成“框架提供的一层额外功能”,把 context 理解成“传参数的工具”。这种理解不能说错,但还远远不够。只要你开始认真做后端服务,就会很快发现:日...
Go 的错误处理看起来很朴素:函数返回 error,调用方判断 if err != nil。这种设计非常直接,也很符合 Go 的风格。但真正写后端服务时,问题并不在“知不知道怎么判断错误”,而在“这个...
很多同学刚开始写服务时,对日志的理解往往很朴素:哪里想看就 fmt.Println 一下,出错了就打印一个字符串。这种方式在本地调试时当然够用,但只要服务开始跑在测试环境、上线环境,日志的角色就完全变...