LeanCloud 遗憾谢幕:基于 EdgeOne KV 打造高性能 PV/UV 访客统计

本文最后更新于 2026年2月16日 上午

2026 年 1 月 12 日,LeanCloud 官宣停服。对于数以万计的静态博客主而言,这无异于一场“地震”:原本依赖它实现的文章阅读量(PV)与站点访客(UV)统计将在一年后彻底停摆

面对终局,博主们面临抉择:是继续寻找下一个易损的 BaaS 平台,还是斥资租赁云服务器、投入繁琐的运维成本去“大炮打蚊子”?

其实,对于追求轻量的静态博客,我们需要的仅仅是一个纯粹、快速且自主的计数器。相比复杂的服务器自建方案,基于边缘计算的 SaaS 化改造显然更契合 Hexo 的极简灵魂。

又是熟悉的配方

与其被动等待下一个“关停通知”,不如利用 Serverless + KV 存储 技术,打造一个轻量、完全可控的计数器(甚至还是免费的)。

这就是 OpenKounter 诞生的故事。

危机时刻

让我们回到 2026 年 1 月发布停服公告的那一刻。

当你像往常一样打开 LeanCloud 控制台查看数据时,映入眼帘的是一行醒目且冰冷的公告:

LeanCloud 官方公告(2026-01-12):平台将于 2027-01-12 正式停止对外服务。

LeanCloud 停服公告

虽然此刻你的博客阅读量还在正常显示,但倒计时的钟声已经敲响。你知道,如果不采取行动,一年后的今天,所有文章辛辛苦苦积累的阅读数据,都将随着服务器的关闭而彻底归零。

Hexo 文章的 PV统计

你的第一反应是:“我的数据怎么办?”

幸运的是,LeanCloud 提供了数据导出功能。但导出之后呢?这些 JSON 文件该往哪儿放?重新找一个第三方服务?还是自己搭建一个后端?

如果选择自建,传统方案需要:

  • 一台云服务器(价格不高,主要是需要维护)
  • 一个数据库(MySQL/MongoDB)
  • 一套后端框架(Express/Flask/Django)
  • 定期维护、备份、监控……

对于一个月度 PV 大概 1W 次的网站来说博客来说,单独维护这一套内容,有一些太“重”了。尤其是 Hexo 这样的静态博客网站:

Mintimate's Blog 的 PV

有没有一种方案,既免费、又轻量、还能完全掌控数据?

答案是:Serverless + 边缘计算。尤其是 Hexo 博客也是部署在静态托管服务上的,完全可以利用同一平台(EdgeOne Pages)的 Serverless 功能来实现计数器的功能。

EdgeOne Pages

在介绍 OpenKounter 之前,我们先聊聊它的“地基”——EdgeOne Pages

EdgeOne Pages 是腾讯云推出的 Serverless 静态网站托管服务,类似于 Cloudflare Pages、Vercel 或 Netlify。它集成了静态托管、Edge Functions 和 Node.js Functions。它的核心能力包括:

  • 静态资源托管:自动部署你的前端项目(Vue、React、Hexo 等)。
  • Edge Functions:在边缘节点运行的 Serverless 函数,响应速度极快,支持操作 KV 存储。
  • Node.js Functions:支持完整的 Node.js 运行时,适合复杂的业务逻辑。
  • KV 存储:全球分布式的 Key-Value 数据库,读写延迟低至毫秒级(目前仅支持 Edge Functions 调用)。

EdgeOne Pages 架构图

什么是 KV

如果你用过 Redis,你可以把 KV 当作 Lite 版本的 Redis:

能力 Redis EdgeOne KV
典型用途 缓存热点数据、Session 存储、限流计数器 页面访问计数、配置存储、临时状态
使用方式 需要自建/租用 Redis 实例,维护连接池 直接通过 Edge Functions 调用,零运维
数据结构 支持 String、Hash、List、Set 等丰富类型 纯 Key-Value,Value 存储字符串或 JSON
持久化 支持 RDB/AOF 持久化 自动持久化,无需备份
TTL 过期 主动删除,到期自动清理 被动过期,可逻辑自动清理,但无法主动过期清理
部署位置 通常是中心化的单个或集群节点 全球边缘节点就近访问

举个例子:用 Redis 做页面计数,你需要:

1
2
3
// 需要额外购买 Redis 服务,配置连接
const redis = new Redis('redis://your-redis-host:6379');
await redis.incr('counter:/posts/hello-world/');

