【计网】TCP在可靠传输中都干了啥
文章目录
- 1、概述
- 2、校验和
- 3、序列号和确认应答机制
- 4、重传机制
- 4.1、介绍
- 4.2、超时重传
- 4.3、快速重传
- 5、滑动窗口协议
- 5.1、介绍
- 5.2、发送方的滑动窗口
- 5.3、接收方的滑动窗口
- 6、流量控制
- 7、拥塞控制
- 7.1、介绍
- 7.2、慢开始
- 7.3、拥塞避免
- 7.4、快重传和快恢复
1、概述
TCP 是面向连接的、可靠的、基于字节流的传输层通信协议,处于OSI模型的第四层传输层。
那么什么是可靠传输呢?可靠传输就是保证接收方收到的字节流和发送方发出的字节流是完全一样的。也就是说,通过 TCP 连接传输的数据,无差错、不丢失、不重复、并且按序到达。
网络层是没有可靠传输机制的,尽自己最大的努力进行交付。而传输层使用 TCP 实现可靠传输,TCP 保证可靠传输的机制有如下几种:
- 校验和 Checksum
- 序列号和确认应答机制
- 重传机制
- 流量控制(滑动窗口协议)
- 拥塞控制
2、校验和
所谓 TCP 的校验和(Checksum)就是说:由发送端计算待发送 TCP 报文段的校验和,然后接收端对接收到的 TCP 报文段验证其校验和(TCP 的校验和是一个端到端的校验和)。其目的是为了发现 TCP 的首部和数据在发送端到接收端之间是否发生了变动。如果接收方检测到校验和有差错,则该 TCP 报文段会被直接丢弃。
TCP 在计算校验和时,需要加上一个 12 字节的伪首部。伪首部的数据是从 IP 数据报头获取的,共有 12 字节,包含如下信息:源 IP 地址、目的 IP 地址、保留字节 (置 0)、传输层协议号 (TCP 是 6)、TCP 报文长度 (首部 + 数据):
3、序列号和确认应答机制
这个机制类似于问答的形式。比如在课堂上老师会问你“明白了吗?”,假如你没有隔一段时间没有回应或者你说不明白,那么老师就会重新讲一遍。
其实计算机的确认应答机制也是一样的,发送端发送信息给接收端,接收端会回应一个包,这个包就是应答包(ACK),而序列号则是标识发送者是谁。
4、重传机制
4.1、介绍
在错综复杂的网络,并不一定能够顺利的传输报文,报文存在丢失的可能性。报文丢失的可能因素有很多种,包括应用故障,路由设备过载,或暂时的服务宕机。报文级别速度是很高的,通常来说报文的丢失是暂时的,因此 TCP 能够发现和恢复报文丢失显得尤为重要。
重传机制是 TCP 最基本的错误恢复功能,常见的重传机制有如下:
- 超时重传
- 快速重传
4.2、超时重传
超时重传是最常看到的一种重传机制,如在之前提及到的《【计网】什么是三次握手四次挥手》中,便多次提及到了在三次握手四次挥手中若报文丢失或超时变回触发超时重传。
超时重传就是 TCP 发送方在发送报文的时候,设定一个定时器,如果在规定的时间内没有收到接收方发来的 ACK 确认报文,发送方就会重传这个已发送的报文段。
超时重传时间我们一般用 RTO(Retransmission Timeout)来表示,RTT (Round-Trip Time 往返时延)就是数据从网络一端传送到另一端所需的时间,也就是报文段的往返时间。
显然,超时重传时间 RTO 的值应该略大于报文往返 RTT 的值:
我们可以假想一下,如果超时重传时间 RTO 远大于或小于 RTT,会发生什么情况:
- RTO 远大于 RTT:网络的空闲时间增大,降低了网络传输效率。即如果真的丢失了,等待的时间过长,原本一分钟能干五碗饭,在RTO远大于RTT后,一分钟只能干两碗了,使得两端之间的网络传输效率变差;
- RTO 小于 RTT:不必要的重传,导致网络负荷增大,甚至无法完成正常的网络传输。简单来说就是,如果通过TCP传输一个数据包最快需要2ms,但是由于RTO小于RTT,假设设置RTO为1ms,那么在这个数据包还未传输到接收方时便已经触发超时重传机制,导致永远无法完成该次网络传输。
如果超时重传的数据又超时了该怎么办呢?TCP 的策略是重传的超时间隔加倍。
也就是说,每进行一次超时重传,都会将下一次重传的超时时间间隔设为先前值的两倍。
超时触发重传存在的问题是,超时周期可能相对较长。有没有一种机制可以减少超时重传的等待时间呢?于是快速重传机制应运而生。
4.3、快速重传
快速重传(Fast Retransmit)机制不以时间为驱动,而是以数据驱动重传。
快速重传机制的原理:每当接收方收到比期望序号大的失序报文段到达时,就向发送方发送一个冗余 ACK,指明下一个期待字节的序号。简单来说,就是接收方收到的数据包如果不是按照顺序来的,不管是乱序还是丢失,也会给客户端回复冗余ACK,用来标记到发送到哪里的时候乱序或丢失了。
对于何时重传有这么一个阈值,当冗余ACK达到3个时,便会触发重传,即发现三个乱序或丢失的数据包时,便会触发快速重传。
注意:是冗余ACK达到3个,不是收到3个重复的ACK便会触发重传,因为除了3个冗余ACK外,还有一个是最开始的正确的ACK,所以重复的ACK是4个,其中冗余ACK3个,有1个是正确的ACK。
举个例子:发送方已经发送 1、2、3、4、5报文段
- 接收方收到报文段 1,返回 1 的 ACK 确认报文(确认号为报文段 2 的第一个字节)
- 接收方收到报文段 3,仍然返回 1 的 ACK 确认报文(确认号为报文段 2 的第一个字节)
- 接收方收到报文段 4,仍然返回 1 的 ACK 确认报文(确认号为报文段 2 的第一个字节)
- 接收方收到报文段 5,仍然返回 1 的 ACK 确认报文(确认号为报文段 2 的第一个字节)
- 接收方收到 3 个对于报文段 1 的冗余 ACK,认为报文段 2 丢失,于是重传报文段 2
- 最后,接收方收到了报文段 2,此时因为报文段 3、4、5 都收到了,所以返回 6 的 ACK 确认报文(确认号为报文段 6 的第一个字节)
5、滑动窗口协议
5.1、介绍
我们都知道 TCP 是每发送一个数据,都要进行一次确认应答。当上一个数据包收到了应答了, 再发送下一个。
这个模式就有点像我和你面对面聊天,你一句我一句。但这种方式的缺点是效率比较低的。
如果你说完一句话,我在处理其他事情,没有及时回复你,那你不是要干等着我做完其他事情后,我回复你,你才能说下一句话,很显然这不现实。
所以,这样的传输方式有一个缺点:数据包的往返时间越长,通信的效率就越低。
为解决这个问题,TCP 引入了窗口这个概念。即使在往返时间较长的情况下,它也不会降低网络通信的效率。
那么有了窗口,就可以指定窗口大小,窗口大小就是指无需等待确认应答,而可以继续发送数据的最大值。
窗口的实现实际上是操作系统开辟的一个缓存空间,发送方主机在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。
假设窗口大小为 3
个 TCP 段,那么发送方就可以「连续发送」 3
个 TCP 段,并且中途若有 ACK 丢失,可以通过「下一个确认应答进行确认」。
图中的 ACK 600 确认应答报文丢失,也没关系,因为可以通过下一个确认应答进行确认,只要发送方收到了 ACK 700 确认应答,就意味着 700 之前的所有数据「接收方」都收到了。这个模式就叫累计确认或者累计应答。
那么窗口大小由哪一方决定?
TCP 头里有一个字段叫 Window
,也就是窗口大小。
这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。
所以,通常窗口的大小是由接收方的窗口大小来决定的。
发送方发送的数据大小不能超过接收方的窗口大小,否则接收方就无法正常接收到数据。
5.2、发送方的滑动窗口
我们先来看看发送方的窗口,下图就是发送方缓存的数据,根据处理的情况分成四个部分,其中深蓝色方框是发送窗口,紫色方框是可用窗口:
- #1 是已发送**
并
**收到 ACK确认的数据:1~31 字节 - #2 是已发送**
但
**未收到 ACK确认的数据:32~45 字节 - #3 是未发送但总大小**
在
接收方处理范围内
**(接收方还有空间):46~51字节 - #4 是未发送但总大小**
超过
**接收方处理范围(接收方没有空间):52字节以后
在下图,当发送方把数据「全部」都一下发送出去后,可用窗口的大小就为 0 了,表明可用窗口耗尽,在没收到 ACK 确认之前是无法继续发送数据了。
在下图,当收到之前发送的数据 32~36
字节的 ACK 确认应答后,如果发送窗口的大小没有变化,则滑动窗口往右边滑动 5 个字节,因为有 5 个字节的数据被应答确认,接下来 52~56
字节又变成了可用窗口,那么后续也就可以发送 52~56
这 5 个字节的数据了。
那么程序是如何表示发送方的四个部分的呢?
TCP 滑动窗口方案使用三个指针来跟踪在四个传输类别中的每一个类别中的字节。其中两个指针是绝对指针(指特定的序列号),一个是相对指针(需要做偏移):
SND.WND
:表示发送窗口的大小(大小是由接收方指定的);SND.UNA
(Send Unacknoleged):是一个绝对指针,它指向的是已发送但未收到确认的第一个字节的序列号,也就是 #2 的第一个字节。SND.NXT
:也是一个绝对指针,它指向未发送但可发送范围的第一个字节的序列号,也就是 #3 的第一个字节。可用窗口大小 = SND.WND -(SND.NXT - SND.UNA)
- 指向 #4 的第一个字节是个相对指针,它需要
SND.UNA
指针加上SND.WND
大小的偏移量,就可以指向 #4 的第一个字节了。
5.3、接收方的滑动窗口
接下来我们看看接收方的窗口,接收窗口相对简单一些,根据处理的情况划分成三个部分:
- #1 + #2 是已成功接收并确认的数据(等待应用进程读取);
- #3 是未收到数据但可以接收的数据;
- #4 未收到数据且不可以接收的数据;
其中三个接收部分,使用两个指针进行划分:
RCV.WND
:表示接收窗口的大小,它会通告给发送方。RCV.NXT
:是一个指针,它指向期望从发送方发送来的下一个数据字节的序列号,也就是 #3 的第一个字节。- 指向 #4 的第一个字节是个相对指针,它需要
RCV.NXT
指针加上RCV.WND
大小的偏移量,就可以指向 #4 的第一个字节了。
那么接收窗口和发送窗口的大小是相等的吗?
答案是并不完全相等,接收窗口的大小是约等于发送窗口的大小的。
因为滑动窗口并不是一成不变的。比如,当接收方的应用进程读取数据的速度非常快的话,这样的话接收窗口可以很快的就空缺出来。那么新的接收窗口大小,是通过 TCP 报文中的 Windows 字段来告诉发送方。那么这个传输过程是存在时延的,所以接收窗口和发送窗口是约等于的关系。
6、流量控制
想象一下这个场景:主机 A 一直向主机 B 发送数据,不考虑主机 B 的接收能力,则可能导致主机 B 的接收缓冲区满了而无法再接收数据,从而导致大量的数据丢包,引发重传机制。而在重传的过程中,若主机 B 的接收缓冲区情况仍未好转,则会将大量的时间浪费在重传数据上,降低传送数据的效率。
所以引入了流量控制机制,主机 B 通过告诉主机 A 自己接收缓冲区的大小,来使主机 A 控制发送的数据量。总结来说:所谓流量控制就是控制发送方发送速率,保证接收方来得及接收。
TCP 实现流量控制主要就是通过 滑动窗口协议。
在前面说到滑动窗口的大小是由接收方告知发送方的,那么是如何告知的呢?在《【计网】什么是三次握手四次挥手》中其实有展示过只是未提及,在数据报文中是存在这么一个16位的 窗口大小 Window 字段。
该字段的含义是指自己接收缓冲区的剩余大小,于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。
因此,通常来说窗口大小是由接收方来决定的。
接收方会在发送 ACK
确认应答报文时,将自己的即时窗口大小(接收窗口 rwnd
)填入,并跟随 ACK
报文一起发送出去。而发送方根据接收到的 ACK
报文中的窗口大小的值改变自己的发送速度。如果接收到窗口大小的值为 0,那么发送方将停止发送数据。并定期的向接收端发送窗口探测数据段,提醒接收端把窗口大小告诉发送端。
7、拥塞控制
7.1、介绍
所谓拥塞就是说:在某段时间,对网络中某一资源的需求超过了该资源所能提供的可用部分(即 需大于供),网络的性能变差。
如果网络出现拥塞,TCP 报文可能会大量丢失,此时就会大量触发重传机制,从而导致网络拥塞程度更高,严重影响传输。
其实只要「发送方」没有在规定时间内接收到 ACK 应答报文,也就是触发了重传机制,就会认为网络出现了拥塞。
因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。
流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度,防止过多的数据注入到网络中。
为了调节发送方所要发送数据的量,定义了「拥塞窗口 cwnd
」的概念。拥塞窗口是发送方维护的一个状态变量,它会根据网络的拥塞程度动态变化:
- 只要网络中出现了拥塞,
cwnd
就会减少; - 若网络中没有出现拥塞,
cwnd
就会增大。
在引入拥塞窗口概念之前,发送窗口大小和接收窗口大小基本是相等的关系,即取决于接收窗口大小。引入拥塞窗口后,发送窗口的大小就等于拥塞窗口和接收窗口的最小值。
7.2、慢开始
慢开始的思路就是:TCP 在刚建立连接完成后,如果立即把大量数据字节注入到网络,那么很有可能引起网络阻塞。好的方法是先探测一下,逐步提高发送数据包的数量,即由小到大逐渐增大拥塞窗口数值。cwnd 初始值为 1,每经过一个传播轮次,cwnd 加倍(指数增长)。
当然不能一直执行慢启动,这里会设置一个慢启动轮限 ssthresh 状态变量:
- 当
cwnd < ssthresh
时,继续使用慢启动算法; - 当
cwnd >= ssthresh
时,开始使用拥塞避免算法。
7.3、拥塞避免
拥塞避免算法的思路是让拥塞窗口 cwnd
缓慢增大,即每经过一个往返时间 cwnd
加 1。
注意,无论是慢开始阶段还是拥塞避免,只要出现了网络拥塞(触发超时重传机制),慢开始轮限 sshresh
和 拥塞窗口大小 cwnd
的值都会发生变化(乘法减小):
ssthresh
设为cwnd/2
cwnd
重置为1
由于拥塞窗口大小重置为 1 了,所以就会重新开始执行慢启动算法。
7.4、快重传和快恢复
快速重传和快速恢复算法一般同时使用。当触发快速重传机制,即接收方收到三个重复的 ACK
确认的时候,就会执行快重传算法(触发快速重传机制和超时重传机制的情况不同,TCP 认为触发快速重传的情况并不严重,因为大部分没丢,只丢了一小部分),快速重传做的事情有:
- 阻塞窗口减半,即
cwnd = cwnd/2
; - 慢开始轮限 = 阻塞窗口,即
ssthresh = cwnd
; - 重新进入拥塞避免阶段。
后来的 快速恢复 算法是在上述的“快速重传”算法后添加的,当收到 3 个重复ACK时,TCP 最后进入的不是拥塞避免阶段,而是快速恢复阶段。
快速恢复的思想是数据包守恒原则,即同一个时刻在网络中的数据包数量是恒定的,只有当旧数据包离开了网络后,才能向网络中发送一个新数据包,如果发送方收到一个重复的 ACK
,那么根据 TCP 的 ACK
机制就表明有一个数据包离开了网络,于是 cwnd
加 1。如果能够严格按照该原则那么网络中很少会发生拥塞,事实上拥塞控制的目的也就在修正违反该原则的地方。
具体来说快速恢复的主要步骤:
- 把
cwnd
设置为ssthresh
的值加 3,然后重传丢失的报文段,加 3 的原因是因为收到 3 个重复的ACK
,表明有 3 个旧数据包离开了网络; - 再收到重复的
ACK
时,拥塞窗口cwnd
增加 1 - 当收到新的数据包的
ACK
时,把cwnd
设置为第一步中的ssthresh
的值。原因是因为该ACK
确认了新的数据,说明从重复ACK
时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态。
相关文章:

【计网】TCP在可靠传输中都干了啥
文章目录 1、概述2、校验和3、序列号和确认应答机制4、重传机制4.1、介绍4.2、超时重传4.3、快速重传 5、滑动窗口协议5.1、介绍5.2、发送方的滑动窗口5.3、接收方的滑动窗口 6、流量控制7、拥塞控制7.1、介绍7.2、慢开始7.3、拥塞避免7.4、快重传和快恢复 1、概述 TCP 是面向…...

windows下载安装FFmpeg
FFmpeg是一款强大的音视频处理软件,下面介绍如何在windows下下载安装FFmpeg 下载 进入官网: https://ffmpeg.org/download.html, 选择Windows, 然后选择"Windows builds from gyan.dev" 在弹出的界面中找到release builds, 然后选择一个版本࿰…...

SwipeDelMenuLayout失效:Could not find SwipeDelMenuLayout-V1.3.0.jar
一、问题描述 最近在工作上的项目中接触到SwipeDelMenuLayout这个第三方Android开发库,然后我就根据网上的教程进行配置。这里先说一下我的开发环境:Android Studio版本是android-studio-2020.3.1.24-windows,gradle版本是7.0.2。 首先是在se…...

C++ 类和对象篇(零) 面向过程 和 面向对象
目录 一、面向过程 二、面向对象 三、两种编程思想的比较 四、C和C 一、面向过程 1.是什么? 是一种以解决问题的过程为中心的编程思想。即先分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现。 2.为什么? 面向过程就纯粹是分析…...
列表list
列表 列表是将数据组织在一个一维集合中,从这个组织方式来看,它与c()函数是相似的。但是,列表并不是将具体的值组织起来,而是组织R对象,如列表、数据框、矩阵、函数、向量等等。 列表非常好用,因为列表可…...
gcc编译出现bar causes a section type conflict with foo问题解决
这里bar是变量名,foo是函数名。 如下是charGPT给出的答复,结论是:bar和foo放在同一个section内,但是它们的类型不同,函数应该放置在一个可执行(executable)类型的section,而变量应该…...

12. Mybatis 多表查询 动态 SQL
目录 1. 数据库字段和 Java 对象不一致 2. 多表查询 3. 动态 SQL 使用 4. if 标签 5. trim 标签 6. where 标签 7. set 标签 8. foreach 标签 9. 通过注解实现 9.1 查找所有数据 9.2 通过 id 查找 1. 数据库字段和 Java 对象不一致 我们先来看一下数据库中的数…...

操作系统专栏1-内存管理from 小林coding
操作系统专栏1-内存管理 虚拟地址内存管理方案分段分页页表单级页表多级页表TLB 段页式内存管理Linux内存管理 malloc工作方式操作系统内存回收回收的内存种类 预读失败和缓存污染问题预读机制预读机制失效解决方案缓存污染 内核对虚拟内存的表示内核对内核空间的表示直接映射区…...
SpringCloud远程服务调用
下面介绍在SpringCloud中如何使用openfeign实现远程服务调用 1.在字典服务中有这么2个接口 Api(tags "数据字典接口") RestController RequestMapping("/admin/cmn/dict/") CrossOrigin public class DictController {Autowiredprivate DictService dic…...

Arcgis通过模型构建器计算几何坐标
模型 模型中,先添加字段,再计算字段 计算字段 模型的计算字段中,表达式是类似这样写的,其中Xmin表示X坐标,Ymin表示Y坐标 !Shape.extent.Xmin!...
java设计模式-工厂模式(下)
接java设计模式-工厂模式(上) 抽象工厂模式 针对耳机的生产需求,我们可以知道,刚才的工厂已经不满足了,因为只是生产一类产品-手机,但是现在我们需要的工厂类是要生产一个产品族(手机和耳机&a…...

深蓝学院C++基础与深度解析笔记 第13章 模板
1. 函数模板 ● 使用 template 关键字引入模板: template<typename T> //声明:T模板形参void fun(T); // T 函数形参template<typename T> //定义void fun(T) {...}– 函数模板不是函数 –…...

装饰器模式——扩展系统功能
1、简介 1.1、概述 对新房进行装修并没有改变房屋用于居住的本质,但它可以让房子变得更漂亮、更温馨、更实用、更能满足居家的需求。在软件设计中,也有一种类似新房装修的技术可以对已有对象(新房)的功能进行扩展(装…...

无涯教程-jQuery - jQuery.get( url, data, callback, type )方法函数
jQuery.get(url,[data],[callback],[type])方法使用GET HTTP请求从服务器加载数据。 该方法返回XMLHttpRequest对象。 jQuery.get( url, [data], [callback], [type] ) - 语法 $.get( url, [data], [callback], [type] ) 这是此方法使用的…...

【Vue3】递归组件
1. 递归组件mock数据 App.vue <template><div><Tree :data"data"></Tree></div> </template><script setup lang"ts"> import { reactive } from vue; import Tree from ./components/Tree.vue; interface Tr…...

【Python】数据分析+数据挖掘——探索Pandas中的索引与数据组织
前言 在数据科学和数据分析领域,Pandas是一个备受喜爱的Python库。它提供了丰富的数据结构和灵活的工具,帮助我们高效地处理和分析数据。其中,索引在Pandas中扮演着关键角色,它是一种强大的数据组织和访问机制,使我们…...

matlab进阶:求解在约束条件下的多元目标函数最值(fmincon函数详解)
🌅*🔹** φ(゜▽゜*)♪ **🔹*🌅 欢迎来到馒头侠的博客,该类目主要讲数学建模的知识,大家一起学习,联系最后的横幅! 喜欢的朋友可以关注下,私信下次更新不迷路࿰…...

Kotlin知识点
Kotlin 是 Google 推荐的用于创建新 Android 应用的语言。使用 Kotlin,可以花更短的时间编写出更好的 Android 应用。 基础 Kotlin 程序必须具有主函数,这是 Kotlin 编译器在代码中开始编译的特定位置。主函数是程序的入口点,或者说是起点。…...

亚马逊云科技联合霞光社发布《2013~2023中国企业全球化发展报告》
中国企业正处于全球聚光灯下。当企业全球化成为时代发展下的必然趋势,出海也从“可选项”变为“必选项”。中国急速扩大的经济规模,不断升级的研发和制造能力,都在推动中国企业不断拓宽在全球各行业的疆域。 过去十年,是中国企业…...

【解析excel】利用easyexcel解析excel
【解析excel】利用easyexcel解析excel POM监听类工具类测试类部分测试结果备注其他 EasyExcel Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题&…...

Tailwind CSS 实战:基于 Kooboo 构建 AI 对话框页面(六):图片上传交互功能
在 《Tailwind CSS 实战:基于 Kooboo 构建 AI 对话框页面(五)》 中,完成了语音交互功能的优化。本文作为该系列教程的第六篇,将聚焦于图片上传功能的开发。通过集成图片上传与预览能力,我们将进一步完善 AI…...

有意向往gis开发靠,如何规划学习?
听说GIS开发工资不错、还不像互联网那么卷?心动了?但一看那些“WebGL”、“空间分析”、“OGC规范”的词儿就头大?别急! 今天咱就聊聊零基础/转行选手,咋规划学习GIS开发这条路。不整高大上,就讲实在的&am…...
在 Caliper 中执行不同合约的方法
在 Caliper 中执行不同的智能合约需要通过正确配置工作负载(workload)和测试轮次(rounds),下面我将详细介绍如何执行不同的合约。 1. 通过 config.yaml 配置不同测试轮次 你可以在 config.yaml 中为不同的合约定义不同的测试轮次: rounds:- label: test-helloworlddescript…...
深入理解MySQL死锁:从原理、案例到解决方案
一、MySQL死锁的概念与定义 1. 死锁的基本定义 MySQL中的死锁是指两个或多个事务在同一资源上相互等待对方释放锁,导致这些事务都无法继续执行的情况。从本质上讲,死锁是多个事务形成了一个等待环路,每个事务都在等待另一个事务所持有的锁资…...
使用API网关Kong配置反向代理和负载均衡
简介 Kong 是一个微服务API网关。 Kong是一个云原生,快速,可扩展和分布式微服务抽象层(也称为API网关,API中间件或在某些情况下为Service Mesh)。 作为2015年的开源项目,其核心价值在于高性能和可扩展性。…...
AI对测试行业的应用
AI对测试行业的应用 AI技术在软件测试领域的应用已从概念验证全面迈向工程化落地,正在重构测试流程、提升效率边界,并为质量保障体系带来范式级变革。以下从技术突破、行业实践与未来趋势三个维度展开深度解析: ⚙️ 一、核心技术突破&#…...

数据分析实战2(Tableau)
1、Tableau功能 数据赋能(让业务一线也可以轻松使用最新数据) 分析师可以直接将数据看板发布到线上自动更新看板自由下载数据线上修改图表邮箱发送数据设置数据预警 数据探索(通过统计分析和数据可视化,从数据发现问题…...
Android四大组件通讯指南:Kotlin版组件茶话会
某日,Android王国举办Kotlin主题派对。Activity穿着Jetpack Compose定制礼服,Service戴着协程手表,BroadcastReceiver拿着Flow喇叭,ContentProvider抱着Room数据库入场。它们正愁如何交流,Intent举着"邮差"牌…...
《深度体验 Egg.js:打造企业级 Node.js 应用的全景指南》
🚀 核心亮点:Koa 的二次觉醒 企业级基因:阿里多年双十一验证的框架稳定性插件化架构:config.plugins 实现功能模块即插即用渐进式演进:从 50 行代码到 5 万行代码的无缝扩容能力 🔧 实战配置解析ÿ…...
placeholder不显示and模板字符串无效
一、placeholder"请输入"不显示请输入? input框里写了placeholder为什么不显示呢? 检查代码,input是否有初始值 在 Vue.js 中,v-model 是双向绑定的语法糖,它会动态更新输入框的 value。如果绑定的数据有初…...