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


