电费 9 毛/天:我让一台 9 年前的旧 MacBook 替我上班,它比入门云服务器还能打

副业掘金系列第 1 篇。不辞职、不融资、不买服务器------我用一台 2017 款的旧笔记本跑起了一个真实收费的 SaaS。这篇文章里有:13 倍的性能翻盘实测、四条隧道三条坑的血泪史、一次亲手拆掉自己公网入口的合规决策、以及一个 kill -9 杀不死的进程。全部数据真实可复现。

一、凌晨一点,我做了个被朋友嘲笑的决定

朋友的原话是:"2026 年了,你用 9 年前的笔记本当生产服务器?"

我的回答是一张电费账单:

方案 月成本 备注
轻量云服务器(2C4G) ¥50+ 还要备案、迁移、续费焦虑
Serverless ¥20-80 流量一上来账单失控
我家抽屉里的 2017 款 MacBook Pro ¥27(电费) i7-7700HQ / 16G,60W × 24h × 0.6 元/度

算下来每天 9 毛钱。 一杯奶茶的三分之一,买一台"从不请假的服务器"。

有人会说笔记本不稳定。先别急着反驳,看到第三节------我用数据说话。## 二、产品就 60 行代码,但它解决真问题

做什么?短链 + 点击统计 API。别看不起眼,做投放、做社群、做私域的人天天在用,市面上的同类服务定价 29 元/月起。

技术选型只有一条原则:零第三方依赖 。Node 24 内置了 node:sqlite,整个后端一个文件:

js 复制代码
const { DatabaseSync } = require('node:sqlite');
const db = new DatabaseSync('./data/musklink.db');

// 产品的核心动作:跳转 + 记点击
const link = db.prepare('SELECT * FROM links WHERE code = ?').get(code);
if (link) {
  db.prepare('UPDATE links SET clicks = clicks + 1 WHERE code = ?').run(link.code);  db.prepare('INSERT INTO clicks (code, ua, referrer) VALUES (?, ?, ?)').run(code, ua, referer);
  res.writeHead(302, { Location: link.long_url });
  return res.end();
}

零依赖不是极简主义洁癖,是商业决策:

  • 没有 node_modules,就没有供应链投毒风险
  • 部署 = 拷一个 .js 文件
  • 客户付费点在"点击统计报表":来源渠道(referrer)、UA、按日聚合------这些我全做了

接入极简,一个 curl 就能用:

bash 复制代码
curl -X POST http://your-host:3456/api/shorten \
  -H "X-API-Key: mk_xxx" \
  -d '{"url":"https://example.com/promo","code":"musk","ttl_days":7}'# => { "short": "http://your-host:3456/musk", "expires_at": "..." }

支持自定义码、有效期、免费版 100 条/付费版 10 万条(超额返回 402 Payment Required------没错,HTTP 状态码自带付费墙)。

三、压测翻车 10 倍:性能优化最贵的不是代码,是没测量就动手

服务写完,我先做了基线压测(2000 请求 / 50 并发)。结果当场打脸:

bash 复制代码
[基线] /health(纯 CPU)    →  2849 req/s
[基线] /TxZy(跳转+写库)   →   290 req/s | 平均 165ms | p99 341ms

同一个进程,读写库路径比纯 CPU 慢了 10 倍。 我的第一反应不是改代码,而是把怀疑范围缩小:不是 Node 不行,不是这台 2017 款的 CPU 不行,问题只能在磁盘写。

真相:SQLite 默认日志模式下,每次写事务都强制 fsync 刷盘。290 QPS 不是我的代码在等 CPU,是在等磁盘转圈。 修复只用了两行:

js 复制代码
db.exec('PRAGMA journal_mode = WAL; PRAGMA synchronous = NORMAL;');
// 顺便:所有 SQL 启动时预编译,请求路径零解析开销

复测:

bash 复制代码
[优化后] 跳转+写库  →  3899 req/s | 平均 11.5ms | p99 28ms

13.4 倍。p99 延迟砍掉 92%。 一台 9 年前的笔记本,写库路径直接追平了纯 CPU 路径。

划重点:优化前先测量。靠猜的话,你大概率会去买新服务器------然后带着同样的瓶颈搬家。

四、公网血泪史:四条隧道,三条是坑,最后我把成功的那条也拆了

