
11-OSS对象存储加速配置静态资源、图片、视频缓存加速与防盗链一、为什么需要 OSS Nginx 配合无人售货柜系统里有大量静态资源商品图片、商品视频、广告轮播图、促销素材。一开始可能直接放在服务器本地但随着设备数量增长几千台柜子、几万种商品问题就来了存储不够一台服务器挂几块硬盘扩容要停机带宽不够几千台设备同时拉商品图片单机带宽扛不住可靠性差服务器挂了图片全没了这时候就轮到 OSS对象存储服务出场了。阿里云 OSS、腾讯云 COS、MinIO 自建都可以本质都是分布式存储容量无限、高可用、按量付费。但直接让用户/设备访问 OSS 有两个问题OSS 域名不统一你的域名是img.vending.comOSS 的域名是vending-bucket.oss-cn-hangzhou.aliyuncs.com不好看也不安全每次都回源 OSS热门商品图片被频繁访问每次都从 OSS 拉取浪费流量费用所以标准架构是OSS 做存储后端Nginx 做反向代理 缓存层用户只跟 Nginx 打交道。二、Nginx 反向代理 OSS基础代理配置server { listen 443 ssl; server_name img.vending.com; ssl_certificate /etc/nginx/ssl/vending.pem; ssl_certificate_key /etc/nginx/ssl/vending.key; location / { proxy_pass https://vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; proxy_set_header Host vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 5s; proxy_read_timeout 10s; proxy_buffering on; proxy_buffer_size 16k; proxy_buffers 8 64k; } }几个关键点proxy_pass用内网域名oss-cn-hangzhou-internal.aliyuncs.com是内网地址Nginx 服务器和 OSS 在同一区域时走内网不消耗公网带宽速度快且免费。这个省钱技巧很多新手不知道。proxy_set_header Host必须设为 OSS 域名OSS 是通过 Host 头来识别请求属于哪个 Bucket 的如果 Host 传成img.vending.comOSS 会返回404。这是最容易踩的坑。proxy_buffering on开启缓冲Nginx 先把 OSS 返回的数据完整接收到本地内存/磁盘再发给客户端。避免慢客户端把 Nginx 和 OSS 之间的连接占着不放。三、缓存策略配置proxy_cache光代理不缓存等于白搞加上proxy_cache才是真正的加速。缓存配置# http 块中定义缓存区域 http { proxy_cache_path /data/nginx/cache levels1:2 keys_zoneoss_cache:100m max_size50g inactive7d use_temp_pathoff; }参数详解levels1:2缓存目录层级Nginx 会把缓存文件按hash值的前1位和后2位分目录存储避免单目录文件过多导致性能下降keys_zoneoss_cache:100m缓存区名称叫oss_cache分配100MB内存存储缓存key1MB大约能存8000个key100MB够存80万个文件的索引max_size50g缓存文件最大占用50GB磁盘空间超过后Nginx自动淘汰最久没用的缓存inactive7d缓存文件7天没被访问就删除不管它有没有过期use_temp_pathoff临时文件直接写在缓存目录里避免跨磁盘拷贝在 location 中启用缓存server { listen 443 ssl; server_name img.vending.com; ssl_certificate /etc/nginx/ssl/vending.pem; ssl_certificate_key /etc/nginx/ssl/vending.key; # 图片缓存 location ~* \.(jpg|jpeg|png|gif|webp|ico)$ { proxy_cache oss_cache; proxy_cache_key $scheme$request_method$host$request_uri; proxy_cache_valid 200 7d; proxy_cache_valid 404 1m; proxy_cache_use_stale error timeout updating invalid_header http_500 http_502 http_503 http_504; proxy_pass https://vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; proxy_set_header Host vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; # 添加缓存命中状态到响应头方便调试 add_header X-Cache-Status $upstream_cache_status; add_header Cache-Control public, max-age604800; } # 视频缓存 location ~* \.(mp4|flv|m3u8|ts)$ { proxy_cache oss_cache; proxy_cache_key $scheme$request_method$host$request_uri; proxy_cache_valid 200 30d; proxy_cache_valid 404 1m; proxy_cache_use_stale error timeout updating; proxy_pass https://vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; proxy_set_header Host vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; add_header X-Cache-Status $upstream_cache_status; add_header Cache-Control public, max-age2592000; # 视频文件大开启分片传输支持 proxy_force_ranges on; } }proxy_cache_valid 200 7dHTTP 200响应缓存7天。proxy_cache_valid 404 1m404也缓存1分钟防止恶意刷不存在的URL把OSS打爆。proxy_cache_use_stale这个参数很实用——当 OSS 不可用时Nginx 可以继续返回旧的缓存数据即使已过期保证用户还能看到图片而不是白屏。X-Cache-Status响应头的值含义状态含义MISS未命中缓存回源OSS获取HIT命中缓存直接从Nginx返回EXPIRED缓存已过期回源获取新数据UPDATING缓存已过期正在后台更新STALEOSS不可用返回了旧缓存四、图片处理压缩/裁剪/格式转换阿里云 OSS 和腾讯云 COS 都自带图片处理功能通过 URL 参数就能实现压缩、裁剪、格式转换不需要在服务端做任何处理。location ~* \.(jpg|jpeg|png)$ { proxy_pass https://vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; proxy_set_header Host vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; proxy_cache oss_cache; proxy_cache_key $scheme$request_method$host$request_uri; proxy_cache_valid 200 7d; # 替换请求URL统一追加图片处理参数 # 小程序端统一返回webp格式 质量压缩 set $args ${args}x-oss-processimage/format,webp/quality,q_80; }这段配置的巧妙之处在于set $args——所有图片请求自动追加 OSS 图片处理参数把 PNG/JPG 统一转成 WebP 格式体积减少30%-50%质量压缩到80%。前端完全不用改Nginx 层面统一处理。当然如果不同场景需要不同尺寸列表缩略图 vs 详情大图建议前端直接在URL里拼参数Nginx 只做缓存和防盗链# 缩略图200x200裁剪 webp https://img.vending.com/products/1001.jpg?x-oss-processimage/resize,m_fill,w_200,h_200/format,webp # 详情图800x800等比缩放 webp https://img.vending.com/products/1001.jpg?x-oss-processimage/resize,w_800/format,webp不同参数的URL会被 Nginx 当成不同缓存key不会混淆。五、防盗链配置商品图片和视频是业务资产不能让人随便白嫖你的带宽。Nginx 提供两种防盗链方式。方式一valid_referers 域名白名单location ~* \.(jpg|jpeg|png|gif|mp4|webp)$ { valid_referers none blocked server_names *.vending.com *.vending.cn localhost 192.168.0.0/16; if ($invalid_referer) { return 403; } proxy_pass https://vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; proxy_set_header Host vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; proxy_cache oss_cache; proxy_cache_key $scheme$request_method$host$request_uri; proxy_cache_valid 200 7d; }none允许没有 Referer 头的请求直接在浏览器地址栏输入URLblocked允许有 Referer 头但被代理删掉值的请求*.vending.com允许你自己的域名$invalid_referer为 true 时返回403这种方式简单有效但 Referer 头可以被伪造安全性一般。方式二签名URL更安全对于高价值资源比如付费视频教程用签名URL。签名URL是后端生成的、带过期时间和签名的临时URL// Java后端生成签名URL有效期30分钟StringsignedUrlossClient.generatePresignedUrl(vending-bucket,videos/promotion.mp4,newDate(System.currentTimeMillis()30*60*1000)).toString();Nginx 层面只需要做透传不需要额外配置location /videos/ { proxy_pass https://vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; proxy_set_header Host vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; # 签名URL自带鉴权不需要valid_referers proxy_cache oss_cache; proxy_cache_key $scheme$request_method$host$request_uri; proxy_cache_valid 200 30d; }六、CDN 加速配置如果售货柜分布在全国各地Nginx 缓存只部署在单机房偏远地区的设备访问延迟依然很高。这时候需要 CDN。CDN 架构下 Nginx 的角色变化设备/用户 → CDN边缘节点 → CDN中心节点 → Nginx(回源) → OSS此时 Nginx 作为 CDN 的回源服务器需要做两个适配server { listen 443 ssl; server_name img.vending.com; # CDN回源时携带的头部用于识别CDN节点 real_ip_header X-Forwarded-For; set_real_ip_from 0.0.0.0/0; location / { proxy_pass https://vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; proxy_set_header Host vending-bucket.oss-cn-hangzhou-internal.aliyuncs.com; proxy_set_header X-Real-IP $remote_addr; # CDN回源时带缓存控制头 proxy_cache oss_cache; proxy_cache_key $scheme$request_method$host$request_uri; proxy_cache_valid 200 7d; proxy_cache_use_stale error timeout updating; # 关键CDN回源时带上Range头支持分片请求 proxy_set_header Range $http_range; proxy_set_header If-Range $http_if_range; } }Range头是 CDN 分片回源的关键——CDN 节点可能只要视频的某一段通过 Range 请求告诉 Nginx 只拉指定字节范围的数据避免整文件传输。七、缓存清理商品图片更新了但 Nginx 缓存还是旧的怎么办两种方案方案一文件名加版本号推荐前端引用图片时带hash版本号/products/1001.jpg?v20260811。换图后改版本号URLNginx 自然就是新缓存。方案二主动清除缓存使用proxy_cache_purge模块location ~ /purge(/.*) { allow 192.168.0.0/16; # 只允许内网清除 deny all; proxy_cache_purge oss_cache $scheme$request_method$host$1; }清除缓存curl https://img.vending.com/purge/products/1001.jpg架构设计上OSS 做存储、Nginx 做缓存和代理、CDN 做边缘加速三者配合才能应对全国几万台设备的图片视频分发需求。单靠任何一个组件都不够。