Squid Web Cache Wiki

Squid Web Cache 文档

🔗 操作 Squid

🔗 如何查看系统级别的 Squid 统计信息?

Squid 分发版包含一个名为 cachemgr.cgi 的 CGI 工具,您可以使用 Web 浏览器查看 Squid 统计信息。有关其用法和安装的更多信息,请参阅 CacheManager

🔗 如何让 Squid 不缓存某些服务器或 URL?

您可以使用 cache 选项来指定不可缓存的请求以及对您可缓存规则的任何例外。

例如,这使得来自 10.0.1.0/24 网络中源服务器的所有响应都不可缓存

acl localnet dst 10.0.1.0/24
cache deny localnet

此示例使所有带有“.html”的 URL 都不可缓存

acl HTML url_regex .html$
cache deny HTML

此示例使特定 URL 不可缓存

acl XYZZY url_regex ^http://www.i.suck.com/foo.html$
cache deny XYZZY

此示例在早上 8 点到 11 点之间不缓存任何内容

acl Morning time 08:00-11:00
cache deny Morning

🔗 如何从我的缓存中清除一个对象?

除非在 squid.conf 中配置了访问控制,否则 Squid 不允许您清除对象。首先,您必须添加类似以下的内容:

acl PURGE method PURGE
acl localhost src 127.0.0.1
http_access allow PURGE localhost
http_access deny PURGE

上面的内容仅允许来自本地主机的清除请求,并拒绝所有其他清除请求。

要清除一个对象,您可以使用 squidclient 程序。

squidclient -m PURGE http://www.miscreant.com/

如果清除成功,您将看到“200 OK”响应。

HTTP/1.0 200 OK
Date: Thu, 17 Jul 1997 16:03:32 GMT
...

有时,如果缓存中未找到该对象,您将看到“404 Not Found”响应。

HTTP/1.0 404 Not Found
Date: Thu, 17 Jul 1997 16:03:22 GMT
...

此类 404 不是故障。它仅仅意味着该对象已被其他方式清除或从未存在过。因此,您想要的结果(对象不再存在于缓存中)已经实现。

🔗 如何从我的缓存中清除多个对象?

不可能;您必须按 URL 逐个清除对象。这是因为 Squid 不会在内存中保留它存储的每个对象的 URL,而只保留其紧凑的表示形式(一个哈希)。给定 URL 找到哈希很容易,反之则不可能。

很遗憾,目前不支持通过通配符、域名、时间段等方式进行清除。

🔗 如何找到我缓存中最大的对象?

sort -r -n +4 -5 access.log | awk '{print $5, $7}' | head -25

这可能需要一段时间,取决于您的缓存有多忙。

🔗 如何添加缓存目录?

  1. 编辑 squid.conf 并添加一个新的 cache_dir 行。
  2. 关闭 Squid squid -k shutdown
  3. 通过运行 squid -z 初始化新目录
  4. 重新启动 Squid

🔗 如何删除缓存目录?

:information_source: 如果您的 squid.conf 中没有任何 cache_dir 行,那么 Squid 使用的是默认设置。从 Squid-3.1 开始,默认已更改为仅内存缓存,不涉及 cache_dir。

  1. 编辑您的 squid.conf 文件,注释掉或删除您想删除的缓存目录的 cache_dir 行。
  2. 您无法从正在运行的 Squid 进程中删除缓存目录;您不能简单地重新配置 squid。
  3. 您必须关闭 Squid: squid -k shutdown
  4. 一旦 Squid 退出,您可以立即重新启动它。

由于您从 squid.conf 中删除了旧的 cache_dir,Squid 将不会尝试访问该目录。如果您使用 RunCache 脚本,Squid 应该会自动重新启动。

现在 Squid 不再使用您从配置文件中删除的缓存目录。您可以通过缓存管理器检查“Store Directory”信息来验证这一点。在命令行中,键入:

squidclient mgr:storedir

🔗 我想用干净的缓存重新启动 Squid

Squid-2.6 及更高版本包含机制,可以自动检测缓存目录和 swap.state 文件中的“脏”信息。当 squid 启动时,它会运行这些验证和安全检查。任何因任何原因失败的对象都将从缓存中自动清除。

可以通过在重新启动之前关闭 Squid 并删除每个 cache_dir 中的 swap.state 日志文件来手动触发上述机制,以强制 squid 进行完整的 cache_dir 扫描并从磁盘重新加载所有对象。

