grpc-go源码剖析三十五之滑动窗口基本介绍以及整体流程图介绍?

2023-11-05

已发表的技术专栏
0  grpc-go、protobuf、multus-cni 技术专栏 总入口

1  grpc-go 源码剖析与实战  文章目录

2  Protobuf介绍与实战 图文专栏  文章目录

3  multus-cni   文章目录(k8s多网络实现方案)

4  grpc、oauth2、openssl、双向认证、单向认证等专栏文章目录)

从本小节开始,我们开始分享在gRPC-go框架源码中最核心,也是最难的滑动窗口原理(也可以称为流量控制原理);

我们最基本的目的之一,就是,搞清楚grpc服务器端或者grpc客户端是如何控制发送数据量大小,接收数据量大小的;

知道原理后,是不是可以将这种思想应用到自己的项目中去。

1、滑动窗口基本介绍

滑动窗口基本介绍:

  • 滑动窗口并不是一个函数,或者一个方法,是客户端跟服务器端运行时交互的效果。也可以称为流控等等,类似的词语。
  • 滑动窗口针对的是数据帧传输的场景
  • 滑动窗口的目的是,计算出下次发送数据帧的最大字节数
  • 滑动窗口过程描述:
    • a)客户端的帧发送器在发送数据帧时存在一些发送指标,服务器端在接收数据帧的不同阶段,也存在一些指标;
    • b)服务器在接收数据帧时,会根据自己的接收数据帧、存储数据帧、读取数据帧的速度,向客户端发送窗口更新帧或者设置帧;
    • c)客户端接收到服务器端发送过来的设置帧或者窗口更新帧后,会更新本地的发送指标
    • d)发送指标的更新,会影响到客户端下次发送数据帧的最大字节数
    • e)最大字节数的计算,服务器端会通过发送窗口更新帧或者设置帧来动态的影响客户端计算数据帧大小的参数,从而影响下次发送的最大字节数。
  • 简单描述:服务器端将自己的接收情况,通知客户端,客户端根据服务器端的接收的情况,来决定下次发送数据帧的最大字节数。
  • 服务器端一侧:
    • a)在数据帧存储到缓存前,大概需要经历3种流控;
    • b)在从缓存里读取数据前,需要做一次窗口更新
    • c)每读取完一次数据,会执行一次流控;(从缓存里读取数据时,很有可能会读取多次,才能完整的获取到数据帧里的所有数据)

备注:
这里描述的滑动窗口是,客户端向服务器端发送数据帧的情况,当然,服务器端向客户端发送数据帧时,滑动窗口原理是一样的。

2、滑动窗口整体流程图

2.1、滑动窗口流程图

可以从下面的图中,了解滑动窗口的流程:
(该图在某些细节上并不是非常的准确,不必担心;主要是希望通过该图能够描述清楚滑动窗口的整体处理流程,某些细节可以忽略)
gRPC-go滑动窗口整体处理流程

主要流程说明:

1 )客户端一侧
  • 构建好数据帧dataFrame
  • 通过发送参数指标,计算本次发送的最大字节数maxSize;
  • 数据帧截取器,从数据帧里截取指定的字节数maxSize,交由帧发送器
  • 帧发送器将截取的字节,转换成http2原生的帧,发送给服务器端
2 )服务器端一侧
  • 帧接收器接收到数据帧,交由帧分发器处理
  • 帧分发器根据帧的类型,交由数据处理器handleData处理
  • 数据处理器handleData:
    • a)抽样级别流控:对本地的接收参数进行更新(如b.sampelCount,b.sample,b.bwMax,b.bdp),触发阈值条件后,会向客户端发送窗口更新帧outgoingWindowUpdate,其中设置streamID=0,或者发送设置帧outgoingSettings
    • b)链接级别流控:对本地的接收参数进行更新(如f.unacked,f.limit),触发阈值条件后,会向客户端发送窗口更新帧outgoingWindowUpdate,其中设置streamID=0
    • c)流级别流控:对本地的接收参数进行更新(如f.pendingData,f.pendingUpdate,f.limit,f.delta),触发阈值条件后,会向客户端发送窗口更新帧outgoingWindowUpdate,其中设置streamID=0
    • d)将数据帧存储到go语言原生自带的缓存bytes.Buffer里
    • e)构建recvMsg结构体,将bytes.Buffer存储到recvMsg里;(recvMsg就是对bytes.Buffer封装)
    • f)将recvMsg存储到recvBuffer里:存储逻辑是
      • i.若recvMsg类型的通道里,没有数据的话,就直接将recvMsg存储到该通道里
      • ii.若recvMsg类型的通道里,已经有数据了的话,就将recvMsg添加到类型为recvMsg的切片的尾部。
  • 接收数据并解压recvAndDecompress:
    • a)读取数据前,先对本地的窗口参数进行调整,如f.delta;满足触发阈值条件的话,就向客户端发送窗口更新帧outgoingWindowUpdate,其中streamID非0;
    • b)recvBufer读取器:
      • i.从recvBuffer的通道里获取数据recvMsg
      • ii.数据获取到后,recvBuffer缓存中,将切片的第一个数据,加载到通道里;(因为通道里刚才已经消费了数据,需要重新添加上)
      • iii.从recvMsg里获取到bytes.Buffer对象
      • iv.将bytes.Buffer里的数据读取到字节切片里
    • c)读取完成数据后,更新流级别参数,如f.pendingData,f.pendingUpdate若满足触发阈值条件的话,就向客户端发送窗口更新帧outgoingWindowUpdate,其中streamID非0;
    • d)对切片里的数据进行解压,对解压后的数据,交由handle方法
    • e)handle方法:就是grpc服务器内部,真正执行客户端请求的方法入口
      • i.对解压后的数据,进行反序列化,得到请求方法的具体参数值
      • ii.真正的执行客户端的请求方法,得到执行结果
    • f)将执行结果封装到数据帧里,存储到controlBuf缓存里
    • g)帧发送器,从帧缓存里获取到数据帧,发送给客户端
