我们有一个Rails应用程序,我们在Unicorn(2个工作者)和nginx上运行。我们希望集成第三方API,其中单个请求的处理需要1到20秒。如果我们只是创建一个代理该服务的新控制器,整个应用程序都会受到影响,因为只需2个人就可以通过我们的API向该服务发出请求,并且20秒内其他用户无法访问其他用户应用
我们正在考虑两种解决方案。
哪种解决方案可能会更好?或者我们还能做些什么。
我个人觉得节点偶数循环更适合这里的工作,因为在选项2中我们仍然会阻塞许多线程并等待HTTP请求完成,而在选项1中,我们可能会在等待时做更多请求为了缓慢完成。
谢谢!
答案 0 :(得分:1)
我们已经在生产中使用X-Accel-Redirect
解决方案已经有一段时间了,而且效果很好。
在服务器下的nginx配置中,我们有外部服务的条目(在我们的例子中用node.js编写),例如。
server {
...
location ^~ /some-service {
internal;
rewrite ^/some-service/(.*)$ /$1 break;
proxy_pass http://location-of-some-service:5000;
}
}
在rails中我们对请求进行身份验证和授权,当我们想将其传递给其他服务时,在控制器中我们会执行类似
的操作headers['X-Accel-Redirect'] = '/some-service'
render :nothing => true
现在,rails已完成处理请求并将其交还给nginx。 Nginx会看到x-accel-redirect
标头,并将请求重播到新网址 - /some-service
,我们将其配置为代理我们的node.js服务。即使node.js + nginx仍在处理原始请求,Unicorn和rails现在也可以处理新请求。
这样我们就可以使用Rails作为我们应用程序的主要入口点和守门员 - 这就是身份验证和授权发生的地方。但是,当更合适时,我们能够将大量功能转移到这些较小的独立node.js服务中。
答案 1 :(得分:0)
您可以在现有的Rails应用中使用EventMachine
,这意味着更少的重写。您可以向API发出net/http
请求并添加回调,而不是向API发出EM::HttpRequest
请求。这类似于node.js选项,但不需要特殊的服务器IMO。