20.7 因特网缓存协议
ICP(因特网缓存协议)允许缓存在其兄弟缓存中查找命中内容。如果某个缓存中没有 HTTP 报文所请求的内容,它可以查明内容是否在附近的兄弟缓存中,如果在,就从那里获取内容,以避免查询原始服务器而带来的更多开销。可以把 ICP 当作一个缓存集群协议。HTTP 请求报文的最终目的地可以通过一系列的 ICP 查询确定,从这个角度来说,它就是一个重定向协议。
ICP 是一个对象发现协议。它会同时去询问附近的多个缓存,看看它们的缓存中是否有特定的 URL。附近的缓存如果有那个 URL 的话,就会返回一个简短的报文 HIT,如果没有,就返回 MISS。然后,缓存就可以打开一条到拥有此对象的邻居缓存的 HTTP 连接了。
ICP 是很简单直接的。ICP 报文是一个以网络字节序表示的 32 位封装结构,这样更便于进行解析。为了提高效率,可以由 UDP 数据报承载其报文。UDP 是一种不可靠的因特网协议,说明在传输的过程中数据可能会被破坏,因此使用 ICP 的程序要具有超时功能,以检测丢失的数据报。
下面简要描述一下 ICP 报文中的部分信息。
Opcode(操作码)
Opcode 是个 8 位的二进制值,用以描述 ICP 报文的含义。基本的 opcode 包括 ICP_OP_QUERY 请求报文和 ICP_OP_HIT 和 ICP_OP_MISS 响应报文。
版本
8 位的版本号描述了 ICP 协议的版本编号。Squid 使用的 ICP 版本记录在 RFC 2186 第 2 版中。
报文长度
以字节为单位的 ICP 报文总长。因为只有 16 位,所以 ICP 报文的长度不能超过 16 383 字节。URL 通常都小于 16 KB,如果超过这个长度,很多 Web 应用程序就无法处理它了。
请求编号
支持 ICP 的缓存会用请求编号来记录多个同时发起的请求和响应。ICP 应答报文数必须与触发应答的 ICP 请求报文数相同。
选项
32 位的 ICP 选项字段是个包含了若干标记的位矢量,这些标记可用来修改 ICP 的行为。ICPv2 定义了两个标记,这两个标记都会修改 ICP_OP_QUERY 请求。ICP_FLAG_HIT_OBJ 标记用来启动或禁止在 ICP 响应中返回文档数据。ICP_FLAG_SRC_RTT 标记请求由兄弟缓存测量的、到原始服务器的环回时间的估计值。
可选数据
保留了 32 位的可选数据用于可选特性。ICPv2 使用了可选数据的低 16 位来装载从兄弟缓存到原始服务器的可选环回时间的估计值。
发送端主机地址
承载了报文发送端 32 位 IP 地址的著名字段。实际中并未使用。
净荷
净荷内容的变化取决于报文的类型。对 ICP_OP_QUERY 来说,净荷是一个 4 字节的原始请求端主机地址,后面跟着一个由 NUL 结尾的URL。对 ICP_OP_HIT_OBJ 来说,净荷是一个由 NUL 结尾的URL,后面跟着一个 16 位的对象长度,接着是对象数据。
更多有关 ICP 的信息,请参见 RFC 2186 和 RFC 2187。从美国应用网络研究国家实验室的网站上(http://www.nlanr.net/Squid/)也可以获得一些很棒的有关 ICP 和对等实体的参考文献。

