使用POST In Rails进行持久/保持活动的HTTP连接

时间:2013-12-16 21:05:15

标签: ruby-on-rails http post stream keep-alive

有没有办法在rails中维护/使用POST命令的持久连接?<​​/ p>

我想创建一个API,其中我的应用程序接受来自外部服务的数据流(我正在编写此外部服务,因此我可以在此处灵活设计)。速度至关重要。我需要以每秒1000点以上的速度从外部源获取信息。与一些计算机科学家交谈时,人们提出了使用持久连接的想法,这样昂贵的TCP握手只需要执行一次。使用外部服务中的库,然后我会创建多个POST项目,这些项目被推送到我的rails应用程序中,然后逐个处理这些POST项目。

我对rails范例的理解是每个请求(POST,GET,PUT等)都需要一个TCP连接。有没有办法利用一个TCP连接来获取多个POST?

我目前正在使用以下内容:

  • Rails 3.2
  • Ruby 1.9.3(必要时可以切换到2.0)

修改

帮助澄清我的目标:

我有一个外部系统,每秒收集1,000个数据点(3个浮点数,一个时间戳和2个整数)。我想将这些数据推送到我的Ruby on Rails服务器上。我希望配置正确的系统我可以实时使用HTTP堆栈(收集数据点后,我将其推送到我的rails服务器)。我还可以降低传输速率并将数据点组合在一起发送它们。我已经看过使用消息传递队列,但我想看看在转到专门的队列API之前是否可以编写更“标准”的HTTP API。

2 个答案:

答案 0 :(得分:5)

认为 Net::HTTP::Persistent库是您正在寻找的。还有this库通过在持久连接上实现连接池而更进了一步。但是,因为听起来你只有一个API点,这可能有点矫枉过正。

一些额外的想法:如果您真的关注原始速度,可能需要发送单个多部分POST请求以进一步减少开销。这将归结为实施reverse server push

要实现此功能,您的rails应用需要接受chunk-encoded请求。这很重要,因为我们不断地将数据流式传输到服务器,而不知道最终消息体最终会持续多长时间。 HTTP / 1.1要求所有消息(即响应请求)要么进行块编码,要么使用Content-Length标头指定其正文大小(cf RFC 2616, section 4.4)。但是,大多数客户更喜欢后一种选择,导致一些网络服务器没有很好地处理块编码的请求(例如,nginx没有在v1.3.9之前实现这一点)。

作为一种序列化格式,我可以安全地推荐JSON,这对于生成和广泛接受非常快。可以找到RoR的实现here。您可能希望查看this实现,以及它本身使用流,因此可能更适合。如果您发现JSON不符合您的需求,请尝试MessagePack

如果您达到网络饱和度,则可能值得研究request compression的可能性。

所有内容放在一起,您的请求可能看起来像这样(压缩和块编码为了易读性而剥离):

POST /api/endpoint HTTP/1.1
Host: example.com
Content-Type: multipart/mixed; boundary="---boundary-"
Transfer-Encoding: chunked
Content-Encoding: deflate

---boundary-
Content-Type: application/json

{...}
---boundary-
Content-Type: application/json

{...}
---boundary---

mime类型是multipart/mixed因为我觉得它是最合适的。它实际上意味着消息部分具有不同的内容类型。但据我所知,这是强制执行的,所以multipart/mixed在这里使用是安全的。 deflate选择gzip作为压缩方法,因为它不需要生成CRC32校验和。这样可以提高速度(并节省几个字节)。

答案 1 :(得分:0)

我知道你想要一个HTTP解决方案,但老实说如果速度至关重要,我会把HTTP排除在外。 Web套接字似乎更好地适应了这个问题。

查看Heroku的示例应用:https://devcenter.heroku.com/articles/ruby-websockets

一般来说,请看Twitter流API获取灵感:https://dev.twitter.com/docs/streaming-apis

最重要的是,您可以传输二进制数据而不是文本,进一步加快传输速度,然后让工作人员摄取并保存数据。

只是我的2cents