我想为移动应用实现文件服务器。此应用在开始工作之前需要从服务器下载大量小文件,并且随着版本更新,某些文件会被覆盖,某些文件会被修改或删除。
尝试过的解决方案:
为每个版本存档分块下载,这意味着我为每个版本创建一个 zip 文件,然后我们提供分块的 zip 文件。这样做的问题是效率低下,因为在客户端解压需要太多额外空间,第二个问题是很难处理更新(当客户端上已经有一些文件时,只下载必要的文件)
TCP 下载不包含存档,这种方式效率低下,因为每个文件的 TCP 握手开销太大,浪费了太多时间
UDP 下载不包含存档,这种方式并不安全,我们无法保证客户端上下载的文件是健康的。此外,在客户端对每个文件进行校验也是一个昂贵的过程,我们不想陷入其中。
非常感谢您的任何建议。
也许值得一提的是,我在服务器端使用了 java spring boot
答案1
为每个版本存档分块下载,这意味着我为每个版本创建一个 zip 文件,然后我们提供分块的 zip 文件。这样做的问题是效率低下,因为在客户端解压需要太多额外空间,第二个问题是很难处理更新(当客户端上已经有一些文件时,只下载必要的文件)
您不需要专门使用 zip 存档。许多此类系统(例如 Steam 或 Battle.Net 等游戏启动器)使用可流式传输的自定义存档格式,即无需先下载整个内容即可提取,并且通常支持某种形式的修补。(Casync 是一个开源示例。)
您的平台可能已经提供此功能,例如通过“Play 资产交付“在Android上。
TCP 下载不包含存档,这种方式效率低下,因为每个文件的 TCP 握手开销太大,浪费了太多时间
您不需要为每个文件单独进行 TCP 握手。大多数文件传输协议(除古老的 FTP 和 AFS 外)已经解决了此问题非常很久以前。
例如,HTTP/1.0 获得了连接保持支持1996年(它在 HTTP/1.1 中成为官方规定)并且几乎每个 HTTP 客户端库都会支持连接重用。
这仍然是一个请求一次在 HTTP/1.1 中,但不太新的 HTTP/2 及其多流支持已专门设计用于同时高效处理许多并发请求(使用平铺图像作为流行的演示)。
您的移动应用可能已经有一个 HTTP/2 客户端库。确保您的服务器支持 HTTP/2,然后发出 100 个异步 HTTP 请求,让库自行解决。(此外,不要托管 Java 应用中静态资产 - 将它们托管在专门用于托管静态文件的单独 Web 服务器中。)
(类似地,几乎所有现代文件系统访问协议 - SFTP、NFSv4、SMB - 都使用单个长寿命 TCP 连接来处理许多请求。只有 FTP 和 AFS 不这样做。)
UDP 下载不带存档,这个不安全,我们无法保证客户端下载的文件是健康的。
你永远不会直接使用 UDP——它是构建的基础传输协议开启,这将提供您所需的可靠性。例如,HTTP/3 使用 QUIC 作为其传输协议,提供与 TCP 相同的可靠性。
另外,在客户端对每个文件进行校验是一个昂贵的过程,我们不想陷入其中。
与实际下载相比,这并不昂贵,而且你反正已经在做了如果您使用任何类型的“安全”协议 - 例如,使用 HTTPS,TLS 库将计算每个数据包的 MAC(这比计算普通哈希值更昂贵)。