Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

建议:聚合 checkLocationWorkerRoute 请求以减少 worker 请求数及使用 Cloudflare D1 存储数据 #46

Open
Tsuk1ko opened this issue Jul 4, 2024 · 15 comments · May be fixed by #47
Labels
enhancement New feature or request

Comments

@Tsuk1ko
Copy link

Tsuk1ko commented Jul 4, 2024

看了下目前的实现,每个 checkLocationWorkerRoute 都会发出独立的请求来请求自身,这相当于每个此设置都会增加1440请求/天

这在一般情况下也许无关紧要,但当设置此项的节点数较多,并且用户也部署了其他请求消耗不低的服务的情况下,这个请求量也许不能忽视

是否可以进行改进,将相同 checkLocationWorkerRoute 的请求聚合,例如

const groupedCheckLocationWorkerRoute = new Map<string, string[]>();

workerConfig.monitors.forEach(({ id, checkLocationWorkerRoute }) => {
  const targets = groupedCheckLocationWorkerRoute.get(checkLocationWorkerRoute) || [];
  if (!groupedCheckLocationWorkerRoute.has(checkLocationWorkerRoute)) {
    groupedCheckLocationWorkerRoute.set(checkLocationWorkerRoute, targets);
  }
  targets.push(id);
});

for (const [checkLocationWorkerRoute, targets] of groupedCheckLocationWorkerRoute) {
  const resp = await fetch(checkLocationWorkerRoute, {
    method: 'POST',
    body: JSON.stringify({
      targets,
    }),
  }).json<{ location: string; status: Array<{ id: string; ping: number; up: boolean; err: string }> }>();
}

然后修改 fetch handler 以支持批量 getStatus

@lyc8503 lyc8503 added the enhancement New feature or request label Jul 4, 2024
@lyc8503
Copy link
Owner

lyc8503 commented Jul 4, 2024

确实 UptimeFlare 占用的免费资源配额较多(特别是 KV 写), 请求对我来说倒还好.

我暂时的 workaround 是, 我单独开了一个账号用于部署 UptimeFlare, 防止和我其他服务相互干扰. 我记得上次搜索发现一个人持有多个 Cloudflare 账号不违反 Cloudflare 的 TOS.

@Tsuk1ko
Copy link
Author

Tsuk1ko commented Jul 4, 2024

创建单独的账号确实是一个办法,但是有点麻烦,并且如果要自定义域名的话就很难办了

你这么一说确实对 KV 的写入消耗的会比较多,而且限制1000/天

我的想法是可以换成用 D1 去记录,限制10w/天,这是绰绰有余的,而且也完全可以摆烂,跟以前 KV 一样记一行字符串就行