用 EdgeOne KV,直接在 Edge Function 里写:

1
2
3
4
// KV_DEMO 是内置绑定,无需配置连接
const data = await KV_DEMO.get('counter:/posts/hello-world/');
const count = data ? JSON.parse(data).time + 1 : 1;
await KV_DEMO.put('counter:/posts/hello-world/', JSON.stringify({ time: count }));

KV 存储不是万能的,它不像 Redis 能执行 INCREXPIRELPUSH 等原子操作,也不适合存储大量热数据。但对于博客计数、配置开关、简单状态这类需求,它足够简单、足够快

sequenceDiagram
    participant U as 👤 用户
    participant EO as ☁️ EdgeOne
    participant KV as 📦 KV 存储
    
    Note over U,EO: 🏢 传统方案
    U->>EO: 访问博客页面
    EO->>EO: 云服务器处理
    EO->>EO: Express/Flask 应用
    EO->>EO: 数据库查询
    EO-->>U: 返回页面 (200-500ms)
    
    Note over U,KV: ☁️ EdgeOne 方案
    U->>EO: 访问博客页面
    EO->>EO: 边缘节点处理
    
    alt 静态资源
        EO->>EO: CDN 缓存命中
        EO-->>U: 返回静态资源 (< 50ms)
    else Edge Functions
        EO->>EO: Edge Functions 执行
        EO->>KV: KV 存储读写
        KV-->>EO: 返回数据
        EO-->>U: 返回动态内容 (< 50ms)
    else Node.js Functions
        EO->>EO: Node.js Functions 执行
        EO->>KV: KV 存储读写
        KV-->>EO: 返回数据
        EO-->>U: 返回复杂逻辑
    end
    
    Note right of EO: 零运维 + 自动扩展

EdgeOne Pages 的免费额度非常慷慨:

  • 安全加速流量 / 请求:不限量
  • Edge Functions 请求:300 万次/月
  • Cloud Functions 请求:100 万次/月
  • KV 存储空间:1 GB

对于个人开发者来说,这些额度足够用到天荒地老。当然,如果你对 SLA 有较高的要求,那么更推荐使用自有服务。

OpenKounter

有了 EdgeOne Pages 这个”地基”,我们就可以开始搭建 OpenKounter 了。首先是项目地址:

OpenKounter 管理员面板

OpenKounter 的设计哲学是:简单至上,性能优先

我没有使用关系型数据库(MySQL、PostgreSQL等),完全基于 KV 存储 来实现计数逻辑:

graph TB
    User[👤 访客] -->|访问博客| Blog[Hexo 博客页面]
    Blog -->|加载| Adapter[🔌 OpenKounterClient.js]
    
    subgraph EdgeOne[☁️ 腾讯云 EdgeOne]
        Adapter -->|API 请求| Function[⚡️ Edge Functions]
        Admin[🔑 管理员] -->|访问| Dashboard[📊 管理后台]
        Dashboard -->|API 请求| Function
        
        Function -->|读写| KV[(📦 KV 存储)]
    end
    
    style EdgeOne fill:#e1f5ff,stroke:#01579b,stroke-width:2px
    style Function fill:#fff3e0,stroke:#ff9800,stroke-width:2px
    style KV fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px

简单说(技术视角):

  • 零运维 / 低成本 — 完全 Serverless,EdgeOne 的额度通常足够个人开发者使用。
  • 毫秒级响应(O(1)) — 边缘执行 + KV 的 O(1) 读取,单次计数延迟通常 < 50ms。
  • 无缝替换 LeanCloud — 提供兼容的 OpenKounterClient.js 用于作为客户端接入 Demo。
  • 数据可控 & 易备份 — 数据存在你的 EdgeOne 账号;同时 OpenKounter 提供管理员界面,支持导入/导出 JSON 数据,也支持 LeanCloud 数据导入。

Easy!

架构设计

OpenKounter 代码量不大,核心也就几百行。但考虑到 KV 存储没有 Redis 那样的查询语句、批量查询和自带排序算法,还得兼容 LeanCloud 老数据,设计上确实得小动脑子一下。

咱们平时用惯了 MySQL 或 MongoDB,换到 KV 存储可能会有点不适应。

这东西就像 Redis,快是真快,但“毛坯”也是真“毛坯”——没复杂查询,没事务,连排序都得自己想办法。

