在 HAProxy 中设置后端某个站点的图片文件缓存时间为一年,主要通过 HTTP 响应头 来实现,HAProxy 本身不存储缓存内容,但可以在响应中添加 Cache-Control 和 Expires 头,指示客户端和中间缓存(浏览器、CDN)缓存图片一年。
方案一:基于文件扩展名匹配(推荐)
frontend web_frontend
bind *:80
bind *:443 ssl crt /path/to/cert.pem
# 使用 ACL 匹配图片文件扩展名
acl is_image path_end .jpg .jpeg .png .gif .webp .svg .bmp .ico
# 为图片设置缓存头
http-response set-header Cache-Control "public, max-age=31536000, immutable" if is_image
http-response set-header Expires "%[date(),http_date(31536000)]" if is_image
default_backend app_servers
backend app_servers
server app1 192.168.1.10:80 check
server app2 192.168.1.11:80 check
方案二:基于路径匹配(如 /static/images/ 目录)
frontend web_frontend
bind *:80
# 匹配特定路径下的图片
acl is_image_path path_beg /static/images/ /uploads/avatars/
acl is_image_ext path_end .jpg .jpeg .png .gif .webp
# 组合条件
http-response set-header Cache-Control "public, max-age=31536000, immutable" if is_image_path is_image_ext
default_backend app_servers
方案三:为特定后端站点单独配置
如果需要对某个特定的后端站点(如 img.example.com)设置图片缓存:
# 图片专用前端
frontend img_frontend
bind *:80
bind *:443 ssl crt /path/to/cert.pem
# 根据域名区分
use_backend img_backend if { hdr(Host) -i img.example.com }
# 主前端
frontend web_frontend
bind *:80
default_backend app_backend
# 图片后端(缓存一年)
backend img_backend
# 为所有响应设置缓存头(如果是纯图片服务)
http-response set-header Cache-Control "public, max-age=31536000, immutable"
http-response set-header Expires "%[date(),http_date(31536000)]"
server img_server 192.168.1.20:80 check
# 普通应用后端
backend app_backend
server app_server 192.168.1.10:80 check
方案四:条件判断避免覆盖已有缓存头
如果后端服务器可能已经设置了缓存头,可以使用 unless 避免覆盖:
backend app_backend
# 仅当响应中没有 Cache-Control 时才设置
http-response set-header Cache-Control "public, max-age=31536000, immutable" \
if is_image { res.hdr(Cache-Control) -m found } !{ res.hdr(Cache-Control) -m found }
# 或更简洁的方式:使用 set-header 但允许覆盖(通常没问题)
http-response set-header Cache-Control "public, max-age=31536000, immutable" if is_image
server app1 192.168.1.10:80 check
完整配置示例(生产推荐)
global
log /dev/log local0
maxconn 4096
user haproxy
group haproxy
defaults
log global
mode http
option httplog
option dontlognull
retries 3
timeout connect 5000
timeout client 50000
timeout server 50000
frontend web_frontend
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/example.pem
# ACL 定义
acl is_image path_end .jpg .jpeg .png .gif .webp .svg .bmp .ico .tiff
# 为图片设置一年缓存
http-response set-header Cache-Control "public, max-age=31536000, immutable" if is_image
http-response set-header Expires "%[date(),http_date(31536000)]" if is_image
# 可选:设置 Vary 头,支持缓存压缩变体
http-response set-header Vary "Accept-Encoding" if is_image
default_backend app_servers
backend app_servers
balance roundrobin
option httpchk HEAD /health HTTP/1.1\r\nHost:\ example.com
server app1 192.168.1.10:80 check inter 3000 rise 2 fall 3
server app2 192.168.1.11:80 check inter 3000 rise 2 fall 3
关键配置说明
| 配置项 | 说明 |
|---|---|
max-age=31536000 |
缓存时长:365天(秒) |
immutable |
表示资源不会改变,浏览器可放心缓存(现代浏览器支持) |
public |
允许任何中间节点(CDN、代理)缓存 |
%[date(),http_date(31536000)] |
HAProxy 的 fetches,动态计算当前时间 + 31536000 秒后的日期 |
path_end |
ACL 匹配文件扩展名 |
set-header |
设置响应头,如果已存在则覆盖 |
验证方法
配置生效后,通过 curl 验证:
curl -I http://your-domain.com/images/logo.png
预期响应头:
HTTP/1.1 200 OK
Cache-Control: public, max-age=31536000, immutable
Expires: Thu, 27 Mar 2025 10:00:00 GMT
Content-Type: image/png注意事项
- HAProxy 不缓存实际内容:只添加响应头,真正的缓存由浏览器/CDN 完成
- 动态图片谨慎处理:如果图片内容会变化,不应设置过长缓存
- 与后端协调:如果后端(如 Nginx)已设置缓存头,HAProxy 的
set-header会覆盖 - SSL 配置:如果使用 HTTPS,确保证书路径正确
- Expires 动态计算:使用
%[date(),http_date(31536000)]需要 HAProxy 2.2+ 版本
如果你需要针对特定后端服务器(而非域名或路径)进行缓存配置,或者需要配合 CDN 设置 s-maxage,我可以进一步补充。
文档更新时间: 2026-03-27 07:28 作者:月影鹏鹏