前言

最近我突然意识到我的对象存储还有很多余量,我就想把 子悦汉化组论坛 的资源文件放上去,正好减轻服务器压力。Flarum 的 FoF Upload 插件可以配置 AWS S3 的上传,但没法直接配置对象存储的。虽然很多对象存储都会提供兼容 S3 的接口,但在用的时候难免会遇到一些小问题。这篇文章的核心内容一是教各位如何完美配置对象存储,二是如何把现有的资源迁移过去。

准备工作

这里就不具体教各位怎么准备了,相信大家都会。

  1. Flarum 的 FoF Upload 插件:composer require fof/upload:"*"
  2. Flarum 的 AWS S3 协议:composer require league/flysystem-aws-s3-v3:1.*
  3. 腾讯云对象存储的存储桶(公开读私有写)
  4. 腾讯云的 API 秘钥:https://console.cloud.tencent.com/cam/capi

配置上传插件

这个部分的最下面有一张插件配置的总览图。

  1. 进入 Flarum 后台,启用 FoF Upload 并把上传方式都改为“AWS S3 或 S3 兼容”。

  2. 还是插件配置界面,拉到最下面把“存储设置”里的“文件链接前缀”改成你的存储桶的访问域名。

    在腾讯云后台的存储桶的“配置管理”右下角可以找到默认访问域名。由于默认域名有一些限制(任意类型文件不支持预览,apk、ipa 类型文件不支持下载),所以有已备案域名的话可以配置一个自定义源站域名

  3. 在“AWS S3 存储设置”处填写“Key”和“Secret”,分别为腾讯云 API 访问秘钥的“SecretId”和“SecretKey”。
  4. “存储空间(Bucket)”字段留空,原因会在第 8 步提到。
  5. “地域(Region)”字段对应的数据可以在存储桶的“配置管理”左上角找到,填写上去。

  6. 在“高级 S3 存储设置”处填写“访问域名(Endpoint)”,格式为 https://存储桶名称.cos.地域.myqcloud.com,然后把下面的“使用 path-style 访问域名”勾选上。

    虽然腾讯云禁止使用“path-style 域名”进行读写,但实际上这个并不算,所以可以正常用。存储桶名称可以在腾讯云后台的“存储桶列表”找到。

  7. “访问控制列表(ACL)”字段填写为 public-read
  8. 点击最下面的“保存”按钮保存设置。

    到这里配置还并未完成。刚才在第 4 步时我们留空了“存储空间(Bucket)”字段,这样是无法使用的。但如果你“正确”填写了这个字段,就会发现你上传文件的链接实际上是 https://访问域名/存储桶名称/日期/文件名。而 Flarum 上传完文件后自动生成的链接里并没有“存储桶名称”那个部分,所以没法正常用。要解决这个问题,需要前往你的网站服务器后台,修改插件的代码。

  9. 打开网站服务器后台,在 Flarum 安装目录下找到 vendor/aws/aws-sdk-php/src/InputValidationMiddleware.php 并打开。
  10. 把第 62 行到第 67 行删掉。

    if ($argument === '' || $argument === null) {
        $commandName = $cmd->getName();
        throw new \InvalidArgumentException(
            "The {$commandName} operation requires non-empty parameter: {$member}"
        );
    }

    由于这个插件本质上还是以 AWS S3 为标准设计,所以配置时必须要填写“存储空间”字段,但这样的话,腾讯云对象存储里就会多一个没有意义的文件夹。因此刚才在第 4 步留空,并且在第 6 步直接包含了存储桶名称以供读写。

  11. 完成!

附录:FoF Upload 插件配置一览。

资源迁移

如果你的网站是新部署的,以前没有文件的话,那么在刚才就已经结束了。但我是先开的网站,后弄的对象存储,所以我的网站里还有需要迁移过去的资源文件。

如果你嫌麻烦的话,也可以不做这个操作。但我的目的之一是给服务器减小压力,所以要把现有的文件迁移过去。

  1. 打开网站服务器后台,在 Flarum 安装目录下找到 public/assets/files 文件夹。里面应该是一些以日期为名的文件夹,把那些文件夹全部复制到你的对象存储里去。
  2. 打开数据库管理后台(比如 phpMyAdmin,或者直接开 SQL 控制台),运行以下 SQL 语句:

    UPDATE posts SET content = REPLACE(content, 'https://网站域名/assets/files/', 'https://对象存储访问域名/');
    UPDATE fof_upload_files SET url = REPLACE(url, 'https://网站域名/assets/files/', 'https://对象存储访问域名/');

    以上两条语句分别会把现有帖子的文件链接替换,并把用户媒体管理器的链接改掉。如果你安装网站时设置了数据库前缀,需要在 postsfof_upload_files 的前面加上你的前缀。

  3. 完成!

结语

这种办法是我目前探索出来的最完美的办法,不仅可以提高文件访问速度,也可以减小网站服务器压力。当然对象存储要另花钱。

标签: 云服务器, Flarum, 对象存储