使用Nginx同时反代Jsdelivr和Gravatar

由于网络环境原因,国内访问 Jsdelivr CDN 和 Gravatar 头像服务时常会遇到速度慢或无法访问的问题。通过 Nginx 反向代理,我们可以自建加速节点,有效提升资源加载速度和稳定性。本文将详细介绍如何配置 Nginx 同时反代这两个服务。

前提条件

  • 一台境外服务器(推荐延迟低于 100ms)
  • 已安装 Nginx(版本 ≥ 1.18)
  • 已配置 SSL 证书(Let’s Encrypt 即可)
  • 域名(如 cdn.example.com

    替代方案:使用 Vercel 或 Netlify

    如果你没有国内访问性能比较好的服务器,那么你可以尝试使用 Vercel 和 Netlify 来反代。这两个平台提供全球 CDN 加速,且免费额度充足,非常适合作为个人项目的反向代理解决方案。 可以使用我的开源项目:ZeinkCDN-Proxy,该项目提供了开箱即用的 Vercel 和 Netlify 部署配置,支持 Jsdelivr、Gravatar 等多个服务的反代,只需点击一键部署即可拥有自己的 CDN 加速节点。 当然了如果你连折腾都嫌麻烦的话,可以使用我现成的:cdn.zeinklab.com

    配置步骤

  1. 基础配置结构 创建一个新的 Nginx 配置文件:
    sudo nano /etc/nginx/conf.d/reverse-proxy.conf
  2. Jsdelivr 反代配置 Jsdelivr 主要提供 npm、GitHub、WordPress 等 CDN 服务,我们分别配置不同路径:
    # npm 包反代
    location /npm/ {
     proxy_pass https://cdn.jsdelivr.net/npm/;
     proxy_set_header Host cdn.jsdelivr.net;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_cache_valid 200 304 12h;
    }
    # GitHub 文件反代
    location /gh/ {
     proxy_pass https://cdn.jsdelivr.net/gh/;
     proxy_set_header Host cdn.jsdelivr.net;
     proxy_cache_valid 200 304 12h;
    }
  3. Gravatar 反代配置 Gravatar 提供全球头像服务,配置如下:

    location /avatar/ {
     proxy_pass https://www.gravatar.com/avatar/;
     proxy_set_header Host www.gravatar.com;
    
     # 可选:指定默认头像和大小
     proxy_set_header Accept-Encoding "";
     sub_filter 'www.gravatar.com' 'cdn.example.com';
     sub_filter_once off;
    
     proxy_cache_valid 200 304 7d;
    }
  4. 完整配置示例

    server {
     listen 80;
     listen 443 ssl http2;
     server_name cdn.example.com;
    
     # SSL 配置
     ssl_certificate /etc/letsencrypt/live/cdn.example.com/fullchain.pem;
     ssl_certificate_key /etc/letsencrypt/live/cdn.example.com/privkey.pem;
    
     # 安全 Headers
     add_header X-Content-Type-Options nosniff;
     add_header Cache-Control "public, immutable";
    
     # 日志
     access_log /var/log/nginx/cdn.access.log;
     error_log /var/log/nginx/cdn.error.log;
    
     # npm CDN 反代
     location /npm/ {
         proxy_pass https://cdn.jsdelivr.net/npm/;
         proxy_set_header Host cdn.jsdelivr.net;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
         # 缓存配置
         proxy_cache cache_zone;
         proxy_cache_valid 200 304 12h;
         proxy_cache_valid 404 1m;
         proxy_cache_use_stale error timeout updating;
    
         # 超时设置
         proxy_connect_timeout 5s;
         proxy_send_timeout 10s;
         proxy_read_timeout 10s;
     }
    
     # GitHub CDN 反代
     location /gh/ {
         proxy_pass https://cdn.jsdelivr.net/gh/;
         proxy_set_header Host cdn.jsdelivr.net;
         proxy_cache cache_zone;
         proxy_cache_valid 200 304 12h;
     }
    
     # Gravatar 反代
     location /avatar/ {
         proxy_pass https://www.gravatar.com/avatar/;
         proxy_set_header Host www.gravatar.com;
         proxy_set_header User-Agent $http_user_agent;
    
         # 图片优化缓存
         proxy_cache cache_zone;
         proxy_cache_valid 200 304 7d;
         proxy_cache_valid 404 1h;
    
         # 可选:修改响应内容中的域名
         sub_filter 'www.gravatar.com' 'cdn.example.com';
         sub_filter_once off;
     }
    
     # 根路径重定向
     location / {
         return 301 https://your-main-site.com;
     }
    }
    # 缓存区域配置(添加到 http 块)
    http {
     # ... 其他配置
    
     proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_zone:100m inactive=30d use_temp_path=off;
    }
  5. 缓存目录创建
    sudo mkdir -p /var/cache/nginx
    sudo chown -R nginx:nginx /var/cache/nginx
  6. 测试并重载配置
    # 测试配置语法
    sudo nginx -t
    # 重载 Nginx
    sudo systemctl reload nginx

    使用方式

    Jsdelivr 资源

    将原链接:

    https://cdn.jsdelivr.net/npm/vue@3.3.4/dist/vue.global.js

    替换为:

    https://cdn.example.com/npm/vue@3.3.4/dist/vue.global.js

    Gravatar 头像

    将原链接:

    https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50?s=200

    替换为:

    https://cdn.example.com/avatar/205e460b479e2e5b48aec07710c08d50?s=200

    高级优化

  7. 缓存策略
    # 在 http 块中配置
    map $request_uri $cache_time {
     ~*\.(js|css|woff2)$  30d;
     ~*\.(jpg|png|gif)$   60d;
     default               12h;
    }
  8. 防盗链配置
    location ~* \.(js|css|png|jpg)$ {
     valid_referers none blocked *.example.com example.com;
     if ($invalid_referer) {
         return 403;
     }
     # ... 其他代理配置
    }
  9. HTTP/3 支持

    listen 443 quic reuseport;
    add_header Alt-Svc 'h3=":443"; ma=86400';

    缓存规则配置详解与推荐

    缓存层级结构设计

    建议采用多层级缓存策略,根据资源类型设置不同缓存时长:

    # 在 http 块中定义缓存区域(推荐配置)
    proxy_cache_path /var/cache/nginx/cdn levels=1:2 keys_zone=cdn_cache:200m inactive=60d max_size=50g use_temp_path=off;
    server {
     # ... 其他配置
    
     # npm 包缓存(版本固定,可长期缓存)
     location /npm/ {
         proxy_pass https://cdn.jsdelivr.net/npm/;
         proxy_cache cdn_cache;
         proxy_cache_key "$scheme$proxy_host$request_uri";
         proxy_cache_valid 200 301 302 365d;  # 成功响应缓存一年
         proxy_cache_valid 404 5m;            # 404错误仅缓存5分钟
         proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
         proxy_cache_background_update on;    # 后台更新过期缓存
         proxy_cache_lock on;                 # 防止缓存击穿
    
         # 添加缓存状态头(调试时用)
         add_header X-Cache-Status $upstream_cache_status;
    
         # 忽略源站缓存控制,强制缓存
         proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;
         proxy_hide_header Set-Cookie;
     }
    
     # GitHub 文件缓存(可能更新,缓存时间适中)
     location /gh/ {
         proxy_pass https://cdn.jsdelivr.net/gh/;
         proxy_cache cdn_cache;
         proxy_cache_key "$scheme$proxy_host$request_uri";
         proxy_cache_valid 200 301 302 30d;   # GitHub文件可能更新,缓存30天
         proxy_cache_valid 404 10m;
         proxy_cache_use_stale error timeout updating;
         proxy_cache_background_update on;
     }
    
     # Gravatar 头像缓存(极长时间缓存)
     location /avatar/ {
         proxy_pass https://www.gravatar.com/avatar/;
         proxy_cache cdn_cache;
         proxy_cache_key "$scheme$proxy_host$request_uri";
         proxy_cache_valid 200 301 302 180d;  # 头像很少变化,缓存半年
         proxy_cache_valid 404 1d;
         proxy_cache_use_stale error timeout updating;
    
         # 对头像进行 WebP 转换(需要额外模块)
         # image_filter_buffer 10M;
         # image_filter_webp_quality 85;
     }
    }

    缓存键设计要点

  • proxy_cache_key 应包含足够区分度的信息,通常 $scheme$proxy_host$request_uri 已足够
  • 对于 Gravatar,建议将尺寸参数纳入缓存键,避免不同尺寸共用缓存导致图片变形
  • 使用 proxy_cache_lock 防止高并发时多个请求同时回源

    缓存清理与监控

    # 手动清理缓存(按URL模式)
    sudo find /var/cache/nginx/cdn -name "*vue@3.3.4*" -delete
    # 查看缓存统计
    sudo tail -f /var/log/nginx/cdn.access.log | grep -v "HIT"
    # 在Nginx配置中添加缓存监控接口
    location /purge_cache {
      allow 127.0.0.1;
      allow <你的IP>;
      deny all;
    
      proxy_cache_purge cdn_cache "$scheme$proxy_host$1";
    }

    配置文件深度优化

    性能优化配置

    # 在 http 块中
    http {
      # 启用 sendfile 零拷贝
      sendfile on;
      tcp_nopush on;
      tcp_nodelay on;
    
      # 调整缓冲区
      proxy_buffering on;
      proxy_buffer_size 4k;
      proxy_buffers 32 8k;
      proxy_busy_buffers_size 64k;
    
      # 开启 Gzip 压缩
      gzip on;
      gzip_comp_level 6;
      gzip_min_length 1000;
      gzip_proxied any;
      gzip_types
          text/plain
          text/css
          text/xml
          text/javascript
          application/json
          application/javascript
          application/xml+rss
          application/atom+xml
          image/svg+xml;
    
      # 连接复用
      upstream jsdelivr {
          server cdn.jsdelivr.net:443 max_fails=3 fail_timeout=30s;
          keepalive 32;
      }
    
      upstream gravatar {
          server www.gravatar.com:443 max_fails=3 fail_timeout=30s;
          keepalive 32;
      }
    }
    # 在 server 块中优化 location
    location /npm/ {
      proxy_pass https://jsdelivr/npm/;  # 使用 upstream
      proxy_http_version 1.1;            # 启用 HTTP/1.1
      proxy_set_header Connection "";     # 保持长连接
      # ... 其他配置
    }

    安全防护配置

    # 限制请求速率
    limit_req_zone $binary_remote_addr zone=cdn_limit:10m rate=10r/s;
    server {
      # ... 其他配置
    
      location /npm/ {
          limit_req zone=cdn_limit burst=20 nodelay;
          limit_req_status 429;
    
          # IP 白名单(可选)
          # allow 123.45.67.0/24;
          # deny all;
    
          # CORS 头
          add_header Access-Control-Allow-Origin *;
          add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS";
          add_header Access-Control-Allow-Headers "Origin, Authorization, Accept";
    
          if ($request_method = 'OPTIONS') {
              return 204;
          }
    
          # ... 其他代理配置
      }
    }
    # 隐藏 Nginx 版本信息
    server_tokens off;

    日志与监控优化

    # 自定义日志格式(包含缓存状态)
    log_format cdn_log '$remote_addr - $remote_user [$time_local] '
                     '"$request" $status $body_bytes_sent '
                     '"$http_referer" "$http_user_agent" '
                     'rt=$request_time uct="$upstream_cache_time" cs=$upstream_cache_status';
    access_log /var/log/nginx/cdn.access.log cdn_log;
    # 启用 Nginx 状态页面(需编译时包含 stub_status 模块)
    location /nginx_status {
      allow 127.0.0.1;
      allow <你的监控IP>;
      deny all;
    
      stub_status on;
      access_log off;
    }

    举一反三:扩展更多服务

    掌握了 Jsdelivr 和 Gravatar 的反代方法后,可以轻松扩展到其他常用服务:

  1. 反代 Cloudflare CDNJS
    location /cdnjs/ {
     proxy_pass https://cdnjs.cloudflare.com/ajax/libs/;
     proxy_set_header Host cdnjs.cloudflare.com;
     proxy_cache cdn_cache;
     proxy_cache_valid 200 301 302 365d;  # CDNJS 资源极稳定
     proxy_cache_valid 404 5m;
     proxy_ignore_headers Cache-Control;
    }

    使用方式:将 https://cdnjs.cloudflare.com/ajax/libs/vue/3.3.4/vue.min.js 替换为 https://cdn.example.com/cdnjs/vue/3.3.4/vue.min.js

  2. 反代 Google Fonts & AJAX
    # Google Fonts
    location ~ ^/fonts/(.*) {
     proxy_pass https://fonts.googleapis.com/$1;
     proxy_set_header Host fonts.googleapis.com;
     proxy_cache cdn_cache;
     proxy_cache_valid 200 30d;
    }
    # Google AJAX Libraries
    location ~ ^/ajax/(.*) {
     proxy_pass https://ajax.googleapis.com/ajax/libs/$1;
     proxy_set_header Host ajax.googleapis.com;
     proxy_cache cdn_cache;
     proxy_cache_valid 200 365d;
    }
  3. 反代 Unsplash / GitHub Raw
    # Unsplash 图片
    location /unsplash/ {
     proxy_pass https://images.unsplash.com/;
     proxy_set_header Host images.unsplash.com;
     proxy_cache cdn_cache;
     proxy_cache_valid 200 60d;
    }
    # GitHub Raw 文件
    location ~ ^/github/([^/]+)/([^/]+)/(.*) {
     proxy_pass https://raw.githubusercontent.com/$1/$2/$3;
     proxy_set_header Host raw.githubusercontent.com;
     proxy_cache cdn_cache;
     proxy_cache_valid 200 301 302 7d;  # Raw 文件可能更新
     proxy_cache_valid 404 10m;
    }
  4. 反代 npm 官方 registry

    # 注意:此配置仅用于加速下载,不适用于发布
    location /registry/ {
     proxy_pass https://registry.npmjs.org/;
     proxy_set_header Host registry.npmjs.org;
     proxy_cache cdn_cache;
     proxy_cache_valid 200 301 302 1h;  # npm 包元数据更新频繁
     proxy_cache_valid 404 1m;
    
     # 对于 tarball 文件使用更长的缓存
     location ~* \.tgz$ {
         proxy_cache_valid 200 30d;
     }
    }

    通用模式总结

    所有反代配置都遵循以下模式:

  5. 路径匹配 :使用 location 精确匹配需要反代的路径
  6. 上游地址 :proxy_pass 指向目标服务,注意末尾 / 的处理
  7. Host 头:必须正确设置 proxy_set_header Host
  8. 缓存策略:根据资源更新频率设置 proxy_cache_valid
  9. 优化选项:按需添加压缩、CORS、防盗链等 快速复制模板:
    location /服务名称/ {
     proxy_pass https://目标域名/路径/;
     proxy_set_header Host 目标域名;
     proxy_cache cdn_cache;
     proxy_cache_valid 200 301 302 缓存时长;
     add_header Access-Control-Allow-Origin *;  # 如需跨域
    }

    参考链接:

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容