不过 D1 我自己也只是粗略用过的程度,如果真的需要切换到 D1,需要研究的点还挺多的

  1. D1 使用前需要用 sql 初始化数据库表,如何将这一步纳入自动化
  2. D1 不知道是否可以像 KV 一样直接内嵌到 pages 中使用,不能的话就额外用 pages function,就跟现在提供的 json api 一样,但是其实也不是个坏事,前后端分离的话数据定时更新就不用像现在这样刷新整个页面了
  3. 迁移问题,老用户的 KV 数据要怎么迁移到新的 D1 里,或者直接不管了重新开始(

@lyc8503
Copy link
Owner

lyc8503 commented Jul 6, 2024

我主要比较头疼的是 (3), 迁移到 D1 还得写代码帮助现有用户迁移数据, Cloudflare 平台调试起来灵活度并不高, 比较繁琐, 而且目前发布也没有明确的版本号, 也很难指示用户如何升级. 作为个状态监控不能太折腾, 简单稳定就行.

还发现一个问题: 根据文档, 最大的一个 row 只能存储 1MB 的 string, 相比 KV 的 25MB 还是少了些的, 监控一多容易超. 用关系型数据库强行存长 string 感觉也不太好, 虽然从表面参数上看来 D1 几乎全方位超越了 KV, 我甚至可以把长 JSON 字符串切成多份存起来.

但是有点麻烦,并且如果要自定义域名的话就很难办了

Pages 是支持 CNAME 绑定域名的, 你可以把你主账号的域名直接用 CNAME 接入 Cloudflare 小号的状态页. 我目前就是这么干的.

前后端分离的话数据定时更新就不用像现在这样刷新整个页面了

现在也是可以加个 API 返回最新数据, 然后不刷新的情况下更新页面. 只是我偷懒了, 我测试下来原地刷新页面的话, 体验也还好, 不会有长时间空白, 就稍微闪一下.

@Tsuk1ko
Copy link
Author

Tsuk1ko commented Jul 6, 2024

确实,长度问题的话还得重新设计一下储存方式

不过我目前试着改了一下,已经能用 D1 了,完成了上述的(1)和(2),准备再解决一下你说的行容量问题😂

Tsuk1ko@fe28062

而且你说的解决方案我一想很对啊,直接把 JSON 切分是最简单又节省 db 读写次数的办法,反正这个应用目前一定是要读取完整的 state 的

Tsuk1ko@5485170

image

Pages 是支持 CNAME 绑定域名的, 你可以把你主账号的域名直接用 CNAME 接入 Cloudflare 小号的状态页. 我目前就是这么干的.

这个我知道是可以,但如果要使用 checkLocationWorkerRoute 的话要给 worker 绑路由,这个应该就只能把域名放小号上才行?

@lyc8503
Copy link
Owner

lyc8503 commented Jul 6, 2024

非常感谢你的代码实现, D1 看起来确实很不错. 我之后有空的时候尝试看看能不能解决旧数据迁移和长度的问题, 然后尽量在某次升级时平稳自动迁移数据到 D1.

但如果要使用 checkLocationWorkerRoute 的话要给 worker 绑路由,这个应该就只能把域名放小号上才行?

这确实是的, 我找了个不用的 eu.org 绑到了我的小号😂

而且你说的解决方案我一想很对啊,直接把 JSON 切分是最简单又节省 db 读写次数的办法,反正这个应用目前一定是要读取完整的 state 的

简单粗暴, 但很有效.

@Tsuk1ko Tsuk1ko linked a pull request Jul 7, 2024 that will close this issue
@lyc8503 lyc8503 changed the title 建议:聚合 checkLocationWorkerRoute 请求以减少 worker 请求数 建议:聚合 checkLocationWorkerRoute 请求以减少 worker 请求数及使用 Cloudflare D1 存储数据 Aug 21, 2024
@Yuk-0v0
Copy link

Yuk-0v0 commented Oct 4, 2024

目前有在推进迁移到D1吗,部署第一天就发邮件超出上限了😭

@lyc8503
Copy link
Owner

lyc8503 commented Oct 4, 2024

目前有在推进迁移到D1吗,部署第一天就发邮件超出上限了😭

最近比较忙, 升级数据结构比较麻烦, 要解决一些兼容性问题, 如有其他项目建议单独创建新账号部署.

@lyc8503
Copy link
Owner

lyc8503 commented Oct 5, 2024

目前有在推进迁移到D1吗,部署第一天就发邮件超出上限了😭

你也可以尝试使用这里提到的方法降低 KV 写入数量: #63 (comment)

@Yuk-0v0
Copy link

Yuk-0v0 commented Oct 6, 2024

目前有在推进迁移到D1吗,部署第一天就发邮件超出上限了😭

你也可以尝试使用这里提到的方法降低 KV 写入数量: #63 (comment)

感谢

@nickdlkk
Copy link

nickdlkk commented Oct 7, 2024

天天报警 希望能修复

@lyc8503
Copy link
Owner

lyc8503 commented Oct 7, 2024

天天报警 希望能修复

这目前不是一个 Bug,尽管将来迁移到 D1 确实能缓解这个问题... 如果你希望有关闭警告的方法,你需要和 Cloudflare 官方提出反馈。(我也没找到关闭警告的方法)

目前我使用 Gmail 的筛选器功能自动删除相关警告邮件,供参考:

image

@AkarinLiu
Copy link

我在使用的时候发现产生了很多费用,Workers 创建了一个 R2 API 令牌,我比较担心费用经不起消耗。

@lyc8503
Copy link
Owner

lyc8503 commented Nov 1, 2024

我在使用的时候发现产生了很多费用,Workers 创建了一个 R2 API 令牌,我比较担心费用经不起消耗。

什么意思?本项目目前并没有使用 R2,每天调用的最贵的资源应该也只是 KV 写入(小于 1000 次每天,在免费额度内,就算按现在付费定价也小于 0.005 美元每天),不应该造成过多的费用消耗。

@lyc8503
Copy link
Owner

lyc8503 commented Nov 19, 2024

确实,长度问题的话还得重新设计一下储存方式

看起来不用了,因为我发现 Cloudflare Workers CRON Job 进行 JSON.parse 时可能会超过 10ms 的 CPU 限制,所以还是要严格控制存储状态的 JSON 大小。现在比较奇怪的是 Cloudflare 之前似乎没有严格执行文档中说明的 10ms 限制,最近在某次更新中补充了,不到两天之后又去除了,处于一种不太稳定的状态。(Workers 的文档和功能最近都有一次大更新)

我正在尝试使用本项目申请 Cloudflare 的 Project Alexandria,后续如果通过的话我会发 Support Case 问一下。

另,使用 D1 可以得到比 KV 存储强得多的一致性,我可能可以实现更多功能(例如在网页上编辑历史事件,如添加事件说明,删除 false positive 事件等),我会尝试在后续更新中实现。

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


Indeed, if the length is a problem, we have to redesign the storage method.

It seems that there is no need, because I found that the Cloudflare Workers CRON Job may exceed the 10ms CPU limit when performing JSON.parse, so it is still necessary to strictly control the JSON size of the stored state. What is strange now is that Cloudflare did not seem to strictly implement the 10ms limit stated in the document. It was recently added in an update and then removed less than two days later, leaving it in an unstable state. (Workers’ documentation and functionality have recently been updated)

I am trying to use this project to apply for Cloudflare's Project Alexandria. If it is approved, I will send a Support Case to ask.

In addition, using D1 can get much stronger consistency than KV storage. I may be able to implement more functions (such as editing historical events on the web page, such as adding event descriptions, deleting false positive events, etc.). I will try to update in the future. realized in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants