一直以来都想给博客添加个访问计数器,考察了几个方案,有几个要求得不到满足。一是支持静态博客,二是不需备案,三是没有被墙,四是稳定可靠,最好能独立部署。

其实计数系统功能可以简单也可以复杂,简单到一个API返回一张带有数字的图片,复杂到后台的统计图表。其中的关键点有两个,一是数据库,二是API。至于后台界面可以用SPA通过静态页解决。

Google Firebase的实时数据库技术支持远程访问,特别是支持JavaScript SDKREST APIZeit Now是新的Serverless部署方案,支持Node.js在内的多种平台。Google Firebase的不足是国内无法访问,Now的不足是没有持久化数据库。Now支持访问第三方API获取数据,配合Google Firebase 的REST API正好解决了持久化的问题。

Now最新的Serverless部署方案叫做Lambdas,支持monorepo部署方式。

比如now.json

{
  "version": 2,
  "builds": [
    { "src": "test.html", "use": "@now/static" },
    { "src": "*.php", "use": "@now/php" },
    { "src": "api/index.js", "use": "@now/node" }
  ]
}

对同一项目REPO运行多种程序,暴露多个API,方便混合部署方案,增加了灵活性。

Zeit Now对于敏感数据还提供了Secrets,可用于保存Google OAuth2 访问令牌,或者其他机密配置。

前期技术背景调查的差不多了,没有发现硬性缺陷导致无法实现最终功能的问题。现在可以创建一个最简单的项目,暴露一个Vue的Hello World单页应用,和一个Node的Hello World REST API,然后集成Google Firebase,实现点击计数的逻辑,最终实现点击计数的后台统计页面。

经过两天的功能开发,发现Zeit Now的本地开发流程不是十分友好,比如Lambdas函数不能本地运行,部署后依赖导入失败。由于系统版本升级,文档对于混合编程中的Lambdas函数介绍不是很丰富,就先简单使用[Zeit Micro]实现了第一版的计数程序。

效果见标题上方比较突兀的数字,由于使用SVG作为图像,所以看起来与其他文字不协调。不过使用图片的优点就是简单,不需要JavaScript的执行。

Nodejs后端代码见https://marskid-blog-counter.now.sh/_src

在Ghost Theme中post.hbs合适的位置插入以下代码就可以显示当前文章的阅读次数:

<img src="https://marskid-blog-counter.now.sh/?url={{url absolute="true"}}"/>

使用REST API导致服务性能不高,每个请求都要耗时900毫秒以上。如果服务端采用JavaScript SDK能提高性能的话也可以尝试。不过JavaScript SDK采用的是WebSocket长连接技术,维护一个长连接对于Zeit Now这样可能随时进入休眠状态的服务不知道是否稳定可靠,而且Zeit Now还有打包大小限制,引用的库大小限制在5MB。

原文链接:https://marskid.net/2018/11/18/serverless-click-counter/