当前位置: 首页 > news >正文

新一代通信协议 - Socket.D

一、简介

Socket.D 是一种二进制字节流传输协议,位于 OSI 模型中的5~6层,底层可以依赖 TCP、UDP、KCP、WebSocket 等传输层协议。由 Noear 开发。支持异步流处理。其开发背后的动机是用开销更少的协议取代超文本传输协议(HTTP),HTTP 协议对于许多任务(如微服务通信)来说效率低下。

二、设计目标

  • 协议接口丰富,包括 Send, SendAsRequest, SendAndSubscribe,Reply,ReplyEnd
  • 支持应用层流量控制
  • 支持单连接双向、多次复用
  • 支持断连后自动重连
  • 可以更好的使用 WebSocket 协议

三、消息驱动

网络通信是异步的,Socket.D 协议包含这一点,并将所有通信建模为在单个网络连接(TCP)上的、多路复用的消息流,在等待响应时从不同步阻塞。

响应式宣言指出:

反应式系统依赖异步的消息传递,从而确保了松耦合、隔离、位置透明的组件之间有着明确边界。 这一边界还提供了将失败作为消息委托出去的手段。 使用显式的消息传递,可以通过在系统中塑造并监视消息流队列, 并在必要时应用回压, 从而实现负载管理、 弹性以及流量控制。 使用位置透明的消息传递作为通信的手段, 使得跨集群或者在单个主机中使用相同的结构成分和语义来管理失败成为了可能。 非阻塞的通信使得接收者可以只在活动时才消耗资源, 从而减少系统开销。

此外,HTTP/2 FAQ 很好地解释了在持久连接上采用多路复用的面向消息的协议的动机:

  • HTTP/1.x 有一个叫做 “head-of-line blocking(队头阻塞)” 的问题,在这种情况下,即在一个连接上一次只能有一个未完成请求。

  • HTTP/1.1 试图通过流水线(Pipelining)来解决这个问题,但它并没有完全解决这个问题(大的或慢的响应仍然会阻塞后面的其他响应)。此外,人们发现流水线很难部署,因为许多代理和服务器不能正确地处理它。
    在HTTP/1中使用并发连接和域名分片来缓解HOL问题

  • 并发连接,浏览器针对每个源(域名)可以打开4-8个TCP连接,提升并发度。

  • 域名分片,浏览器和HTTP/1限制了并发连接的数量,那么就把多个域名指向一台服务器,从而提升连接数量。
    这迫使客户端使用一些启发式方法(通常是猜测)来确定什么请求在什么时候放在与源站的哪个连接上;由于加载一个页面的次数通常是可用连接数量的10倍或者更多。这会导致被阻塞的请求“瀑布式”的增长,从而严重的影响性能。

多路复用通过允许多个请求和响应消息在一个连接上同时传输来解决这些问题;甚至可以将一条消息的部分与另一条消息的部分混合在一起。

使用HTTP/1,浏览器为每个源打开4-8个连接,由于许多站点使用多个源,这可能意味着打开单个页面要加载30多个TCP连接。

一个应用程序同时打开如此多的连接,打破了TCP所建立的许多假设;由于每个连接都会在响应中传输大量的数据,因此TCP缓冲区很大可能会溢出,从而导致拥塞事件和超时重传。

一个应用程序同时打开如此多的连接,此外,使用如此多的连接不公平地垄断了网络资源,“窃取”了其他性能更好的应用程序(如VoIP)的资源。

四、协议交互模型

不合适的协议会增加系统开发的成本。它可能是一个不匹配的抽象,但是我们必须将系统设计强加到他允许的交互模型中。这迫使开发人员花费额外的时间来解决它的缺点,以处理错误并获得可接受的性能。在多语言环境中,这个问题被放大了,因为不同的语言将使用不同的方法来解决这个问题,这需要团队之间的额外协调。到目前为止,通信协议事实上的标准是HTTP,它只支持请求/响应的交互模式。在某些情况下,这可能不是最理想通信模型。

  • Send(只管发送,不要结果)

发完就不管是请求/响应的优化,在不需要响应时很有用。它允许显着的性能优化,不仅仅是通过跳过响应来节省网络使用,而且还可以减少客户端和服务器的处理时间,因为客户端不需要记录和等待请求关联的响应和取消请求。

此交互模型对于支持有损的用例非常有用,例如非关键事件日志记录、或者设备信息上报。

像这样使用:

clientSession.send("/demo", entity);
  • SendAsRquest(发送一个请求,并要求一个响应)

仍然支持标准请求/响应语义,并且仍有望代表 Socket.D 连接上的大多数请求。这些请求/响应交互可以被认为是优化的“只有 1 个响应的流”,并且是在单个连接上多路复用的异步消息。

消费者“等待”响应消息,所以它看起来像一个典型的请求/响应,但它从不同步阻塞。

就像 http 一样使用:

