问题 在Rails上阻止IO / Ruby


我正在考虑用Rails编写Web应用程序。用户做出的每个请求都取决于被调用的外部API。这个外部API可以随机非常慢(2-3秒),因此显然会影响单个请求。

在代码等待外部API返回的这段时间内,是否会阻止进一步的用户请求?

只是为了进一步澄清,因为似乎有些混乱,这是我期待的模型:

  1. Alice向我的网络应用程序发出请求。为此,需要调用API服务器A. API服务器A很慢,需要3秒才能完成。
  2. 在Rails应用程序调用API服务器A的等待时间内,Bob发出一个请求,该请求必须向API服务器B发出请求。

Ruby(1.9.3)解释器(或Rails 3.x框架中的某些东西)是否会阻止Bob的请求,要求他等到Alice的请求完成后?


7756
2018-01-20 21:04


起源

我实际上有类似的问题..但我只是想知道,你是通过activerecord从你的rails应用程序进行数据库查询,还是数据纯粹是从后端API服务器驱动的,这使得数据库查询并将结果返回到你的rails前端 - 结束? - Benny Tjia
@BennyTjia两个。单个请求将使用本地存储的数据和API服务器返回的唯一数据。 - Matty


答案:


如果您只使用一个单线程,非事件服务器(或者不使用带有事件服务器的事件I / O),是的。使用其他解决方案  和 EM-同步性 会避免这种情况。

根据您的更新进行阐述:

不,Ruby和Rails都不会导致您的应用程序被阻止。但是你遗漏了那部分:Web服务器。您需要多个进程,多个线程或一个事件服务器,以及使用事件I / O库执行Web服务请求。

@alexd描述了使用多个进程。我个人支持一个事务服务器,因为我不需要提前知道/猜测我可能有多少并发请求(或者根据负载使用一些旋转进程的东西。)单个 nginx 处理单一的过程 thin 进程可以服务大量的并行请求。


7
2018-01-20 21:13



他仍然会遇到网络延迟。 - Srdjan Pejic
网络 潜伏?如果你的意思是当前的用户将被迫等待,当然他们会(但我从他写这个问题的方式来看,这是不可避免的)。我读的问题不是关于避免用户点击外部服务的延迟,而是关于阻止其他并发请求。 - smparkes
@smparkes我已经对这个问题进一步澄清了 - Matty
更新了我的回答...... - smparkes


您的问题的答案取决于运行Rails应用程序的服务器。你现在在用什么?瘦?独角兽?阿帕奇+乘客?

我全心全意地推荐Unicorn,因为它可以很容易地并行运行多个服务器进程,只需更改配置文件中的数字即可配置并行进程数。当一名Unicorn工作人员处理Alice的高延迟请求时,另一名Unicorn工作人员可以使用您的空闲CPU周期来处理Bob的请求。


3
2018-01-20 21:52





最有可能的是,是的。显然,有很多方法,但没有一个是容易的。

更好的问题是,为什么你需要在每个请求上点击外部API?为什么不在Rails应用程序和外部API之间实现缓存层,并将其用于大多数请求?

这样,通过一些用于使缓存过期的自定义逻辑,您将拥有一个快速的Rails应用程序,并且仍然能够利用外部API服务。


0
2018-01-20 21:12



返回的数据随每个请求而变化。因此不可能进行缓存。 - Matty
那么,你所说的是你的API是你的数据库?从长远来看,这听起来不太可行...... - Srdjan Pejic
API不充当数据库。 - Matty