架构设计-如何选择数据传输方式?

架构设计-如何选择数据传输方式?

上篇文章介绍了协议设计的通用准则。协议设计好之后,保存在服务器里面的视频数据,如何平稳得传输到APP也是值得讨论的问题

后台开发中,传输的数据类型基本包括信令数据、二进制数据。

  • 信令数据都是一些结构体数据的封装,一般都在KB以下。
  • 二进制数据根据业务场景的不同,有超过1GB,有KB级别的、也有大小未知的。

对于上述的信令和二进制数据,如果直接调用send一次性发送,会有哪些问题?

  • 如果采用UDP协议时,数据包大小超过MTU,会被截断,产生丢包。
  • 发包速率不平稳,窗口频繁变化,易产生网络拥塞。
  • 连接收发包速度过大,影响本服务其他连接传输速度。
  • 发送/接收的数据超过机器内存大小时,会出现OOM,进程被系统kill。
  • 发送端发送速度过快,接收端处理速度过慢,接收端需要缓存收到的数据,产生OMM的概率会增大。

 基于上述原因,在实际开发中基本的原则是,小块数据会采用一次性传输,大块数据会采用分块传输。具体到RPC框架中,就是Unary(一问一答)、Stream流式传输。

Unary传输

发送端发起单个Request,接收端收到后进行处理,处理完成后直接回复单个Response。

  • 信令结构可放在协议的Body部分,二进制数据可放在协议的attachment,协议结构简单、处理性能强。
  • 适用于信令协议、小数据对象、单次传输可处理完成的业务场景。例如,心跳、图片上传、聊天消息。
  • 不适用大对象、数据大小未知、实时流传输。例如,文件上传、VoIP通话、视频下载。

Stream流式传输

发送端与接收端根据业务场景建立单向/双向流,双方均可以持续发送/接收消息,请求/响应像流一样在持续不停的流动。

  • 在数据传输之前,会先建立流式传输通道,对流的各个状态进行管理。
  • 发送端和接收端根据流类型,可多次向流中写入Request/Response,二进制数据需要写入Attachment,流内部会对数据准确性进行校验。
  • 适用于批量作业、实时流传输、大数据传输场景。例如,早上9点要定时执行数据推送任务,VoIP通话、屏幕共享。
  • 不适用小对象、单次信令协议传输。

从适用场景上看,Stream流式几乎适合所有场景,可在实际开发中使用的比较少,主要原因如下。

  • Stream流式有多种流状态,要实现流状态管理,支持双端流式传输,有一定的性能开销。
  • 框架流式功能不健全,不支持Attachment,无法直接传输不序列化的二进制数据,性能开销大。
  • 框架缺少流式功能,例如 thrift,应用层自己实现流式功能。

在实际使用中,无论是Unary还是Stream流式,还要考虑发送的数据,接收端是否能够及时处理完

上述场景中,App与Proxy之间是公网传输,Proxy与VideoSvr之间是内网传输。内网的传输速度要远大于公网。

这个时候就要控制流式传输的速度,如果速度过快,就有可能导致Proxy 内存消耗过大,被操作系统OOM掉。

回到最初的问题,现在可以回答APP与Proxy、Proxy与VideoSvr之间通过Stream流式传输视频数据,APP与Proxy之间通过Unary传输HeartBeat。

架构设计中,要根据业务场景特点选择数据传输方式,小数据和信令可采用Unary、大数据或者数据大小未知的情况,采用Stream流式。在使用的过程中,还要考虑流量控制,Stream流式成本开销。


发表评论

邮箱地址不会被公开。 必填项已用*标注