设 Tokinx 09-30 Typecho-Workers 安装指南 在前面的几篇文章中,我梳理了把博客搬迁到 Cloudflare 边缘无服务器(Serverless / Edge)架构的完整过程:从最开始处理 10ms CPU 超时、平滑迁移历史文章与笔记,到构建平台层零 CPU 缓存,再到重构主题并实现评论动静分离。 在这段重构与打磨后,这个名为 Typecho-Workers 的项目已经在我的生产环境平稳运行。对于同样希望摆脱传统 VPS 维护繁琐、搭建一套轻量且低成本个人博客的朋友,这篇文章将详细介绍这套系统的全貌,并提供一份清晰完整的部署上手指南。 一、系统全貌与核心特性 Typecho-Workers 是基于经典博客系统 Typecho 的数据库设计,使用 TypeScript 在 Astro + Cloudflare Workers 架构下重写的一套现代博客系统。 它拥有静态博客的低维护成本与极速响应,同时完整保留了动态博客的在线写作后台、原生评论互动与插件扩展能力。 1. 现代边缘计算架构 运行环境:跑在 Cloudflare 全球 300+ 节点的 Workers 运行时中; 数据与存储:使用 Cloudflare 原生 #随笔
设 Tokinx 08-31 前台体验重塑 —— 从笔记动态到评论动静分离 底层的初始化、数据迁移以及多级缓存搞定后,博客的基础设施基本稳了。接下来,我把精力转回到了读者与作者端的前台体验——如何让随笔记录更轻快,以及如何让前台主题在拥有丰富交互的同时,保持极高的边缘缓存命中率。 为什么我需要“微动态/笔记”? 写正经长文往往需要构思提纲、组织段落、排版配图,写一篇得花上几个小时甚至几天。这种较重的心理负担,很容易让人一拖再拖。 在日常生活中,我经常会有一些零碎的想法、随手拍的照片、一段代码片段,或者只是几句随感。这些内容发长文显得单薄,发在第三方社交平台又容易淹没在算法信息流里。 我希望博客里有一块轻量记录的自留地: 发布足够轻便:随手写两句话、传几张图就能直接发; 支持多媒体:不仅能发多图,还要有自适应九宫格、灯箱预览,以及音视频内嵌播放; 话题聚合:支持正文直接写 #话题 进行归类; 权限灵活:支持发布仅自己可见的私密随感。 基于这些需求,我开始动手开发 typecho-plugin-notes 插件。 1. 坚持不改动原生表结构 在规划数据存储时,我坚持了一个原则:不修改 Typecho 的原生数据库 Schema。 这样能保证 #随笔
设 Tokinx 08-27 从多级缓存到 Workers Caching,资源开销骤降 98.7% 性能优化实践 历史数据全部导入完成后,博客终于像模像样地跑起来了。本以为接下来就能安稳地写写笔记,没想到第二天一早打开 Cloudflare 控制台,迎面而来的却是一条鲜红的配额超限报警。 在没有任何突发流量、仅仅是搜索引擎爬虫日常抓取和少量正常访问的情况下,D1 Database 的单日读操作行数直接飙到了 600 万 ~ 900 万行,直接击穿了 Cloudflare 每天 500 万行的免费额度。 Cloudflare D1 Usage: 6.8M / 5.0M rows read per day (Quota Exceeded Alert) 不仅数据库报警,Worker 的执行次数与 CPU 时间也一直在高位徘徊。 为什么读操作会暴涨? 我让 AI 分析近 12 小时日志排查原因。结果原因很简单,在未加缓存的纯 SSR(服务端渲染)模式下,每次请求到达 Worker,都会完整走一遍 Astro 的服务端渲染流程: 查 typecho_options 加载全站站点配置; 查 typecho_metas 加载分类和标签列表; 查 typecho_contents 加载文章正文和自 #随笔
设 Tokinx 08-25 从 WordPress 到 Typecho-Workers 的数据映射与导入 书接上回,解决完初始化的 10ms CPU 超时问题后,程序总算能顺利运行了。接下来最重要的任务,就是把旧博客里的历史数据完整搬过来。 我的旧数据来自 WordPress 导出的 WXR(XML)备份文件。正经的文章和页面数据其实不算多,但十多年里积累下来的上万条读者评论,每一条都是弥足珍贵的互动记录;再加上数年来随手记录的日常笔记,构成了整个博客最核心的数字资产。 数据的构成与难点 常规内容的迁移相对直接: 文章与页面:标题、正文、发布时间、分类与标签的映射关系很明确,直接转换成 typecho_contents 和 typecho_metas 即可; 评论数据:主要在于维护父子层级的 parent 引用,按时间先后顺序插入并关联对应的文章 cid。 比较麻烦的是笔记(Notes)。 早年在 WordPress 中,我为了记录零散的想法与日常随笔,专门通过自定义文章类型(Custom Post Type)扩展了一套微贴系统。这部分数据在导出文件里非常特殊: 字段分散:正文属于 post_type = 'note',但点赞数、话题、关联的多张图片附件 ID 全部分散在 #随笔
设 Tokinx 08-23 10ms 魔咒 —— PBKDF2 降档与 HMAC Pepper 安全加固 书接上回,选定 Typecho-CF 之后,我兴冲冲地把它打包部署到了 Cloudflare Workers 上,本以为马上就能用上,没想到出师不利,初始化这一步就被卡住了。 代码发布上去后,我打开绑定的域名进入 /install 页面,输入站点名称、管理员账号和密码,点击“开始安装”。浏览器转圈两三秒,随后弹出了一个红色错误页: Error 1102: Worker exceeded CPU time limit. 博客没能初始化成功,数据库里的初始表和管理员账号也只写了一半。 为什么会 CPU 超时? 我把当时的 Worker 运行日志和安装代码发给 AI 协助排查。AI 顺着调用栈逐行分析,很快指出了问题所在:在创建管理员账号时,密码哈希计算耗尽了 CPU 时间。 Cloudflare Workers 对请求有严格的算力限制: Free 计划:单个请求的纯 CPU 时间上限为 10ms。 Paid 计划:默认 50ms,最高可调整至 3000ms。 这里的 10ms 指的是 CPU 实际计算时间,等待数据库读写或网络 IO 的时间并不计入其中。 原项目为了遵循 #随笔
设 Tokinx 08-22 将 Typecho 跑在 Cloudflare Workers 一、为什么想折腾这个? 其实工作之后博客就很少更新了。很多时候脑子里冒出一个不错的想法,真打算坐下来写的时候,又总觉得内容太简单、不太值得分享,于是慢慢养成了只写“笔记”的习惯——记录一些零碎的想法和短篇随笔。 然而,一个更新频率并不高的博客,传统架构的维护成本却一点也没少: 服务器维护繁琐:要维护服务器、运行环境、程序更新,偶尔还得防范扫盘和挂马; 资源浪费严重:就像一台服务器二十四小时开着,却只为了一个偶尔才有人访问的页面,开销不少,性价比极低。 中途我也动过把博客彻底迁移到 Hugo、Hexo 这类静态博客(SSG)上的念头。静态托管在 GitHub Pages 或 CDN 上确实能免去服务器运维,但实际体验下来却发现并不顺手: 发布流程冗长:每次写篇随笔或改个错字,都得开本地编辑器编译、提交 Git 仓库、再等 CI/CD 部署,完全失去了随手记录的即时感; 评论与互动割裂:静态博客无法原生处理动态评论,只能依赖第三方挂件(如 Waline、Twikoo 等)或自建服务,评论管理和审核都极为割裂。 既想要静态博客的免运维、低成本与高并发,又想要动态博客的在线写作 #随笔
设 Tokinx 2025-08-07 1Panel V1 升级 V2,以及命令注入漏洞 CVE-2025-54424 相关问题 一大早收到腾讯云漏洞通知的邮件,显示 1Panel 命令注入漏洞 CVE-2025-54424,等级是高危,查了下这是 V2 版本才有的漏洞,我 V1 你提示个 der? 不过几个服务器基本都是 Proxy 用,没放什么东西,看了下官方更新记录 V2.0.6 已经修复了这个问题,索性花一点时间把 1Panel 升级到 V2 尝尝鲜。 CVE-2025-54424 目前影响返回仅 V2.0.0 ~ V2.0.5,V1 用户不在此次楼都影响范围内,可以不用升级。当然跟我一样想升级 V2 尝鲜除外。 因为我现在还是 V1.10.32,所以还得先想办法升级到 V2 再升级 2.0.6,好在查了下官方已经有迁移脚本了: 郑重提醒 升级有风险,操作需谨慎。一切操作请提前备份好文件或创建磁盘快照。 安装升级脚本 此处以 X86 架构为例,升级版本为 v2.0.6,如果使用其它加购或要升级到其它版本请参考官方数据迁移脚本 1panel-migrator: # 1. 进入临时目录 cd /tmp # 2. 下载适用于您服务器架构的二进制文件(以 amd64 架构为例) wget htt #代码
设 Tokinx 2025-07-09 白嫖Cloudflare R2,失误反被扣费 前段时间不小心把服务器搞墙了,临时想办法套了下CF,顺便研究了下大善人家里都有哪些服务可以白嫖,正好看到R2有免费10G的存储空间,想着服务器也没有设置自动备份,不如把这空间拿来做数据备份吧。 谨慎选择“不频繁访问” 说干就干,结果创建存储桶时看着“默认存储类”,想着备份数据确实是“不频繁访问”的数据,就选这个吧(明明下面那么明显的颜色提示免费层不适用于不频繁访问存储的使用,愣是完全忽略掉了) 愉快了自动备份了一段时间,结果8号收到银行卡的扣费通知,扣费9.92刀 好嘛,总共就用了10来天,结果原本是来白嫖的,结果居然被反嫖了 仔细翻了下文档才发现,只有Standard storage 标准存储桶免费!!! 行吧,钱也扣了,就当免费用CF的嫖资了,也顺便把存储桶改成标准存储桶,以免再次扣费。 Cloudflare又称赛博大善人,我也一直用CF的DNS解析服务,今年陆陆续续把域名都转到CF了,托管到CF可以非常丝滑的白嫖他们家各种服务,Catch-all Email、Workers、D1 database、Tunnels都正在免费使用中,这次R2误操作被扣费完全是手太快导致 #随笔
设 Tokinx 2022-05-14 WordPress社交营销优化之OpenGraph 最近主题想实现一个分享链接自动解析 URL,并以卡片形式展示目标链接内容的功能,几经调研发现这个需求早在10多年前就已经有相应的标准了,它就是有 FaceBook 提出的 OpenGraph 协议(开放图谱协议) OpenGraph是什么 我们知道,构建一个网站采用的技术和实现方式并不相同,普通方法无法完美地解析目标页面的基本信息,导致没有 OpenGraph 协议时分享的链接展示形式相当有限,而且看起来没有非常大的点击欲望。 OpenGraph 协议简单来说就是向网页 head 下插入一些统一标准的 meta 元信息,支持标题、描述、缩略图等信息,大大方便了第三方网站和应用地解析出目标页面的基本信息,并加以优化展示链接的目标页面,使其点击率可以大大提升。 比较直观的讲就是,网页只需要加入 OpenGraph 元信息,当页面被分享到微博、FB、Twitter 时,URL 会被智能地解析成一个非常精美地卡片显示: 实际应用 了解了这么多,我们自己的网站和应用如果想要优化链接展示让然也可以读取 OpenGraph 元信息。 其中PHP就可以使用 get_meta_tags 方 #代码
设 Tokinx 2022-04-07 Image()函数加载base64图片无onload事件的前端兼容方案 Image()函数将会创建一个新的HTMLImageElement实例。它的功能等价于 document.createElement('img') 正常情况下,我们使用下面方法加载图片,是能能够获取到onload事件的: const img = new Image(); img.src = 'picture.jpg'; img.onload = () => { console.log('success'); } 但是如果你需要加载的图片是base64图片时,可能是因为没有请求发出,onload事件是无法执行的。 几经尝试,最终考虑将base64图片转位ObjectUrl再加载,好处是无需后端,纯前端即可兼容。移动端兼容性也非常不错。 具体实现如下: // base64转Blob const base64ToBlob = (base64Data) => { const arr = base64Data.split(','), type = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), len = bstr.length, u #代码