:information_source: 在关闭之前删除 swap.state 将导致 Squid 生成新的 swap.state 文件,并且无法执行您想要的重新扫描。

🔗 我想用空的缓存重新启动 Squid

要擦除缓存的全部内容并让 Squid 重新开始,以下命令可提供最快的恢复时间:

squid -k shutdown
mv /dir/cache /dir/cache.old

对您希望清空的每个 cache_dir 位置重复此操作。

squid -z
squid
rm -rf /dir/cache.old

rm 命令可能需要一些时间,但由于 Squid 已经重新启动并运行,服务停机时间已缩短。

🔗 使用 ICMP 测量网络延迟

Squid 能够利用 ICMP 往返时间 (RTT) 测量来选择将缓存未命中转发到最佳位置。以前,缓存未命中会转发到返回第一个 ICP 回复消息的父缓存。这些在 access.log 文件中被记录为 FIRST_PARENT_MISS。现在我们可以选择 RTT(与源服务器之间)最近的父级。

🔗 在您的 Squid 缓存中支持 ICMP

您的父缓存启用 ICMP 功能更为重要。如果您充当父级,您可能希望在缓存中启用 ICMP。此外,如果您的缓存测量 RTT,它将直接获取对象,如果您的缓存比任何父级都近。

如果您希望您的 Squid 缓存测量到源服务器的 RTT,Squid 必须使用 USE_ICMP 选项进行编译。这可以通过取消注释 src/Makefile 和/或 src/Makefile.in 中的“-DUSE_ICMP=1”来轻松完成。

一个名为 pinger 的外部程序负责发送和接收 ICMP 数据包。它必须以 root 权限运行。Squid 编译完成后,必须单独安装 pinger 程序。一个特殊的 Makefile 目标将以适当的权限安装 pinger

% make install
% su
# make install-pinger

有三个配置选项可用于调整缓存中的测量数据库。netdb_lownetdb_high 指定了将数据库保持在特定大小的高低水位线(例如,就像 IP 缓存一样)。netdb_ttl 选项指定了 ping 一个站点的最小速率。如果 netdb_ttl 设置为 300 秒(5 分钟),则不会在五分钟内向同一个站点发送两次 ICMP 数据包。请注意,一个站点仅在收到对该站点的 HTTP 请求时才会被 ping。

另一个选项 minimum_direct_hops 可用于尝试查找靠近您的缓存的服务器。如果到源服务器的测量跳数小于或等于 minimum_direct_hops,则请求将直接转发到源服务器。

🔗 利用您的父级数据库

您可以要求您的父级缓存在其 ICP 回复中包含 RTT 测量。为此,您必须在配置文件中启用 query_icmp

query_icmp on

这会在您的传出 ICP 查询中设置一个标志。

如果您的父级缓存返回 ICMP RTT 测量,则您的 access.log 的第八列将包含类似以下内容的行:

CLOSEST_PARENT_MISS/it.cache.nlanr.net

在这种情况下,这意味着 it.cache.nlanr.net 返回到源服务器的 RTT 最低。如果您的缓存测量的 RTT 低于任何父级,则请求将记录为:

CLOSEST_DIRECT/www.sample.com

🔗 检查数据库

可以通过选择“Network Probe Database”从 cachemgr 中查看测量数据库。主机名被聚合到 /24 网络中。所有进行的测量都经过平均。测量是针对特定主机的,这些主机来自 HTTP 请求的 URL。recv 和 sent 字段是发送和接收的 ICMP 数据包的数量。目前它们仅供参考。

典型的数据库条目如下所示:

    Network          recv/sent     RTT  Hops Hostnames
    192.41.10.0        20/  21    82.3   6.0 www.jisedu.org www.dozo.com
bo.cache.nlanr.net        42.0   7.0
uc.cache.nlanr.net        48.0  10.0
pb.cache.nlanr.net        55.0  10.0
it.cache.nlanr.net       185.0  13.0

这意味着我们已经向 www.jisedu.org 和 www.dozo.com 发送了 21 次 ping。平均 RTT 为 82.3 毫秒。接下来的四行显示了来自我们的父级缓存的测量值。由于 bo.cache.nlanr.net 的 RTT 最低,因此它将被选为转发 www.jisedu.org 或 www.dozo.com URL 请求的位置。

🔗 为什么很少有请求被记录为 TCP_IMS_MISS?

