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

Lan*_*opp 10 sockets architecture rest networking ruby-on-rails

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

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

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

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

谢谢.

更新

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

Bri*_*lly 15

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

在开始编写代码之前,您应该检查应用程序的要求并设计它们,而不是试图在假想的性能博客之前与之作斗争.不要让感知到的问题驱动你的设计.

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

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

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

  • 您需要定义丢失"尽可能少的数据"的要求.您是否正在为将要跟踪设备位置的移动设备构建一种飞行数据记录器?如果是这样,即使每隔(比如说)10秒更新仍然会使最后一个已知位置非常接近实际位置.无论如何,即使发送大约1Kb /秒,每月8小时的活动也会导致每月大约900Mb.顺便说一句,你确实意识到不断从移动设备发送数据绝对会扼杀它的电池,对吗?这就是为什么像长寿命同步调用(ala Direct Push)这样的技术在那里被大量使用的原因. (2认同)

jga*_*fin 9

坚持使用HTTP.

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

更新

你需要重新实现自己:

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

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

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

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


Ela*_*lad 5

您的老板和您都是对的,正确的选择取决于业务需求:您需要多长时间进行扩展。

如果您是一家推出新服务的初创公司,并且担心无法在 3 个月内管理即将拥有的数百万新用户,那么 @Brian-Kelly 是对的 - 现在还为时过早优化。OTOH,如果您是 Twitter 并且正在构建新的基于位置的服务,那么规模是您应该处理的主要问题。如果您介于两者之间,那么,这是您的事 - 做出选择。

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

然而,HTTP 确实增加了很多开销。如果您的消息长度为 20 字节,则实际上每条消息的开销是有效负载的几倍。这意味着更多的网络带宽和更多的 CPU 时间。是的,您可以添加更多服务器来处理它,但这会增加您的成本 - 需要多台服务器来完成一台服务器可以完成的工作。

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

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

更新,在问题更新之后:

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

至于您不选择合并消息以免丢失任何信息,您必须问自己可以丢失多少消息。也许一分钟太多了,但是十秒不是问题吗?以 60 英里/小时的速度行驶的客户在 10 秒内只能行驶 0.16 英里。

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