在Rails中使用POST的持久/保持活动HTTP连接



有没有一种方法可以维护/使用rails中POST命令的持久连接?

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

我对rails范式的理解是,每个请求(POST、GET、PUT等)都有一个TCP连接。有没有一种方法可以利用一个TCP连接来获得多个POST?

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

  • 轨道3.2
  • Ruby 1.9.3(如果需要,可以切换到2.0)

编辑

为了帮助澄清我的目标是什么:

我有一个外部系统,每秒收集1000个数据点(3个浮点数字、一个时间戳和2个整数)。我想把这些数据推送到我的RubyonRails服务器上。我希望通过一个正确配置的系统,我可以实时使用HTTP堆栈(当收集到数据点时,我会将其推送到rails服务器)。我还可以降低传输速率,并将数据点分组发送。我已经研究过使用消息队列,但我想在使用专门的队列API之前,看看是否可以编写一个更"标准"的HTTP API。

I认为您正在寻找Net::HTTP::Persistent库。这个库还通过在持久连接上实现连接池更进一步。但由于这听起来像你只得到了一个API点,这可能是杀鸡用牛刀。

一些额外的想法:如果你真的关注原始速度,那么发送一个单独的多部分POST请求以进一步减少开销可能是值得的。这将归结为实现反向服务器推送。

为了实现这一点,rails应用程序需要接受一个块编码的请求。这一点很重要,因为我们不断地将数据流式传输到服务器,而不知道最终得到的消息正文会有多长。HTTP/1.1要求所有消息(即响应请求)都进行块编码,或者由Content-Length标头指定其正文大小(参见RFC 2616,第4.4节)。然而,大多数客户端更喜欢后一种选择,这会导致一些Web服务器不能很好地处理块编码的请求(例如nginx在v1.3.9之前还没有实现这一点)

作为一种序列化格式,我可以放心地推荐JSON,它生成速度非常快,并且被广泛接受。RoR的实现可以在这里找到。您可能还想看看这个实现,因为它本身就与流一起工作,因此可能更适合。如果您发现JSON不适合您的需求,请尝试MessagePack。

如果网络饱和,那么研究请求压缩的可能性是值得的。

所有的东西放在一起,你的请求可能看起来是这样的(为了易读性,压缩和块编码被剥离):

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在这里使用是安全的。选择CCD_ 5而不是CCD_ 6作为压缩方法,因为它不需要生成CRC32校验和。这样可以提高速度(并节省几个字节)。

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

请参阅Heroku的示例应用程序:https://devcenter.heroku.com/articles/ruby-websockets

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

除此之外,您可以传输二进制数据而不是文本,从而进一步加快传输速度,然后让工作人员接收并保存数据。

只有我的2个

最新更新