RESTful Web服务与数据密集型应用程序的套接字编程

我正在使用Ruby on Rails构建一个Web应用程序,它需要具有高度可伸缩性。 在此应用程序中,数据由移动客户端(大约20个字节)每秒产生。 所有这些数据必须在某个时刻传输到服务器,最好是尽快。

要完成此任务,我希望服务器充当RESTful服务。 客户端可以缓冲位置(例如每5到30秒),然后将其作为HTTP put请求进行拍摄,然后服务器可以存储它们。 我相信这个模型更容易实现,并且更好地处理大量流量,因为客户端可以保持缓冲数据,直到他们听到服务器的响应。

另一方面,我的老板想要使用套接字编程来实现服务器。 他认为套接字编程将导致更少的数据传输,这将提高系统的总效率。 我不能不同意这一点,但我认为考虑到现代带宽,HTTP的额外开销是值得的。 另外,我认为尝试维护数千(或数百万)的用户同时连接会导致自身问题,并大大增加服务器的复杂性。

老实说,我不知道解决这个问题的正确方法,所以我想我会把它发布在这里并得到比我更聪明的人的意见。 如果有任何答案包括所提出的解决方案的优缺点,我将不胜感激。

谢谢。

更新

我们现在已经刷新了一些额外的要求。 首先,移动客户端每月无法上传超过5 GB的数据。 在这种情况下,我们每个月每天八小时通话一条消息。 其次,我们希望尽可能少地组合消息。 这是为了确保移动客户端发生某些事情(比如车祸),我们会尽可能少地丢失数据。

你的老板似乎过早地进行了优化,这不是一个好主意。

在你开始编写代码之前,你应该检查你的应用程序的要求并设计它们,而不是试图与想象中的性能博主打架。 不要让感知到的问题驱动你的设计。

如果涉及到它,让你的老板准确地概述他如何在他的套接字连接中编组数据,然后做一些快速计算,看看你是否可以匹配或击败他们的HTTP。 他会使用谷歌的协议缓冲区,还是编写自己的编组协议? 如果是这样,它会自我描述吗? 应用程序“动词”如何在HTTP中免费获得? 他的关系会坚持下去吗? “套接字”还有很多东西,而不仅仅是打开连接并向其喷出字节。

您还正确地指出,您的老板似乎更喜欢套接字的原始速度而不是其他所有内容:可伸缩性,可维护性,开发和测试工具的可用性,协议嗅探器,HTTPS动词的有用语义等等。 负载均衡器和防火墙等可以很好地理解HTTP。 您的专有套接字协议将不会那么幸运。

我建议您查看所有选项,并通过测试,原型设计和基准测试从性能角度评估它们。 然后权衡这些数字与使用该技术构建和维护应用程序的难度。

坚持使用HTTP。

创建一个HTTP服务器园并将它们置于负载均衡器之后要比为自己的协议尝试做同样的事情要容易得多。 为什么? HTTP已经存在的一切。

更新

你需要重新实现自己:

  • 缓冲区管理(如果负载很高,则很重要)
  • 确保您收到了整条消息(简单的Receive / BeginReceive是不够的)
  • 异步套接字处理
  • 认证
  • 负载均衡器(这部分很棘手,你需要仔细设计)
  • 您自己的协议(您需要一种方法来识别您收到整条消息的时间)

如果您使用ASP.NET MVC + JSON(merb或rails的步骤类似):

  1. 创建一个新网站
  2. 在IIS中激活摘要式身份validation
  3. 创建一个新控制器,使用[Authorize]属性对其进行标记
  4. 添加动作

什么是最便宜的? 服务器还是你花了一个月的时间做过一些已经完成的事情?

HTTP的设计基于绝大多数请求都是GET的假设进行扩展。 听起来你的大多数交互都是客户端向服务器发送数据。 我认为很有可能存在比REST更好的架构风格来实现你想要做的事情。

问题是,您是否有时间从头开始,或者HTTP是否足以满足您的需求。 如果不了解有关您的应用的更多详细信息,我认为很难给出好的建议。

你的老板和你都是对的,正确的选择取决于业务要求:你需要多久才能扩展。

如果你是一个开始推出新服务的人并且你担心你将无法管理你将在3个月内拥有的数百万新用户,那么@Brian-Kelly是对的 – 这是不成熟的优化。 OTOH,如果你是Twitter并且你正在建立一个新的基于位置的服务,那么扩展是你应该处理的主要问题。 如果你介于两者之间,那么,这是你的事 – 做出选择。

使用Rails构建RESTful Web服务既快速又简单,并且从移动客户端调用它也很简单(尽管在移动客户端上缓冲需要更多代码)。 在您的情况下,这是这种方法的主要(也是唯一的imho)优势 – 这是一个巨大的优势。

但是,HTTP确实增加了很多开销。 如果您的消息长度为20个字节,那么实际上每个消息的有效负载数是其开销的几倍 。 这意味着更多的网络带宽和更多的CPU时间。 是的,您可以添加更多服务器来处理它,但它会花费您 – 需要多台服务器才能完成一项服务。

如果您的服务只是从移动客户端收到非常短的消息,并且如果它可以丢失偶尔的消息,那么我会考虑使用UDP。 您的20个字节应该适合单个数据包。 与TCP的几次往返首先建立连接,然后发送数据相比,这节省了很多。

在考虑优化是否为时尚早的时候要记住的另一件事是移动客户端:对服务器进行更改很简单,但是将使用更优化的消息传递协议的新版本推送到数百万台设备中。领域’并非无足轻重。

在更新问题后更新:

每月5 GB就足够了。 一个月一秒的消息意味着86,400 * 30 = ~2.6M消息。 这允许您为每条消息花费近2K。 如果你的有效载荷大约是20个字节,那不是问题……

至于你不喜欢组合消息以免丢失任何信息,你将不得不问自己有多少消息可以丢失。 也许一分钟太多了,但10秒不是问题? 以60英里每小时的速度移动的客户只需在10秒内移动0.16英里。

在任何情况下,如果这是一个应该拯救生命的实时系统,请考虑在现实条件下进行一些测试(路上的移动客户端)。 这是确定移动网络行为方式的唯一方法 – 您可以预期的延迟,数据包丢失的频率,到达顺序等等。