🔗 Squid 组件概述
Squid 由以下主要组件组成
🔗 客户端套接字
此处接受、解析新的客户端连接,并发送回复数据。每个连接的状态信息保存在一个名为 ConnStateData 的数据结构中。每个请求的状态信息存储在 clientSocketContext 结构中。对于 HTTP/1.1,我们可能在一个 TCP 连接上有多个请求。
🔗 客户端请求
此处处理请求。我们确定请求是否需要重定向,是否通过访问列表,以及为内部请求设置初始客户端流。此处理的临时状态保存在 clientRequestContext 结构中。
🔗 客户端回复
此处我们确定请求是缓存命中 (HIT)、刷新 (REFRESH)、未命中 (MISS) 等。这涉及(可能多次)查询存储,以处理 Vary 列表和该列表。每个请求的状态信息存储在 clientReplyContext 结构中。
🔗 Client Streams
这些例程实现了一个单向、非阻塞的拉取管道。它们允许在需要时将代码插入回复逻辑。例如,传输编码逻辑仅在发送 HTTP/1.1 回复时才需要。
🔗 服务器端
这些例程负责根据协议将缓存未命中转发到其他服务器。缓存未命中可能会转发到源服务器或其他代理缓存。请注意,所有(FTP、Gopher)请求到其他代理都会作为 HTTP 请求发送。 gopher.c 有点复杂和混乱,因为它必须将 Gopher 协议转换为 HTTP。 Wais 和 Gopher 并没有得到太多关注,因为它们在互联网流量中所占比例相对较小。
🔗 存储管理器
存储管理器是客户端和服务器端之间的粘合剂。缓存中保存的每个对象都会分配一个 StoreEntry 结构。在访问对象时,它还有一个 MemObject 结构。
Squid 可以快速定位缓存的对象,因为它(在内存中)保留了所有 StoreEntry 的哈希表。哈希表的键是对象 URI 的 MD5 校验和。此外,还有像 LRU 这样的存储策略,它跟踪对象并确定在需要回收空间时移除的顺序。对于 LRU 策略,它实现为一个双向链表。
对于每个对象,StoreEntry 通过 sdirn 和 sfilen 映射到 cache_dir 和位置。对于“ufs”存储,该文件号 (sfilen) 通过 L2 和 L1 的简单模运算转换为磁盘路径名,但其他存储驱动程序可能会以其他方式映射 sfilen。缓存交换文件由两部分组成:缓存元数据和对象数据。请注意,对象数据包括完整的 HTTP 回复——头部和正文。HTTP 回复头部与缓存元数据不同。
客户端请求向 StoreEntry 注册,以便在数据到达时收到通知。多个客户端可以通过单个 StoreEntry 接收数据。对于 POST 和 PUT 请求,此过程反向工作。服务器端函数在从客户端读取更多数据时收到通知。
🔗 请求转发
🔗 对等选择
这些函数负责选择一个(或零个)邻居缓存作为适当的转发位置。
🔗 访问控制
这些函数负责根据许多不同参数允许或拒绝请求。这些参数包括客户端的 IP 地址、请求资源的域名、请求方法等。某些必要信息可能无法立即获得,例如源服务器的 IP 地址。在这些情况下,ACL 例程会发起查找必要信息的查找,并在信息可用时继续访问控制检查。
🔗 身份验证框架
这些函数负责处理 HTTP 身份验证。它们遵循一个模块化框架,允许随时添加不同的身份验证方案。有关使用身份验证方案的信息,请参阅“身份验证框架”章节。
🔗 网络通信
这些是用于通过 TCP 和 UDP 网络套接字进行通信的例程。在此处打开、关闭、读取和写入套接字。此外,请注意 Squid 的核心(comm_select() 或 comm_poll())存在于此处,即使它处理所有文件描述符,而不仅仅是网络套接字。这些例程不支持为写入排队多个数据块。因此,每次写入请求都会发生一个回调。
🔗 文件/磁盘 I/O
用于读取和写入磁盘文件(和 FIFO)的例程。将网络和磁盘 I/O 函数分开部分是历史原因,部分是由于行为不同。例如,我们不担心网络套接字会收到“设备空间不足”错误。磁盘 I/O 例程支持为写入排队多个数据块。在某些情况下,可以将多个数据块合并为一个写入请求。写入回调不一定每次写入请求都会发生。
🔗 邻居
维护邻居缓存的列表。发送和接收与邻居的 ICP 消息。决定给定请求应查询哪些邻居。文件:neighbors.c。
🔗 IP/FQDN 缓存
名称到地址和地址到名称查找的缓存。这些是基于名称和地址的哈希表。 ipcache_nbgethostbyname() 和 fqdncache_nbgethostbyaddr() 实现非阻塞查找。文件:ipcache.c,fqdncache.c。
🔗 缓存管理器
这提供了缓存管理员所需的某些信息的访问权限。一个配套程序,
cachemgr.cgi
可用于通过 Web 浏览器提供此信息。到 Squid 的缓存管理器请求使用以下形式的特殊 URL 进行
cache_object://hostname/operation
缓存管理器提供基本是只读的
信息访问。它不提供在运行时配置 Squid 的方法。
🔗 网络测量数据库
在许多情况下,Squid 发现了解其与源服务器之间的估计网络往返时间 (RTT) 非常有用。一个特别有用的例子是同级选择算法。通过进行 RTT 测量,Squid 缓存将知道它或它的一个邻居离给定源服务器最近。实际测量是使用下面描述的 pinger 程序进行的。测量值存储在按两个键索引的数据库中。主索引字段是源服务器 IP 地址的 /24 前缀。其次,一个完全限定主机名的哈希表具有指向适当网络条目的数据结构的链接。这允许 Squid 在给定 IP 地址或主机名时快速查找测量值。 /24 前缀聚合用于减小数据库的整体大小。文件:net_db.c。
🔗 自治系统编号
Squid 支持将自治系统 (AS) 编号作为另一个访问控制元素。 asn.c 中的例程查询将 AS 编号映射到 CIDR 前缀列表的数据库。这些结果存储在一个基数树中,该树允许快速搜索给定 IP 地址的 AS 编号。
🔗 配置文件解析
主配置文件规范在 cf.data.pre 文件中。一个简单的实用程序 cf_gen 读取 cf.data.pre 文件并生成 cf_parser.c 和 squid.conf。 cf_parser.c 在编译时直接包含到 cache_cf.c 中。
🔗 回调数据分配器
Squid 大量使用回调函数,这使其非常容易出现内存访问错误。必须小心确保 callback_data 内存在使用回调函数时仍然有效。 cbdata.c 中的例程提供了一种统一的方法来管理回调数据内存、取消回调以及防止错误的内存访问。
🔗 调试
Squid 包含 extensive 的调试语句,以帮助跟踪 bug 和异常行为。每个调试语句都被分配一个节和级别。通常,同一源文件中的每个调试语句具有相同的节。级别的选择取决于生成的输出量或提供的信息的有用性。配置文件中的 debug_options 行决定显示哪些调试语句,哪些不显示。 debug_options 行为每个节分配一个最大级别。如果给定的调试语句的级别小于或等于该节配置的级别,则会显示它。这个描述可能听起来比实际复杂。文件:debug.c。请注意,debug() 本身是一个宏。
🔗 错误生成
errorpage.c 中的例程根据模板文件和特定请求参数生成错误消息。这允许自定义错误消息和多语言支持。
🔗 事件队列
event.c 中的例程维护一个链表事件队列,用于在未来执行的函数。事件队列用于周期性函数,例如执行缓存替换、清理交换目录,以及一次性函数,例如 ICP 查询超时。
🔗 文件描述符管理
在此我们跟踪使用的文件描述符数量,以及已从每个文件描述符读取或写入的字节数。
🔗 HTTP 匿名化
这些例程支持对离开缓存的 HTTP 请求进行匿名化。可以移除特定的请求头部(标准模式),或者只允许特定的请求头部(“偏执”模式)。
🔗 延迟池
延迟池通过限制 squid 从服务器读取数据然后再发送到客户端的速率来提供带宽调节。它们不会阻止缓存命中以最大容量发送。延迟池可以聚合来自多台机器和用户的带宽,以提供或多或少的通用限制。
🔗 Internet Cache Protocol
在此我们实现 Internet Cache Protocol。该协议记录在 RFC 2186 和 RFC 2187 中。大部分代码在 icp_v2.c 文件中。另一个 icp_v3.c 是一个用于处理来自 Netcache/Netapp 缓存的 ICP 查询的函数;它们使用不同的版本号和略有不同的消息格式。
🔗 Ident 查询
这些例程支持 RFC 931 Ident查询。在主机上运行的 ident 服务器将报告与已连接 TCP 套接字关联的用户名。一些站点使用此功能进行访问控制和日志记录。
🔗 内存管理
这些例程为常用数据结构分配和管理内存池。当
memory_pools
配置选项启用时,未使用的内存实际上不会被释放。而是将其保留供将来使用。这可能以更大的进程大小为代价,从而更有效地利用内存。
🔗 多播支持
目前,多播仅用于 ICP 查询。此文件中的例程实现了将 UDP 套接字加入多播组(或组),并在传出数据包上设置多播 TTL 值。
🔗 持久服务器连接
这些例程管理与源服务器和邻居缓存的空闲、持久 HTTP 连接。空闲套接字按其套接字地址(IP 地址和端口号)在哈希表中索引。每个套接字地址最多保留 10 个空闲套接字,但仅保留 15 秒。 15 秒后,空闲套接字连接将关闭。
🔗 刷新规则
这些例程根据
refresh_pattern
配置选项决定缓存对象是过时还是新鲜。如果对象是新鲜的,则可以将其作为缓存命中返回。如果它已过时,则必须使用 If-Modified-Since 请求对其进行重新验证。
🔗 SNMP 支持
这些例程为 Squid 实现 SNMP。目前,我们已通过 SNMP 提供了几乎所有的 cachemgr 信息。
🔗 URN 支持
我们正在尝试在 Squid 版本 1.2 中支持 URN。请注意,我们这里说的不是功能齐全的通用 URN。这主要针对使用 URN 作为处理镜像站点列表的智能方法。有关更多详细信息,请参阅 Squid 中的 URN 支持。
🔗 ESI
ESI 是 Edge Side Includes 的实现。 ESI 实现为一个客户端流以及对 client_side_reply.c 的小修改,以检查是否应将 ESI 插入到回复流中。
导航:网站搜索,网站页面,分类,🔼 向上