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

问题描述:

有没有办法在rails中为POST命令维护/使用持久连接?使用POST的持久/保持HTTP连接在Rails中

我想创建一个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。

+0

知道你通过'POST'发送什么是很有意思的。如果可以将它安装到多部分MIME消息中,则可以传输请求,进一步减少开销。 – DaSourcerer

+0

@DaSourcerer我更新了我的问题,希望能够让你了解我正在努力完成的任务。我从来没有听说过“流式传输”一个请求。我可以通过谷歌了解这一点? –

+0

谢谢。我必须说,这是一个非常有趣的问题。我有一些想法可以帮助你。随着时间的推移,我会更新我的答案。 – DaSourcerer

认为Net::HTTP::Persistent图书馆是你在找什么。还有this图书馆通过持续连接实现连接池还有一步。但是,因为听起来你只有一个API点,这可能是矫枉过正的。

一些额外的想法:如果你真的看到原始速度,可能需要发送一个多部分POST请求来进一步减少开销。这将归结为执行reverse server push

为此,您的rails应用程序需要接受chunk-encoded请求。这一点非常重要,因为我们不断地将数据流式传输到服务器,而不知道最终的消息体最终会持续多久。 HTTP/1.1要求所有消息(即响应请求)要么是块编码的,要么是由Content-Length标头(参见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校验和。这可以提高速度(并节省几个字节)。

+0

感谢您的详细回复。我不熟悉HTTP协议栈。它是请求持久(分块)连接的客户端,还是我需要在服务器上进行一些配置? –

+0

这是客户端请求它,它是需要支持它的服务器。很抱歉,我在农村地区并没有稳定的联系。 – DaSourcerer

+0

你知道配置是否只是在网络服务器(我使用nginx)还是有一些设置,我需要在Rails中检查?感谢所有帮助,顺便说一句。它非常有用。 –

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

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

而在一般看到Twitter的流API的一个灵感:https://dev.twitter.com/docs/streaming-apis

最重要的是,你可以传递的,而不是文本的二进制数据,加快转移进一步,然后有工作人员摄取和保存数据。

只是我的2分

+0

我想我正在寻找像Twitter的流媒体API,但不是通过HTTP处理? –

+0

实际上是的,但持续连接必须由谁启动它进行配置。因此,如果您希望其他人打开连接以将数据注入服务器,则必须建立持久连接。使用套接字,您只需要担心处理数据。 – aledalgrande

+0

我想我接近了解你在暗示什么。纠正我,如果我错了:我会创建一个人们将连接到WebSocket启用服务。然后他们会将信息推送到这个WebSocket服务,并且这个WebSocket服务会将信息推送到我的后端? –