3 )客户端一侧
  • 客户端接收到窗口更新帧后,
    • a)若streamID=0,则更新l.sendQuota值,对其进行累加n;
    • b)若streamID!=0,则更新str.bytesOutStanding,对其进行递减n
  • 客户端接收到设置帧:
    • a)则更新l.oiws值
  • 若接收到数据帧,得到了请求服务的最终的执行结果。

如果客户端的数据帧,需要多次发送的话,是重复交互的过程;

服务器端每接收到一次数据帧,就会执行上面的一次流程,向客户端发送窗口更新帧,设置帧;

客户端收到后,会更新本地的的发送指标参数,重新计算下次发送的最大字节数。

2.2、帧发送器的发送参数指标

大概有5个:

  • l.sendQuota、
  • str.bytesOutStanding、
  • l.oiws、
  • http2MaxFrameLen、
  • dataFrame字节数;

但是,服务器端发送的窗口更新帧或者设置帧,其实主要是影响客户端中帧发送器的三个参数:

  • l.sendQuota、
  • str.bytesOutStanding、
  • l.oiws;

其中:

  • http2MaxFrameLen,为固定值16384;
  • dataFrame字节数,不同的请求,数据帧的字节数可能不一样。

3、总结
  • 对滑动窗口进行了简单概述,以及滑动窗口是用来实现什么目的的;
  • 通过滑动窗口流程图描述了滑动窗口的整体处理流程;
  • 最核心的是通过发送参数指标来计算出每次发送的数据帧大小;而这些发送参数指标会受到服务器端的发送的窗口更新帧或者设置帧影响。

有了这些基本认识后,接下来,学习、理解滑动窗口的核心原理以及源码时就不会没有头绪了。

下一篇文章
  帧发送器是如何将数据帧发送给服务器端的基本流程图介绍

点击下面的图片,返回到专栏大纲

gRPC-go源码剖析与实战之专栏大纲

gRPC-go源码剖析与实战感谢

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

grpc-go源码剖析三十五之滑动窗口基本介绍以及整体流程图介绍? 的相关文章

