1202年了,Disqus还在用iframe加载,我除了露出 震撼猫咪.jpg 的表情之外,已经没有什么更能形容遭受的震惊感了。无奈Valine不支持邮件提醒新评论,虽然Disqus的提醒也日常无法收到,但至少比起手动检查还是要心理安慰很多了。直到前几天,机缘巧合之下我发现了Waline这款衍生自Valine却同时具有后端管理功能的评论框架,于是就萌生了迁移评论系统的新想法。
相关介绍
Waline - 一款从 Valine 衍生的带后端评论系统。可以将 Waline 等价成 With backend Valine.
—— Waline 官网的介绍
Waline同时具有Valine的轻量和后端管理的方便两大特性,并且提供了简单方便的Serverless部署方案,遵循轻量化、集约化设计思路的指导,可以方便地部署在各种FaaS平台上,包括著名的Vercel、腾讯云CloudBase以及使用Docker独立部署的方案,提供LeanCloud、MongoDB、MySQL、PostgreSQL和SQLite的数据库支持,支持邮件通知、Telegram通知、QQ通知及微信通知接口的接入,提供大量可自定义参数接口。强大的扩展组合能力让Waline成为了集几乎所有优点于一身的评论系统组合,只要配置适当,相信能成为静态站点的一大优秀评论服务合作伙伴。
迁移记录
本次我使用了Vercel作为部署平台,连接MongoDB提供的免费512MB数据库平台作为评论存储系统,通知系统接入了Telegram和邮件。经过两天的测试,发现除了慢之外似乎没有什么问题。经过一般的测试,仅仅是在全站有60条评论的情况下,不少操作(包括更新文章阅读量统计、获取评论数、获取评论内容)几乎都需要花费1500~3000ms的运行时间。当然,其中包含了不少连接数据库操作的延迟,并且本主题有非阻塞的评论加载模式,所以只要没有开访问量统计,使用懒加载的体验应该是还能过得去的…
而本以为将 Disqus 的评论数据迁移去Waline数据库会很麻烦,事实上却发现官方已经提供了迁移使用的工具,只需要选择 从 Disqus
迁移至 Waline MySQL/PostgreSQL/SQLite
存储服务,将从 Disqus 导出(可以在 //YOUR_SITE.disqus.com/admin/discussions/export/ 导出,好像有些不太全)的评论压缩包,解压出XML内容粘贴在数据框内,单击转换
即可下载转换完成的csv文件(后缀名居然是txt,坏耶)。使用 MongoDB Compass 连接到我们的 MongoDB 实例,批量导入csv文件就能将评论都恢复回去。只是由于Disqus的隐私设置,头像、邮箱等等无法导出的账户相关信息都已经丢失了。
然后就迁移过来了,预计会花上一段时间用于相关的调整与改进云云,升级了也不能坏了安全性和体验呀。过两天估计会能整理出完整的教程,有遇到什么问题随时来找我就可以。
Waline 配置时的鉴权方式只有Referer域名,频率限制方式只有IP请求频率,虽然可以连接Akismet反垃圾系统,也可以设置人工评论审查,但防止CC攻击/防止被作为邮件轰炸工具之类的安全性也许还有待进一步的提升吧。
迁移教程
导出 Disqus 的评论数据
首先从 Disqus 请求导出旧的评论数据。 Disqus 会开始整理数据并归档成一个压缩包,并当数据准备完成时通知我们。
当数据准备完成时,我们会收到一封附带有下载地址的邮件,邮件里给出的下载地址就是评论数据的压缩包链接,直接点击即可开始下载。
压缩包是 gzip 格式压缩的,我是用 7zip 就能轻松提取出里面的同名(少了 .gz )文件。文件格式是 XML ,文件编码是 UTF-8 。使用文本编辑器打开,复制所有的内容备用。
打开迁移使用的工具,选择从 Disqus
迁移至 Waline MySQL/PostgreSQL/SQLite
存储服务,将刚才复制的数据粘贴到输入框内,单击转换
按钮,我们会得到一个output.txt文件用于保存。
保存得到的文件,这个文件是使用 UTF-8 编码的 CSV (Comma-Separated Values,逗号分隔值) 文件,可以直接喂给 MongoDB Compass 用于导入数据。为了方便识别,我把后缀名 .txt 改成了 .csv 。
题外话:如果您有安装 Excel ,此时您会发现它的图标变成了 Excel 的文档,这是因为 Excel 也支持 csv 的编辑处理。但很可惜的是导出的文档没有 BOM 头,而 Excel 没有读到 BOM 头的时候就会用默认编码(简体中文系统中使用的是GB系列)进行处理,因而打开的时候将会呈现一大片的乱码。但这并不影响我们数据的导入—— MongoDB Compass 这种现代软件使用的是 UTF-8 默认编码,只要导出的文件的内容没有被动过,那么不会出现编码导致的问题。
创建数据库
新建集群
最好是选择美国西部的服务器节点。 Vercel 个人账号的后端服务器在华盛顿,因而距离美国西部的服务器最近,延迟最小。我选择了咕咕噜云的台湾机房,导致每次请求的速度那可是相当之缓慢啊(猫咪摊手.jpg
我使用了 MongoDB Atlas 提供的免费额度,可以参照官方文档,创建完账号后新建一个 Cluster , Cloud Provider & Region 建议选择带有★标识的集群(我用的是 Google Cloud 的平台), Cluster Tier 选择
M0 Sandbox
免费级实例, Cluster Name 按照要求填写(之后无法更改),创建完成后即可在控制台看到它:(请注意初始创建的 Cluster 是几乎没有数据的,我是写入了一些数据之后截的图)
授权连接方式
单击
Connect
进入连接方式提示界面。由于我们是新建的项目,在进行连接之前,系统会提示我们先配置可连接的IP地址域与管理用户账户。根据 Vercel 的文档中对于部署 IP 访问的说明,我们很无奈地授权所有 IP 段访问。选择第三项(没记错的话),保存。
主数据库用户倒是可以随意配置,请记得记录对应的账户名与密码(忘了也不怕,可以重新生成的),在导入数据时会使用到。而出于安全因素的考虑,建议新建一个专用于 Vercel 连接集群的用户,稍后的步骤中也会有提及。
以上两点配置完成后,就可以准备进行连接了。
记录集群
选择第2项
Connect your application
,进入应用连接指导界面。由于waline目前的写法问题,我们无法使用新的连接方式,因而需要选择Node.js
和2.2.12 or later
选项,获得一长串的连接信息。例如我的链接:
1
mongodb://<username>:<password>@cluster-0-shard-00-00.dzwkk.mongodb.net:27017,cluster-0-shard-00-01.dzwkk.mongodb.net:27017,cluster-0-shard-00-02.dzwkk.mongodb.net:27017/<dbname>?ssl=true&replicaSet=atlas-sgse0y-shard-0&authSource=admin&retryWrites=true&w=majority
我们需要的信息有:
- 集群端点
- cluster-0-shard-00-00.dzwkk.mongodb.net
- cluster-0-shard-00-01.dzwkk.mongodb.net
- cluster-0-shard-00-02.dzwkk.mongodb.net
- 集群端口:全是27017,没什么好说的(
ssl=true
连接启用SSLreplicaSet=atlas-sgse0y-shard-0
集群信息为 atlas-sgse0y-shard-0authSource=admin
认证源为 admin
根据 Waline 文档中 MongoDB 相关的配置,整理成环境变量的格式:
1
2
3
4
5
6
7
8
9
10
11
12# 环境变量名 = 值
## 备注
MONGO_HOST = ["cluster-0-shard-00-00.dzwkk.mongodb.net","cluster-0-shard-00-01.dzwkk.mongodb.net","cluster-0-shard-00-02.dzwkk.mongodb.net"]
##根据上文的 1 ,依次列出
MONGO_PORT = [27017,27017,27017]
##根据上文的 2 ,与端点依次对应
MONGO_REPLICASET = atlas-sgse0y-shard-0
##根据上文的 4 设置
MONGO_AUTHSOURCE = admin
##根据上文的 5 设置
MONGO_OPT_SSL = true
##根据上文的 3 设置- 集群端点
(可选)创建专用账户
为了提升系统的安全性,个人习惯创建一个专用的账户用来管理相关的数据。
返回 MongoDB Atlas 控制台,进入 Security 下的 Database Access 模块,新建一个用户:
根据提示配置:
- Authentication Method 认证模式选择默认的 Password 密码验证,自行设置对应的用户名和密码;
- Database User Privileges 数据库用户权限选择 Grant specific privileges 授权特定的权限,
- Specific Privileges 特定权限下选择 readWrite 读写,
- 后方 Database 处填入您希望 Waline 使用的数据库名,
- Collection 留空(因为 Waline 需要不止一个集);
- Restrict Access to Specific Clusters/Data Lakes 右边的开关设置为开启模式,
- 下方 Grant Access To 勾选之前创建的 Cluster ,并且单击右边的
Done
以确认;
- 下方 Grant Access To 勾选之前创建的 Cluster ,并且单击右边的
- Temporary User 请务必保持关闭(因为这个选项的意思是该用户为临时用户,一定时间后会被自动删除)
记录下此步骤中的用户名、密码和数据库名,在配置 Waline 后端时需要提供。
提示:我初始化连接时是没有数据库的,因而使用的是最高权限的管理员(也就是在 Connect 可用之前,和授权 IP 一起分配的那个管理员账户);因而我不知道这样限制访问权限的管理员是否会导致无法创建数据库等问题,因而更推荐您先授权最高权限管理员账户,等初始化完成后再使用权限受限的管理员身份作为长期部署解决方案。
建立后端
创建 Vercel 账号,如果有就直接登录,此步骤不再赘述。
参照 Waline 官方文档中 Vercel 部署 相关的部分进行部署。
- 需要注意的是,由于我们使用的是 MongoDB Atlas 的服务,因而无需申请也无需填写 LeanCloud 相关的配置参数。
- 在部署过程中配置的环境变量全部会被配置为机密参数,删除需要使用命令行工具手动删,比较麻烦,我是部署完成后再去设置里手动配置环境变量的。而且不知为何我这边生成了两个项目,也许在部署过程中修改项目名会导致生成一个新的?
我开启的功能有:
- MongoDB 数据库存储
- 隐藏评论者 UA
- Akismet 反垃圾
- 邮件通知
- Telegram 通知
- 社交登录 (Github 授权登录)
- 评论数统计(前端)
- 阅读量统计(前端)
因而设置的环境变量有:
环境变量 备注 SITE_NAME 站点名 SITE_URL 站点地址 SECURE_DOMAINS 授权域名 DISABLE_USERAGENT 是否隐藏评论者 UA AKISMET_KEY Akismet 的反垃圾 Key AUTHOR_EMAIL 博主邮箱(区分是否通知) SMTP_SERVICE 支持的邮件发送服务提供商 SMTP_USER SMTP 认证账户名 SMTP_PASS SMTP 认证密码 SENDER_NAME 发件用户名 SENDER_EMAIL 发件邮箱 TG_BOT_TOKEN Telegram Bot API Token TG_CHAT_ID Telegram Chat ID GITHUB_ID Github OAuth Client ID GITHUB_SECRET Github OAuth Secret MongoDB 相关的参数 请参见上文 有必要的话,可以考虑重新生成后端的部署。
方法: 进入 项目 - Deployments,找到最新的部署,右边的三个点,选择 Redeploy 即可重新构建部署。
需要注意的是,虽然旧的项目不会占用计费资源,但出于对于云服务提供商的尊重,建议还是及时删除不使用的项目。
测试后端
输入您部署后端的站点地址,您应当能看到一个评论区示例页面:
切换至 //your-project.vercel.app/ui ,您应当能加载出登录界面:
单击右下角的 用户注册
,输入您的信息,注册成功且没有出现问题,并且您应当可以登录管理系统了,那么您的后端应当是已经配置完成了。
第一个注册的用户会自然成为管理员。
导入旧评论数据
连接数据库
我使用了
MongoDB Compass
作为连接工具。(主要是觉得有 GUI 方便操作)回到 MongoDB Atlas 控制台,单击
Connect
进入连接方式提示界面,选择第3项,进入 MongoDB Compass 的连接指导界面。没有 MongoDB Compass 的话,就下载安装一个吧。复制连接串,粘贴到 Compass 的连接框内,调整用户名和密码为您在上一步中设置的值,单击
Connect
即可建立与 Cluster 的连接。导入数据
在导入之前,最好是能先去发送一条测试用的评论,以方便生成对应的数据表结构。
然后进入 站点数据库 - Comment 集,应当能看到那些已经提交上去的
测试评论了:单击 绿色的
ADD DATA
(添加数据),选择Import File
(从文件导入)选择需要导入的文件,记得修改右下角的文件后缀名筛选,默认是 JSON ,我们需要手动改成 CSV :
Compass 会自动识别出 CSV 文件,并且展示 10 条样例数据方便检查是否正确:
确认无误后,单击
IMPORT
即可将数据全部导入至数据库。请注意,由于Disqus备份与相关隐私的问题,数据会有部分的丢失:例如评论者头像、评论者身份等等。
而由于MongoDB使用的是_id.$oid
索引,不是SQL的id
字段,因而导入之后需要根据ID调整各条评论的pid和rid关系,以避免因为找不到父评论内容而无法显示的情况发生。
至此应该就全部完成啦。别忘了测试一下是否工作正常哦。