嘿嘿,真实难倒我了

为了解决这些痛点,我用了几种设计模式来搭”骨架”.

KV 存储模式

在 OpenKounter 中,每一个页面的阅读量都是 KV 存储中的一个键值对。

  • Key: counter:{页面路径} (例如 counter:/posts/hello-world/)
  • Value: JSON 字符串,包含计数值和时间戳。
1
2
3
4
5
{
"time": 1024,
"created_at": 1700000000000,
"updated_at": 1700000000000
}

这种设计使得读取特定页面的计数极其高效(O(1) 复杂度)。

当用户访问 /posts/hello-world/ 时,系统只需执行一次 KV 查询:

1
2
const data = await OPEN_KOUNTER.get('counter:/posts/hello-world/');
const count = data ? JSON.parse(data).time : 0;

相比传统数据库的 SELECT * FROM counters WHERE path = '/posts/hello-world/',KV 存储的查询速度快了数十倍

索引旁路模式

KV 存储的一个缺点是难以进行”范围查询”或”获取所有 Key”。比如,你想在管理后台展示”最近更新的 20 个计数器”,传统数据库可以轻松实现:

1
SELECT * FROM counters ORDER BY updated_at DESC LIMIT 20;

但 KV 存储没有 ORDER BY,也没有 LIMIT。怎么办?

OpenKounter 的解决方案是:维护一个索引列表

每当创建或更新一个计数器时,系统会更新一个特殊的 Key:system:counter_index。这个 Key 存储了一个数组,包含了所有已存在的计数器 Key,按更新时间排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// edge-functions/api/counter.js 中的核心逻辑
async function updateIndex(target) {
const indexKey = 'system:counter_index';
// 1. 获取现有索引
const indexData = await OPEN_KOUNTER.get(indexKey);
let index = indexData ? JSON.parse(indexData) : [];

// 2. 移除旧位置(如果存在)
const idx = index.indexOf(target);
if (idx > -1) {
index.splice(idx, 1);
}
// 3. 将当前 Key 移到末尾(表示最近更新)
index.push(target);

// 4. 写回索引
await OPEN_KOUNTER.put(indexKey, JSON.stringify(index));
}

通过这种方式,我们在管理后台就可以轻松实现”按更新时间排序”的计数器列表,而无需遍历整个 KV 数据库。

1
2
3
4
// 获取最近更新的 20 个计数器
const indexData = await OPEN_KOUNTER.get('system:counter_index');
const index = JSON.parse(indexData);
const recentKeys = index.slice(-20).reverse(); // 取最后 20 个,倒序排列

这种模式被称为 Index-Aside(索引旁路),是 KV 存储中常用的优化技巧。

Passkey 认证

OpenKounter 内置了基于 WebAuthn 的 Passkey 认证,支持指纹、Face ID 等生物识别方式登录管理后台,告别繁琐的 Token 密码输入。

核心流程分为注册和认证两个阶段:

sequenceDiagram
    participant U as 👤 用户
    participant F as 🖥️ 前端
    participant E as ⚡️ Edge Function
    participant KV as 📦 KV 存储

    Note over U,KV: 注册流程
    U->>F: 点击绑定 Passkey
    F->>E: generateRegistrationOptions
    E->>KV: 保存 Challenge (TTL 5min)
    E-->>F: 返回注册选项
    F->>U: 调用 WebAuthn API
    U-->>F: 返回凭证
    F->>E: verifyRegistration
    E->>KV: 验证并删除 Challenge
    E->>KV: 保存凭证
    E-->>F: 注册成功

    Note over U,KV: 认证流程(管理令牌)
    U->>F: 验证 Passkey 更新 Token
    F->>E: generateAuthenticationOptions
    E->>KV: 保存 Challenge
    E-->>F: 返回认证选项
    F->>U: 调用 WebAuthn API
    U-->>F: 返回签名
    F->>E: generateManagementToken
    E->>KV: 验证并删除 Challenge
    E->>KV: 保存管理令牌 (TTL 5min)
    E-->>F: 返回管理令牌
    F->>E: 使用令牌更新 Token

KV 存储结构设计如下:

Key 说明 TTL 说明
passkey:user:{userId} 用户信息(token、凭证列表) 永久 -
passkey:credential:{credId} 凭证信息(公钥、计数器) 永久 -
passkey:challenge:{challengeId} 临时 Challenge 5 分钟 被动过期
passkey:mgmt_token:{tokenId} 管理令牌 5 分钟 被动过期

