我正在考虑用Rails编写Web应用程序。用户做出的每个请求都取决于被调用的外部API。这个外部API可以随机非常慢(2-3秒),因此显然会影响单个请求。
在代码等待外部API返回的这段时间内,是否会阻止进一步的用户请求?
只是为了进一步澄清,因为似乎有些混乱,这是我期待的模型:
- Alice向我的网络应用程序发出请求。为此,需要调用API服务器A. API服务器A很慢,需要3秒才能完成。
- 在Rails应用程序调用API服务器A的等待时间内,Bob发出一个请求,该请求必须向API服务器B发出请求。
Ruby(1.9.3)解释器(或Rails 3.x框架中的某些东西)是否会阻止Bob的请求,要求他等到Alice的请求完成后?
如果您只使用一个单线程,非事件服务器(或者不使用带有事件服务器的事件I / O),是的。使用其他解决方案 瘦 和 EM-同步性 会避免这种情况。
根据您的更新进行阐述:
不,Ruby和Rails都不会导致您的应用程序被阻止。但是你遗漏了那部分:Web服务器。您需要多个进程,多个线程或一个事件服务器,以及使用事件I / O库执行Web服务请求。
@alexd描述了使用多个进程。我个人支持一个事务服务器,因为我不需要提前知道/猜测我可能有多少并发请求(或者根据负载使用一些旋转进程的东西。)单个 nginx
处理单一的过程 thin
进程可以服务大量的并行请求。
您的问题的答案取决于运行Rails应用程序的服务器。你现在在用什么?瘦?独角兽?阿帕奇+乘客?
我全心全意地推荐Unicorn,因为它可以很容易地并行运行多个服务器进程,只需更改配置文件中的数字即可配置并行进程数。当一名Unicorn工作人员处理Alice的高延迟请求时,另一名Unicorn工作人员可以使用您的空闲CPU周期来处理Bob的请求。
最有可能的是,是的。显然,有很多方法,但没有一个是容易的。
更好的问题是,为什么你需要在每个请求上点击外部API?为什么不在Rails应用程序和外部API之间实现缓存层,并将其用于大多数请求?
这样,通过一些用于使缓存过期的自定义逻辑,您将拥有一个快速的Rails应用程序,并且仍然能够利用外部API服务。