Reqable 3.0版本云同步的实践过程

Reqable 3.0上线了的云服务功能,支持数据云端存储和多设备实时同步,就这一个不大不小的功能却花费了我们很大的心思和精力,今天写了这篇文章来和大家分享一下我们的实践过程。

首先,大家可以先看看下面的Reqable的多设备云同步的视频,左边是手机,右边是电脑。在右边电脑上操作数据时,左边手机上可以实时看到最新的API数据,这对团队多人协作非常有用!

下面简单聊聊我们的思考和实践过程。

1. 方案调研

仅仅实现数据存储到云端其实并不难,暴力点一个上传和一个下载接口可能就干完事了。但是为了用户体验我们并不能这么做,有很多需要考虑的点,比如下面这些。

  • 数据何时上传,何时下载?这个问题本质其实就是如何保证本地数据和云端数据的时效性。简单点的方式,是交给用户去操作,用户手动触发上传云端,手动触发从云端下载。逻辑复杂些,再增加一个定时逻辑,每隔一段时间和服务器交互一次,上传数据或者下载数据。让用户来操作,体验必然不会很好,比如数据忘记同步了等等。

  • 如何解决数据版本冲突?单设备的情况下,不会出现数据版本问题。但是多设备的时候,必然会出现版本冲突问题。比如两台设备同时上传数据,这个问题其实好解决,先来先存储,后到的失败。这个问题衍生开来,还有一些情况,例如本地数据和云端数据都更新了采用哪一个,无论最后是保留本地数据还是保留云端数据,都有数据丢失了,丢失数据的概率和多少取决于上一个问题中同步的时效性,同步的间隔越长,丢失数据的概率和数据量就越大。

  • 如何上传,如何下载?在数据量不大的情况下,把所有数据一起丢到接口就可以了,但是如果数据量大了,就非常不合适了,同步时间变慢不说,服务器的带宽也吃不消。我们没办法控制用户接口到底有多少,可能一个API的请求体就好几M了。对此,我们只能做增量更新,比如可以考虑用git来管理数据。为了用户体验,我们决定既要做实时又要做增量更新。无论是REST接口,还是GIT管理,或者是Webdav同步文件,似乎都无法满足,我们只能自己来造个轮子了。

2. WebSocket长连接

因为考虑到要做实时性,我们只能上长连接了。常用的长连接网络通信方案有WebSocket、MQTT、HTTP2等,相对来说WebSocket更加稳妥一点,这也是我们目前采用的方案。

至于增量上传,就是用户每一个操作都需要实时通过WebSocket来与服务器进行同步,比如创建了一个API请求,修改了某个环境变量,修改了API请求的数据,删除了集合等等,无需将全部数据都上传到服务器,只需将用户的操作指令和操作的相关的数据上传即可。

服务器接收到用户的操作指令后,更新云端数据,再将操作指令和数据发送给所有连接的其他设备,其他设备接收到服务器下发的指令后更新本地数据,这样保证服务器和所有的客户端数据都是最新且一致的。

增量更新很容易出现数据版本不一致的问题,比如某台设备接收到操作指令后数据处理出错,这时候这台设备的数据就无法和其他设备保持一致了,这种情况我们就需要做全量同步了。此外,每次启动应用加载数据后,为了保持数据一致,我们也要做全量同步。

全量同步如果触发太过频繁,对服务器也是一个很大的压力,比如用户有几十个API集合,仅仅因为一个操作指令没法完成,所有集合数据都从服务器下载一遍,就太浪费资源了。为此,我们给每个API集合都增加了一个revision字段,服务端集合数据每更新一次revision值都加1,客户端请求全量同步的时候上传本地的revision,如果本地的revision和服务端相同,服务器就无需将数据同步给客户端。

3. 离完美还有距离

我们这种方案虽然解决了数据实时性和数据增量更新两个问题,但是却有一个非常大的缺点,就是太依赖服务器了。如果服务器故障或者用户设备离线,用户的操作指令无法同步到服务器,该怎么办?

