轮询的困境与局限性
如果你干过后端或者前端,你一定写过类似这【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。样的代码:`setInterval(()【未经授权禁止转载】原创内容,盗版必究。 => fetch(‘未经授权,禁止复制转载。原创内容,盗版必究。/api/status’),【转载请注明来源】【本文受版权保护】 3000)`。别急着否认,我们都干过。【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net轮询这东西,就像快餐——不健康,但方便、著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。便宜、随叫随到。项目早期,谁有空搞什么消【版权所有】唐霜 www.tangshuang.net【本文受版权保护】息队列、WebSocket、事件驱动?一本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net个定时器解决问题,多好。
本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshu【未经授权禁止转载】【本文首发于唐霜的博客】ang.net【未经授权禁止转载】【原创不易,请尊重版权】但业务一旦跑起来,轮询就开始还债了。
【访问 www.tangshuang.n转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。et 获取更多精彩内容】【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。想象一个场景:页面上有 10 个任务需要【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net通过轮询来获取最新状态,每个都跑着一个 本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。3 秒一次的轮询。算一下,每 3 秒就是未经授权,禁止复制转载。【未经授权禁止转载】将近 30 个请求,而且其中 99% 的【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】请求返回的数据跟上次一模一样——服务器在【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】那儿白忙活,带宽在那儿白白流,用户的设备【转载请注明来源】【作者:唐霜】也在那儿白白耗电。
本文作者:唐霜,转载请注明出处。【作者:唐霜】这还不是最糟糕的。当你的系统从单页面变成转载请注明出处:www.tangshuang.net【作者:唐霜】多页面,从单终端变成多终端——手机上点了转载请注明出处:www.tangshuang.net原创内容,盗版必究。”生成”,电脑上【原创内容,转载请注明出处】【版权所有,侵权必究】想看进度——轮询就彻底抓瞎了。你开始在各转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】处补同步逻辑,今天这个页面加一段 `us【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】eEffect` 监听,明天那个组件加一【本文受版权保护】未经授权,禁止复制转载。个 `refetch` 调用,后天发现两原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】个页面的状态互相打架。代码库里到处散落着著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】”同步”的碎片,【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】像打地鼠一样,按下去了这个,那个又冒出来【本文受版权保护】原创内容,盗版必究。。
原创内容,盗版必究。本文作者:唐霜,转载请注明出处。【本文受版权保护】WebSocket 固然是最好的,但是一本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。方面它一直占着一个长链接,用户一多,服务【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。器成本高。另一方面,前后端在接入 web原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】socket 时,需要协调好连接的建立、【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net维护和关闭,这给开发带来了额外的复杂性。【关注微信公众号:wwwtangshuangnet】【作者:唐霜】另外,还有一种 SSE 的方案,但是,仍原创内容,盗版必究。本文作者:唐霜,转载请注明出处。然有长链接占用服务器连接数,一旦出现高并本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net发就会导致服务器长期被占用,新用户进不来【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】的问题。相比之下,轮询更可控,更简单。
【本文受版权保护】【本文受版权保护】未经授权,禁止复制转载。所以问题的本质不是”轮询好不【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net好”,而是我们需要一套系统性的方案来管理状态传播。轮询可以是这套方案的一部分,但不能是全【转载请注明来源】【未经授权禁止转载】部。
【作者:唐霜】转载请注明出处:www.tangshua【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。ng.net问题的本质:构建分层状态传播机制
先明确一下目标。我们要建的不是什么花哨的【转载请注明来源】【版权所有,侵权必究】实时通信系统,而是一套分层的状态传播机制。这个机制要能覆盖三种典型场景:
未经授权,禁止复制转载。【作者:唐霜】未经授权,禁止复制转载。第一种,日常状态。大部分时候系统很安静,没有任务在跑,没【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。有什么需要频繁更新的。这时候我们希望用最原创内容,盗版必究。未经授权,禁止复制转载。低的成本来维持”感知能力转载请注明出处:www.tangshuang.net【本文受版权保护】8221;——有变化了我能知道,没变化的【本文受版权保护】【作者:唐霜】时候你别来烦我。事件通知天然适合干这个。
【访问 www.tangshuang.n未经授权,禁止复制转载。【转载请注明来源】et 获取更多精彩内容】【访问 www.tangshuang.n本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.netet 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。第二种,忙碌状态。用户点了个”生成视频【本文受版权保护】【关注微信公众号:wwwtangshuangnet】221;,进度条在那儿转,停止按钮随时可【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。能被按下去。这时候你不能等事件慢悠悠地来【未经授权禁止转载】原创内容,盗版必究。,用户对延迟的容忍度几乎是零。需要局部的【作者:唐霜】未经授权,禁止复制转载。、短周期的高频同步来保障体验。
原创内容,盗版必究。本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】第三种,出了问题的时候。网络抖了,消息丢了,服务重启了——这种【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。事一定会发生,区别只是早晚。你需要一个兜【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net底机制,在事件链路和同步链路都掉链子的时【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】候,还能把数据拉回来,保证最终一致性。
【作者:唐霜】【版权所有,侵权必究】【访问 www.tangshuang.n【原创内容,转载请注明出处】【本文受版权保护】et 获取更多精彩内容】这三层各司其职,互相补充。后面所有的设计原创内容,盗版必究。原创内容,盗版必究。决策,都是围绕这个三层模型展开的。
转载请注明出处:www.tangshua【本文受版权保护】著作权归作者所有,禁止商业用途转载。ng.net【转载请注明来源】核心设计原则:通知与数据解耦
在我见过的消息系统里,最容易犯的一个错误【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。就是往消息体里塞太多东西。任务状态变了?【未经授权禁止转载】本文作者:唐霜,转载请注明出处。好,把整个任务对象塞进消息里。资源更新了转载请注明出处:www.tangshuang.net【未经授权禁止转载】?把完整的资源数据也带上。听起来挺方便—【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。—前端收到消息直接用,不用再发请求了,多转载请注明出处:www.tangshuang.net【转载请注明来源】省事。
本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】【关注微信公众号:wwwtangshua【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。ngnet】【本文受版权保护】省事是省事了,但后患无穷。
【原创不易,请尊重版权】原创内容,盗版必究。首先,消息体一大,吞吐量就下来了。你本来本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。一秒能发一万条轻量通知,现在一条消息就几本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。 KB,同样的带宽能承载的量直接缩水。其原创内容,盗版必究。【本文受版权保护】次,业务字段一变,消息协议就得跟着变。今【版权所有,侵权必究】【本文受版权保护】天加个字段,明天改个结构,消息的消费端全【本文首发于唐霜的博客】未经授权,禁止复制转载。得跟着改——这就是耦合的代价。最要命的是【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】,前端收到一个”大消息【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。221;之后,到底要不要刷新?如果消息里【原创内容,转载请注明出处】【转载请注明来源】的数据已经是最新的了,那确实不用刷;但如【转载请注明来源】【原创不易,请尊重版权】果消息在路上耽搁了一会儿,数据库又更新了【转载请注明来源】【关注微信公众号:wwwtangshuangnet】呢?你拿消息里的数据去渲染,反而是错的。
【关注微信公众号:wwwtangshua【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】ngnet】【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshu【本文受版权保护】本文版权归作者所有,未经授权不得转载。ang.net所以正确做法是:消息只告诉你”哪里脏了【版权所有,侵权必究】原创内容,盗版必究。221;,具体脏成了什么样,你自己去查。
本文作者:唐霜,转载请注明出处。【未经授权禁止转载】【原创不易,请尊重版权】一条消息大概长这样:实体类型是̶【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。1;项目”,实体 ID 是 【原创内容,转载请注明出处】【未经授权禁止转载】123,任务类型是”视频生成【本文受版权保护】本文作者:唐霜,转载请注明出处。”,时间戳是变更发生的时刻。【作者:唐霜】【转载请注明来源】就够了。前端收到这条消息,知道̶著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。1;项目 123 的视频生成任务有变化&【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。#8221;,然后自己去拉最新的数据。消【原创内容,转载请注明出处】【原创内容,转载请注明出处】息体小、协议稳定、前端按需刷新——三赢。
著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】【原创内容,转载请注明出处】原创内容,盗版必究。幂等与去重:消息可靠性的基石
很多人在设计消息系统的时候,潜意识里假设【本文受版权保护】原创内容,盗版必究。消息是可靠的——发一条,收一条,顺序还对转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net。但现实是:消息可能重复发送(网络超时触本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】发了重试),可能乱序到达(走了不同的链路【本文首发于唐霜的博客】【作者:唐霜】),可能延迟很久才到(某个中间件卡了一下【原创内容,转载请注明出处】【访问 www.tangshuang.net 获取更多精彩内容】)。如果你不考虑这些,用户就会看到进度条原创内容,盗版必究。【作者:唐霜】先跳到 100% 又弹回 50%,或者一【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】个已经完成的任务突然变成”进转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。行中”——这种体验,比没有通【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】知还糟糕。
【未经授权禁止转载】原创内容,盗版必究。【原创内容,转载请注明出处】所以在协议层面就要把去重和幂等做好。每条【版权所有】唐霜 www.tangshuang.net【作者:唐霜】消息带一个单调递增的 `timestam转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】p`(注意,必须是业务更新的真实时间,不【转载请注明来源】著作权归作者所有,禁止商业用途转载。是消息发送的时间),前端收到消息后先跟本【作者:唐霜】本文作者:唐霜,转载请注明出处。地记录比一下:时间戳没前进?忽略。时间戳著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】前进了但 payload 一样?也忽略。本文作者:唐霜,转载请注明出处。【未经授权禁止转载】时间戳前进了且 payload 有变化?本文作者:唐霜,转载请注明出处。【本文受版权保护】更新本地记录,触发刷新。
【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】还有一种常见的场景:短时间内同一个实体连【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。着来了好几条通知。比如一个视频生成任务,【未经授权禁止转载】【转载请注明来源】先是”开始”,再未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】是”进度 30%”【版权所有】唐霜 www.tangshuang.net【本文受版权保护】;,再是”进度 60%转载请注明出处:www.tangshuang.net【本文受版权保护】221;——三条消息在一秒内扎堆到达。你【转载请注明来源】【本文首发于唐霜的博客】不需要刷三次,合并成一次刷新就够了。这就原创内容,盗版必究。原创内容,盗版必究。是所谓的”通知合并̶转载请注明出处:www.tangshuang.net【作者:唐霜】1;,在桥接层做。
【版权所有,侵权必究】【原创内容,转载请注明出处】三层架构设计:采集、桥接与运行时
好,原则讲完了,来看具体的架构。整个系统【原创不易,请尊重版权】【关注微信公众号:wwwtangshuangnet】分三层,从上到下分别是消息采集层、客户端著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】桥接层和页面运行时层。听起来挺唬人,其实【版权所有】唐霜 www.tangshuang.net【转载请注明来源】每层做的事情都很明确。
未经授权,禁止复制转载。【版权所有】唐霜 www.tangshu本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。ang.net【版权所有,侵权必究】第一层:消息采集层
这一层跑在后端,职责很简单:定期看看最近著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】有哪些实体发生了变化,整理成一个R未经授权,禁止复制转载。未经授权,禁止复制转载。21;脏列表”返回给前端。
本文版权归作者所有,未经授权不得转载。【本文受版权保护】你可能会问:这不是还是轮询吗?对,但它跟原创内容,盗版必究。本文作者:唐霜,转载请注明出处。页面的业务轮询有本质区别。页面轮询是转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】8221;我要查某个具体的东西有没有变&【原创内容,转载请注明出处】【本文受版权保护】#8221;,采集层是”有什【原创内容,转载请注明出处】未经授权,禁止复制转载。么东西变了告诉我”。前者是 【原创不易,请尊重版权】【转载请注明来源】N 个页面各轮询各的,后者是统一的、聚合原创内容,盗版必究。【本文受版权保护】的状态变更源。前端只需要跟这一个源头打交【访问 www.tangshuang.net 获取更多精彩内容】【未经授权禁止转载】道,不用关心后端有多少个业务模块在产生变本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net更。
【版权所有,侵权必究】转载请注明出处:www.tangshua【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】ng.net【本文受版权保护】本文版权归作者所有,未经授权不得转载。采集层吐出来的数据也很轻量:变更对象的类【原创内容,转载请注明出处】【作者:唐霜】型和 ID、变更的范围(比如是资源变了还原创内容,盗版必究。原创内容,盗版必究。是任务状态变了)、任务类型、时间戳。就这【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】么几个字段,JSON 序列化完也就一两百【本文受版权保护】转载请注明出处:www.tangshuang.net字节。
原创内容,盗版必究。【原创不易,请尊重版权】【关注微信公众号:wwwtangshua【作者:唐霜】原创内容,盗版必究。ngnet】第二层:客户端桥接层
这一层跑在前端,是整个系统的中枢。它全局本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】监听采集层吐出来的脏列表,写入本地的 d本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。irty store,然后分发给各个页面【版权所有】唐霜 www.tangshuang.net【本文受版权保护】。
【作者:唐霜】【版权所有,侵权必究】未经授权,禁止复制转载。【本文首发于唐霜的博客】桥接层要做的四件事,我在前面其实都提过了【原创不易,请尊重版权】【原创内容,转载请注明出处】:去重(基于时间戳)、合并(同实体多次通【本文受版权保护】本文版权归作者所有,未经授权不得转载。知合并成一个)、限频(短时间窗口内的突发【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。通知攒一批再处理)、分发(转给对应的页面【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】或模块)。这四件事做好了,下游的页面就不本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。用操心消息的可靠性问题了——你给它的就是【作者:唐霜】【原创不易,请尊重版权】干净、去重、合并过的信号。
本文作者:唐霜,转载请注明出处。【转载请注明来源】第三层:页面运行时层
这一层是离用户最近的地方,也是最容易写出【本文受版权保护】原创内容,盗版必究。面条代码的地方。
【本文首发于唐霜的博客】【本文首发于唐霜的博客】页面收到 dirty 信号后,要决定怎么【本文受版权保护】未经授权,禁止复制转载。刷新。最直觉的做法是在事件回调里写一堆条【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。件判断:如果任务类型是 A 就刷这个接口【本文首发于唐霜的博客】【原创不易,请尊重版权】,如果是 B 就刷那个接口,如果两个都有【未经授权禁止转载】【原创不易,请尊重版权】就都刷……写着写着,回调函数就膨胀成了几【关注微信公众号:wwwtangshuangnet】【作者:唐霜】百行的怪物,而且逻辑散落各处,谁也不敢改未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net。
【转载请注明来源】【原创内容,转载请注明出处】更好的做法是抽象出一个策略映射表。输入是任务类型、变更范围和当前页面的上【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。下文(是不是忙态、页面可不可见、当前选中【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。了什么),输出是一个明确的”【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】刷新计划”——需要刷哪些接口【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。、以什么粒度刷、串行还是并行。这样逻辑集【原创内容,转载请注明出处】【原创内容,转载请注明出处】中在一处,新增任务类型只需要加一行映射,【未经授权禁止转载】本文作者:唐霜,转载请注明出处。不用动流程代码。
原创内容,盗版必究。本文作者:唐霜,转载请注明出处。刷新执行完之后,还要做一次”【本文首发于唐霜的博客】本文作者:唐霜,转载请注明出处。收敛检查”——确认本地的状态著作权归作者所有,禁止商业用途转载。【转载请注明来源】跟远端的状态一致了。如果不一致,说明中间【本文受版权保护】【本文首发于唐霜的博客】可能漏了什么,这时候就触发兜底拉取。
【转载请注明来源】原创内容,盗版必究。本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。系统工作流程:注册、采集与消费的完整链路
前面讲了三层架构各自负责什么,但光知道&【访问 www.tangshuang.net 获取更多精彩内容】【访问 www.tangshuang.net 获取更多精彩内容】#8221;谁干什么”还不够著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net——你得看到数据是怎么从头到尾流转的,才【版权所有】唐霜 www.tangshuang.net【本文受版权保护】能真正理解这套系统为什么这么设计。
【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。整个工作流程分六个步骤,先用一张图把全局【访问 www.tangshuang.net 获取更多精彩内容】【未经授权禁止转载】串起来:
【未经授权禁止转载】【本文受版权保护】【作者:唐霜】【转载请注明来源】下面逐步拆解。
【本文首发于唐霜的博客】【未经授权禁止转载】【作者:唐霜】① 注册:业务模块告诉系统”转载请注明出处:www.tangshuang.net【本文受版权保护】我能检测变化”
原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。这是整个流程的起点。每个业务模块在服务启【原创不易,请尊重版权】【作者:唐霜】动的时候,向 MessageRegist本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.netry 注册自己:我叫什么名字(type)转载请注明出处:www.tangshuang.net【转载请注明来源】,以及怎么检测变化(handler)。比本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】如通知模块注册了 `notificati原创内容,盗版必究。【未经授权禁止转载】on.announcement`,视频任【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。务模块注册了 `video.genera【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】tion`——每个模块只需要管好自己的 【本文受版权保护】本文版权归作者所有,未经授权不得转载。handler,不用关心谁在消费这些消息原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net。
【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.n本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】et 获取更多精彩内容】handler 的接口很简单:给它一个用转载请注明出处:www.tangshuang.net【作者:唐霜】户 ID,它返回 `{ has_new:【本文受版权保护】【版权所有,侵权必究】 true/false, data: {转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】…} }`。至于”【本文受版权保护】【本文受版权保护】;怎么判断有没有新消息”,那转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。是每个业务模块自己的事——查数据库也好,未经授权,禁止复制转载。【作者:唐霜】读缓存也好,MessageRegistr转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】y 不操心。
【转载请注明来源】原创内容,盗版必究。② 采集:统一入口,并发调用所有 han本文作者:唐霜,转载请注明出处。【本文受版权保护】dler
【转载请注明来源】著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshua本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。ngnet】【未经授权禁止转载】当前端发来 `GET /api/mess【原创内容,转载请注明出处】【未经授权禁止转载】ages` 请求时,API 层调用 `M【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。essageRegistry.colle【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。ct(uid)`。这个方法会遍历所有已注本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net册的 handler,用 `Promis著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】e.allSettled` 并发调用——原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。注意是 `allSettled` 而不是【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net `all`,意思是某个 handler【关注微信公众号:wwwtangshuangnet】【版权所有,侵权必究】 挂了不影响其他 handler 的结果【版权所有】唐霜 www.tangshuang.net【转载请注明来源】。最后把 `has_new` 为 tru原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】e 的消息筛出来返回。
【原创内容,转载请注明出处】【版权所有,侵权必究】【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。这就是”通知与数据解耦【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】221;的具体体现:返回的不是完整业务数【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net据,而是一个轻量的”有没有变【转载请注明来源】本文作者:唐霜,转载请注明出处。化”的信号。前端拿到这个信号【作者:唐霜】【本文受版权保护】,再决定要不要去拉具体数据。
转载请注明出处:www.tangshua【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。ng.net本文版权归作者所有,未经授权不得转载。③ 轮询:前端的统一心跳
本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】【访问 www.tangshuang.n未经授权,禁止复制转载。【转载请注明来源】et 获取更多精彩内容】本文作者:唐霜,转载请注明出处。MessagePoller 是前端唯一跟本文版权归作者所有,未经授权不得转载。【作者:唐霜】消息系统打交道的地方。它每 3 秒发一次【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】 `GET /api/messages`【本文受版权保护】【未经授权禁止转载】,不管页面上有多少个业务模块在等消息——【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net只需要这一个轮询就够了。跟之前̶【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net1;每个业务各轮询各的”相比【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。,请求量从 N 降到 1。
【原创内容,转载请注明出处】【关注微信公众号:wwwtangshua【版权所有,侵权必究】【本文受版权保护】ngnet】著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。返回的数据也很精简:一组 `{ type【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。, has_new, data }` 加【版权所有,侵权必究】【本文首发于唐霜的博客】一个全局时间戳。如果没有任何变化,响应就转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。是空的,几乎不占带宽。
原创内容,盗版必究。本文作者:唐霜,转载请注明出处。原创内容,盗版必究。④ 广播:把”脏信号R【转载请注明来源】【转载请注明来源】21;分发出去
原创内容,盗版必究。【本文首发于唐霜的博客】【版权所有,侵权必究】【本文首发于唐霜的博客】Poller 收到响应后,遍历所有 `h【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.netas_new` 的消息,通过 `glob【转载请注明来源】原创内容,盗版必究。alEvent.emit(‘未经授权,禁止复制转载。原创内容,盗版必究。MSG:${type}’, 【原创不易,请尊重版权】【访问 www.tangshuang.net 获取更多精彩内容】data)` 广播出去。这一步就是【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】221;桥接层”在干活——它著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】把后端的轮询响应转化成了前端内部的事件总【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net线。
【访问 www.tangshuang.n【未经授权禁止转载】【转载请注明来源】et 获取更多精彩内容】【关注微信公众号:wwwtangshua未经授权,禁止复制转载。【原创内容,转载请注明出处】ngnet】【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。为什么要用事件总线而不是直接调各个模块的【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】方法?因为解耦。Poller 不需要知道原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】页面上有哪些模块在监听,也不需要知道每个【原创不易,请尊重版权】【版权所有,侵权必究】模块拿到消息后要干什么。它只管̶【转载请注明来源】【原创内容,转载请注明出处】1;谁有变化,就喊一嗓子”,【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net至于谁来听、听了之后做什么,各自负责。
【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。⑤ 订阅:各取所需,按类型监听
【版权所有】唐霜 www.tangshu【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。ang.net【版权所有】唐霜 www.tangshu【原创内容,转载请注明出处】【转载请注明来源】ang.net本文作者:唐霜,转载请注明出处。每个业务模块在前端通过 `globalE【原创内容,转载请注明出处】【原创内容,转载请注明出处】vent.on(‘MSG:$未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】{type}’, handl著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.neter)` 监听自己关心的消息类型。通知模【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】块听 `MSG:notification【原创内容,转载请注明出处】【作者:唐霜】.announcement`,视频任务模未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net块听 `MSG:video.genera未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.nettion`——互不干扰,各自拿到各自的信转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。号。
【版权所有】唐霜 www.tangshu本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】ang.net【本文首发于唐霜的博客】转载请注明出处:www.tangshua【版权所有】唐霜 www.tangshuang.net【作者:唐霜】ng.net著作权归作者所有,禁止商业用途转载。这种模式的好处是:新增一个业务模块,只需【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】要在后端注册一个 handler、在前端【转载请注明来源】【转载请注明来源】加一个 `on` 监听,不用改 Poll未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。er、不用改 API、不用改任何其他模块原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。的代码。真正的”开闭原则【本文受版权保护】著作权归作者所有,禁止商业用途转载。8221;。
未经授权,禁止复制转载。【未经授权禁止转载】【版权所有】唐霜 www.tangshu著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。ang.net著作权归作者所有,禁止商业用途转载。⑥ 拉取与渲染:按需获取完整数据
【未经授权禁止转载】【原创内容,转载请注明出处】Hook 收到”脏信号【本文受版权保护】本文版权归作者所有,未经授权不得转载。221;之后,才去调具体的业务接口拉完整【原创不易,请尊重版权】未经授权,禁止复制转载。数据——这就是所谓的”按需拉【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。取”。拉到数据后更新本地状态【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。,UI 组件自动响应式渲染。
【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。整个链路串起来就是:业务模块注册 → Poller 轮询触发本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】采集 → Registry 并发调用 h【未经授权禁止转载】【转载请注明来源】andler → 返回脏信号 → Pol【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.netler 广播 → Hook 订阅 → 按著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】需拉取 → UI 更新。每一步职责清晰,每一步都可以独立演进。
【访问 www.tangshuang.n【本文受版权保护】原创内容,盗版必究。et 获取更多精彩内容】转载请注明出处:www.tangshua【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】ng.net并发控制:刷新风暴的防御策略
这是实际落地中很容易踩的坑。想象一下:用原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】户一口气提交了 10 个生成任务,每个任【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】务的状态变更都会触发刷新,短时间内你可能【原创内容,转载请注明出处】【原创不易,请尊重版权】面临几十次刷新请求同时发出的情况——这就【本文受版权保护】【版权所有,侵权必究】是刷新风暴。
【版权所有】唐霜 www.tangshu【本文受版权保护】本文版权归作者所有,未经授权不得转载。ang.net转载请注明出处:www.tangshua未经授权,禁止复制转载。【原创不易,请尊重版权】ng.net有三个招可以防。
【版权所有】唐霜 www.tangshu【原创不易,请尊重版权】转载请注明出处:www.tangshuang.netang.net【本文首发于唐霜的博客】未经授权,禁止复制转载。未经授权,禁止复制转载。第一招:请求合并(In-flight C本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。oalescing)。 同一个接口的请求如果在飞了(还没回来)未经授权,禁止复制转载。【本文受版权保护】,后来的请求不要重复发,只打个标记。等前【关注微信公众号:wwwtangshuangnet】【本文受版权保护】面的请求回来了,根据标记决定要不要再发一本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net次。这样就算一瞬间来了 10 个通知,同转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。一个接口最多也就 2 次请求:一次处理已【本文受版权保护】本文作者:唐霜,转载请注明出处。有的变更,一次处理积攒的新变更。
未经授权,禁止复制转载。【本文受版权保护】第二招:模式升级(Mode Escala转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】tion)。 有时候一个”轻刷新R【作者:唐霜】【本文首发于唐霜的博客】21;(比如只拉任务状态)和一个R【作者:唐霜】本文作者:唐霜,转载请注明出处。21;重刷新”(比如拉完整的著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。资源列表)同时触发了。与其分别执行两次,【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。不如直接升级成重刷新一次搞定。反正重刷新转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net的结果包含轻刷新的结果,做一次就够了。
本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshua著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。ngnet】未经授权,禁止复制转载。第三招:软超时兜底。 正常情况下,事件链路会自然收敛——任务未经授权,禁止复制转载。【原创不易,请尊重版权】结束了,最后一轮刷新确认了状态,皆大欢喜【作者:唐霜】著作权归作者所有,禁止商业用途转载。。但万一没收敛呢?比如最后一条消息丢了,未经授权,禁止复制转载。【原创内容,转载请注明出处】前端一直卡在”进行中R【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net21;。这时候需要一个软超时:如果过了指【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】定时间还没有收敛确认,就主动触发一次兜底【未经授权禁止转载】未经授权,禁止复制转载。拉取,强行把状态拉对。注意是”【原创不易,请尊重版权】【未经授权禁止转载】;软”超时——不是硬中断,而未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】是温和地补一次。
转载请注明出处:www.tangshua【版权所有,侵权必究】【作者:唐霜】ng.net未经授权,禁止复制转载。生命周期策略:忙态与闲态的分治管理
如果你的系统在任何时候都以同样的策略运行【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。,那一定有什么地方在浪费。没有任务跑的时【转载请注明来源】【关注微信公众号:wwwtangshuangnet】候,没必要每 3 秒同步一次;任务跑得正【本文受版权保护】原创内容,盗版必究。欢的时候,你也不能指望事件通知能跟上用户原创内容,盗版必究。【转载请注明来源】对即时反馈的期望。
【本文受版权保护】【原创不易,请尊重版权】所以需要区分两种状态:忙态和闲态。
本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】转载请注明出处:www.tangshua【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。ng.net忙态就是有任务在跑的时候。这时候保持一个短周【作者:唐霜】本文作者:唐霜,转载请注明出处。期的局部同步(比如 2~3 秒一次),主【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】要为了保障进度条的即时更新、锁定状态的准【未经授权禁止转载】原创内容,盗版必究。确显示、停止按钮的快速响应。这个同步范围本文作者:唐霜,转载请注明出处。【未经授权禁止转载】要尽量小——只同步当前关心的那个实体的任转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】务状态,不要全量拉。
【原创不易,请尊重版权】【转载请注明来源】原创内容,盗版必究。【未经授权禁止转载】闲态就是没有活动任务的时候。这时候关掉高频同著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net步,主要依赖事件通知来唤醒刷新。没变化就本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。什么都不做,有变化了事件会告诉你。
【版权所有,侵权必究】【关注微信公众号:wwwtangshua著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。ngnet】关键在于怎么切换。进入忙态不能只看本地状态——用户可能在【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】另一个设备上启动了任务——必须结合远端状【转载请注明来源】【本文受版权保护】态一起判断。退出忙态也不能急,必须确认状【原创内容,转载请注明出处】【原创内容,转载请注明出处】态已经收敛了(本地状态跟远端状态一致了)著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net才能退,不然 UI 会抖。
【原创内容,转载请注明出处】【转载请注明来源】这里有个细节值得注意:退出忙态的时机太早著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net,用户会看到进度条突然跳回旧状态;太晚,著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。又白白多轮询了好几轮。实践中,我们会在最【本文受版权保护】著作权归作者所有,禁止商业用途转载。后一轮同步确认”没有活跃任务【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。”之后,再等一个周期做二次确【作者:唐霜】【版权所有,侵权必究】认,然后才真正退出忙态。两轮确认,换来的【原创不易,请尊重版权】【版权所有,侵权必究】是 UI 的稳定。同时,为了在有新任务时【转载请注明来源】【本文首发于唐霜的博客】,避免闲态轮询间隔时间过长,我们可以在发转载请注明出处:www.tangshuang.net【未经授权禁止转载】起新任务的地方,立即激活忙态,让轮询恢复未经授权,禁止复制转载。【本文首发于唐霜的博客】较短间隔。
【关注微信公众号:wwwtangshua【版权所有】唐霜 www.tangshuang.net【转载请注明来源】ngnet】转载请注明出处:www.tangshua原创内容,盗版必究。【版权所有,侵权必究】ng.net转载请注明出处:www.tangshua【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。ng.net【原创内容,转载请注明出处】数据一致性与异常场景处理
设计消息系统的时候,有一些边界情况特别容转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net易忽略,但一旦出问题就特别显眼。
转载请注明出处:www.tangshua原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】ng.net原创内容,盗版必究。【原创内容,转载请注明出处】【访问 www.tangshuang.n【关注微信公众号:wwwtangshuangnet】【访问 www.tangshuang.net 获取更多精彩内容】et 获取更多精彩内容】乱序问题。*消息 A 先发出,消息 B 后发出,但 【原创内容,转载请注明出处】【访问 www.tangshuang.net 获取更多精彩内容】B 先到了。如果你简单地”收【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】到就更新”,就会用旧数据覆盖【本文受版权保护】本文作者:唐霜,转载请注明出处。新数据。解决方案是永远以更新的版本为准—【本文受版权保护】本文作者:唐霜,转载请注明出处。—不是”后到为准”原创内容,盗版必究。未经授权,禁止复制转载。;,而是”时间戳更大为准【本文受版权保护】本文作者:唐霜,转载请注明出处。8221;。
【原创内容,转载请注明出处】未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。停止的语义。 “用户点了停止”【本文受版权保护】【版权所有】唐霜 www.tangshuang.net;和”任务已经停了̶【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net1;是两个不同的状态。点了停止之后,任务【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】可能还需要一段时间才能真正停下来。如果 未经授权,禁止复制转载。【原创内容,转载请注明出处】UI 在用户点完停止后就直接显示R【未经授权禁止转载】【原创不易,请尊重版权】21;已完成”,用户会以为结【版权所有,侵权必究】【作者:唐霜】果已经出来了;如果一直显示”原创内容,盗版必究。原创内容,盗版必究。停止中”不动,用户又以为系统著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。卡死了。正确的做法是有一个明确的R【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。21;停止中”过渡态,等任务【原创不易,请尊重版权】【未经授权禁止转载】真正停了再切换到最终状态。
本文版权归作者所有,未经授权不得转载。【作者:唐霜】【访问 www.tangshuang.n【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.netet 获取更多精彩内容】原创内容,盗版必究。失败恢复。 刷新失败了怎么办?第一反应可能是立即重转载请注明出处:www.tangshuang.net原创内容,盗版必究。试,但这是错的——如果失败是因为服务端过【转载请注明来源】【版权所有】唐霜 www.tangshuang.net载,立即重试只会让情况更糟。应该用指数退未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net避:第一次等 1 秒重试,第二次等 2 未经授权,禁止复制转载。【原创不易,请尊重版权】秒,第三次等 4 秒……同时保留一个最小著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。兜底路径,确保即使重试都失败了,用户下次原创内容,盗版必究。【转载请注明来源】操作时也能拿到正确数据。别忘了打点记录失未经授权,禁止复制转载。【本文首发于唐霜的博客】败原因——这些数据在排查问题的时候是无价原创内容,盗版必究。【原创内容,转载请注明出处】之宝。
【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。可观测性设计:上线后的关键指标
系统做完了不是结束,是开始。没有可观测性【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net的消息系统,上线之后就是一个谁都不敢动的【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net黑盒——出了问题不知道,知道了不知道为什著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】么,知道了为什么不知道怎么修。
本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。建议关注四组指标。
【版权所有】唐霜 www.tangshu原创内容,盗版必究。本文作者:唐霜,转载请注明出处。ang.net本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】链路健康:消息采样成功率怎么样?`has_new本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。` 的命中率是多少(如果命中率太低,说明【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net采样周期内大部分时候都没变化,可以适当拉【访问 www.tangshuang.net 获取更多精彩内容】【转载请注明来源】长周期)?客户端消费成功率呢(有没有消息未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net到了前端但没被处理的情况)?
【版权所有】唐霜 www.tangshu本文版权归作者所有,未经授权不得转载。【本文受版权保护】ang.net转载请注明出处:www.tangshua原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】ng.net【本文受版权保护】著作权归作者所有,禁止商业用途转载。性能:单用户每分钟的消息量是多少?单页面每分【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】钟的刷新请求量是多少?刷新的平均耗时和 【未经授权禁止转载】【未经授权禁止转载】P95 是多少?这些数字能帮你判断系统有本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。没有在”空转”。
【作者:唐霜】转载请注明出处:www.tangshua著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.netng.net转载请注明出处:www.tangshua本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】ng.net正确性:兜底同步触发了多少次?如果兜底同步触发本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。太频繁,说明主链路有问题。状态收敛超时率【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】是多少?前端有没有”卡在运行未经授权,禁止复制转载。【本文首发于唐霜的博客】中”一直不恢复的情况?
【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。体验:从任务实际结束到 UI 显示更新,用户【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。等了多久?从用户按下”停止&转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net#8221;到看到停止反馈,又等了多久?未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。这两个延迟是用户最直接能感知到的。
本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshu转载请注明出处:www.tangshuang.net原创内容,盗版必究。ang.net【本文受版权保护】工程化落地路径
说了这么多,真正动手的时候应该从哪一步开原创内容,盗版必究。转载请注明出处:www.tangshuang.net始?我建议按这个顺序来:
本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。【原创不易,请尊重版权】先定义统一的 dirty 协议。这是整个【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。系统的基石,协议不定好,后面都白搭。然后【原创不易,请尊重版权】【原创不易,请尊重版权】搭服务端采集器,按 TTL 返回最近变化本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】。接下来搭前端桥接层,把去重、合并、分发【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。做好。这三步做完,基础设施就有了。
转载请注明出处:www.tangshua【作者:唐霜】未经授权,禁止复制转载。ng.net【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.n著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。et 获取更多精彩内容】然后抽象刷新策略映射表,把页面里的面条逻转载请注明出处:www.tangshuang.net【原创不易,请尊重版权】辑收拢。再接入页面运行时,实现忙态轮询和【本文受版权保护】原创内容,盗版必究。闲态消息唤醒。加上 in-flight 【作者:唐霜】【本文受版权保护】合并和软超时兜底之后,系统的可靠性就基本原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。有保障了。
【本文首发于唐霜的博客】【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】最后补观测指标和报警,做灰度验证,对比改本文作者:唐霜,转载请注明出处。原创内容,盗版必究。造前后的指标变化。千万别跳过灰度——消息【本文受版权保护】【本文受版权保护】系统是底层基础设施,全量上线出问题就是全本文版权归作者所有,未经授权不得转载。【本文受版权保护】局性的。
原创内容,盗版必究。【关注微信公众号:wwwtangshua本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。ngnet】【原创内容,转载请注明出处】常见反模式与规避策略
在结束之前,再聊几个我见过的典型反模式,本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。希望你看了能绕开。
【转载请注明来源】转载请注明出处:www.tangshua转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。ng.net把完整业务对象塞进消息体。 前面说过这个了,再说一遍是因为真的太常本文版权归作者所有,未经授权不得转载。【作者:唐霜】见了。图一时方便,后面维护的时候就知道什本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】么叫”牵一发而动全身R著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】21;。
【作者:唐霜】【本文受版权保护】【作者:唐霜】页面里到处都是”收到通知就全未经授权,禁止复制转载。【转载请注明来源】量刷新”。 这种做法简单粗暴,短期内能跑,但请求量【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】大、用户体验差、服务器压力大。而且每个页【作者:唐霜】本文版权归作者所有,未经授权不得转载。面的刷新逻辑都是独立的,改一个地方容易,【本文受版权保护】【原创不易,请尊重版权】改十个地方就呵呵了。
著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshua【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.netng.net【作者:唐霜】原创内容,盗版必究。不做去重。 重复通知触发重复请求,重复请求返回重复【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。数据,重复数据触发重复渲染——这条链路每【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net一环都在浪费。
【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshu著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。ang.net任务结束只靠单一信号判断。 比如只看”任务状态变成了 转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.netcompleted”,但如果【转载请注明来源】本文版权归作者所有,未经授权不得转载。这条消息丢了呢?或者来了但被去重逻辑误判本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。了呢?必须有兜底手段。
【本文受版权保护】转载请注明出处:www.tangshua【作者:唐霜】【版权所有】唐霜 www.tangshuang.netng.net本文作者:唐霜,转载请注明出处。用固定高频轮询覆盖所有场景。 不管有没有任务在跑,都 3 秒轮询一次本文作者:唐霜,转载请注明出处。【本文受版权保护】。这是偷懒的做法,对用户、对服务器都不友【转载请注明来源】【原创内容,转载请注明出处】好。
【作者:唐霜】【版权所有】唐霜 www.tangshu著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.netang.net本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。小结
说到底,一套好的消息通知系统就在做三件事【转载请注明来源】未经授权,禁止复制转载。:用事件减少无效同步的成本,用运行时策略【本文受版权保护】未经授权,禁止复制转载。保障关键交互的体验,用兜底机制守住最终一【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】致性。
【访问 www.tangshuang.n转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。et 获取更多精彩内容】未经授权,禁止复制转载。【转载请注明来源】【转载请注明来源】它不是某个框架的特性,也不是某段代码的技转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。巧,而是一种可以复制的工程化能力。只要你【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。的系统存在”异步任务 + 状【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。态反馈 + 多端一致性”的问【作者:唐霜】【访问 www.tangshuang.net 获取更多精彩内容】题——说白了,只要你做过任何涉及异步状态【版权所有,侵权必究】【作者:唐霜】的 Web 应用——这套方案都能落地,而【作者:唐霜】【关注微信公众号:wwwtangshuangnet】且能跟着业务一起演进。
本文作者:唐霜,转载请注明出处。【未经授权禁止转载】当然,这篇文章里的每一条都是过来人的经验本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。总结,不是什么金科玉律。你的业务场景可能【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。有自己的特殊性,该调整的地方就调整。重要【转载请注明来源】【本文受版权保护】的是理解背后的思路:分层、解耦、幂等、可【访问 www.tangshuang.net 获取更多精彩内容】【转载请注明来源】观测——这四个词记住了,设计出来的系统就【版权所有,侵权必究】原创内容,盗版必究。不会差到哪里去。
【关注微信公众号:wwwtangshua【版权所有】唐霜 www.tangshuang.net【作者:唐霜】ngnet】本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。2026-05-29 46