随机推荐

  • 应急响应 - Windows启动项分析,Windows计划任务分析,Windows服务分析

    作者简介 CSDN top100 阿里云博客专家 华为云享专家 网络安全领域优质创作者 推荐专栏 对网络安全感兴趣的小伙伴可以关注专栏 网络安全入门到精通 Windows应急响应 一 启动项分析 1 msconfig 2 gpedit ms
  • Mybatis

    第1章 框架概述 1 1 软件开发常用结构 1 1 1 三层架构 三层架构包含的三层 界面层 User Interface layer 业务逻辑层 Business Logic Layer 数据访问层 Data access layer 三
  • 小熊带你学Python(六)——字符串

    上一节提到序列的应用 序列就是指代的字符串 列表 元组 集合 字典等数据结构的一个集合 我们先从字符串开始讲起 字符串 是一串字母的集合 我们在编程实现各种功能时 很多时候其实都是在操作这些字符串 字符串的变化中实现了各种功能 1 字符串的
  • Springboot项目优化日志logback-spring.xml详解

    Springboot项目优化日志logback spring xml详解 一 描述 二 配置文件 三 效果 一 描述 几种常见的日志 Log4j 是最早的日志框架 是apach旗下的 可以单独使用 也可配合日志框架JCL使用 Log4j2
  • 仅提供信息存储空间服务器,Docker本身的存储空间管理

    原标题 Docker本身的存储空间管理 目标 两台host主机透过一个网络接口共享磁盘设备 iSCSI 共享设备的主机和名字 target dev loop8 gt initiator dev sdb gt initiator docker
  • 摄影毁一生单反穷三代顺口溜_什么?这点预算你竟买了一套摄影设备!

    图片 来自网络 文字 小松鼠 看了文章标题而点进来的朋友们 都是有这方面想法的 本文适合于家境一般的业余摄影爱好者 如果家里有矿或是立志成为专业摄影师的 就没必要往下看了 注 文末有福利 以下为正文 先来一组图 光照的光 花光的光 俗话说
  • 简单的线性单向链表

    数组的不足 我们之前用的数组也是一种数据结构 数组是顺序存储的 数组逻辑关系上相邻的两个元素在物理位置上也相邻 这就导致了在对数组进行插入或删除操作时 需移动大量数组元素 并且数组的长度是固定的 而且必须预先定义 数组的长度难以缩放 对长度
  • glut实现雪花动态效果

    glut实现雪花动态效果 实验题目 总体思路 3 2主要函数说明 按键操作 实验结果 实验题目 1 绘制雪花 2 在屏幕的多个随机位置绘制雪花 3 使每朵雪花绕自己的中心旋转 4 使每朵雪花下降 5 翻页键控制相机视野 按UP键增加物体与观
  • Vue中使用element-plus中的el-dialog定义弹窗-内部样式修改-v-model实现-demo

    效果图 实现代码
  • Three.js系列: 造个海洋球池来学习物理引擎

    github地址 https github com hua1995116 Fly Three js 大家好 我是秋风 继上一篇 Three js系列 游戏中的第一 三人称视角 今天想要和大家分享的呢 是做一个海洋球池 海洋球大家都见过吧 就
  • 北京突然宣布,元宇宙重大消息

    北京青年报记者从2022全球数字经济大会新闻发布会上了解到 2022全球数字经济大会将于7月28日至30日在国家会议中心举行 本届大会将聚焦绿色创新发展 数字贸易 数据价值化 全球规则治理等热点议题 深度探讨互联网3 0 数据要素 开源 5
  • JS的100道经典面试题(一)只看这四篇就够了,收藏起来以后偷偷看

    年轻人你不讲武德 耗子尾汁 总结就是为了形成自己的js知识网 提升自己 加油 开始干 1 介绍js的基本数据类型 答 Undefined Null Boolean Number String 2 js有哪些内置对象 答 数据封装类对象 Ob
  • 深度学习优化学习方法(一阶、二阶)

    深度学习优化学习方法总结 一阶为主 https blog csdn net sunflower sara article details 81321886 常用的优化算法 梯度下降法 牛顿法 拟牛顿法 共轭梯度法 二阶为主 https bl
  • Block底层原理读书笔记-《高级编程- iOS与OS多线程和内存管理》(更新中)

    1 一个Block 真正的底层都有些什么 Block会被解析成一个结构体 这里成为Block结构体 这个结构体里有 1 isa指针 说明Block的本质是一个对象 指向Stack 堆 2 有函数指针 这个函数指针指向一个函数体 该函数体的内
  • C# 企业微信接口发送消息出现错误代码60020解决方案,希望能给大家带来帮助。

    这是企业微信接口发送消息调用的代码源地址 https blog csdn net wanglui1990 article details 79744407 代码运行起来是没有问题的 但唯一出现的问题就是错误代码60020 点击企业微信 应用
  • 数据结构——单链表OJ题(第二弹)

    单链表OJ题 前言 一 返回链表开始入环的第一个节点 思路一 思路二 二 返回链表的深度拷贝 总结 前言 此次练习题有两道 有点小难度 但相信难不住大家的 我也会给出两道OJ题的链接 大家也赶快去试一试吧 一 返回链表开始入环的第一个节点
  • vue2.x与vue3.x中自定义指令详解

    目录 前言 一 自定义指令分类 二 Vue2 x自定义指令钩子函数 1 bind与update区别 2 update与componentUpdated区别 3 钩子函数的参数 4 局部自定义指令 5 全局自定义指令 6 简写形式 三 Vue
  • springboot下配置mybatis的call-setters-on-nulls属性

    使用Mybatis时 如果查询语句中某些字段值是null的 则这个字段就无法返回 对于后台数据处理来说 这是一个致命的问题 于是通过修改Mybatis的配置来解决这个问题 在springmvc下 在mybatis的配置文件里面增加以下配置即
  • C++ opencv处理kinect红外数据和彩色数据

    kinect好像已是明日黄花 但现在需要用这个做交互的人还不少 要做手势识别 于是入手一枚二手kinect2 0 入坑玩玩 做手势识别 直觉上要用opencv 从网上搜的资料来看 大多是通过openNi来操作kinect 而且要openNi
  • grpc-go源码剖析三十五之滑动窗口基本介绍以及整体流程图介绍?

    已发表的技术专栏 0 grpc go protobuf multus cni 技术专栏 总入口 1 grpc go 源码剖析与实战 文章目录 2 Protobuf介绍与实战 图文专栏 文章目录 3 multus cni 文章目录 k8s多网