发布本身不是难点,难点是新版本有问题时能在多大范围快速止损。滚动发布逐个替换实例,回滚要数十分钟,这段时间全部用户都在受影响面。蓝绿和灰度解决的都是这件事:把"回滚"换成"切流",把止损时间从重建实例的量级压缩到改一次路由配置的量级。 蓝绿与灰…
Architecture
System design, architecture patterns and engineering practice.
谈高并发时,话题经常一上来就跳到缓存、分库分表、消息队列。这些手段都对,但都属于"单机能力之外的补救"。真正决定一个系统能不能横向长大的,是更基础的一件事:服务本身能不能无状态地复制。这一层没打通,加多少台机器都是在跟自己较劲。 有状态服务的…
"前后端分离"在国内技术圈流行了十年以上,如今已经很少有人把它当成新概念讨论。但有意思的是,近几年随着服务端组件、岛屿架构等形态的出现,渲染逻辑又开始往服务端回流。回头看这段演进,驱动变化的从来不是某种风格的优劣,而是页面复杂度、团队协作方…
做桌面工具这类软件,技术选型的讨论往往陷入"哪个语言更好"的口水仗,但真正决定成败的是职责怎么划分。我参与开发的 7AA7工具箱是一套 C++/Qt 客户端加 Go 服务端的组合,这篇文章把当年几个关键取舍的思考过程摊开,不讲结论的正确性,讲推理的过程。 一…
消息队列是后端架构里最容易被"上车"的组件:加一层 MQ,流量尖峰扛住了,系统之间也不直接调用了,看上去两全其美。但队列解决的是时间维度上的耦合,代价是把一次调用拆成了"发"和"收"两段,中间多了消息丢失、重复投递、顺序错乱等一整排新问题。把它用对…
缓存是性能优化里收益最直接的一招,也是出问题时最难查的一类。数据不对、缓存雪崩、重建风暴,这些事故的共同点是:缓存引入的不只是速度,还有一套独立于数据库的失效逻辑。把缓存当成"加一层就快"的透明加速器,迟早要为它补课。 读写模式先选对 缓存读…
单机应用里调用就是一次函数调用,失败立即抛异常。服务拆开后调用跨了网络,故障从"失败"扩展成"慢""超时""半死不活"三种新形态,而且往往先慢后挂、局部扩散。注册发现、熔断、限流处理的分别是"调用谁""要不要继续调""允许多少进来"。 注册发现与健康检查…
关于"要不要上微服务"的讨论里,情绪往往盖过事实。一边是把单体等同于"落后",另一边是把微服务嘲讽为"把网络当函数调"。抛开这些口水,工程上真正要回答的只有一个问题:当前系统的哪些痛点,是非拆不可的?如果列不出具体条目,拆分就是在用确定的复杂度…
下单要扣库存、创建订单、冻结优惠券,三个动作跨了三个库。单机事务保证的同生共死在这里失效。所有分布式事务方案处理的其实是同一个困境:参与者没有共享的内存和锁表,谁也无法替谁做承诺,只能靠协议协商。差别在于承诺的强度,以及维持这个强度要付多…
服务之间用事件通信,看起来只是把同步调用换成异步消息。真正的差别在于:事件里带回多少信息、谁来使用它、以及系统的真实状态到底存在哪里。把这三件事想清楚,才知道该选事件通知、事件携带状态转移还是事件溯源,以及是否需要 CQRS。 三种事件模式的差…
所有外部流量汇聚到一个入口,天然适合做统一处理。问题是"统一处理"很容易失控:路由、鉴权、限流、日志、协议转换、数据聚合、业务校验、流程编排越堆越多,网关从基础设施变成最复杂的单点,改一行配置要全公司排期。划清职责边界,比挑选具体的网关实现…
"这块代码该重构了"很难争取到资源,它描述的是主观感受,而排期表上每一行都是可交付的功能。技术债管理的第一步不是动手重构,而是把感受翻译成能用同一套标准比较的东西——否则偿还永远排在交付之后,直到某天以故障的形式强制偿还。 债务先要分类 不同类…
用户点了一次"支付",结果扣了两笔钱。这类事故几乎总能追溯到同一个原因:某个环节没做幂等。另一面是,团队知道要做幂等,于是给每个接口都加了一张去重表,最后系统又慢又复杂,边角场景上依然会漏。 幂等不是"加个锁"或"加张表",而是一套需要分层的防护…
一个订单系统迭代到第三年,代码里出现了四个不同含义的"订单"。交易域的订单是支付前的待付款单据,履约域的是待发货清单,结算域的是待开票账目,客服域的是投诉凭证。四者都叫 Order,却因为同名被反复复用、强行兼容。这不是命名问题,是模型边界缺失。…
很多团队的架构评审有两个极端:一种是走形式,方案讲完二十分钟没人提问,上线后集体救火;另一种是挑刺会,资深工程师围着命名和框架选型争论,会议结束没人记得决定了什么。两者源于同一个问题——没说清评审要产出什么。 什么时候做评审 评审应该在方案定…
讨论服务间通信时,最常见的误判是把问题理解成"哪种协议更快"。沿着这条路走下去就变成基准测试数据的比拼,最后得出"gRPC 比 REST 快"这个既正确又没什么用的结论。 真正的差别在通信语义。协议只是语义的载体,语义决定了你的系统怎么失败、怎么重试、怎…
一套系统同时服务多家客户,每家客户看不到别人的数据,还能各自配置、各自扩容、各自退租——这就是多租户。听起来简单,真正落地时你会发现,难点从来不是"加个 tenant_id 字段",而是从这一刻起,系统的每一个查询、每一条索引、每一次统计、每一次数据导出…
线上出问题时的第一诉求永远是"发生了什么"。而常见的处境是:监控面板一片绿,用户投诉却有几十条;或者告警显示某个接口错误率上升,翻遍日志找不到一条异常。缺的不是数据,是数据之间的关联,以及据此回答未知问题的能力。 三者各自回答什么 三类数据的…