如何在Nginx中实现文件存在则本地返回,否则反向代理?
实现Nginx驱动的BLOB缓存分发服务
需求概述
- 搭建BLOB服务,负责图片、视频、音频等静态资源分发,请求示例:
https://blob.example.com/blogPost/background.webp - Nginx优先检查本地硬盘中是否存在请求的文件,存在则直接返回给客户端
- 若文件不存在,Nginx将请求反向代理至上游应用,由上游应用从云存储异步下载文件并保存到本地目录,供后续请求直接复用
现有Nginx配置
server { listen 80; server_name example.com; return 301 https://$server_name$request_uri; } server { listen 443 http2 ssl; server_name example.com; client_max_body_size 0; ssl_certificate /Project/SiteQwik/Certificate.pem; ssl_certificate_key /Project/SiteQwik/Key.pem; error_page 502 /502.html; location /502 { root /Base/Infra/Nginx; internal; } location / { proxy_pass http://localhost:56710; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; } location ~ ^/(fa|en|ar|ru|tr)(/|$) { rewrite ^/(fa|en|ar|ru|tr)/(.*)$ /$2?locale=$1 break; rewrite ^/(fa|en|ar|ru|tr)$ /?locale=$1 break; proxy_pass http://localhost:56710; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; } }
改造后的完整配置
# 保留原example.com的配置不变 server { listen 80; server_name example.com; return 301 https://$server_name$request_uri; } server { listen 443 http2 ssl; server_name example.com; client_max_body_size 0; ssl_certificate /Project/SiteQwik/Certificate.pem; ssl_certificate_key /Project/SiteQwik/Key.pem; error_page 502 /502.html; location /502 { root /Base/Infra/Nginx; internal; } location / { proxy_pass http://localhost:56710; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; } location ~ ^/(fa|en|ar|ru|tr)(/|$) { rewrite ^/(fa|en|ar|ru|tr)/(.*)$ /$2?locale=$1 break; rewrite ^/(fa|en|ar|ru|tr)$ /?locale=$1 break; proxy_pass http://localhost:56710; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; } } # 新增BLOB服务专属Server块 server { listen 80; server_name blob.example.com; return 301 https://$server_name$request_uri; } server { listen 443 http2 ssl; server_name blob.example.com; client_max_body_size 0; # 复用原有通配符证书,若为单域名证书需替换为对应证书路径 ssl_certificate /Project/SiteQwik/Certificate.pem; ssl_certificate_key /Project/SiteQwik/Key.pem; # 本地BLOB文件存储根目录,需根据实际环境修改 root /var/blob-storage; # 核心逻辑:优先返回本地文件,不存在则转发至上游 location / { try_files $uri @fetch_from_upstream; # 可选:添加静态资源缓存策略,优化客户端体验 expires 30d; add_header Cache-Control "public, immutable"; } # 上游应用转发配置,需替换为实际上游服务地址 location @fetch_from_upstream { proxy_pass http://localhost:56710; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; # 传递原始请求URI,供上游应用定位云存储文件 proxy_set_header X-Original-URI $request_uri; } }
关键配置说明
- 独立Server隔离:新增
blob.example.com专属Server块,与原有业务请求完全隔离,避免互相干扰 - 本地文件检测逻辑:
try_files $uri @fetch_from_upstream是核心指令,Nginx会先在root目录下匹配请求URI对应的文件,找到则直接返回;未找到则触发上游转发 - 上游协作要求:上游应用需要通过
X-Original-URI头或原始请求URI定位云存储文件,下载后必须保存到/var/blob-storage目录的对应路径下(比如请求/blogPost/background.webp需保存为/var/blob-storage/blogPost/background.webp) - 缓存优化:添加的
expires和Cache-Control头可让客户端长期缓存静态资源,减少重复请求次数
内容的提问来源于stack exchange,提问作者Ali Radan
相关产品推荐
相关产品推荐

