静态路由把人烦疯之后,为什么还会回头研究RIP
我最早接触RIP是被逼的。那时候帮一家公司维护一个二十几台设备的办公网络,总部加三个分支机构,用的还是老一套华为和思科混搭的设备。一开始图省事,全上静态路由,一条一条配,配完还要写文档记录,生怕哪天下班之后某个维护兄弟改错了网段。结果后来真的出事了:一条专线半夜闪断,备用链路带过来的网段没写静态路由,第二天早上一堆人上不了内网OA。我凌晨三点爬起来查路由表,那一刻脑子里只有一个念头——要是当初用了动态路由,根本不需要我动手。
从那之后我重新把学习重心放回动态路由协议上,而这一切的起点,正是很多人嫌它"老土"的RIP。RIP全称Routing Information Protocol,路由信息协议,是目前公认的使用最广泛、历史最久的动态路由协议之一。虽然现在生产环境里OSPF和BGP才是主角,但RIP在入门学习、小型网络和兼容老旧设备这些场景下,依然有一整套值得吃透的逻辑。这篇文章我就把自己从配静态路由翻车,到系统学完RIP、再回到生产环境用它解决实际问题的完整思路写下来,里面包含命令、机制、坑点和选型判断,希望对正在从静态路由往动态路由过渡的同行有点用。
1. 静态路由把人难住之后,RIP解决的是哪一层的痛点
1.1 动态路由真正解决的问题不是"少敲几条命令"
很多人觉得动态路由就是替代手敲静态路由,省事而已。这个理解太浅了。静态路由最大的问题不是配置量,而是它不具备"感知网络变化"的能力。链路断开、设备重启、路径拥塞,静态路由表不会自己更新,你必须人为判断哪里出了故障、该把流量引到哪条备份链路上,再手动修改配置。如果是几条链路还好,一旦网段数量上去,这个脑力负担会非常重。
RIP这类动态路由协议做的事情,本质上是把"路由表的维护和收敛"从人脑转移到了路由器之间的协作上。每一台运行RIP的路由器,周期性把自己已知的路由信息通告给邻居,同时接收邻居的通告,然后根据某种度量标准(metric)决定把哪条路由放进路由表。链路断了、邻居路由消失了,这种变化会被协议自动感知,并在一定时间内完成全网路由表的重新收敛。
这里要说清楚:RIP追求的从来不是"最优路径",而是"够用且能自愈"。它不像OSPF那样通过复杂的SPF算法计算最短路径树,而是采用最简单直接的思路——用跳数(hop count)衡量路径长短,选跳数最少的那条路。
1.2 RIP在网络工程师学习路径里的准确定位
RIP在网络技术体系里的地位有点像汽车驾驶里的手动挡。你说现在自动挡都普及了,手动挡还有什么用?但你要考驾照、要理解变速箱和发动机配合的逻辑,手动挡就是最好的教学工具。RIP是距离矢量协议的代表,理解了RIP,你后面学EIGRP、BGP都会轻松很多,因为这几个协议在"路由通告、度量计算、防环机制"这些层面,思路是一脉相承的。
另外一点很实际:在很多老旧网络、教育实验网、某些工业生产内网里,RIP并没有完全退休。我遇到过一些还在稳定运行的老设备,它们支持的动态路由协议里只有RIP最可靠,其余协议因为设备代码太老反而容易出兼容性bug。这时候懂RIP就变成了一个能解决实际问题的技能,而不是书本上的概念。
1.3 RIP能干什么、不能干什么,先摆清楚
一个协议学了半天,最怕不知道它的边界。RIP的边界非常清晰:
- 适合小型网络:直径(最多跳数)被限制在15跳以内,第16跳视为不可达
- 配置简单:没有复杂的区域、邻居关系、DR/BDR选举这些概念
- 收敛慢:依赖周期性更新和超时计时器,通常需要几十秒到几分钟才能完成全网收敛
- 不适合高可靠性核心网:如果链路越多、越复杂,RIP的更新开销和收敛慢的问题会被放大
我见过有人拿RIP去跑一个几百台设备的大网,结果路由表震荡不断,链路切换半天都缓不过来,最后不得不全网迁到OSPF。这就是没搞清楚协议边界导致的——工具没选对,不是工具本身不行。
2. RIP核心机制拆解:距离矢量、跳数与防环自救的完整逻辑
2.1 距离矢量算法的本质:把"我不知道的路"变成"我听邻居说的路"
RIP用的是距离矢量(Distance Vector)算法,这个名字很多人背过,但真正理解的不多。我用一句话概括:每台路由器不掌握全网的拓扑图,它只知道"我要去某个网段,该往哪个邻居方向走,经过多少跳"。
类比一下就像你在一个陌生的城市问路。你不需要知道整座城市的街道地图,你只需要知道遇到路口往左还是往右、大概再走几个路口能到。每个你遇到的本地人(邻居路由器)告诉你他那边的情况,你就组合出了一个方向;他们也在向你打听去其他地方的路。这就是距离矢量——信息全靠邻居间的口口相传,而不是自己绘制全图。
RIP通告的内容很简单:目标网段(前缀+掩码)、metric(到达该网段的跳数)、下一跳(通常是通告者的接口地址)。收到通告后,路由器会检查这个网段是否在路由表里:
- 如果不在,加入路由表,metric=收到的跳数+1
- 如果在,且新metric更小,替换为更优路径
- 如果在,且新metric相同或更大,但通告者正好是现有路径的下一跳,则以新metric为准更新(防止链路变化后还沿用旧信息)
这套逻辑单独看很容易理解,但麻烦在于"口口相传"会带来一个经典问题:如果某个网段断了,信息在邻居间传着传着,会不会永远找不到尽头?这正是RIP设计的精彩之处,也是它后续各种机制要解决的核心矛盾。
2.2 跳数上限15和计数到无穷:RIP最著名的两个数字
RIP规定,一条路由的metric取值范围是1到15,16代表不可达。也就是说,一个数据包在网络里最多经过15台路由器中转,超过这个数字就被认为目的不可达。为什么是这个数字?从工程角度看,这是为了限制"信息传播环路"带来的无限循环问题。
如果不设上限,假设一条路由在R1和R2之间互相通告、形成环路,metric就会不断增加:R1告诉你这条路由是5跳,R2告诉你是6跳,R1再告诉你是7跳……永远没有尽头,这就是"计数到无穷"(Count to Infinity)问题。RIP的解法很朴素:把16定为无穷大,一旦metric增长到16,就判定路由不可达,从路由表中删除。
这种设计带来两个后果:第一,网络规模被死死限制在15跳内,所以RIP天然与大规模网络无缘;第二,在没有额外防环机制的情况下,当一个真实链路断开后,路由信息还是会在环路上来回倒腾很多轮,直到metric增加到16才彻底消除,这个过程需要很长时间——往往是几十秒到几分钟,这就是"收敛慢"的根源之一。
2.3 四大防环机制,记住它们等于看透了RIP的一半
既然距离矢量协议天生有环路的毛病,RIP就得靠外部机制打补丁。这四个机制我在实际项目中都分别遇到过对应的坑,逐一说明:
水平分割(Split Horizon):从某个接口学习到的路由,不再从该接口回通告给同一个邻居。这个规则堵住了最常见的两人环形拓扑:A告诉B有一条路,B不会把这条路再原封不动告诉A。因为A本来就知道这条路,你再说回去没有意义,反而可能形成错误环路。
毒性逆转(Poison Reverse):直接在通告中包含"这条路不可达"的信息,把metric设为16,明确告诉邻居"这条路由已经死了,别往这个方向发了"。它比单纯不通告更有效,因为它消除了"一条路由突然消失后,邻居还在盲目依赖它"的时间窗口。
触发更新(Triggered Update):正常情况下RIP每30秒通告一次全部路由。触发更新则是当路由发生变化时,立即发送更新报文,不用等30秒周期。这个机制能显著缩短故障后的收敛时间,但它只能保证你尽快告诉邻居,真正完成全网收敛还要等所有路由器都收到并处理。
抑制计时器(Hold-down Timer):当某条路由的metric增加(或者变为16/从通告中消失),在180秒内,除非收到来自其他方向的、metric更小的更新,否则不轻易改变这条路由的状态。这个机制防止了"路由一下被标不可达、一下又恢复"的震荡,但也因此牺牲了收敛速度。
这四个机制叠加之后,RIP在小型网络里基本能保证:链路断了,最坏情况下几分钟内全网路由表稳定,不会无限循环下去。代价就是收敛慢,这是所有距离矢量协议的天性,不是bug,是设计取舍。
2.4 计时器和更新报文:30秒周期里的全部细节
RIP的更新方式很规律,由三个计时器支撑,这个名字叫"周期更新"的东西在实际排错中特别重要:
- 更新计时器(Update Timer):默认30秒,路由器每30秒向所有启用了RIP的接口发送完整路由表
- 失效计时器(Invalid Timer):默认180秒,如果180秒没有收到某个邻居的任何更新,就认为该邻居失效,把从它学到的路由标记为不可用
- 清除计时器(Flush Timer):默认240秒,在失效标记后继续等待60秒,到240秒时把这些路由从路由表彻底删除
看到这里就明白了:一台路由器掉电后,其他路由器最多等180秒能判定它失效,等到240秒才能彻底清理路由。这就是RIP收敛慢在每个具体数字上的体现。所以RIP的设计者后来推出了触发更新,试图减少这个等待窗口,但在真实网络中,触发更新报文不可靠(可能丢包),周期更新依然是保底手段。
3. 从RIPv1到RIPv2再到RIPng:二十多年协议演进的三个关键节点
3.1 RIPv1的往事:有类地址时代的老古董
RIPv1诞生于1980年代末,那时候IP地址还是标准的A/B/C类划分,没有VLSM(可变长子网掩码)、CIDR(无类域间路由)这些概念。RIPv1的通告报文里没有掩码字段,路由器只能根据IP地址的前缀位去猜这个网段的掩码。比如你看到一个10.0.0.0网段的通告,默认猜它是A类地址的标准掩码255.0.0.0。
这带来一个实际问题:如果你在RIPv1网络里划分了不标准的子网,比如把192.168.1.0/24又划分成两个/25,RIPv1是区分不出来的,它会把子网信息搞乱。此外,RIPv1使用广播地址255.255.255.255发送更新报文,所有同网段的设备都要接收和解析,既浪费带宽又效率低,在早期链路窄、设备性能弱的条件下还不算大问题,放到今天就是灾难。
所以RIPv1那套东西,现在基本只存在于教材里,实际设备配置时基本不会再用。但搞懂它有历史意义:你会明白为什么后来RIPv2要把VLSM支持和组播更新加进去。
3.2 RIPv2的升级:VLSM、认证和组播三大革新
RIPv2是1994年推出的修订版本,它解决了RIPv1几乎所有的硬伤。关键变化有三个:
第一,通告报文里显式携带子网掩码,支持VLSM和CIDR。你可以放心地在一个RIP网络中混合使用/24、/25、/30等不同掩码的子网,路由器不会再猜错。
第二,更新报文从全网广播改成组播发送,目标地址224.0.0.9。只有启用了RIP的设备会监听这个组播地址,其余设备不会被打扰,带宽消耗也明显下降。
第三,支持明文密码和MD5认证。在扩接外部网络时,你可以为RIP更新报文加认证,避免非信任设备注入伪造的路由信息。这个在真实网络里很重要——我之前就见过有人往测试网段里顺手接了一台配置了错误RIP的设备,结果全网路由表混乱。如果有认证,这种事根本不会发生。
RIPv2还支持将特定接口配置为被动接口(Passive Interface),只接收不发送更新,这对保护主机网段、减少广播风险非常有用。
3.3 RIPng:IPv6时代的路由信息协议
到了IPv6时代,RIP也推出了对应的新版本,叫RIPng(RIP Next Generation)。它基于RIPv2的逻辑,但为适应IPv6做了几个调整:
- 使用IPv6组播地址FF02::9发送更新,而不是224.0.0.9
- 通告内容是IPv6前缀和前缀长度
- 使用链路本地地址(Fe80::开头的地址)作为下一跳
- 端口从UDP 520变为UDP 521
RIPng本身使用场景很少,因为IPv6网络里大家更倾向于用OSPFv3或者静态路由。但在一些特定的低复杂度IPv6环境中,RIPng依然是一个不可忽视的备选。它的配置思路和RIPv2一脉相承,学会RIPv2之后,RIPng只是换个地址格式而已。
4. 手把手配置RIP:从拓扑搭建到命令验证的完整过程
4.1 一套适合动手练习的拓扑与地址规划
我先给出一套最常用的三路由器拓扑,方便跟着往下配。路由器分别叫R1、R2、R3,互联链路使用/30子网,回环地址用来模拟终端网段。
- R1:Loopback0为192.168.1.1/24,G0/0连接到R2的G0/0,网段10.0.12.0/30
- R2:Loopback0为192.168.2.1/24,G0/0连接R1为10.0.12.2/30,G0/1连接R3为10.0.23.0/30
- R3:Loopback0为192.168.3.1/24,G0/1连接R2为10.0.23.2/30
这个拓扑覆盖了三节点串行互联的场景,既能验证RIP的逐跳转发,也能在后面排错时模拟"一条链路断了,路由如何沿着另一条路径收敛"的典型问题。
4.2 Cisco IOS下的RIP配置命令与含义
以Cisco IOS为例,配置RIPv2的步骤如下:
R1(config)# router rip R1(config-router)# version 2 R1(config-router)# network 192.168.1.0 R1(config-router)# network 10.0.0.0 R1(config-router)# no auto-summary这里有个容易被新手忽略的重点:network命令后面跟的是"主类网络号"(classful network),不是精确的子网号。在Cisco IOS的RIP配置里,network 10.0.0.0的意思是"在所有属于10.0.0.0这个主类网络的接口上启用RIP"。R2上的network 10.0.0.0和network 192.168.2.0同理。
注意,这里不能用network 10.0.12.0 0.0.0.3这种带反掩码的写法,那是OSPF的语法。RIP的network命令不支持精确匹配子网,只接受分类网络。这个差异是我见过很多人配置失败的原因。
no auto-summary非常重要。RIPv2默认在通告路由到跨主类网络边界时会自动汇总成主类网络(比如把192.168.1.0/24汇总成192.168.1.0,这是RIPv1的行为)。在一些有连续子网的场景里,自动汇总会导致路由信息不精确,所以最好显式关闭。
R2和R3的配置完全同理,只需要把接口所在的主类网络都加进去。配置完成后,每个路由器上执行show ip route,能看到类似下面这样以R开头的路由条目:
R 192.168.3.0/24 [120/2] via 10.0.23.2, 00:00:17, GigabitEthernet0/1这个条目里的[120/2]是RIP的两个关键参数:120是管理距离(Administrative Distance),表示RIP路由的可信度;2是metric,表示到达192.168.3.0/24需要跳2跳。这个数字就是判断路径好坏的依据。
4.3 验证与排错三件套:show、debug和抓包
配置完有没有生效,不能只看配置,要用验证命令确认。我最常使用的三件套:
show ip protocols:查看RIP进程的运行状态,包括版本号、计时器数值、通告的网段、被动接口等show ip route rip:只显示RIP学习的路由条目,方便聚焦排查debug ip rip:实时打印RIP更新报文的收发过程
debug ip rip是最直观的,配置完RIP后你会看到这样的输出:
RIP: sending update to 224.0.0.9 via Ethernet0/0 RIP: build update entries network 192.168.1.0 metric 1 RIP: received update from 10.0.12.2 network 192.168.2.0 metric 1第一次看到这种输出时,你会切身体会到"路由器在周期性地通告路由"不是抽象概念,而是实打实发生的报文交互。验证完毕记得及时关闭debug(用undebug all),因为debug在真实设备上会大幅拉高CPU负载。
4.4 华为设备上的RIP配置对照
国内华为设备也用得很多,配置逻辑和思科一样,只是命令略有差异。我以华为AR系列为例给出对照:
[R1] rip 1 [R1-rip-1] version 2 [R1-rip-1] network 192.168.1.0 [R1-rip-1] network 10.0.0.0 [R1-rip-1] undo summary华为版的network命令可以写精确网段,用起来比思科的宽松一些。查看路由则用display ip routing-table或者display rip 1 route。
5. 我在生产环境里踩过的RIP坑:故障排查全链路复盘
5.1 案例一:启用RIP后,办公网PC突然无法访问服务器
有一次我给一个公司分支网络启用RIPv2替代静态路由后,业务方很快反馈部分PC无法访问内部服务器。我当时第一反应是RIP路由没学全,但一查路由表,每条路由都在,问题就显得很奇怪。
后来排查到接口层级,发现有问题的PC所在交换机上连了一台非RIP设备——那台设备的网关正好也在RIP通告的网段里。RIP的更新报文是组播的,交换机默认会把组播报文泛洪到同一VLAN的所有接口。那台非RIP设备收到更新后,虽然没有运行RIP协议,但它会对路由信息做处理(某些设备默认开启重定向ICMP),导致它错误地向客户端通告自己是一个可用的路由器。客户端一旦把默认网关指向这台"幽灵设备",流量就发到了错误的位置。
这个案例给我的教训是:启用动态路由前,必须先梳理整个二层广播域的成员。RIP更新报文虽然不再是广播,但组播在很多情况下也会被交换机泛洪到非成员端口。解决办法是启用被动接口(passive-interface),把所有连接终端的接口都设为只接收不发送,从源头避免终端网段收到RIP更新报文。
5.2 案例二:一条测试链路误接,全网路由表出现环路
第二次踩坑是更经典的"水平分割没挡住"的故事。当时我们网络里有一台测试路由器,同事为了调试方便,把它同时接入了两台上游路由器。这台测试设备上我忘记配置任何防环策略,默认RIP。
问题很快爆发:测试设备从上游R1学到一条到某业务网段的路由,又从上游R2学到同一网段的另一条路由,它把两条都收下,然后统一通告回去。R1接收到来自测试设备的更新后发现,咦,这条路由的metric怎么比我自己还大?按RIP逻辑,它不会替换自己原来的路由,但会记录下存在另一条路径。而R2那边也收到了测试设备发来的反向通告,误以为可以通过测试设备更短地到达业务网段,于是把路由替换成"下一跳指向测试设备"。
结果,业务流量在上游路由器和测试设备之间来回跳,TTL耗尽被丢弃,业务中断。解决方式分两步:先切断测试设备的接入,让全网路由表重新收敛;再在测试设备上添加出接口的ip rip poison-reverse策略,确保任何情况下都不会把"听来的路由"原样说回去。
这个案例让我深刻意识到:所有防环机制都只是概率性防护,不是绝对隔离。只要网络里出现"额外连接"(例如两台路由器之间有多条物理链路,但只配了一个RIP进程),环路就有可乘之机。这也是后来很多工程师在核心网络拒绝RIP的原因——收敛慢容忍不了,协议本身的脆弱性更无法接受。
5.3 案例三:RIPv1和RIPv2混跑导致部分路由静默丢失
还有一次遇到的是版本兼容问题。一个分支网络的旧设备只支持RIPv1,新加入的设备默认开了RIPv2。RIPv1用广播发送更新,RIPv2用组播发送更新,两者互相听不懂。
从现象上看,就是部分网段的路由时有时无,非常零散。排查时我打开show ip route rip,发现缺少几条远端分支路由,同时在RIP配置模式里改了版本后,路由表立刻补齐了。RIPv2路由器能处理RIPv1的广播报文(兼容模式),但RIPv1路由器完全收不到RIPv2的组播报文。解决方案很简单:要么全网统一用RIPv2(推荐),要么在Cisco设备上用ip rip v1-compatible让RIPv2同时使用广播发送。不过后者只是在过渡期临时方案,长期混跑始终是隐患。
5.4 案例四:30秒更新报文的带宽与CPU代价
最后想谈谈RIP更新的资源开销。很多人觉得RIP那么"轻量",肯定不耗资源。但在一个路由条目很多(几百条)的网络里,每30秒就要把整张路由表广播给所有邻居一次,这个开销会集中体现在设备CPU和链路带宽上。
我曾在业务高峰期观察过,一台低端路由器在收到几百条RIP更新时,CPU利用率会冲到60%以上,而同期同链路的OSPF设备CPU负载几乎可以忽略。RIP的更新机制是"全量路由表周期发送",不像OSPF那样只有链路状态变化时才发送增量LSA。所以对性能敏感的场景,RIP并不是一个真正的轻量协议——它在路由量小的时候轻量,路由量一大就开始笨重。
后来我用的方案是,把RIP的更新计时器调大,比如从30秒调整到90秒:timers basic 90 180 300 300。但这里有个代价——收敛时间也会相应变长,因此只适合那些对网络变化不敏感的业务网段,核心链路绝不能这样干。
6. RIP和OSPF、EIGRP到底怎么选:一张表看清楚各自的适用边界
6.1 三种协议的核心差异对照
只要讨论动态路由,RIP几乎必然要和OSPF、EIGRP拉出来对比。我把实际使用中最关键的几个维度列成了一张表:
| 对比维度 | RIP | OSPF | EIGRP |
|---|---|---|---|
| 算法类型 | 距离矢量 | 链路状态 | 高级距离矢量 |
| 度量标准 | 跳数(15跳上限) | 带宽+延迟(Cost) | 复合度量(带宽+延迟+负载+可靠性) |
| 收敛速度 | 慢(秒级到分钟级) | 快(秒级) | 快(秒级) |
| 网络规模 | 小(直径≤15) | 大(支持区域划分) | 中到大 |
| 更新方式 | 周期全量更新 | 事件触发增量更新 | 事件触发增量更新 |
| 厂家兼容性 | 全兼容 | 开放标准,全兼容 | CISCO私有 |
| 配置复杂度 | 极低 | 较高(区域、邻居) | 中 |
从这张表能看出,RIP唯一真正占优的是配置简单和全兼容,其他方面几乎都是短板。OSPF是大型网络的默认选择,EIGRP在纯思科环境里表现很出色,但非思科设备不支持,生态受限。
6.2 什么场景下我应该认真考虑用RIP
尽管选型上有那么多更强的替代品,我在下面几种场景里依然会认真用RIP:
- 小规模分支网络:整网不超过10台路由器,网段数少。RIP的简单性会成为最大优势,配置和维护成本远低于OSPF
- 老旧设备兼容:某些老型号路由器可能不支持OSPF的完整功能,但RIP一定支持
- 学习和培训:作为距离矢量协议的入门模板,RIP是最容易理解、最容易观察行为的协议
- 临时网络快速搭建:比如展会网络、临时项目组网络,需要快速互通,RIP配置一次即可自动发现,比逐条配静态路由省时间
6.3 什么场景千万不要用RIP
反过来,我在下面这几种场景中毫不犹豫地排除RIP:
- 核心骨干网或数据中心网络:收敛慢、跳数限制、更新开销这几个短板都是致命的
- 任何要求秒级切换的语音、视频业务承载网:链路断开后RIP需要几十秒以上才能恢复转发,通话和视频会直接中断
- 超过15跳的广域网:RIP会在设计上直接拒绝传递远端路由
- 有严格安全性要求的网络:RIP报文的认证机制虽然有,但在实际自动化操作中极易被绕过,整体安全性不如OSPF的区域隔离设计
6.4 一个折中思路:静态路由+RIP混合使用
在实际项目里,我经常用"静态路由+RIP"的混合模式。比如总部核心网段之间用静态路由或OSPF保证稳定,接入分支的网段启用RIP自动学习,避免每条分支链路变动都要手工改总部路由。
这个模式的好处是:RIP管理的范围小,路由条目少,即使触发更新频繁也不会影响全网稳定性;同时分支设备的配置极简——两条network命令即可。坏处是RIP的快收敛加分优势在被限制的范围里才能发挥得够好,任何超出范围的网段增长都必须提前规划。
7. 关于RIP,我最后想分享的几句实在话
如果你问我,学了RIP到底值不值,我会说看目的。如果是为了CCNA考试、为了理解动态路由的底层逻辑、为了应对老旧设备,RIP必须吃透。如果是为了搭一个生产网络上最稳定的路由体系,RIP大概率不会是我的首选,但它仍然是一块很好的"试金石"——它帮你理解所有动态路由协议共有的问题,比如环路、收敛、度量、防环,这些底层逻辑在OSPF和BGP里依然存在,只是被更复杂的机制包装起来了。
我建议每一个网络工程师都亲手配一遍RIP,看一遍debug ip rip的输出,再亲手制造一次人为环路观察它是如何恢复的。这个过程比背一万道选择题都管用——因为你真的理解了路由协议是怎么工作的,之后再看OSPF的区域、BGP的AS路径,都会有豁然开朗的感觉。
最后留一个实操小技巧:无论是在思科还是华为设备上,配置RIP时别忘了把连接终端的接口设置为被动接口。一个接口发送RIP更新报文,看似无伤大雅,但在VLAN泛洪的场景下,它可能把一个本不该参与路由的设备卷进来,到时候排错排到怀疑人生。先把这个习惯养成,RIP的坑就已经绕开了一大半。