1. 项目背景:为什么需要部署Squid代理缓存服务
做运维和网络这块的朋友,迟早会碰上一个需求:内网服务器数量一多,重复下载变成常态。几十台机器每天拉同一个系统镜像、同一批依赖包、同一类安装文件,流量浪费不说,带宽被占满之后,真正关键的业务反而卡死。我自己是在一次大规模环境交付时被这个问题逼着去搞Squid的,那会儿连续三天带宽跑满,镜像下载平均耗时从原来的3分钟涨到20分钟,整个交付节奏全乱套了。后来用Squid做了一台缓存代理服务器,同样的镜像第二次请求直接命中本地缓存,下载耗时压回秒级,带宽占用直接降了一个数量级。
很多朋友一提Squid就只想到"代理"两个字,其实它的核心价值不只是转发流量,而是缓存和访问控制这两把刷子。作为老牌代理服务器,Squid从上世纪九十年代发展到现在,已经是非常成熟的HTTP/HTTPS缓存代理方案,在CDN边缘节点、企业办公网出口、数据中心的离线包分发场景里都有大量部署。它支持正向代理、反向代理和透明代理三种模式,可以按源IP、目标域名、URL路径、请求方法做细粒度控制,还能配合基础认证做身份审计。无论是帮研发团队加速依赖下载,还是替运维团队收敛内网资源的访问权限,Squid都是相当顺手的基础设施。
这篇文章我准备把一次完整的Squid部署过程从头捋一遍,覆盖架构选型、安装步骤、ACL配置、缓存调优、故障排查这几个关键环节。适合刚接触代理缓存的运维小白,也适合部署过但没吃透配置项的进阶读者。我尽量把每个配置背后的原理讲清楚,而不是甩一堆参数让你自己背。
2. 部署前的方案选型与整体设计
动手安装之前,先花十分钟想清楚两个问题:Squid在这套环境里扮演什么角色?流量要怎么走?没有这一步,后面配置大概率会反复返工。
2.1 正向代理:最常用的缓存加速场景
正向代理是Squid最常见的用法,代理服务器部署在企业内网出口,内网设备把HTTP/HTTPS请求统一交给Squid,由它代为请求外部资源并缓存结果。下次有其他设备请求同样的资源,Squid直接把缓存内容返回给客户端,源站流量和带宽消耗全省了。
我在实际环境里最典型的应用就是内网软件源加速。研发团队几十台机器反复拉取同一个系统仓库的软件包、容器镜像、依赖库,命中缓存的请求根本不需要出网,速度直接从"等半天"变成"秒开"。这个模式下,客户端需要显式配置代理地址,比如浏览器设置、系统环境变量里的http_proxy/https_proxy,或者包管理工具的代理参数。
2.2 反向代理与透明代理:什么场景才会用到
反向代理模式下,Squid扮演的是服务端入口,外部客户端访问的是Squid地址,由Squid把请求转发给后端的真实服务器。这个模式适合做Web应用的访问入口收敛,可以把多个后端服务统一暴露在同一个端口下,还能顺便做请求头和响应头的修改。不过现在这个场景更多被Nginx接管了,Squid在这里的优先级不高,除非你手头环境比较老,或者需要同时复用Squid的缓存能力。
透明代理则比较特殊,它部署在网络链路上,客户端不用做任何配置,Squid通过iptables或者交换机策略把流量拦截下来再转发。好处是客户端无感知,坏处是调试复杂,而且对HTTPS流量的处理比较吃力。我的建议是:如果客户端可控,优先用正向代理;如果客户端不能动、只能从网络层拦截,才考虑透明代理,并且要提前评估好证书放行策略。
2.3 单机部署还是集群?先看规模再决定
Squid的部署架构没有那么玄乎。缓存量小、并发几百的场景,一台合理配置的虚拟机就能扛住;缓存量上TB级、并发几千以上,就要考虑多台Squid做分层或者哈希分流。第一次部署没必要一开始就铺集群,先把单机的配置、缓存策略、监控跑顺,再根据缓存命中率和磁盘IO数据决定要不要扩容。
资源规划上我给出一个参考基线:2核CPU、4GB内存、50GB以上磁盘足够支撑一个500人规模的办公网或者100台服务器的内网环境做缓存代理。磁盘是Squid最重要的资源,因为缓存全部落盘,建议用单独的SSD数据盘挂载缓存目录,不要跟系统盘混在一起,否则IO抢占会把整个机器拖垮。网络层面,Squid所在的主机需要能正常访问外网、能和内网客户端互通,防火墙放行代理端口即可。
3. 安装部署:从零跑起一台Squid服务
安装环节不复杂,但不同的Linux发行版、不同的安装方式,带来的目录结构和后续运维方式差别不小。我尽量把主流路径都列出来。
3.1 系统环境准备
我这边演示用的是Ubuntu 22.04 LTS,内核版本5.15,这套流程在Debian系和RedHat系上基本通用,差异点我会单独标注。系统装好后先做三件事:
- 更新软件源索引,确保能装到最新版本的Squid包。
- 检查系统时间和时区,日志审计依赖准确时间戳,时间错乱的排查过程非常痛苦。
- 关闭SELinux(RedHat系)或检查AppArmor(Ubuntu系),避免安全模块拦截Squid的磁盘写入和端口监听。
磁盘规划上,我单独挂载了一个数据盘到/data/squid_cache,格式化后修改/etc/fstab实现开机自动挂载,这一步不要省略,不然重启之后缓存目录可能变成空目录,Squid会报缓存目录无效的致命错误。
# 查看磁盘信息 sudo fdisk -l # 格式化新数据盘(以 /dev/sdb 为例,请根据实际盘符调整) sudo mkfs.ext4 /dev/sdb # 创建缓存目录并挂载 sudo mkdir -p /data/squid_cache sudo mount /dev/sdb /data/squid_cache # 写入开机自动挂载 echo '/dev/sdb /data/squid_cache ext4 defaults 0 0' | sudo tee -a /etc/fstab3.2 安装Squid:两条路线对比
Ubuntu/Debian系直接走apt安装,省时省力,适合绝大多数场景:
sudo apt update sudo apt install -y squid安装完成后,Squid服务会自动启动,主配置文件在/etc/squid/squid.conf,默认缓存目录在/var/spool/squid,日志目录在/var/log/squid/。如果只是验证功能,这个状态已经能跑了,但生产环境我强烈建议改掉默认配置再上,默认配置只允许本机访问,内网其他机器根本连不上。
CentOS/RHEL系对应的是:
sudo yum install -y squid主配置在/etc/squid/squid.conf,逻辑结构类似,只是某些默认参数值略有差异。
编译安装适合对性能有极致要求或者需要定制模块的场景,比包管理安装多了编译这一步,耗时在5到10分钟,但好处是可以自己控制编译优化参数。标准流程是这样:
# 下载源码包并解压(版本号按官方最新LTS为准) wget http://www.squid-cache.org/Versions/v6/squid-6.10.tar.gz tar -zxvf squid-6.10.tar.gz cd squid-6.10 # 配置编译参数,指定安装路径和缓存目录 ./configure --prefix=/usr/local/squid \ --enable-ssl \ --enable-ssl-crtd \ --with-openssl \ --enable-arp-acl \ --enable-htpc # 编译并安装 make -j$(nproc) sudo make install--enable-ssl和--enable-ssl-crtd这两个参数是为后面处理HTTPS流量预留的,如果确认纯HTTP环境,可以去掉以减小体积。新手第一次部署不要盲目上编译安装,先用发行版自带的包跑通流程,等理解每个配置项的作用之后,再考虑性能定制。我最早就是因为迷信编译安装,结果依赖缺了好几个,一个下午全耗在解决编译错误上了。
3.3 安装后的目录结构与权限检查
装完先确认两件事:Squid的运行用户和目录可写权限。默认情况下,包管理器安装会创建proxy用户,编译安装则通常用nobody或者你手动指定的用户。Squid主进程以root启动,但工作进程会降权到低权限用户,所以缓存目录和日志目录必须对这个运行用户可写,否则启动时直接报权限错误。
# 创建缓存目录并授权 sudo mkdir -p /data/squid_cache sudo chown -R proxy:proxy /data/squid_cache sudo chmod -R 750 /data/squid_cache # 查看Squid版本信息 squid -v这里有个隐藏坑:如果你用了/etc/fstab挂载,但挂载参数里带了noexec或者nodev,Squid初始化缓存目录时可能会异常,建议挂载选项保持默认的defaults,至少第一版先这么跑,后面稳定了再根据安全要求收紧。
4. 核心配置解析与实践操作
Squid的学习曲线其实很平缓,配置文件是典型的行式指令风格,核心配置项不超过20个。我把我从实际踩坑中整理出来的配置模板拆开讲,每一段都说明白为什么这么写。
4.1 监听端口和基本可见性设置
Squid默认监听3128端口,这是传统默认端口。如果你在内网部署,3128够用;如果跟其他服务有端口冲突,可以改,但一定要同步修改防火墙规则和客户端配置。下面这段是基础配置:
# 监听所有网卡的3128端口 http_port 3128 # 若需要处理HTTPS请求的缓存,需要额外监听443端口并配置证书 # https_port 443 cert=/etc/squid/cert.pem key=/etc/squid/key.pem # 对外显示的主机名,建议设为服务器主机名 visible_hostname squid-proxy-01 # 出错时显示管理员联系方式 admin_email ops@example.comhttp_port还可以追加参数,最常用的是transparent表示透明代理模式,intercept表示配合iptables的拦截模式。默认不加参数就是标准正向代理模式,客户端必须显式设置代理。
4.2 ACL访问控制:重中之重
ACL不只是安全访问控制,它直接决定Squid能缓存什么、拒绝什么、放行什么。配置逻辑分两步:先定义ACL条目,再定义http_access规则。ACL条目相当于给流量打标签,http_access规则决定标签对应动作。
# 定义内网网段 acl localnet src 10.10.0.0/16 acl localnet src 192.168.1.0/24 # 定义允许访问的目标端口 acl Safe_ports port 80 acl Safe_ports port 443 acl Safe_ports port 8080 acl Safe_ports port 21 acl Safe_ports port 22 # 定义SSL CONNECT方法的目标端口 acl SSL_ports port 443 # 定义本地请求 acl localhost src 127.0.0.1/32 # 定义允许的方法 acl SSL_method method CONNECT # 访问规则:先拒绝危险请求,再放行白名单 http_access deny !Safe_ports http_access deny CONNECT !SSL_ports http_access allow localhost http_access allow localnet http_access deny all这里面的关键点在规则顺序。Squid的ACL规则是自上而下逐条匹配,匹配即停止,所以必须是"先拒绝、后放行、最后兜底拒绝"的顺序。如果把http_access allow localnet写在deny !Safe_ports前面,非安全端口的请求就会被内网放行规则提前命中,后面的限制形同虚设。
还需要注意!叹号表示取反,!Safe_ports表示"不属于安全端口列表的所有端口"。deny !Safe_ports的意思是:凡是目标端口不在白名单里的请求,直接拒绝。这套写法在社区里很流行,安全性和可维护性都不错。
如果要限制特定域名,可以这样定义:
# 放行特定下载域名 acl allowed_domains dstdomain .example.com acl allowed_domains dstdomain .mirrors.internal # 放在其他allow规则之前 http_access allow allowed_domains域名匹配支持前导点通配,.example.com会匹配www.example.com、download.example.com等所有子域名。需要注意的是,dstdomain只对HTTP请求有效,HTTPS请求在握手阶段Squid无法看到完整的URL域名,需要依赖SNI或者开启SSL bump。
4.3 缓存存储策略:决定命中的关键
Squid的缓存存储核心是cache_dir指令,默认在/var/spool/squid,但我建议用独立数据盘并调整参数。典型配置如下:
# 缓存目录 大小(MB) 一级目录数 二级目录数 cache_dir ufs /data/squid_cache 10240 16 256 # 缓存条目上限 maximum_object_size 512 MB minimum_object_size 0 KB maximum_object_size_in_memory 512 KB # 缓存保留带参数URL和cookie的响应 cache_vary onufs是Squid自带的存储类型,适合中小规模部署。一级目录和二级目录数这段很多人不理解,它是为提升文件查找效率设置的目录树层次,底层原理是哈希散列分散文件,避免单个目录文件过多导致IO性能下降。经验值是一级16个、二级256个,缓存目录容量越大,二级目录数要适当增加到512或1024。如果cache_dir后跟的是rock,则是一种固定块存储方式,适合固态硬盘,性能更好但配置稍复杂,新手先用ufs没问题。
maximum_object_size控制单个文件能被缓存的最大体积,默认值是4MB,对于系统镜像、安装包这类大文件场景完全不够。我处理软件源加速时把这个值调到512MB甚至1GB,效果立竿见影。但注意缓存大小和磁盘容量要匹配,如果你盘只有50GB,上限却设2GB,很快缓存目录就满了,Squid会频繁清理旧对象,命中率反而下降。
4.4 客户端身份认证与审计
有些场景需要对使用代理的人做身份区分,Squid支持基础认证、Digest认证和外部认证程序。生产环境用得最多的是基础认证配合/etc/squid/passwd文件存储用户密码。配置过程分两步:
第一步,用htpasswd工具创建用户文件:
# 创建用户并设置密码 sudo htpasswd -c /etc/squid/passwd user001 # 添加更多用户 sudo htpasswd /etc/squid/passwd user002第二步,在squid.conf里启用认证:
# 指定认证程序 auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd auth_param basic children 5 auth_param basic realm Welcome to Internal Proxy Server auth_param basic credentialsttl 2 hours # 定义认证用户组 acl authenticated_users proxy_auth REQUIRED # 在访问规则中启用认证 http_access allow localnet authenticated_usersREQUIRED表示所有需要匹配localnet的请求都必须通过认证。这里的坑在于:认证规则必须放在允许内网其他请求的规则之前,并且如果同一IP下多个用户共享代理,credentialsttl设太短会导致频繁弹认证框,设太长又不利于审计,2小时是一个比较折中的值。
启用认证后,内网客户端的代理配置里需要携带用户名密码。Linux环境变量方式是在/etc/profile里设置:
export http_proxy="http://user001:password@10.10.0.8:3128" export https_proxy="http://user001:password@10.10.0.8:3128"4.5 HTTPS流量处理与SSL bump的取舍
HTTPS是代理场景里绕不开的话题。传统的正向代理对HTTPS只做隧道转发:客户端和Squid建立CONNECT隧道,Squid在中间只是把加密流量原样转发,不做内容解析,更不缓存。这带来的结果是HTTPS流量走代理没问题,但缓存完全失效,因为Squid看不到加密内容。
如果想对HTTPS做缓存或者内容审计,就需要开启SSL bump功能,让Squid充当中间人,动态生成证书对客户端解密流量、再与目标服务器重新加密。这个功能非常敏感,配置不当会直接让客户端报证书错误。我的建议是:默认不开启SSL bump,只有当业务明确需要缓存HTTPS资源、并且客户端可控可以安装自定义CA证书时,才考虑配置。
# 生成CA证书 sudo mkdir -p /etc/squid/certs cd /etc/squid/certs sudo openssl req -new -x509 -days 3650 -nodes \ -out ca.pem \ -keyout ca.key \ -subj "/CN=Squid-Root-CA" # 初始化证书数据库 sudo /usr/lib/squid/security_file_certgen -c -s /var/lib/squid/ssl_db -M 4MB # 开启SSL bump http_port 3128 ssl-bump \ cert=/etc/squid/certs/ca.pem \ generate-host-certificates=on \ dynamic_cert_mem_cache_size=4MB ssl_bump peek all ssl_bump bump allSSL bump开启后,所有客户端必须信任这个CA证书,否则浏览器会拦截。这个环节的复杂度和潜在风险都偏高,如果你只是想要内网下载加速,完全可以绕过它,只对HTTP流量做缓存;HTTPS流量走隧道模式不缓存也比强制中间人解密稳妥得多。这一点我是吃过亏的,曾经为了彻底缓存某个HTTPS接口的返回数据,开了SSL bump,结果一堆客户端设备炸了证书告警,线上问题处理了两个小时才缓过来。
5. 性能调优与上线自检清单
配置写完不等于部署完成,Squid的性能表现和参数调优有很大关系。这一节我讲几个我实测有效的调优点,以及上线前必须做的检查。
5.1 缓存命中率调优
缓存命中率是衡量Squid价值的核心指标。可以用squidclient工具直接查询管理接口:
# 查看缓存信息和命中率 squidclient -h 127.0.0.1 -p 3128 mgr:info squidclient -h 127.0.0.1 -p 3128 mgr:store重点关注两个数据:Request Hit Ratio表示请求命中率,Byte Hit Ratio表示字节命中率。字节命中率比请求命中率更能反映带宽节省情况,因为大文件命中的字节量远高于小文件。我调优前的字节命中率大概在35%左右,调整maximum_object_size、开启cache_vary之后,稳定在60%以上,效果非常明显。
几个实战调优心得:
- URL带签名参数的对象默认不缓存,比如
?token=xxx这类动态参数,Squid会把它们当成不同对象。如果确认某些参数不影响内容变化,可以配置cache_replacement_policy和refresh_pattern来处理。 - refresh_pattern 参数要贴合业务。默认配置对静态资源的刷新间隔偏短,导致缓存频繁失效。对系统镜像这类几乎不变的文件,可以设置较长的过期时间:
# 静态资源缓存30天 refresh_pattern .(iso|zip|tar|gz|rpm|deb|jar) 43200 90% 43200 ignore-no-cache # 软件源仓库文件缓存1天 refresh_pattern .(repomd|xml.gz|Packages|Sources) 1440 80% 1440 ignore-no-cache # 动态页面默认不缓存长时间 refresh_pattern .html 15 20% 2880- 内存大小对命中率影响有限,磁盘缓存才是大头。
maximum_object_size_in_memory设512KB就够,设太大反而浪费内存。
5.2 并发连接与超时参数
Squid的并发能力受文件描述符、内存和磁盘IO三重限制。内核层默认的ulimit往往不够用,需要调整:
# 临时调整当前shell的文件描述符限制 ulimit -n 65535 # 永久调整,编辑 /etc/security/limits.conf proxy soft nofile 65535 proxy hard nofile 65535超时参数直接关系到用户体验和连接资源释放。以下是推荐值:
# 客户端空闲连接超时 client_idle_pconn_timeout 60 seconds # 连接外部服务器时的连接超时 connect_timeout 30 seconds # 请求转发超时 request_timeout 5 minutes # 读取响应数据的超时 read_timeout 15 minutes # 等待客户端发送完整请求的超时 request_header_max_size 64 KBconnect_timeout不建议设太长,因为内网访问外网资源时如果对端不可达,长超时会让大量连接堆积,占满并发资源。我之前遇到过一次事故,源站某个IP被防火墙策略误伤,导致Squid所有转发都卡在TCP连接阶段,客户端全部排队。把connect_timeout从默认值降为30秒后,问题大幅缓解,因为Squid能快速失败并重新调度。
5.3 内存与磁盘参数
Squid内存使用主要包括内存缓存、ACL列表、连接状态等。默认配置下,2GB内存跑满并发几千不是什么新鲜事,但内存不足时Linux会触发swap,性能断崖式下降。建议在/etc/squid/squid.conf里显式设置内存上限:
# 设定Squid可用的最大内存 cache_mem 1024 MB # 内存中单个对象上限 maximum_object_size_in_memory 512 KBcache_mem控制的是Squid用于缓存热对象的额外内存,不是最大内存占用,系统实际占用会更高。4GB总内存的机器,cache_mem设1GB比较合理;8GB机器可以设2GB。如果频繁发生swap交换,先检查cache_mem是否过大,再检查是否有其他进程抢占内存。
磁盘方面,Squid维护一个"替换"策略,当缓存目录满了,会用LRU算法清理旧对象。默认的cache_replacement_policy是lru,一般不用改,但要注意磁盘空间监控。磁盘使用率超过85%以后,Squid清理旧对象的频率会大幅增加,CPU占用和IO延迟同步上涨。我用crontab做了个磁盘检查脚本,超过阈值直接告警,然后人工评估清理策略。
5.4 上线前的自检清单
每次改完配置准备上线,我都按照下面这份清单过一遍,能省掉80%的线上故障处理时间:
- 配置语法检查:
squid -k parse只输出无错误信息,有错误会明确提示行号和原因。 - 缓存目录检查:确认
cache_dir指向的目录已创建且Squid用户有写权限。 - 端口监听检查:
ss -lntp | grep 3128确认Squid正在监听。 - 防火墙放行:内网客户端到Squid主机的3128端口需要放行,注意云安全组和主机防火墙是两层。
- ACL规则自查:从客户端发起一个预期内允许的请求和一个预期外的请求,分别验证行为是否符合预期。
- DNS解析检查:Squid进程需要正常做DNS解析,
/etc/resolv.conf配错会导致所有转发失败。 - 日志滚动:确认日志路径存在,且配置了logrotate避免日志文件无限涨大。
# 一键自检命令汇总 sudo squid -k parse sudo squid -k check sudo ss -lntp | grep 3128 sudo tail -n 50 /var/log/squid/access.log6. 服务启动、开机自启与日常维护
配置文件改好、自检通过,接下来就是把Squid拉起来并做日常维护。
6.1 启动与重启方式
Ubuntu/Debian系用systemd管理,重载配置、重启服务、查看状态分别对应:
# 重载配置(不中断服务) sudo systemctl reload squid # 重启服务 sudo systemctl restart squid # 查看服务状态 sudo systemctl status squid一个非常重要的操作区别:改ACL规则、http_port、cache_dir这类配置后,必须重启服务才生效;但如果只是改了缓存刷新策略、超时参数这类运行时参数,用reload就能热加载。生产环境尽量减少重启次数,因为重启期间所有代理请求会中断,内网会有大量连接报错。我一般这样操作:先squid -k parse验证语法,再用reload热加载,最后在低峰期做一次完整重启。
还有一个冷知识:如果改了cache_dir的目录大小或类型,需要先停服务、删除旧的共享内存缓存状态(一个后缀为.state的文件或数据库),再启动,否则Squid会报缓存状态不匹配的错误。我遇到一次cache_dir从ufs改成rock后反复启动失败,原因就是这个状态没有清掉。
6.2 开机自启
包管理器安装的Squid一般自动注册了systemd服务,默认开机自启。检查一下:
sudo systemctl enable squid sudo systemctl is-enabled squid如果is-enabled输出disabled,手动执行一次enable即可。
6.3 日志管理与审计
Squid的日志体系分几块:access.log记录每个请求的访问详情,cache.log记录缓存事件和运行日志,store.log记录对象的存储与淘汰。日常只用前两个,更大的价值在access.log——它可以精确到哪个源IP、在哪个时间、访问了哪个域名、缓存命中还是未命中、响应大小多少,是内网行为审计的利器。
access.log一条典型记录长这样:
172.16.3.21 - - [10/Oct/2024:14:23:11 +0800] "GET http://mirrors.internal/ubuntu/ubuntu.iso HTTP/1.1" 200 1073741824 - "TCP_MISS:DIRECT"最后一段TCP_MISS:DIRECT是缓存状态,TCP_HIT表示缓存命中,TCP_MISS表示未命中回源拉取。通过统计这两种状态的比例,能直接验证缓存配置是否生效。
需要让日志自动滚动,避免磁盘被日志占满,配置/etc/logrotate.d/squid或直接用系统自带的规则。我用的是默认的daily滚动、保留30天,生产环境完全够用。
6.4 冷备与迁移
Squid的缓存数据本质上是"可重建"的,丢了最多就是命中率下降,不会造成数据丢失。所以备份策略很简单:配置文件定期备份即可。迁移到新机器时,直接把squid.conf原样拷贝过去,重新初始化缓存目录,不需要迁移缓存数据。真正需要留意的反而是ACL规则里的密码文件/etc/squid/passwd,这个文件丢了就等于丢了所有认证用户,建议纳入备份范围。
7. 常见故障排查与处理实录
这部分我从真实运维中挑了五个出现频率最高的故障,每个都写清楚现象、排查过程和解决方式。这些都是踩坑换来的,直接复制思路能省不少时间。
7.1 内网客户端无法连接代理
现象:客户端设置代理后,所有请求都超时,浏览器提示无法连接代理服务器。
排查顺序:
- 确认Squid进程活着:
systemctl status squid,如果状态是active (running),继续下一步。 - 确认端口监听:
ss -lntp | grep 3128,如果没有监听,检查http_port配置和启动日志。 - 确认防火墙放行:从客户端机器
telnet 10.10.0.8 3128测试端口连通性。如果不通,检查云安全组和主机的iptables规则。 - 确认ACL规则:从Squid本机
curl -x 10.10.0.8:3128 http://example.com测试是否正常,如果本机能过、内网不能过,基本是allow localnet没配上或者网段不对。
我遇到的最隐蔽情况是:ACL规则里内网段写错子网掩码,10.10.0.0/16写成了10.10.0.0/24,导致绝大多数IP被兜底规则拒绝,日志里全是TCP_DENIED。这种问题配置解析不会报错,只能靠日志和实包测试定位。
7.2 请求能通但速度特别慢
现象:代理能连上,小文件正常,大文件下载速度极慢。
这一步要先看access.log里的缓存状态。如果全是TCP_MISS,说明缓存根本没生效,请求全部回源。原因通常是这几个:
maximum_object_size太小,大文件不被缓存,每次回源拉取。refresh_pattern没有覆盖大文件后缀,Squid认为对象不可缓存。- 源站响应头带了
Cache-Control: no-store,Squid默认遵守这个头,不缓存。
解决方式是先调大maximum_object_size,然后按资源类型写refresh_pattern,对于确实不可控的源站响应头,可以用ignore-no-cache强制忽略。但注意,ignore-no-cache是双刃剑——如果业务方明确要求某些接口不做缓存,这个参数会破坏业务语义,务必先跟业务确认。
7.3 缓存目录报错导致无法启动
现象:重启Squid后服务起不来,cache.log报Failed to verify swap directory或者No such file or directory。
这类错误八成是缓存目录不存在、权限不对或者挂载异常。排查路径:
# 查看缓存目录 ls -ld /data/squid_cache # 确认目录归属 sudo ls -ld /data/squid_cache # 输出类似 drwxr-x--- 3 proxy proxy 4096 # 手动初始化缓存目录 sudo -u proxy /usr/lib/squid/security_file_certgen -c -s /var/lib/squid/ssl_db -M 4MB # 或者清掉Squid缓存数据库重新生成 sudo rm -rf /data/squid_cache/* sudo systemctl restart squid注意删除缓存目录只在紧急情况下用,重新初始化后命中率会掉到0%,需要一段预热时间才能回到正常。
7.4 认证用户反复被弹窗要求登录
现象:开了auth_param后,同一用户每隔几分钟就重新弹认证框,明显影响使用。
这个问题的核心在credentialsttl参数,它的含义是认证凭据在Squid里的有效时间。设太短(比如默认2分钟),用户很快过期,Squid要求重新认证;设太长则审计时效性变差。我实测下来,办公网场景设2小时比较合适。另外注意,如果客户端和Squid之间还套了一层NAT,所有用户从Squid侧看IP都一样,这会导致认证状态混乱,多个用户挤在同一个IP身份下。这种情况最好的办法是让客户端显式携带认证,而不是依赖IP识别。
7.5 磁盘IO被打满,Squid变卡
现象:Squid服务整体响应变慢,iostat看到磁盘util接近100%。
大文件缓存场景下,磁盘IO是最大瓶颈。处理思路按优先级排序:
- 降低单文件缓存上限,避免超大文件同时写盘。
- 用SSD替换机械盘,提升随机读写能力。
- 把
cache_dir拆成多个目录挂载到不同磁盘,分散IO压力。 - 适当调大
maximum_object_size_in_memory,让热对象走内存,减少磁盘访问。
高并发+大文件场景,我可以直接给个经验值:SATA SSD + ufs存储,500并发左右磁盘会成为瓶颈;NVMe SSD会好很多,一千并发下仍然稳定。如果长期压测发现Squid成了瓶颈,下一步不是继续调参,而是考虑加一台Squid做负载分流。
7.6 运维监控的几个实用技巧
Squid自带的管理接口非常实用,可以定期拉取状态数据投喂给监控系统。我常用的命令:
# 查看整体缓存信息 squidclient -p 3128 mgr:info # 查看各客户端流量排行 squidclient -p 3128 mgr:client_list # 查看当前建立连接数 squidclient -p 3128 mgr:info | grep 'Number of TCP connections'更简单的做法是直接把access.log接入日志采集系统,按客户端IP聚合后就能看到谁在大量消耗带宽。我在部署初期靠这个发现了一个未纳管的测试机在疯狂下载大文件,占比超过总流量的60%,排查下来是某个自动化脚本把下载路径写死成了直连源站,绕过了代理。把脚本改成走代理后,带宽压力瞬间降了下来。
8. 部署完成后的几点个人体会
Squid这套东西我前后折腾过几个环境,最大的体会是:它的难点不在安装,而在配置背后的流量思维。很多人照着网上的模板把squid.conf一贴,跑通了就觉得完事了,但一问到"为什么这个对象没被缓存""为什么这个子网被拒绝",就答不上来。实际运维中,配置模板只能解决60%的问题,剩下40%全是要理解ACL匹配顺序、缓存策略、HTTPS隧道机制这些底层逻辑才能处理。
如果你也是第一次部署,我建议按这个顺序走:先不开启认证、不开启SSL bump,用一套最简单的内网ACL配好缓存,确认内网能走代理、大文件命中缓存,再逐步加上认证和更精细的策略。一上来全部配满,出问题时根本分不清是ACL拒绝还是缓存策略失效,排查难度翻倍。我见过不少同事在configure阶段就开了SSL bump,结果调试了三四天证书问题,最后把功能全关了才恢复正常——这个弯路完全没必要走。
还有一点想特别提一下:缓存目录的磁盘规划和后续扩容要提前想清楚。我最初图省事,缓存目录和系统共用一个根分区,结果一次日志暴涨直接导致根分区100%,Squid强制退出,连带系统其他服务全部不可用。后来把缓存独立挂载到数据盘,并把日志单独做了分割,这类问题再也没有出现过。基础设施的东西,前期规划多花半小时,后面能少熬几个夜。
最后分享一个我在实际维护里经常用的简单检查:每天早上看一眼squidclient mgr:info的字节命中率,如果连续几天持续下降,先查源站侧是不是调整了响应头,再查是不是有新的客户端直接绕开了代理访问源站。Squid不是装完就一劳永逸的,它需要你时不时关注命中率、磁盘空间、日志异常这类基础指标,但这恰恰是运维这份工作最有意思的地方——一套精心调过的缓存服务,真的能达到意想不到的效果。