FoundryVTT 使用 CDN 教程

CDN 使用指南,基于 Docker 部署教程部署后进行,与各云服务提供商利益无关

FAQ

CDN 是什么/干什么/解决了什么问题?

CDN 是云厂商提供的内容分发网络服务,厂商在各地部署成千上万的服务器,而这些服务器上将会缓存你需要加速访问的站点上的多媒体、脚本、样式等体积较大的静态内容(以及使用全站加速时,代理访问你的站点上的动态内容,比如 FVTT 用到的 WebSocket 连接)。

通过这些缓存与代理,用户在访问站点时,通常会根据网络情况,自动就近选择离用户近、网络质量好的服务器,代替你原本站点的服务器来提供内容。

即使你原本站点带宽很小(比如 1Mbps)、与用户之间延迟很高,甚至服务器性能不足。对于一张 10M 大小的图片文件,传递给 5 个用户,每个用户可能需要 7 分钟才能都加载出来。而 CDN 在缓存后,能够以 CDN 自身的速率(可以轻松超过 100 Mbps)就近传输给用户,可能只需一两秒,大大加快了访问速度。

上面的例子也可以看出,使用 CDN 之后,不再需要考虑“同时多少个用户访问之后,服务器带宽不足,每个人都变很慢”的问题,CDN 服务带宽永远是配置足够的。

而且,境内云服务的 CDN 流量价格,常常要比服务器按流量计费来得便宜,静态内容加速通常是 0.2 元/GB 左右或更低(预付费流量包等方式)。

很多 CDN 服务也提供静态内容压缩功能,可以代替你的服务器,对缓存的图片、脚本、样式表文件进行压缩之后传递给用户,降低服务器开销。更棒的是,有些 CDN 服务可以对图片、音频、视频等多媒体资源的缓存,进行动态的剪裁、缩放、压制,大幅降低文件尺寸,实现更快地访问。

加速 FVTT 需要使用什么样的 CDN?

使用 FVTT 进行跑团,会有大量的图片、脚本文件等静态内容,天然的,非常适合使用 CDN 进行加速,几乎是 CDN 最标准的使用场景。

但同时也会发现,FVTT 是实时应用程序。比如指示物的移动、聊天消息的发送接收等,都是实时更新的。这些基于 WebSocket 协议的实时数据传输,以及其他的 API 请求,即是动态内容。动态内容,没有办法进行真正意义上的“缓存”。尽管 WebSocket 是动态内容的一种,但不是所有支持动态内容加速的 CDN 都支持 WebSocket,这一点一定要注意

这就需要支持动态内容加速的 CDN 服务,而国内规模大的云厂商,比如阿里云、腾讯云的全站加速功能,都支持动态内容和 WebSocket 的加速,符合 FVTT 使用的需求。

即,FVTT 使用的 CDN 需要支持:

  • 静态内容,用于提供多媒体、脚本、样式表等各种文件的静态内容加速(只要是 CDN 服务,均支持)
  • 动态内容,用于提供 API 请求的加速(除非自己配置动静分离,需要 CDN 支持)
  • WebSocket,用于提供 FVTT 最常用的 WS 协议的加速(除非自己配置动静分离,需要 CDN 支持)

购买时,境内/境外/全球应该怎么选?

正如教程中域名一章里提到的一样,在境内使用域名提供互联网服务尤其是 CDN 服务,是一定需要备案的。因此,只要想在境内使用 CDN,你也同样要对你的域名进行备案,然后使用这个备案的域名来加速。

境外 CDN 则没有这个问题,在境外提供互联网服务无需备案。而且,境外 CDN 也可以在国内访问。但是,境内的玩家访问境外 CDN 速度不甚理想。如果你的服务器在境内,而 CDN 使用“纯”境外,玩家使用 CDN 时可能不仅起不到加速作用,反而拖累了访问速度,这是出口带宽拥挤和墙所导致的问题,除非使用特定手段访问,或者线路不错,否则不建议当你的玩家都在境内时这么做。

而很多 CDN 包含全球服务,即境内+境外。因为涉及到了提供境内服务,所以同样需要备案。如果你的玩家正好有位于境内的也有境外的,可以考虑使用全球 CDN,一次性解决境内外玩家的加速访问。

购买/配置 CDN

接下来介绍如何购买和配置 CDN。

Docker 部署流程中的注意事项

在购买前,先按照 Docker 部署教程进行自动脚本部署,注意在填写参数时,要输入“FoundryVTT 使用 CDN 时的加速域名”,而且一定不能和“FoundryVTT 已绑定该服务器的域名”一样