//同步等待
let response = clientSession.sendAndRequest("/demo", entity).await();//异步回调
clientSession.sendAndRequest("/demo", entity).thenReply(response => {});
  • SendAndSubscribe(发送一个订阅,可以接收多个答复)

从一个请求一个响应那儿延伸出来的是多个响应,它允许多条消息流回。将此视为“集合”或“列表”响应,但不是将所有数据作为单个响应返回,而是按顺序流回每个元素。

用例可能包括以下内容:获取视频列表,在目录中获取产品,逐行检索文件。

可能有点像 mq,还可能通过 range 指定数据区间(或者不指定):

//异步回调
clientSession.sendAndSubscribe("/demo", entity.range(0,5)).thenReply(reply => {if(reply.isEnd()){//如果需要识别最后一个?}else{//}
});

五、协议形式

  • 连接上传输的数据可称之为流,每个消息都会有一个 sid(流Id)
  • 流(Stream)由帧(Frame)组成
  • 帧(Frame)包含了流Id(Sid)、事件(Event)、元数据字符串(MetaString)及数据(Data)

帧码结构为:

[len:int][flag:int][sid:str(<64)][\n][event:str(<512)][\n][metaString:str(<4k)][\n][data:byte(<16m)]

Socket.D 是一个二进制协议,也就是说在一个 Socket.D 连接上传输的消息体对数据格式没有任何要求,应用程序可以为所欲为的压缩数据量的大小。

这样的二进制协议通常来说能给性能带来极大的提升,但是产生的代价是,网络中间件也会因为无法解读消息体中的数据,丧失了在对具体应用流量进行监控,日志和路由的能力。Socket.D 通过把每个消息体分成 metaString 和 data 的方式,在保证高效传输的前提下,提供了暴露少量元数据给网络中间件的能力。

  • data 一般作为应用本身需要传递的业务数据,采取自定义的高效序列化方式,且对网络基础设施不可见。
  • metaString 采用标准的 urlQueryString 格式。在分布式传输的过程中,这些中间件可以按需求对 metaString 进行读写,然后监控应用健康状况或者调整路由。

Socket.D 有哪些适用的场景?

  • 移动设备与服务器的连接
  • 数据双向传输,且支持流量控制。
  • 支持连接修复,比如手机进地铁之后,网络断开一段时间,其他协议需要重新建立连接,Socket.D 会自动修复连接。
  • 微服务场景

相关文章:

  • javascript编程求三个数中最大的数
  • Pandas实战100例 | 案例 43: 数据排序
  • EtherCAT主站SOEM -- 16 --Qt-Soem通过界面按键控制电机转圈圈PV模式
  • 在开发时如何决定使⽤哪种数据类型?
  • 基于网络爬虫的租房数据分析系统
  • 简单谈一谈pytorch中混合精度训练(torch.cuda.amp)的功效及命令行参数解析器的使用
  • Spring整理-Spring Bean的作用域
  • 【Mybatis系列】Mybatis空值关联
  • Pandas实战100例 | 案例 40: 分组并应用多个聚合函数
  • Windows下Redis5+可视化软件下载、安装和配置教程-2024年1月8日
  • 统计学-R语言-4.2
  • pandas的iloc函数
  • inflate流程分析
  • Oracle篇—实例中和name相关参数的区别和作用
  • Shell脚本入门实战:探索自动化任务与实用场景
  • 【面试系列】之二:关于js原型
  • Angular6错误 Service: No provider for Renderer2
  • Create React App 使用
  • Java多态
  • LintCode 31. partitionArray 数组划分
  • PHP变量
  • ReactNativeweexDeviceOne对比
  • SpringBoot几种定时任务的实现方式
  • Swoft 源码剖析 - 代码自动更新机制
  • 解决iview多表头动态更改列元素发生的错误
  • 一个JAVA程序员成长之路分享
  • 正则表达式
  • Java数据解析之JSON
  • # Maven错误Error executing Maven
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • %@ page import=%的用法
  • (zt)最盛行的警世狂言(爆笑)
  • (八十八)VFL语言初步 - 实现布局
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)ssm码农论坛 毕业设计 231126
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (小白学Java)Java简介和基本配置
  • (一)kafka实战——kafka源码编译启动
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • (轉貼) UML中文FAQ (OO) (UML)
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • .cfg\.dat\.mak(持续补充)
  • .NET CLR Hosting 简介
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .Net的C#语言取月份数值对应的MonthName值
  • .Net中的设计模式——Factory Method模式
  • @Tag和@Operation标签失效问题。SpringDoc 2.2.0(OpenApi 3)和Spring Boot 3.1.1集成
  • [【JSON2WEB】 13 基于REST2SQL 和 Amis 的 SQL 查询分析器
  • [AUTOSAR][诊断管理][ECU][$37] 请求退出传输。终止数据传输的(上传/下载)
  • [C#]winform制作仪表盘好用的表盘控件和使用方法
  • [C/C++]数据结构 循环队列