同一个网址,末尾多一个斜杠,或者路径里多写一层点段,经过代理转发之后拿到的东西会不一样吗?多数时候看不出区别。但只要业务里做过按地址匹配的规则,或者用地址当作缓存的键,这种细小的写法差异就会慢慢浮出来。
一个完整的地址可以拆成协议、主机、端口和路径几段。协议与主机名的大小写一般会被统一成小写;端口如果正好是协议的默认值,多数实现会把它省掉;路径里的相对段和重复斜杠会被解析掉;非 ASCII 字符和特殊符号会转成百分号编码。这几步合在一起,就是常说的地址规范化。
麻烦的地方在于两端改写得不一样。
- 协议与主机
- 统一成小写,端口为默认值时省略
- 路径点段
- 解析相对段,合并重复斜杠
- 百分号编码
- 特殊字符转义,编码大小写也会被统一
规则不一致时会看到什么
常见的有两种表现。一种是缓存命中率莫名偏低,同一张图片反复回源,翻日志才发现每次请求的地址写法都有一点出入,程序按字符串比对,认不出是同一个。另一种是按地址做的白名单偶尔放行失败,人工复核时又看不出毛病,因为人眼看到的地址和程序比对用的地址根本不是同一种写法。这两种都跟IP质量无关,问题出在口径上。
规范化本身不改变资源,改变的是匹配结果。排查这类问题时,先确认代理侧是原样透传还是做过改写,再确认本地拿地址做匹配的地方吃的是哪一种形式。两头问清楚,通常比反复测速有用得多。
让两端看到同一种写法
做法不复杂。先把业务里所有会拿地址做匹配的地方列出来,包括鉴权、缓存、日志归集和统计,确认它们用的是规范化前还是规范化后的形式。如果代理侧不可控,就在本地统一做一次规范化再入库,让内外两侧比对的是同一种字符串。这一步做完,之前那些解释不了的现象常常自己就消失了。
哪些部分其实不会被改
路径的大小写通常不会被改动,多数服务器把路径当成大小写敏感的字符串。真正容易被统一的是协议名和主机名这两段,偶尔还包括默认端口。把范围记准,才不会在排查时把注意力放到错误的位置上。
把规范化这件事提前对齐,代理IP转发链路里的缓存、鉴权和日志对账都能省下不少来回核对的功夫。