后端在处理注册和认证时,会先清理用户的旧 Challenge,防止脏数据堆积:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// edge-functions/api/passkey.js
async function handleGenerateRegistrationOptions(data, rpConfig, env) {
// ...
// 清理旧 Challenge,防止脏数据堆积
if (user && user.currentChallengeId) {
await kvDelete(`passkey:challenge:${user.currentChallengeId}`);
}
// ...
}

async function getAndDeleteChallenge(challengeId) {
const data = await kvGet(`passkey:challenge:${challengeId}`);
if (data) {
await kvDelete(`passkey:challenge:${challengeId}`);
// 清理用户对象上的 Challenge 指针
if (data.userId) {
const user = await getUser(data.userId);
if (user && user.currentChallengeId === challengeId) {
delete user.currentChallengeId;
await saveUser(user);
}
}
}
return data;
}

EdgeOne KV 的 expirationTtl 参数设置的是被动过期,而非主动删除:

  • 过期数据不会在到期时自动从存储中删除(毕竟不是 Redis 那样的内存数据库)。
  • 只有在下次访问该 Key 时,才会检查是否过期并返回 null
  • 过期但未被访问的数据仍然占用 KV 存储空间

因此,代码中采用双重保障策略

  1. 主动清理(主要策略):在生成新 Challenge 前删除旧 Challenge,防止脏数据堆积。
  2. TTL 兜底(安全策略):确保即使主动清理失败,过期的 Challenge 也不会被误用。

这种设计是 KV 存储的常见实践——TTL 是“安全网”,而非“清理工具”。

Hexo 接入示例

为了让 OpenKounter 能够无缝替代 LeanCloud,我们提供了一个 Hexo 客户端接入示例 adapter.js

这个脚本是专门为 Hexo 博客(特别是 Fluid 主题)设计的客户端工具包,它演示了如何在静态博客中集成 OpenKounter 的计数功能。主要特性包括:

  • 读取配置:从 Hexo 配置文件中读取 server_url 等参数
  • 智能收集:在页面加载时,自动检测页面中的计数器元素(PV、UV、页面浏览数)
  • 批量请求:将多个计数器的更新请求打包成一个批量请求
  • 实时显示:更新页面上的计数显示,提供即时反馈
  • 本地环境过滤:支持 ignore_local 配置,避免本地开发时污染数据
  • UV 去重:使用 localStorage 实现 24 小时内的 UV 去重逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// client/adapter.js - Hexo 接入示例的核心逻辑