比如你拥有 fvtt.com 域名,计划使用 my.fvtt.com 作为 FVTT 绑定域名,使用 cdn.fvtt.com 作为加速后的域名。

那么 FoundryVTT 已绑定该服务器的域名就填写 my.fvtt.com 后回车,FoundryVTT 使用 CDN 时的加速域名就填写 cdn.fvtt.com 后回车。

部署相关的其他信息参见 Docker 部署教程

如此,FVTT 就准备好了使用这个域名进行 CDN 加速,然后可以按下列步骤,配置对应域名的 CDN。

以阿里云为例,配置全站加速

以刚才的加速域名 cdn.fvtt.com 为例,接下来是如何在阿里云上配置全站加速的步骤。阿里云界面若更新,或者使用其他云服务,操作大同小异。

记住,对境内提供 CDN 一定需要先备案。

  1. 登入控制台后,找到全站加速,并且按提示开通对应服务

  2. 在全站加速的管理页中,选择域名管理,点击添加域名,然后填写表单

    • 加速域名:使用 CDN 访问 FVTT 的域名,即例中的 cdn.fvtt.com
    • 加速区域:依照上述 FAQ按需选择
    • 端口:和默认一样,选择 80 端口即可

    这里需要注意的是,源站信息的类型域名/IP 两项内容的填写

    • 如果你使用了 FVTT 绑定域名:
      • 类型:选择源站域名
      • 域名:输入框中填入你的 FVTT 绑定域名(不能是加速域名),优先级不需要修改(例 my.fvtt.com
    • 如果你没有使用 FVTT 绑定域名:
      • 类型:选择 IP
      • IP:输入框中填入你运行 FVTT 服务器的公网 IP 地址,优先级不需要修改
  3. 确认后,回到域名管理界面,会显示对应域名的 CNAME 项

    复制这一段 CNAME,我们需要把我们这个加速域名 fvtt.cdn.com 的 CNAME 记录设置为这一段的值。

    阿里云的面板上,提供了如何配置 CNAME 的帮助文档,其他域名解析服务也大同小异。

    在你的域名解析管理面板,类似如此配置子域名的 CNAME 即可,比如域名解析服务设置界面如下。

    注意,别名或者 CNAME 处记录,是从之前全站加速的域名管理面板复制来的。

    如何绑定域名也可以参见 绑定(子)域名

  4. 配置 CDN 在全站加速域名管理面板中点击对应域名的配置,进入配置页面

    • 基本配置:无需修改,只需确认源站信息输入正确即可
    • 回源配置:我们需要修改两项,回源 HOST 以及静态协议跟随回源
      • 回源 HOST:开启,并直接选加速域名即可;或者选自定义域名,然后填写你的加速域名(例 fvtt.cdn.com
      • 静态协议跟随回源:开启,并选择 HTTP 即可
      • 可选:回源请求超时时间,可以酌情调整,比如改为 180 秒
    • 动静态加速规则:
      • 动态加速:确认开关处于开启状态,默认是开启的
      • 协议跟随回源:这里的回源是为动态内容设置的,改为 HTTP 即可
      • 自适应缓存:开启,自适应缓存会尊重源站的缓存协商
      • 可选:在缓存配置里,详细设置不同规则下文件的过期时间,但这样做可能会导致使用过期没更新的缓存的文件,需要手动刷新 CDN 的缓存!详见下文
    • HTTPS 配置:强烈推荐开启 HTTPS 访问,尽管使用 HTTPS 访问,CDN 会额外收取 HTTPS 费用(价格很低)
      • HTTPS 证书:推荐开启 HTTPS 安全加速。如无必要,证书来源选择免费证书,然后同意授权并确认即可
      • HTTP/2 设置:HTTPS 启用后才可以开启,默认使用 HTTPS 就会开启,有效提升站点访问速度
    • 性能优化:
      • 页面优化:推荐开启,除非你是模组开发者并使用 CDN 加速站进行开发
      • 智能压缩:推荐开启,可以小幅度降低静态内容的文件尺寸
    • WebSocket:一定要确保 WebSocket 开关处于开启状态
      • 心跳时间:可以酌情调整,比如改为 120 秒
      • 回源协议:这里的回源是为 WebSocket 设置的,选择 HTTP 即可

如果开启了 HTTPS 访问,等待云服务下发好证书后,即可通过加速域名(例 fvtt.cdn.com)访问
如果没有使用 HTTPS,直接浏览器里打开加速域名即可

如果以上配置完毕后,仍然无法正常连接加速域名,请检查域名 CNAME 解析是否正确。

配置完成后,云服务提供商即会开始按流量、访问次数或者其他计费方式,开始计费。

如果没有特殊需求的话,可以看一下云服务提供商是否有 CDN 流量包(购买前要确认是否适用于全站加速),预先购买这些流量包可以降低开销。

FVTT 使用 CDN 的三种情况

举个例子,FVTT 是可口可乐工厂,CDN 是京东。你一直要喝可乐,但你很鸡掰,只会想喝最新批次的可乐(使用服务器上最新的改动)。

不使用 CDN,直接访问

不用 CDN,直接访问 FVTT 服务器,等同于:

你每次要喝可乐,是可口可乐工厂直销给你。但是因为工厂离你远(服务器远),或者工厂的快递不行(线路不好/带宽小),所以等待可乐快递到家会慢(加载慢)。

好在,你自己家里有个很大的冰箱(浏览器缓存),你可以存很多可乐,方便你不用快递买就可以喝。

然而你很鸡掰,只喝最新批次,所以你在喝自己冰箱里的可乐之前,会有疑虑:

你在喝可乐之前,只用问工厂:“我冰箱里的 10 月批次是最新批次吗”,工厂回复你“是啊”,你就可以放心地直接喝自己冰箱的可乐了(使用浏览器缓存),而不用等工厂慢递;但如果工厂说:“不,我们已经有 12 月的新批次了”,而你家冰箱只有 10 月批次的(缓存过期),你就只能再等一次工厂的慢递了。

这个过程就叫做协商缓存,通过协商确定你用不用缓存(喝不喝你自己家冰箱里的可乐)。

使用 CDN,但是不与源站协商

可口可乐工厂快递给你太慢了,你决定从京东买:

你从京东下订单,京东(CDN)会跑去找可口可乐下订单(CDN 回源),然后在自己的五湖四海的所有仓库里存一大堆可乐(CDN 缓存),然后用离每一个客户最近的仓库给客户送快递,自然就要比工厂的慢递快很多。

这样,你每次要喝可乐的时候都找京东要,京东总会安排最近最快的快递(加载快),然后你也会存很多在自己家大冰箱,方便你冰箱里有可乐的时候,可以更快地喝到(浏览器仍然会缓存)。毕竟京东仓库离你再近,也没有你的冰箱离你近。

但这就有一个问题出现了:当工厂的可乐批次变成 12 月了之后,你从京东买的可能还是 10 月批次(CDN 缓存过期)。

你喝可乐之前,看了下自己家冰箱里的,是 10 月批次,于是你问京东“是不是 10 月是最新批次”(和 CDN 协商缓存)。但其实京东也没从工厂下过新的订单了,京东一看,“我这里最新批次也是 10 月“,你就放心大胆的喝了,结果其实是你不想喝的过期的可乐。

这个可能导致的问题,举例来说,你 FVTT 服务器上更新的模组已经到了 2.0 版,但 CDN 的缓存里还是之前 FVTT 服务器上的 1.0 版(取决于缓存过期时间规则):你直接访问 FVTT 服务器地址,这个模组是 2.0 版;但你用 CDN 访问,这个模组就始终是 1.0 版。

除了模组,图片、翻译、脚本和其他资源等,都可能出现类似的过期情形,严重情况下会导致 FVTT 或者模组无法正常使用(比如后端响应格式变更,前端未更新,无法处理新的结果)。

使用 CDN,并且协商

这种情况下,等同于你还是从京东买,但是你和京东签订了一个合同:

你每次要喝可乐的时候,都会告诉京东,我冰箱里的是 10 月批次的,问京东有没有新批次。然后京东会代替你,问工厂有没有新批次。

如果工厂没有新批次(服务器文件未更改),京东就会告诉你,你就喝你冰箱里的 10 月批次的就行了。

如果工厂有新批次(服务器文件更新),比如 12 月批次。京东就会立马从工厂下新订单,把自己仓库里的 10 月批次的全倒河里(CDN 淘汰过期缓存),然后储备 12 月的,并且给你发 12 月批次的快递,告诉你有新批次,喝这一批。以后即使你冰箱的喝完了(浏览器缓存清空),再找京东要,京东发给你的,也是最新的批次。

这样的话,即使工厂更新批次了,你也可以喝到京东送来的新批次,而不是过期的。

进阶阅读:Cloudflare 源站缓存控制介绍