服务间通信:HTTP、RPC 与消息队列分别适合什么场景
当系统从单体进入多服务阶段以后,最基本也最绕不开的问题之一就是:服务之间到底该怎么通信。表面上看,这好像只是协议和中间件选型问题,但实际决定它的,往往是调用关系、实时性、耦合方式、失败恢复和系统边界。...
当系统从单体进入多服务阶段以后,最基本也最绕不开的问题之一就是:服务之间到底该怎么通信。表面上看,这好像只是协议和中间件选型问题,但实际决定它的,往往是调用关系、实时性、耦合方式、失败恢复和系统边界。...
很多人第一次理解“上线”,通常只是把新版本部署上去,然后替换旧版本。这个思路在早期项目里很自然,也确实够用。但随着系统规模和用户量增长,发布本身就会成为风险最高的动作之一。因为代码不一定有问题,真正的...
当系统只有一个服务时,流量入口通常非常简单。客户端直接访问服务地址,最多前面再放一个反向代理,就能完成大部分访问链路。但当系统里开始出现多个服务、多个域名、多个环境,甚至还有鉴权、限流、灰度、协议转换...
很多人刚开始做服务时,会把配置理解成几个固定文件或者几条环境变量。只要程序能读到数据库地址、端口和几个开关,好像就够用了。但当服务数量增多、环境数量增多、功能开关增多以后,配置就不再只是“程序启动时要...
一个系统在低压状态下能稳定运行,并不意味着它在高峰、异常或者下游故障时也能稳定运行。很多线上事故的共同点并不是功能写错了,而是系统在超出承受范围后还在“硬撑”,结果把局部问题拖成了整体雪崩。 所以到了...
一个请求只要开始跨服务流转,稳定性问题就几乎一定会出现。网络可能抖动,下游可能短暂不可用,某个依赖可能偶尔响应很慢,某个调用可能在高峰期出现大量失败。这时,系统就不能只依赖“每次调用都刚好成功”,而必...
当一个服务有多个实例时,系统就要面临一个非常直接的问题:这一批请求应该发给谁。如果所有流量都打到同一个实例上,那扩容就失去了意义;如果实例之间分发策略不合理,即便节点数量不少,也可能出现有的机器很忙、...
在单体服务里,模块之间调用通常只是函数调用。你知道它在哪个包、哪个文件、哪个接口,引用过来就能用。但当系统开始拆分成多个服务以后,问题一下子就变了:一个服务如果想调用另一个服务,它首先要知道对方在哪里...
很多团队在系统刚起步时,都会从一个单体服务开始。这是非常正常、也非常合理的选择。因为单体部署简单、调试直接、调用链清晰,开发和排查都相对低成本。问题往往不是单体本身,而是当业务不断增长以后,原本只需要...
在前一组 Go 后端工程化 里,我们解决的是一个服务怎么搭、怎么跑、怎么排查、怎么上线。那一组内容更像是在回答一个问题:当你手里只有一个服务时,怎样把它做得像一个真正可以交付的项目。 但服务一旦变多,...