当前位置: 首页 > 科技观察

想想web应用的数据流

时间:2023-03-17 23:39:15 科技观察

之前做过一个玩具,叫Cumulo,大致意思就是把后端的计算数据通过Diff/Patch发给前端,这样前端浏览器的store就不需要业务逻辑了,从而减少开发。但是,这种做法有天然的缺陷。一是性能问题,二是持久化问题。事实上,它们都可以归因于性能。如果要性能,就必须做增量,然后整个架构就会崩溃。本文试图描述一个稍微正常的基于数据流的架构的一个想法。由于缺乏后端开发经验,不打算给出可行方案。在开始之前,让我们回顾一下实时Web应用程序的架构设计。首先,前端Model-View的分离是第一步,这样才能解放View的开发效率。此时的数据流中,Model的数据发送给View,View的更新操作返回给Model。(这里的Model靠近Store,不是纯数据,而是包含更新逻辑):接下来,把服务器放回去,大致就是Cumulo的情况。这时候数据流转,数据直接发送到服务器,前端Model与服务器同步,最后返回给View。这时候Model就变成了一个中间过程:然后结合上面两张图,简化这部分,基本回到第一张图中的情况。不同的是,此时Model被服务端取代,数据流从服务端流向浏览器:当我们考虑数据库时,尤其是比如数据库是增量处理的,问题就出现了。首先,数据发送到Server而不是Database,因为Server是有逻辑的。其次,Database的整个数据流无法发送到Server,因为太大了。Cumulo采用了Diff/Patch的方案,但这对Database来说是行不通的,所以实际情况比较纠结,Server回归Controller的角色:***为了性能,需要去掉Database的更新逻辑,Model应该退回。那么Model一方面要处理数据请求,另一方面要push,所以只能加,整个数据流多了一些线,比较复杂。这也是原来简聊的粗略结构:但是这个图并不严谨,比如Database和Server的具体关系很难画清楚,请求当然是访问一个web服务器,不能直接放在数据库中。这张图的重点在于,与原始流相比,现在有两个流,架构也变了。数据的获取有两种方式:数据抓取,访问页面时直接抓取数据,抓取历史推送,在用户使用过程中从其他客户端获取更新问题,如果不能简化,减少业务的编写代码,思考是没有意义的。两个数据流的计算方式不一致,不能合二为一,所以想着如何从另外一个角度构造自己创建了一个框架来处理数据流,所以整理了一下聊天室需要的常用操作:切换聊天室capture首屏messagecapturemessagereceivemessageupdatequeryhistorymessageuserloginuserpermissionverificationforthefirst4operationsIcompareCare,因为他们之间有一个共同点,比如消息流,都会有操作比如切换,抓取,历史,更新,整体来说,其他可以抽象成流的数据也可以复用Routine,那么整个应用的页面切换,数据查询,数据更新都可以放到一个统一帧,即路由切换时,选择客户端订阅哪些流,然后根据流进行浏览。当然还有一些问题,需要继续思考,消息列表是一个流,那么用户配置是不是一个流?配置通常是JSON对象。要成为一个流程,还必须包括不同时间的修改操作,但这又涉及到新的问题。每个消息都可能被修改,所以它们也是流。因此,我们需要面对一个复杂得多的流概念。另一个是数据关联。消息中会有附件,聊天室中会有成员。如何处理数据关联?API设计接口如何对应,两者解耦?如果数据之间存在循环关系,整个解决方案会失败吗?这是一件很麻烦的事情,一开始可能会尽量避免。另外,即使上面两个问题都解决了,前面列表中剩下的选项还是需要处理的。权限系统和搜索系统独立于流的结构,不能同时抽象。进一步的问题,数据库和服务器可能是分布式的,会有更复杂的数据流。所以实际上抛出的问题更多。