
开发者自建服务器运行四个应用,月均成本仅45美元
来源标题:What It Costs to Run 4 Apps on My Own Servers
一名开发者将自己运营的四款产品全部部署在一台自建服务器上,每月总成本约45美元;同样配置放在托管平台则需每月360至960美元。他说服务器资源仍有富余,其中一款应用承载了超4GB的Postgres数据并支持向量搜索。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
我在自己的服务器上运行着四个产品:Hydrafetch ↗️、DataHyena ↗️、CatchIntent ↗️ 和 Eternal Vault ↗️。有付费客户、后台 worker、定时任务、真正的数据库。整套东西都跑着。
这四个产品全都跑在我自己搭建的一台服务器上,总账单大约是每月 45 美元。
同样的配置放到托管平台上,每月大概要花 360 到 960 美元。
每次我提到这件事,得到的回应都是某种版本的“好吧,但代价是什么?”问得合理。所以这篇文章就是诚实的回答:完整账单、这个价格你放弃了什么、我怎么弥补,以及一路上出过哪些岔子。如果你在运营一个小型 SaaS,而托管账单已经开始让你肉疼,那这篇文章大致就是另一条路的样子。
域名和邮箱是额外开销,但不管托管在哪都要付,所以我没算进去。
让人觉得难以置信的是,这台服务器甚至都没怎么吃力。每个应用都有 CPU 和内存的硬性限制,而且还有余量。
那一个应用就存着超过 4 GB 的 Postgres 数据:11 万多家公司、5.8 万轮融资、6.5 万条招聘事件、20 多万份原始文档,外加向量搜索。它的 worker 每天拉取最多 2000 份新文档。这可不是一个 todo 应用,而且它甚至都不是这台机器上最大的东西。
为了公平,我在常见平台上给同样形态的应用估了价:一个 Web 服务、一个后台 worker、一个足够装下这些数据的 Postgres 数据库,再加一个小 Redis。
单是 DataHyena,每月就要 90 到 240 美元左右,取决于平台以及你在数据库上有多大方。而且问题永远出在数据库上。一旦你需要超过几 GB 的 RAM,托管 Postgres 就会迅速变贵,而向量搜索恰恰很吃 RAM。
四个应用都这么算,就是每月 360 到 960 美元。对比 45 美元。
这个差距就是我这么做的全部原因。但这也不是白捡的钱。托管平台确实替你干了实打实的活,当你离开它时,那些活不会消失,总得有人接手。
你付钱给平台,买的不只是算力,还买了一长串你永远不用操心的事。下面就是这份清单,以及我替代付费的做法。
两者在离开服务器之前都会用 GPG 加密,然后落到站外的对象存储里。任务也错开了时间,所以数据库不会在同一分钟里全都去压缩和上传。
如果你想看细节,我写过 dump 和 point-in-time recovery 是怎么做的。
而且没错,它们是经过测试的,下面会详细说。
部署走 Kamal ↗️。一次 push 会构建新镜像、启动它、等它通过健康检查,然后才切换流量。如果新版本起不来,旧版本就继续服务。
回滚只需一条命令。我不止一次需要它,而每次我都很庆幸它是一条命令,而不是半夜里的“向前修复”。
这些大部分都写在我的“新 VPS 头 30 分钟”清单里。没什么花哨的,只是每次都必须做完,不能跳过任何一步。
每个应用的指标、日志和追踪都汇入同一套 Grafana 栈。除此之外,还有一个外部 uptime 检查,一旦有东西挂了就立刻通知我,让我比客户先知道。
至于更安静的问题,比如卡住的 job 或变慢的查询,我给服务器做了一个看门狗,只在真正要紧的时候才出声。
如果这份清单里只能保留一样,我会选这个。
整台服务器——从用户、防火墙规则到 Postgres 设置、备份计划、监控 agent——都以 Ansible 代码的形式存在一个 git 仓库里。我多年前为自己的 homelab 开始这么做,这是我养成的最好的习惯。
如果服务器今晚挂了,我会租一台新的、跑一遍 playbook、恢复数据库,大约一小时内就能回来。而不是花一周时间去回忆我装了什么、为什么装。
推广 由我构建并发布 为 LLM 提供干净的网页数据。一个 API。 Hydrafetch 能把任意 URL 变成干净的 Markdown 和模型可用的结构化数据。抓取、映射、爬取、搜索和提取都通过一个 API 完成,积分简单,失败的请求永不收费。 无需信用卡
出过的问题 这些一点都不顺利。以下是值得一说的几个。
我的 Ansible 配置里有一个 Postgres 调优步骤。内存设置、查询规划器设置,全都按这台机器配好了。我写了它、审了它,然后就过去了。
设置接线方式上的一个错误,导致服务器上每个数据库都在跑 Postgres 的默认值——那种给笔记本用的默认值。包括 random_page_cost = 4.0,这等于告诉 Postgres 假设它读的是机械硬盘。而在 NVMe 上。
什么都没坏,所以什么都没报警。查询只是比本该的慢,安安静静地,到处都是。直到有一次查询触发了 30 秒的语句超时,我才去挖。
修复只花了几行。教训更大。
不只是“它存在于某个文件里”。现在我的配置在应用设置之后会把运行中的值读回来,对不上就报错。
四个应用都在同一个共享代理后面,由它把流量路由到各自。这也是为什么这套东西这么便宜的一大原因。
而我是以有趣的方式学到这点的。第一次我没多想就重启了那个代理,所有应用同时挂了。只有几秒钟,但每个产品的每个客户都在同一时刻看到了。
现在代理变更被当作“同时部署所有应用”来对待:有计划、动作快、绝不在白天做。这也促使我写清楚将来怎么加第二台机器,这就引出了下一点。
一次部署中途被打断,留下了一个进程,下一次部署看到它就礼貌地等它。永远地等。之后的每次部署都只是挂起,没有任何东西告诉我为什么。
找它花的时间比修它长得多。现在每次部署前都会检查残留进程,而且这条写进了我的 runbook,免得未来的我再去重新发现一遍。
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。