将 1000 多条记录上传到还包含来自 iOS/Android 应用程序的每条记录的图像的服务器的最佳方法是啥?
Posted
技术标签:
【中文标题】将 1000 多条记录上传到还包含来自 iOS/Android 应用程序的每条记录的图像的服务器的最佳方法是啥?【英文标题】:What is the best approach to upload 1000+ records to a server that also contains images for each record from an iOS/Android app?将 1000 多条记录上传到还包含来自 iOS/Android 应用程序的每条记录的图像的服务器的最佳方法是什么? 【发布时间】:2017-10-15 00:26:28 【问题描述】:我有一个离线工作的应用程序。假设在此期间以及建立连接时,每条记录中都会创建 1000 多条记录。将所有 1000 多条记录发送到服务器的方法应该是什么,该服务器还处理网络调用或 API 故障响应之间的任何中断。
我假设我必须分批发送记录,但是如何处理中断并保持一致性并防止任何类型的数据丢失。
【问题讨论】:
我不知道这是不是一个好建议,您为什么不将记录转换为文件(CSV)并上传到服务器并由服务器处理其余部分。 @jagapathi 那么图片呢? 那么你已经跟随本地同步到远程数据库 (1) 你自己的服务器?或者您需要一台服务器作为解决方案的一部分? (2) 你想优化什么?尽可能快地上传?还是在后台以最低的用户成本? (电池、CPU、带宽..) 使用 NSOperationQueue 将记录上传到服务器。它处理失败和成功。通过设置其状态来跟踪故障。在后台队列中以 5/10 分批上传记录。这是 ios 架构。对于类似的android,您可以使用执行程序服务 【参考方案1】:正如其他人所提到的,这是一个相当广泛的问题。很大程度上取决于将接收数据的服务器的架构以及应用程序的架构。
如果您对后端的实施有任何控制权,我建议您实施一个允许暂停和恢复传输的存储解决方案。 Google Cloud Storage 和 Amazon S3 都提供了类似的功能。
这种方法背后的想法是能够从停止的地方继续上传。如果应用程序崩溃或互联网连接出现问题,您不必从头开始重新启动。 在您的情况下,我仍然会为每条记录单独上传并存储它们的上传进度。
您可以在此处找到一个示例,说明如何使用带有 Amazon https://aws.amazon.com/blogs/mobile/pause-and-resume-amazon-s3-transfers-using-the-aws-mobile-sdk-for-android/ 的移动 SDK 使用暂停/恢复方法。
编辑添加对 Amazon iOS SDK 的引用,http://docs.aws.amazon.com/mobile/sdkforios/developerguide/s3transfermanager.html
【讨论】:
iOS 怎么样? AWS 是否提供用于暂停和恢复的移动 sdk? @Adnan 我刚刚编辑了答案,添加了指向 iOS SDK 的链接【参考方案2】:最好的方法是将文件分成 100 个块并在间隔或应用空闲时上传。
【讨论】:
【参考方案3】:我想这里最好的方法是单独发送每条记录(如果它们彼此不相关)。
如果您有媒体附件,如果您通过移动互联网以大约 2 MB/s 的速度上传,则发送每条记录平均需要 2 秒。如果你每次请求都发送大批量的记录,你必须有长期稳定的连接。
您可以将每条记录作为多部分请求发送,其中部分是记录的正文和媒体附件。
您也无需检查互联网连接,或使用接收器来捕捉连接状态的变化。您可以简单地使用这个库来触发同步请求:
-
JobScheduler
Firebase JobDispatcher
Evernote android-job
【讨论】:
【参考方案4】:您可以使用分而治之的方法将任务分成小任务并将数据上传到服务器。 1.取一个以false开头的布尔标志“isFinishData”。 2.开始上传服务器上0到100条记录的数据。 3. 下一条记录从 100 发送到 200。 4.这个过程一直运行到最后一条记录(1000)没有发送。 5.在最后一条记录更新中设置布尔变量true并退出循环。
这个逻辑在 IOS/android 中都可以正常工作。
【讨论】:
【参考方案5】:要采用简单的方法,请在您的数据对象 [NSManagedObject] 类中设置 1 个标志作为 sync。在创建新对象/修改现有对象时将 sync 标志更改为 false > .
过滤同步值为 false 的数据对象。
let unsyncedFilter = NSPredicate(format: "sync = %@", @(false))
现在您将拥有一组要与服务器同步的对象。如果您在请求中逐个发送对象。 成功后将 sync 标志更改为 true 否则,每当您的函数在应用启动/可达性状态更新时再次执行时,它将再次过滤掉未同步的数据并开始同步。
【讨论】:
【参考方案6】:这是一个非常广泛的问题,它涉及架构、UI 体验、限制等。
这似乎是一种同步模式,用户可以在本地和离线与数据进行交互,但在某些时候,您需要将本地数据与服务器端同步,反之亦然。
我认为最好的起点是后台服务(Android,不确定 iOS 上是否有类似的方法)。本质上,无论 Android 应用程序是否运行,服务都必须在后台处理所有同步、中断和故障。
如果它是一个本地数据库,那么您需要适当地管理打开和关闭数据库,我建议使用一个字段来标记任何同步记录,这样如果某些记录确实失败了,您可以在另一个地方重试它们观点。 此外,您可以将记录转换为 json 数组,然后进行发布请求。 至于上传图片,肯定需要批量上传,如果有很多,还要确保跟踪哪些是上传的,哪些不是。
如果您支持来自不同设备和平台的同步,您将遇到的一个问题是与后端同步的数据存在冲突。您需要处理这种情况,否则它可能会非常混乱,并且很可能会导致很多奇怪的问题。
希望这有助于高水平:)
【讨论】:
【参考方案7】: 第一个我想知道你是如何在本地数据库中保存图像的? 您需要创建一个服务来捕获连接状态。每次建立连接时,您都以 Multipart 类型提交您的记录。你可以改造/异步任务。 只需为每个 Retrofit/Asynctask 提交 1 条记录,就可以轻松处理每条记录的成功/失败。 您可以运行一个或多个改造/异步任务来提交一个或多个记录,这取决于您。 如果您的数据有图像,在服务器端,您必须处理从您的服务器到第三台服务器(保存图像的服务器)的过程。【讨论】:
我在本地数据库中保存了图像的路径。该图像是一种传输方式,即从移动设备到服务器。如果我逐个发送记录 1 并且记录无法同步该怎么办? 如果您同步单个图像,则在每次同步完成后,同步下一个图像。它确保每个同步过程都失败,前一个图像被同步。并且每次同步失败时,只需保存一个标志(记录的 id )。并且每次重新建立连接时,从保存的 id 开始同步。【参考方案8】:将您的记录保存在本地 Db 中并为其使用 ORM。使用为 Web 服务调用提供 onSuccess 和 onFailure 方法的 Retrofit。要定期向服务器发送数据,您可以使用同步适配器。
【讨论】:
我了解,但它对大型数据集有效吗?【参考方案9】:我建议使用 Firebase 数据库 API。 它有很好的离线/在线/同步实现。
https://firebase.google.com/docs/database/
并且可以使用 Admin SDK 为您的 NodeJS 服务器读取/写入数据:
https://firebase.google.com/docs/admin/setup
【讨论】:
我在服务器上有一个 mysql 数据库 我说你可以使用 NodeJS 来同步 Firebase 和你的 MySQL。阅读第二个网址。 成本也是一个需要考虑的问题。我正在寻找自定义方法或任何开源工具 参考这个crisp.im/blog/… 我很感激。谢谢以上是关于将 1000 多条记录上传到还包含来自 iOS/Android 应用程序的每条记录的图像的服务器的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
如何将现有表中的 7000 条记录中的前 1000 条记录复制到其他新表中