当 Squid 收到 If-Modified-Since 请求时,除非根据 refresh_pattern 规则需要刷新对象,否则它不会转发该请求。如果确实需要刷新请求,则会将其记录为 TCP_REFRESH_HIT 或 TCP_REFRESH_MISS。

如果未转发请求,Squid 会根据其缓存中的对象回复 IMS 请求。如果修改时间相同,则 Squid 返回 TCP_IMS_HIT。如果修改时间不同,则 Squid 返回 TCP_IMS_MISS。在大多数情况下,缓存的对象不会改变,因此结果是 TCP_IMS_HIT。只有当其他客户端导致更新版本对象被拉入缓存时,Squid 才会返回 TCP_IMS_MISS。

🔗 为什么我需要以 root 身份运行 Squid?为什么我不能只使用 cache_effective_user root?

| | 对于许多提供网络服务的应用程序来说,这完全正常,是的,这是最佳实践。事实上,有些甚至**不允许**您以 root 身份运行它们,而是需要一个非特权用户来运行主进程。这适用于所有不需要 root 状态的程序,而不仅仅是 squid。

原因很简单:

  1. 在启动应用程序时,您需要 root 权限来执行某些操作,例如绑定到网络套接字、打开日志文件、可能读取配置文件等,因此它以 root 身份启动。
  2. 任何应用程序都可能包含导致安全漏洞的错误,这些错误可以通过网络连接被远程利用,并且在错误被修复之前,您至少希望将它们带来的风险降到最低。
  3. 因此,一旦您完成了上面第一步中的所有操作,您就会降低应用程序的权限级别,和/或生成一个权限降低的子进程,这样它仍然可以运行并执行您需要的所有操作,但如果发生漏洞被利用,它就不再拥有 root 权限,因此造成的损害可能没有那么大。

Squid 通过 cache_effective_user 来实现这一点。协调器(守护进程管理器)进程必须以“root”身份运行,以便设置管理详细信息,并在运行任何更具风险的网络操作之前将其权限降低到 cache_effective_user 帐户。

如果配置了 cache_effective_group,Squid 将会放弃额外的组权限,并仅以指定的用户名:组名运行。

-N 命令行选项使 Squid 在不生成用于安全网络的低权限子进程的情况下运行。使用此选项时,Squid 主进程会将其权限降低到 cache_effective_user 帐户,但会尝试保留一些重新配置以恢复 root 权限的方法。一些依赖于更危险的 root 权限的组件将无法仅通过重新配置进行更改,而需要完全重新启动。

🔗 能告诉我一种最小化停机时间的 Squid 升级好方法吗?

这是一种由 Radu Greab 描述的技术。

在一个未使用的 HTTP 端口(例如 4128)上启动第二个 Squid 服务器。这个 Squid 实例可能不需要很大的磁盘缓存。当第二个服务器完成磁盘存储的重新加载后,交换两个 squid.conf 文件中的 http_port 值。将原始 Squid 设置为使用端口 5128,将第二个设置为使用 3128。接下来,为两个 Squid 运行“squid -k reconfigure”。新请求将转到第二个 Squid(现在是 3128 端口),而第一个 Squid 将继续处理其当前请求。几分钟后,就可以安全地完全关闭第一个 Squid 并进行升级。稍后,您可以简单地按相反的顺序重复此过程。

🔗 Squid 能监听多个 HTTP 端口吗?

是的,您可以在 squid.conf 文件中指定多个 http_port 行。Squid 会尝试绑定到您指定的每个端口。有时 Squid 可能无法绑定到某个端口,原因可能是权限问题或端口已被占用。如果 Squid 至少能绑定到一个端口,它就会继续运行。如果它无法绑定到任何端口,Squid 就会停止。

您可以同时指定 IP 地址和端口号(请参阅 squid.conf 注释)。

🔗 通过 Squid 时,我能让源服务器看到客户端的 IP 地址吗?

通常不能。大多数 TCP/IP 堆栈不允许应用程序使用本地端点分配为外部 IP 地址来创建套接字。Linux 在某些情况下允许这样做

在这种情况下,您必须确保所有发送到客户端 IP 地址的 HTTP 数据包都被路由到 Squid 服务器。如果数据包走了另一条路径,真实客户端将向源服务器发送 TCP 重置,从而破坏连接。

回到 FAQ 索引

导航: 网站搜索网站页面分类🔼 向上