一种方案是把用户的操作指令和数据全部存储到本地,等网络恢复再同步。但是操作指令囤积过多又该怎么办,缓存数据会爆炸;另外,就多台设备都缓存了操作指令,同时都同步到服务器该怎么处理。

对于这个问题我们也没想到什么好的解决方案,只好学竞品Postman等一样,在无法连接服务器的时候集合变成只读状态。当然,和Postman完全依赖云端不同,Reqable不会出现集合数据加载不出来的情况,在本地仍然会有数据。即使我们服务器故障,用户仍然可以正常查看集合数据和进行API测试,也可以新建API测试,基本上不会中断大家的工作,限制就是新建或者修改的API无法保存到集合,集合内的数据也没办法删除。

4. 服务端设计

在之前我们对后端是用Java还是Python来实现纠结了很久,最终采纳了多数的建议使用Java,首选当然是Spring Boot了。我们之前后端是使用Dart来写的,这次全部使用Java来重写了。

我们把后端分成了多个子项目来实现,例如常用的接口API,登录注册等等作为一个子项目,云服务作为另一个子项目,和产品功能不相关的像事件统计也单独拆分出来,每个子项目放在不同的服务器上单独部署。这样有个好处,像常规的接口更新会比较频繁,重新部署用户也不会有感知,像云服务使用长连接,我们尽量不去动,因为只要一重新部署所有客户端都会感知到。另外一个考虑,按照我们的规划,云服务这部分代码后面会开源出来,供用户私有部署,如果不放心将数据存储到我们服务器上面的话。

对于数据存储,我们采购了腾讯云的高可用MySQL数据,自带容灾。为了稳妥起见,我们还会每日将数据自动备份到阿里云,毕竟鸡蛋不能放一个篮子里,大家的数据是无价的。

5. 后续规划

目前阶段,多设备同步只能在同一个账户下面进行,后续我们会增加团队功能,同一个团队成员之间可以访问和同步同一个集合的数据。另外,就是不同团队不同账户之间的数据分享功能,例如可以在Reqable内将数据直接分享给指定的用户。

另外一个重要的事项,就是如何让用户自行部署,由于新版本刚上线,还有许多地方需要再思虑和打磨,项目还会有不小的变动,这事情也急不得。

6. 竞品对比

最后,简单聊聊一些知名竞品的实现方案,以及各自的优缺点。

  • Postman,方案和我们类似,也是通过WebSocket向服务器同步用户的操作指令并接收其他账户或者设备的修改指令,然后更新云端和本地数据。只要无法连接服务器,API集合便会进入只读状态。但是我们两者有一个最大的不同点,Postman本质是个浏览器,数据每次都需要从服务器拉取,而且数据只是缓存在本地而不是存储在本地,断网打开Postman可以看到什么数据都没有,加载不出来,直接影响到用户的工作,而Reqable本地的数据仍然可以查看和使用。

  • Bruno,主要是通过Git来管理和同步数据,这也是我们曾经思考过的方案之一。Bruno使用文件来组织API数据,通过Git命令来提交和更新文件。由于使用文本描述语言,可以直观地让用户处理数据版本冲突。缺点是无法做到实时同步,上传数据,需要修改、提交、推送三步走,下载数据还需要暂存本地的修改,其实并不是很方便。

7. 结语

Reqable虽然还有很多不完善的地方,但我们一直在努力更新,一步一个脚印,致力于做最好的API工具,希望大家支持!欢迎访问我们的网站:

reqable.com/

谢谢大家!

相关推荐
恋猫de小郭15 分钟前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
牛奔1 小时前
Go 如何避免频繁抢占?
开发语言·后端·golang
想用offer打牌6 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
KYGALYX8 小时前
服务异步通信
开发语言·后端·微服务·ruby
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
爬山算法8 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate