
如果你正在准备网络方向的面试或考研复试这个标题大概率不会陌生试述资源预留协议RSVP的工作原理。RSVPResource Reservation Protocol是IntServ体系结构中的核心信令协议它解决的问题非常朴素——在默认“尽力而为”的IP网络中为某一条应用流提前占好沿途带宽资源让关键业务不因突发拥塞而丢包、抖动。这篇文章不打算只给你背面试答案的口诀我会把RSVP的设计动机、Path/Resv消息的走向、软状态机制、预留风格等关键点全部拆开顺带讲讲实际工程里它的扩展形态RSVP-TE以及我在学习和调试过程中的一些体会。1. 先搞清楚RSVP到底在解决什么问题1.1 尽力而为网络留下的坑传统的IP网络是个典型的“公共道路”模型。数据包进网络之后每个路由器只负责按照路由表把包转发到下一跳至于这条路堵不堵、后面的车能不能顺利到达网络本身并不关心。这就是所谓的“尽力而为”Best Effort服务网络尽力转发但不做任何质量承诺。这样的模型对网页浏览、邮件收发这类应用完全够用因为短时延、丢包可以通过TCP重传和缓存来弥补。但到了实时音视频、在线会议、工业控制这类场景“尽力而为”就撑不住了。想象一下视频会议的关键帧在路上丢了画面直接卡住几十毫秒的抖动就能让声音断断续续。TCP那种“丢了就重传”的策略在这种场景反而帮倒忙。问题的根源是应用程序需要确定的带宽和延迟保障而网络层完全没有预留资源的机制。RSVP就是为解决这个问题而生的。它的名字已经说明了一切——Resource Reservation Protocol资源预留协议。它的核心动作可以类比成你在一条繁忙的城市快速路上开车出发之前沿途每个路口都提前为你划好一条专用车道并保证绿灯然后在导航里通知你“全程已预约成功放心走”。1.2 IntServ框架让网络“按需记账”地提供服务RSVP并不是孤立存在的它属于端到端服务质量体系中的一部分这个体系在标准化时被统称为IntServIntegrated Services综合服务模型。IntServ的理念是在发送端和接收端之间建立起端到端的服务约定为每一条“流”分配明确的网络资源。IntServ模型里定义了三种服务类型保证服务Guaranteed Service提供严格的带宽和端到端延迟上界适合要求极为苛刻的实时应用。受控负载服务Controlled Load模拟低负载网络下的服务质量即使网络繁忙也能维持近似于空闲时的转发特性。尽力而为服务Best Effort不提供任何保证就是传统IP网络的行为。有了服务类型定义还必须有信令机制来“告诉”沿途设备为哪条流预留多少资源、持续多久这个信令机制就是RSVP。打个比方IntServ是整家餐厅的体制规定了包间、标准间、大厅三种服务标准RSVP就是那通订座电话挨个包间问一遍“今晚几点、几位、要不要靠窗”最后把结果确认下来。理解这一层背景很重要。很多同学一上来就背RSVP的消息类型和工作流程却不清楚它服务的对象是谁。RSVP本身不传输用户数据它只负责传递“资源预约请求”真正的数据包走的还是普通的IP转发路径只不过沿途路由器因为RSVP的请求而开启了相应的队列调度和限速策略。2. RSVP的工作机制为什么是接收者发起预留2.1 方向反直觉的Path与Resv消息RSVP最让人困惑的地方在于预留方向和直觉恰好相反。如果一门心思站在“数据流从发送者流向接收者”的思维定势里很容易被绕晕。数据流方向发送者Sender → 路由器A → 路由器B → 接收者Receiver。RSVP控制消息方向则分成“两段先顺流再逆流”第一段是Path消息从发送者出发沿着数据流的路径逐跳传向接收者。它的作用是向接收者“广播”发送者的流量特征并沿途记录路径上每个节点的状态让接收者知道这条路长什么样。第二段是Resv消息从接收者出发原路返回发送者方向。这次才是真正的“预约请求”沿途每台路由器收到Resv后检查带宽是否够用够用就接纳并安装预留状态不够就拒绝并回报错误。这里面的设计思路非常值得玩味。为什么不能由发送者直接发起预留因为发送者并不知道接收者到底需要什么质量。视频通话里的接收端可能是一个带大屏幕的会议室终端也可能是一个屏幕很小的移动终端它对编码率、缓冲策略的需求完全不同。发送者如果自作聪明地预留了“10M带宽”而接收者只需要2M那等于白白浪费了网络资源。更重要的是组播场景。一发送者对应多个接收者时每个接收者的需求可能各不相同有的要高清、有的只要标清。如果由发送者统一发起预留它根本没法为每一个接收者分别定制路径上的资源。让接收者发起预留每个接收者就可以根据自己的需求和路径条件为自己那一段网络资源做“点单式”预约路由器再在分叉点对不同接收者的请求做合并处理整个体系灵活得多。2.2 会话识别与消息格式里的关键字段RSVP用“会话”Session这个概念来标识一条需要预留资源的流。会话对象由三部分构成目的IP地址、目的端口号、IP协议号。也就是说只要目的IP、目的端口和协议类型相同就被视为同一个会话不管源地址是什么。与Session配套的还有一个Sender Template发送者模板用来标识会话内的具体发送者包含源IP地址、源端口号和协议号。为什么要区分Session和Sender Template因为一个Session可以对应多个发送者比如多方视频会议里多个人的音视频流都发往同一个目的地址和端口组合。预留的时候必须精确到“哪个发送者的流”才能针对不同源做不同的预留策略。Path消息里携带的关键对象主要有三个Sender Tspec描述发送者产生的流量特征一般用令牌桶参数表示核心是峰值速率、令牌桶速率、桶深度。Adspec沿路径逐跳累积的“路径信息”比如路径上的最小带宽、最大传输单元、累积延迟等用于接收端判断端到端服务质量能否被满足。Previous Hop指向上游节点的地址这是Resv消息原路返回的关键依据。其中Adspec是一个很容易被忽略但非常重要的对象。接收端拿到Adspec后就相当于拿到了一张沿途条件清单哪个接口链路带宽较窄、哪段路延迟偏高然后结合自己的应用需求决定“我到底需要预留多少”或者干脆发现无论如何都达不到服务质量要求选择放弃预留。这比盲目要一个固定值靠谱得多。2.3 Resv消息的逐跳处理过程Resv消息回到每一台路由器时路由器要做的事情远不止“看一眼有没有带宽”那么简单。完整流程可以拆成四步第一步准入控制Admission Control。路由器把Resv里请求的带宽和出接口的可用带宽做比较。这里的可用带宽不是“物理带宽减去已用流量”而是要扣除所有已建立预留占用的带宽再考虑链路实际容量。第二步策略控制Policy Control。检查接收者是否有权限发起这个预留有些网络会针对用户或应用做接入认证。策略控制失败的常见场景是普通用户试图预留远超套餐允许的高带宽。第三步安装预留状态。两项检查都通过后路由器就会为这条流建立对应的Reservation State记录流量规格和滤波器规格同时在转发平面配置排队调度规则确保后续匹配该会话的数据包得到预留的带宽待遇。第四步向上游转发Resv。路由器把Resv消息继续往发送者方向转发转发前可能还要做预留合并这一点在讲“预留风格”时会细说。如果中途某台设备准入失败它会直接向下游发送ResvErr消息接收端收到后可以降低资源请求重新尝试。整个链路全部成功预留才算真正建立。发送端收到Resv后一般还会回复一个ResvConf确认消息也就是“我收到预约成功的通知了”。3. 软状态RSVP最独特的设计哲学3.1 为什么预留状态不能“永久生效”RSVP引入了一个特别重要的概念软状态Soft State。意思是说沿途路由器上保存的预留状态不是一劳永逸的它有一个生命周期必须靠周期性的刷新消息来“续命”一旦刷新停止状态就会自动过期并被清理。这个设计初看很反常识。既然是预约为什么不能一次预约、长期有效问题的根源在于IP网络的路由是动态的。路由协议可能随时因为链路故障或拓扑变化而改变路径如果预留状态是永久性的路径一旦切换新路径上的路由器完全不知道有预留这回事资源保障瞬间失效而旧路径上的路由器则一直白白占着资源谁也不释放。软状态把这个问题彻底消解了。发送者周期性发送Path消息接收者周期性发送Resv消息沿途设备上预留状态的生命周期被一次次刷新。假如某条路径发生了切换新的路径上会陆陆续续收到Path消息于是自然地建立新的预留状态旧路径上因为收不到刷新消息状态过一段时间就自动消亡资源被自动回收。整个过程不需要额外的拆除机制也不需要发送者或接收者感知路由变化。这里有一个很重要却很反直觉的点预留状态和“应用是否真的在发包”没有必然关系。即使接收者停止接收数据只要它还在周期发送Resv路由器上的预留就会一直保留。我曾经在实验环境里见过有人因此产生困惑明明业务已经停了查看设备上的预留状态却依然存在。原因就在于RSVP的刷新是信令层面的机制与应用数据的启停完全独立。应用想要释放预留必须通过拆除消息或者主动停止刷新。3.2 刷新周期和清理超时的默认参数RFC 2205对软状态的参数做了明确的默认规定这些默认值在面试中经常被追问。参数默认值说明刷新周期约30秒实际在30到45秒间随机Path和Resv消息都以此周期发送Path状态清理超时3倍刷新周期约90秒连续收不到Path刷新删除路径状态Resv状态清理超时6倍刷新周期约180秒连续收不到Resv刷新删除预留状态刷新周期为什么要引入随机抖动是为了防止多个会话的消息在网络上同步碰撞。如果所有会话都严格按照固定30秒发送经过某些汇聚点后报文会周期性拥塞造成不必要的丢包和延迟尖峰。随机化之后消息的到达时刻被打散对网络的影响更平滑。为什么Resv的清理超时180秒明显长于Path的清理超时90秒因为Resv状态牵扯到具体的资源承诺删除它意味着业务保障的取消必须更加慎重。同时Resv状态的重建比Path状态的重建更复杂接收到错误Resv包时状态需要经过更长时间的容忍期来判断异常是否持续存在。这也是“宁可多留一会儿也不要误删”的设计取舍。3.3 显式拆除消息与故障处理软状态虽然能自动过期但“自动”的背后是要等上十几甚至几十秒这在高实时场景下太慢了。所以RSVP还提供了一套显式拆除机制PathTear消息由发送者或中间路由器主动向上游、下游发送立即删除路径状态。ResvTear消息由接收者或路由器主动发送立即删除预留状态。这两个消息的作用就是“立即注销”把资源占用清零。比如一个视频会议会话结束了接收方应用可以主动发送ResvTear让沿途路由器立刻释放资源不需要等180秒的自然超时。这在资源紧张的网络中非常重要每早一秒释放其他新业务就能早一秒建立预留。RSVP还有一个很实用的特性对直连物理链路故障的处理。假设一台路由器发现自己的某个接口线路断了它会立刻针对经过该接口的所有会话发送PathErr或ResvErr并且会向下游发送PathTear、向上游发送ResvTear把相关会话的状态全部清理掉。相比干等刷新超时这种主动通告机制能让资源在故障发生瞬间就被释放同时让对端快速感知到服务不可用。我在验证故障切换时看到过这个现象链路接口一关闭设备日志里立刻涌出一批RSVP状态删除记录。4. 预留风格与流规格的细节拆解4.1 Tspec、Rspec、Adspec三张“小清单”各管什么RSVP的消息里总是绕不开三个以“Spec”结尾的对象第一次接触时很容易弄混。我帮你把它们按职责分清楚。Tspec描述的是发送者“能产生多少流量”。它通常用令牌桶模型来描述令牌桶速率Token Bucket Rater长期平均速率上限单位是字节/秒。令牌桶深度Bucket Sizeb瞬间突发流量上限相当于桶能存多少令牌单位是字节。峰值速率Peak Ratep认物理链路允许的瞬间最大速率。最小监管单元Minimum Policed Unitm数据包最小计量单位通常取一个字节或链路层最小帧长。最大数据包长度Maximum Datagram SizeM超过这个大小的数据包会被视为违规。这套参数的意义在于接收端在收到Path消息后能精确判断发送端对网络带宽的最高要求平均不能超过多少、突发最多冲多高。路由器做资源预留时也按这个流量模板来分配带宽和缓冲。Rspec描述接收者“希望获得多少预留”。它主要由两个维度构成预留速率R和松弛项S。其中松弛项只在保证服务Guaranteed Service里才会被用到它表示接收方愿意容忍多大的附加排队延迟带宽分配会相应调整。这里的关键点在于Rspec与Tspec不一定相等。接收者完全可以只预留Tspec的一部分带宽比如发送端峰值可能达到4M但接收端的解码器只需要2M就够用那就只预留2M剩下的是网络富余能力。Adspec是Path消息里随路径变化的“体检报告”。它从发送者出发时是空的每经过一台路由器就附加上本地设备的链路特性出接口最大传输单元、链路带宽、经过设备数、累积延迟等。接收者拿到Adspec就能知道路径上最窄的资源瓶颈在哪里。比如路径上有三段链路其中一段是1M的窄带链路那端到端带宽上限再怎么说也不会超过1M接收者就不会发出一个注定无法满足的预留请求。4.2 FF、SE、WF三种预留风格怎么选同一个会话里可能有多个发送者接收者申请预留时必须说明“我这份预留到底给谁用”这就是预留风格Reservation Style要回答的问题。RFC 2205定义了三种风格很多人只会背名字我用一个开会的场景来帮你记忆。第一种是固定过滤器风格Fixed Filter简称FF。它的含义是“为每一个发送者单独预留一份独立的带宽”。开会时A发言占用2M、B发言占用2M两者互不共享。这样做的优点是每条流资源有明确隔离A的突发流量不可能挤占B的带宽缺点是资源利用率较低几个人说话时各自占一份绝大多数时间都在浪费。第二种是共享显式风格Shared Explicit简称SE。它允许接收者指定一组发送者并为这组发送者建立一个共享的预留池。还是那个开会场景A、B两个发送者合起来只预留2M同一时刻只有一个人说话两人共用这2M绰绰有余。SE需要接收者明确写出允许共享的发送者列表所以叫“显式”。第三种是通配过滤器风格Wildcard Filter简称WF。它比SE更进一步接收者不为任何特定发送者做过滤会话里所有发送者统一共享同一个预留池。WF因为不需要维护发送者列表状态存储最轻松但代价是任何发送者的流量都可能在共享池内互相挤占服务质量不如前两种可控。三种风格的选择逻辑很明确如果业务是“多条流同时都重要”比如多路监控视频流并行传输用FF如果业务是“同一时刻一般只有一路在传”比如多人语音会议、即按即说用SE或WF。在工程实际里RSVP预留最常见的场景是视频会议和VoIP这两种场景天然适合共享型风格所以SE/WF的出现频率远比FF要高。4.3 预留合并组播场景下的带宽聚合计算组播是RSVP最初重要的部署场景预留合并机制正是在这里发挥作用。当一台路由器从多个下游接口收到不同接收者发来的Resv时它不能把每份Resv都原样往上游转发否则上游会被请求淹没而且同一会话的资源会被重复计算。对于WF风格路由器把所有下游Resv请求的带宽取最大值然后只向上游转发一份合并后的Resv。这个逻辑和“一群人合用一层楼的电梯按高峰期最大人数定容量”是一样的。对于SE风格路由器需要把下游请求合并成“共享这个池子的发送者列表”同时把带宽需求按最大值合并。对于FF风格路由器则需要为每个发送者分别维护独立的合并结果每个发送者各自对应一个带宽最大值。合并操作最精华的部分是带宽计算。假设下游有三个接收者对同一个发送者分别请求2M、3M、4M合并后向上游请求的带宽是4M而不是9M。因为这条流在瓶颈链路上不可能被三个接收者同时消费取最大值就能满足最苛刻的那一位其他需求自然被覆盖。计算过程本身不复杂难在识别同一个会话的多个下游请求以及在不同预留风格下决定“应该取最大值还是累加”。这也是RSVP协议栈实现里最考验工程能力的地方。接收者发起预留搭配预留合并构成了RSVP扩展性的基石。没有合并组播网中成千上万的接收者请求会把上游链路塞爆有了合并无论下游有多少分支每个节点向上游发出的还是一份请求。5. 常见问题与面试追问实录5.1 经典追问RSVP为什么没有完全普及面试官经常会在最后追问一句“既然RSVP这么好为什么现代互联网核心网并没有普遍部署”这个问题考察的是你对技术背后取舍的理解。RSVP最大的软肋是可扩展性。它本质上是“每流状态”的协议路由器必须为每一条预留流保存状态并且每30秒刷新一次。在核心骨干链路上并发流数量轻松达到数十万甚至百万级别为每一条流都维护状态并周期性刷新对内存、CPU和链路带宽都是巨大开销。更麻烦的是状态需要逐条处理无法批量聚合聚合做不好核心路由器很快被信令消息淹没。另一个问题是RSVP对网络的改造要求很高。它要求所有路径上的设备都支持RSVP信令和对应的队列调度机制任何一个节点不支持端到端预留就建立不起来。对运营商来说全面改造网络设备的代价极高而收益又并非所有业务都刚需。也正因为这些原因RSVP在现代网络中以一种更“轻”的形式存活了下来那就是RSVP-TE。RSVP-TE是MPLS流量工程的信令协议它的主要目标不再是“为每条应用流预留带宽”而是为MPLS标签交换路径建立显式路由在骨干网和大型数据中心出口做了大量部署。RSVP-TE沿用了RSVP的Path/Resv机制和软状态模型但引入了一个关键对象——显式路由对象ERO让发送端可以指定路径必须经过的节点序列同时Resv消息中携带了标签对象用于分配MPLS标签。它本质上是在利用RSVP的“信令通道”来做路径管理核心价值已经超越了资源预留本身。5.2 面试高频问题的回答思路与避坑提醒问RSVP消息是走TCP还是UDP答案是两者都不用。RSVP消息直接用IP协议号46承载属于网络层信令。这个问题很偏但一旦问到就能甩开很多人。问Path消息和Resv消息哪个先发Path先发Resv后回之后两者周期性并行发送。先有路径“探明”才能有针对性的预留。问预留成功之后RSVP就不再工作了吗工作而且必须一直工作。软状态需要持续刷新一旦停止资源就会在超时后被释放。问NAT环境下RSVP能用吗不能直接用。因为RSVP消息里的IP地址和端口是明文携带的NAT设备会修改IP头但通常不会同步修改RSVP消息内部的地址字段导致中间路由器无法正确匹配会话。RSVP对NAT的穿透需要额外的ALG支持这在家庭和办公室网络里往往不具备。我在面试候选人的时候发现一个比较普遍的误区有人把RSVP理解成“带宽分配好了数据就一定不丢”。RSVP只能保证预留带宽内的流量受到保护如果发送端超出发送的Tspec范围超过部分同样会被丢弃或降级处理。这就像你预约了一条专用车道但如果你开的是重卡且超速照样会被拦下来。5.3 我在实测环境里总结的几点经验如果你打算在自己搭的虚拟网络环境里验证RSVP行为我有几个建议。第一把拓扑控制得越小越好。三台路由器加两台主机就足够跑通全流程。先在中间路由器的出接口上故意把可用带宽调低让Resv在中间节点被拒绝然后观察ResvErr返回时接收端的反应。这个过程能帮你直观理解“准入控制”的判定逻辑。第二观察刷新消息别急着抓包。Path和Resv默认30秒才发一次抓包要抓至少90秒才能看到完整状态建立、刷新、清理的过程。可以把刷新计时器调小一点比如5秒实验节奏就会舒服很多。第三查看设备上的RSVP状态时重点区分“路径状态”和“预留状态”两张表。前者通常记录的是Path消息建立的邻居信息和会话信息后者记录的是实际承诺的带宽和过滤器规则。手工清掉预留状态但保留路径状态会看到会话在下一个刷新周期自动重建这是软状态机制最直观的体现。还有一个容易被忽略的点RSVP和路由协议的关系。RSVP本身不参与选路它完全依赖底层路由协议来确定Path消息的转发路径。如果底层路由是等价的负载均衡Path消息和Resv消息可能走不同路径那预留就建立不起来。所以在验证RSVP时尽量关闭等价多路径或者为相关会话配置固定的非等价路径。最后说点自己的感受我第一次系统地啃RSVP的时候花了很长时间才接受“预留方向反向”和“状态需要不断刷新”这两个设定。后来做过几轮组播环境下的实验才意识到这两条设计有多么聪明接收者发起预留给了整个系统最大的弹性让不同接收者可以按需申请软状态机制把路由动态变化带来的复杂性全部消解了网络故障后预留状态能自愈而不需要应用层干预。RSVP在今天已经很难作为端到端服务质量方案大规模铺开但它的思想遗产却无处不在软状态的容错哲学信号与数据分离的信令架构逐跳处理的状态模型这些概念在RSVP-TE、Segment Routing乃至很多网络自动化方案里都能看到影子。理解了RSVP你不只是背下来一个协议的流程更是建立了一张理解网络资源协议族系的地图。如果你准备面试或复试建议把文章里提到的“合并计算”“超时参数”“预留风格”这些细节动手整理一张表面试官追到任何一层都有话可说。这个协议表面絮叨往深了看全是取舍和智慧值得花时间。