(function(window, document) {
'use strict';

// 从 Hexo 配置中获取服务器地址
const API_SERVER = (CONFIG.web_analytics.openkounter && CONFIG.web_analytics.openkounter.server_url) || '';

if (!API_SERVER) {
console.warn('OpenKounter: server_url is not configured');
return;
}

function addCount() {
const enableIncr = CONFIG.web_analytics.enable && validHost();
const getterArr = [];
const incrArr = [];

// 检测并处理站点 PV 容器
const pvCtn = document.querySelector('#openkounter-site-pv-container');
if (pvCtn) {
const pvGetter = getRecord('site-pv').then((record) => {
if (enableIncr) {
incrArr.push(buildIncrement(record.objectId));
}
const ele = document.querySelector('#openkounter-site-pv');
if (ele) {
ele.innerText = (record.time || 0) + (enableIncr ? 1 : 0);
pvCtn.style.display = 'inline';
}
});
getterArr.push(pvGetter);
}

// 检测并处理站点 UV 容器
const uvCtn = document.querySelector('#openkounter-site-uv-container');
if (uvCtn) {
const uvGetter = getRecord('site-uv').then((record) => {
const incrUV = validUV() && enableIncr;
if (incrUV) {
incrArr.push(buildIncrement(record.objectId));
}
const ele = document.querySelector('#openkounter-site-uv');
if (ele) {
ele.innerText = (record.time || 0) + (incrUV ? 1 : 0);
uvCtn.style.display = 'inline';
}
});
getterArr.push(uvGetter);
}

// 检测并处理页面浏览数容器
const viewCtn = document.querySelector('#openkounter-page-views-container');
if (viewCtn) {
const pathConfig = CONFIG.web_analytics.openkounter.path || 'window.location.pathname';
const path = eval(pathConfig);
const target = decodeURI(path.replace(/\/*(index.html)?$/, '/'));

const viewGetter = getRecord(target).then((record) => {
if (enableIncr) {
incrArr.push(buildIncrement(record.objectId));
}
const ele = document.querySelector('#openkounter-page-views');
if (ele) {
ele.innerText = (record.time || 0) + (enableIncr ? 1 : 0);
viewCtn.style.display = 'inline';
}
});
getterArr.push(viewGetter);
}

// 批量发起统计请求
Promise.all(getterArr).then(() => {
if (enableIncr && incrArr.length > 0) {
increment(incrArr);
}
}).catch(error => {
console.error('OpenKounter error:', error);
});
}

addCount();
})(window, document);

这个 Demo 展示了如何将 OpenKounter 集成到 Hexo 博客中。对于其他静态网站生成器(如 Hugo、Jekyll 等),你可以参考这个实现,根据自己的需求进行调整。

这样,Hexo 主题(如 Fluid)无需修改核心代码,只需引入 adapter.js 并配置 server_url 即可完成从 LeanCloud 到 OpenKounter 的迁移。

支持创作

制作教程不易,如果热心的小伙伴,想支持创作,可以加入我们的电圈(还可以解锁远程协助、好友位😃):

WebChart Recognise

志同道合的小伙伴也是知音难觅。

  • 开发者爱好群: 👉 如果你对云服务器、CDN、云数据库和Linux等云计算感兴趣,亦或者喜欢编程、设计、产品、运营等领域,欢迎加入我们的开发者爱好群,一起交流学习(目前可能就我一个人?🤔,毕竟才刚刚创建~)。
QQ_Group Recognise

当然,也欢迎在B站、YouTube或微信公众号上关注我们:

MintimateBlog Recognise

更多:

部署指南

部署 OpenKounter 非常简单,你只需要一个腾讯云账号(用于 EdgeOne Pages 部署),并且开通 Pages 的功能:

开通 EdgeOne Pages

部署项目

EdgeOne Pages 支持直接从 GitHub 仓库部署,并且支持浏览器端的无代码部署流程。点击下方的按钮,直接将项目部署到你的 EdgeOne Pages:

使用 EdgeOne Pages 部署

触发部署

部署完成后,需要绑定 KV 存储。

配置 KV

部署完成后,你需要创建一个 KV 命名空间并绑定到项目:

  1. 进入 EdgeOne Pages 控制台,找到你的项目。
  2. 进入 KV 存储
  3. 创建一个新的 KV 命名空间且变量名称命名为 OPEN_KOUNTER
  4. 重新部署项目以使配置生效。

绑定 KV 存储

测试使用

假设,你的 EdgeOne Pages 域名是 https://your-domain.edgeone.pages.dev,你可以通过以下 API 来测试计数功能:

1
2
3
4
5
6
7
# 查询计数
curl 'https://<your-domain>/api/counter?target=/posts/hello-world/'

# 批量自增(site-pv 和 当前页面)
curl -X POST 'https://<your-domain>/api/counter' \
-H 'Content-Type: application/json' \
-d '{"action":"batch_inc","requests":[{"target":"site-pv"},{"target":"/posts/hello-world/"}]}'

成功响应将返回 code: 0 和计数数据;管理后台首次访问会引导你设置管理员 Token(也可在部署时通过环境变量 ADMIN_TOKEN 预置和找回密码)。

接入博客

在你的 Hexo 博客中(以 Fluid 主题为例),adapter.js 本质上是一个客户端接入的 Demo,你可以直接使用它,也可以根据自己的需求进行修改。

你可以将仓库中的 client/adapter.js 下载下来,放到博客的 source/js 目录下(例如重命名为 openkounter.js),然后在主题配置中引入:

1
2
3
### _config.fluid.yml
custom_js:
- /js/openkounter.js

即使你的主题(如 Fluid)已经内置了 OpenKounter 支持,你也可以通过这种方式引入自定义脚本来覆盖默认行为(需先禁用主题自带的 OpenKounter 或确保脚本执行顺序)。

同时,在博客配置文件中添加 OpenKounter 的服务地址配置(adapter.js 依赖此配置):

1
2
3
4
5
6
7
### _config.yml
web_analytics:
enable: true
openkounter:
server_url: "https://你的项目域名.edgeone.pages.dev"
# 可选:是否忽略本地开发环境 (localhost)
ignore_local: true

当然,同时还需要修改主题的其他配置文件,通常是 analytics.ejsstatistics.ejs 等文件。修改完成后,重新生成并部署博客,刷新页面,你就能看到阅读量统计恢复正常了!

如果你是 Fluid 主题用户,可以查看我的这个 Fork 的这次 Commit: Mintimate/hexo-theme-fluid/commit/dace585020440402641db7e87a189245aa83a0a3,它展示了如何修改主题来兼容 OpenKounter。

修改后的统计组件

如果你使用的是其他主题,可能需要修改 adapter.js 中读取配置(CONFIG 对象)和获取 DOM 用于显示的逻辑。

管理后台

为了管理方便,我在 OpenKounter 里内置了一个基于 Vue 3 的可视化管理后台。

管理后台

访问你的 EdgeOne Pages 域名,首次访问会引导你设置管理员 Token。之后,你可以:

  • 查看计数器列表:按更新时间排序,支持分页。
  • 手动修改计数值:比如从 LeanCloud 迁移数据时,可以批量导入。
  • 配置域名白名单:防止恶意刷量。
  • 导出/导入数据:一键备份所有计数器数据。
  • Passkey 无密码登录:支持生物识别(指纹、Face ID)登录,告别繁琐的 Token 密码输入。

管理后台的设计非常简洁,所有操作都在一个页面内完成,无需跳转。

数据迁移

如果你之前使用 LeanCloud,可以通过以下步骤迁移数据:

  1. 在 LeanCloud 控制台导出数据(JSON 格式)。
  2. 登录 OpenKounter 管理后台。 进入”数据备份”页面,点击”导入数据”。
  3. 上传 JSON 文件,系统会自动解析并导入。

LeanCloud 数据导出

导入完成后,所有计数器的值都会恢复到迁移前的状态。

常见问题(FAQ)

Q: OpenKounter 能直接替代我原来的 LeanCloud 计数吗?

A: 能 — 对于阅读数/站点 PV/UV 等“计数”功能,adapter.js 已经兼容常见主题的调用方式;但它不是完整的 LeanCloud SDK,复杂的 AVObject/查询逻辑需手动替换或迁移。✅

Q: 怎样防止被刷量?

A: 使用域名白名单(管理后台配置 system:allowed_domains)+ 后端的 checkOriginAllowed 校验;对于管理接口请使用 Token 或 Passkey。🔒

Q: 免费额度够用吗?

A: 对于个人博客,大多数情况下 EdgeOne Pages 的免费额度(100 万请求/月、100 GB 流量、1 GB KV)足够;高流量网站请考虑付费方案或缓存优化。💡

Q: 如何在本地调试管理后台?

A: 进入项目目录并运行:

1
2
3
4
5
6
7
8
9
cd open-kounter
# 安装 EdgeOne CLI 工具(如果尚未安装)
npm install -g edgeone
# 登录 EdgeOne CLI
edgeone login
# 关联 EdgeOne Pages 项目
edgeone pages link
# 运行本地开发服务器
edgeone pages dev

具体的调试,可以参考官方文档:

Q: 如何导出备份?

A: 管理后台提供“导出”功能,或使用 API action: "export_all"(需管理员 Token),会返回 countersallowedDomains 的完整 JSON。📦

END

OpenKounter 不仅是一个工具,更是一种思路的展示:利用 Serverless 和边缘计算,我们可以用极低的成本构建高可用、高性能的应用

LeanCloud 的关停,看似是一场危机,实则是一次机遇——它让我们重新思考:我们真的需要一个”大而全”的 BaaS 平台吗?

对于个人博客来说,答案是否定的。我们需要的只是一个简单、可靠、可控的计数器服务。而 OpenKounter,正是这样一个存在。

如果你正在为 LeanCloud 的替代方案发愁,不妨试试 OpenKounter。它开源、免费、且完全属于你。

欢迎 Star 和 Fork,如果有任何问题,欢迎在 Issue 中反馈!

最后,如果你觉得本篇教程对你有帮助,欢迎加入我们的开发者交流群: 812198734 ,一起交流学习,共同进步。



LeanCloud 遗憾谢幕:基于 EdgeOne KV 打造高性能 PV/UV 访客统计
https://www.mintimate.cn/2026/02/14/openKounter/
作者
Mintimate
发布于
2026年2月14日
许可协议