我目前有一个用于我的项目的API和一个负责将导出文件生成为CSV的服务,存档并将它们存储在云中的某个位置。
由于我的API是用Rails编写的,而我的服务是用纯Ruby编写的,我在服务中使用Her gem来与API进行交互。但是我发现我当前的实现性能较差,因为我在我的服务中执行了Model.all
,这反过来触发了一个请求,该请求可能包含响应中的太多对象。
我很好奇如何改进这项任务。这就是我所想到的:
Model.where(page: xxx)
; 如果我使用第一种方法,每页应该检索多少个对象?答案应该有多大?
如果我使用第二种方法,这会给请求带来相当大的开销(我猜API请求不应该花费那么长时间),我也想知道它是否真的是API&# 39;这样做的工作。
我应该遵循什么方法?或者,有什么更好的东西我失踪了吗?
答案 0 :(得分:3)
你需要通过ruby过程传递大量信息,这总是不简单,我不认为你在这里遗漏任何东西。
如果您决定在API级别生成CSV,那么维护服务会得到什么?您可以放弃服务,因为用nginx代理替换您的服务会更好地做同样的事情(如果您只是从API主机传输响应)?
如果您决定分页,肯定会有性能降低,但是没有人可以确切地告诉您应该分页多少 - 更大的页面会更快并消耗更多内存(通过减少工作量来减少吞吐量) ,较小的页面将更慢并且消耗更少的内存,但由于IO等待时间需要更多的工作人员,
确切的数字将取决于您的API应用以及云和您的基础架构的IO响应时间,我担心没有人可以为您提供一个简单的答案,您可以在不进行压力测试的情况下进行操作,并且一旦设置完毕压力测试,无论如何你会得到一些你自己的 - 比任何人估计的要好。
一个建议,写一些关于你的问题,你正在工作的约束等等,也许有人可以帮助你一些更激进的解决方案。出于某种原因,我觉得你真正想要的是像sidekiq或延迟工作这样的后台处理器,或者如果你想要解耦你的应用程序或nginx,可以直接通过数据库视图将你的服务连接到数据库API响应的代理,或者根本没有...但是如果没有更多信息,我真的无法分辨。
答案 1 :(得分:3)
我认为这取决于你想要如何定义'表现'以及您的API目标是什么。您是否希望确保对API的请求响应时间不超过20毫秒,而添加分页将是一种合理的方法。特别是如果CSV生成只是一个边缘情况,并且API实际上是为其他服务构建的。然后,每页的项目数量将受到您提供这些项目的速度的限制。您的服务性能不会特别高(甚至更低),因为它需要多次调用服务。
如果您认为它是转储整个记录集的服务的有效用例,那么创建异步调用(可能使用webhook作为回调)将值得添加到您的API中。
话虽如此,我认为严格来说,API的工作是快速响应。所以也许试着弄清楚缓存如何能够改善响应时间,因此遍历所有记录是合理的。另一方面,服务的工作是要注意对API的调用量,因此可能在本地存储旧记录并且仅轮询更新而不是每次都转储整组记录。