笔记本要对外服务,得有公网入口。我一个下午试了四条路:

| 方案 | 结果 |
|---------------|---------------------------|---|-------------|----------------------------------------|
| localhost.run | 建连成功,但匿名模式不返回分配的 URL(改版了) |
| serveo.net | SSH 能连上,转发确认永远不来 | | cloudflared | brew 安装直接失败(macOS 13.7 已被降为 Tier 3 支持) |
| tunnelmole | 成功,30 秒拿到 https 公网地址 |

到这里故事本该结束。但第二天我做了一件朋友更不理解的事:把唯一跑通的隧道亲手拆了。

原因是一条红线:我查了隧道落地服务器------在境外。技术上国内直连确实能通,但一个面向国内客户的商业服务,把入口架在未备案的境外隧道上,等于把地基放在别人的地雷上。

我把它卸载、杀进程、做了三层审计(进程层/工具层/代码层),确认整个服务零外网依赖。正式路径很清楚:花生壳/cpolar 这类国内正规穿透起步 → 有付费客户后上国内云 + ICP 备案。

这不是矫情。在国内,合规不是成本,是你第一天就比别人多的护城河。

五、kill -9 杀不死的值班员

24/7 服务最怕两件事:进程挂了没人拉,合盖了在睡觉。两个都是工程问题: 第一层保险:launchd 托管。 配置只有十行,KeepAlive + RunAtLoad。我做了个残忍的实验------kill -9 强杀生产进程:

复制代码
上次退出码:-9(被我强杀)
当前 PID:30502 ≠ 被杀的 30452  ← launchd 已经把它救活了

强杀后约 10 秒,服务原地满血复活。重启电脑它也会自己爬起来。

第二层:caffeinate -s 常驻,接电源合盖不休眠。它没有 KPI,但它从不请假。

六、生意经:2.8 个客户回本,之后全是利润

最后算账,这是全文最不像技术、但最重要的一节:

  • 竞品 29 元/月,我定价 9.9------不是价格战,是成本结构碾压:边际成本 ≈ 电费
  • 电费 0.9 元/天 ÷ 9.9 元/月 ≈ 2.8 个客户回本
  • 第 3 个付费客户之后,每一分钱几乎是纯利
  • 一年后用利润买正经服务器,这台 MacBook 光荣退役进博物馆

写在最后

造火箭和赚钱,其实是同一个问题:找到那个物理上成本最低、需求真实存在的点,然后用工程师的方式执行。

性能瓶颈不在硬件,在一句 PRAGMA;护城河不在技术,在合规和诚实;服务器不在机房,在你不肯认输的那股劲里。

你的抽屉里是不是也躺着一台被低估的旧电脑?

评论区聊聊你最想让旧设备跑的第一个项目。点赞过 50,我把完整源码整理开源,并更新一篇《从旧笔记本到备案上线:正规军改造全流程》。


技术标签:Node.js | SQLite | 性能优化 | 独立开发。数据均为本机实测,欢迎复现打脸。

相关推荐
wno7041 天前
node.js中使用jquery
前端·node.js·jquery
damoluomu2 天前
Node 的 Headless 出厂没有前台,Java 的 Headless 是从门户里长出来的
java·开发语言·node.js
Dumbness2 天前
一个手机号验证码登录接口的五个坑:无限发码、无限试码,传个数字就让 Express 进程退出
node.js·express
怒放的生命19912 天前
本地用 pnpm 省磁盘,团队继续用 npm:极简实践
前端·npm·node.js
Hone3 天前
我把「自动发文章到掘金」做成了一个 Agent 技能:juejin-skills
node.js·ai编程·前端工程化
Dumbness3 天前
二十行手写的 SKILL.md 头部解析,遇到 YAML 的折叠写法、单引号和嵌套键就读错:和 js-yaml 逐条对照
node.js·ai编程
只睡四小时4 天前
MCP 弃用 SSE?Node 分帧漏 81.7% 事件
node.js·webassembly·实时通信·mcp·streamable http
hey you~4 天前
个体户门店办理400电话,如何对接订单系统实现来电弹窗
node.js·webhook·400电话·门店数字化·来电弹窗·订单系统对接
YIAN5 天前
RAG 学到最后,我真正学会的不是“检索”,而是让系统知道自己缺什么
langchain·node.js·llm