IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    缓存标头和利用边缘网络加速访问

    静かな森发表于 2024-03-11 12:14:07
    love 0
    该渲染由 Shiro API 生成,可能存在排版问题,最佳体验请前往:https://innei.in/posts/tech/vercel-cloudflare-http-header-about-cache

    本文以 Cloudflare + Vercel 为例。

    了解缓存标头

    在生产中,我们通常会利用 Redis 去缓存接口数据。对于前端应用来说,我们一般会利用内容分发网络(CDN)去缓存页面和其他静态资源。

    我们知道 HTTP 标头 cache-control 可以用来强缓存资源。

    例如,cache-control: max-age=60 表示资源在 60 秒内不会过期,浏览器如果不使用强制刷新的话(例如请求标头含有cache-control: max-age=0)可以直接使用本地缓存。

    在边缘网络或是内容分发网络中,一般都能相关的标头进行缓存。

    比如:s-maxage 的值。

    这个内容只能在原文中查看哦

    而这个值,一般都被 CDN 或者边缘网络用来控制缓存时间。

    在 Vercel 中。Cache 章节中,告诉我们可以使用这个值去控制一个 API 响应的缓存时间。另外也提供了 Vercel 私有的 HTTP 标头,例如 Vercel-CDN-Cache-Control。

    在 Cloudflare 中,When to use CDN-Cache-Control 中的例子可以更好的帮助理解资源在各端的缓存控制。

    Headers:
    
    Cache-Control: max-age=14400, s-maxage=84000
    Cloudflare-CDN-Cache-Control: max-age=24400
    CDN-Cache-Control: max-age=18000

    Cache behavior:

    CachesCache TTL (seconds)
    Origin Server Cache14400
    Network Shared Cache84000
    Cloudflare Edge24400
    Other CDNs18000
    Browser Cache14400

    上表中,Cloudflare 可以消费响应头中的 cache-control: s-maxage 和 Cloudflare-CDN-Cache-Control 控制资源在 Cloudflare 分发网和边缘网络的缓存。

    通过缓存标头,可以更快的让用户访问到资源,减少服务器的负载。

    以 Vercel 部署的 Next.js 为例,下面我们来做一些优化,让短期并发的负载下减少服务器的真实请求。

    Next.js API Route 的响应缓存

    这是一个简单的 Next.js API Route。

    import { NextResponse } from 'next/server'
    import type { NextRequest } from 'next/server'
    
    export const GET = async (req: NextRequest) => {
      return NextResponse.json({})
    }

    现在我们可以增加缓存标头。

    import { NextResponse } from 'next/server'
    import type { NextRequest } from 'next/server'
    
    export const GET = async (req: NextRequest) => {
      return NextResponse.json(
        {},
        {
          headers: {
            'Cache-Control': 'max-age=60, s-maxage=86400',
            'CDN-Cache-Control': 'max-age=86400',
          },
        },
      )
    }

    现在把 API 使用 Cloudflare 代理。

    在第一次请求之后,下一次请求中,我们能看到 Cloudflare 命中了缓存。

    Cf-Cache-Status: HIT

    使用 vercel.json 全局配置标头

    在单个 API 中,每每的添加缓存标头非常的麻烦并且我们也无法控制除了 API Route 之外的其他路由。我们可以使用 vercel.json 全局配置标头。

    在项目根目录下新建 vercel.json,内容如下:

    下面路由参考项目 Shiro,可按需配置路由。

    {
      "headers": [
        {
          "source": "/",
          "headers": [
            {
              "key": "Cache-Control",
              "value": "s-maxage=300, stale-while-revalidate=59"
            },
            {
              "key": "CDN-Cache-Control",
              "value": "max-age=300"
            },
            {
              "key": "Vercel-CDN-Cache-Control",
              "value": "max-age=300"
            }
          ]
        },
        {
          "source": "/og",
          "headers": [
            {
              "key": "Cache-Control",
              "value": "s-maxage=3600, stale-while-revalidate=30"
            },
            {
              "key": "CDN-Cache-Control",
              "value": "max-age=3600"
            },
            {
              "key": "Vercel-CDN-Cache-Control",
              "value": "max-age=3600"
            }
          ]
        },
        {
          "source": "/api/(.*)",
          "headers": [
            {
              "key": "Cache-Control",
              "value": "s-maxage=60, stale-while-revalidate=30"
            },
            {
              "key": "CDN-Cache-Control",
              "value": "max-age=60"
            },
            {
              "key": "Vercel-CDN-Cache-Control",
              "value": "max-age=60"
            }
          ]
        },
        {
          "source": "/feed",
          "headers": [
            {
              "key": "Cache-Control",
              "value": "s-maxage=86400, stale-while-revalidate=3600"
            },
            {
              "key": "CDN-Cache-Control",
              "value": "max-age=86400"
            },
            {
              "key": "Vercel-CDN-Cache-Control",
              "value": "max-age=86400"
            }
          ]
        }
      ]
    }

    使用 Vercel 提供的配置,可以对每个路由进行缓存标头的配置。配置过后,Vercel 会在响应这些请求时,自动添加缓存标头,然后经过 Cloudflare 读取缓存标头,然后在 Cloudflare 网络进行缓存,在下次请求到达时,直接从 Cloudflare 缓存中读取。

    而 stale-while-revalidate= 的值控制了一个资源在过期后,多久内仍然可以使用过期资源,然后在后台异步更新资源,那么在即便过期的场景下,用户也能快速的获取到资源,加快页面加载。

    这个内容只能在原文中查看哦

    参考:https://vercel.com/docs/projects/project-configuration#headers

    Vercel 边缘网缓存

    你可能也注意到 Vercel-CDN-Cache-Control 这个标头。这个标头是 Vercel 私有的标头,用来控制资源在 Vercel 边缘网络的缓存。既然 Vercel 也提供了缓存,为什么还要使用 Cloudflare 呢?

    我想大概有下面的原因:

    1. Cloudflare 一般作为 DNS 提供商,他会有着更加快速的响应时间。
    2. Vercel 的缓存命中很奇怪,有时候会命中,有时候不会命中,让我跟费解;而 Cloudflare 的缓存命中符合文档,在意料之中。

    看完了?说点什么呢



沪ICP备19023445号-2号
友情链接