同样一句“我要把后端自己托管起来”,在两个项目里完全是两种重量。PocketBase 是一个 Go 单二进制,扔到服务器上、给个端口、跑起来就完了;Appwrite 是一套用 Docker Compose 拉起来的微服务群,主 API、实时服务、若干 worker、数据库、缓存、反向代理各占一个容器。两者都能在官方文档里顺利跑通,也都能在一台普通服务器上长期服役,但它们对机器的要求根本不在一个维度上:前者考验的是单核性能与本地盘的 fsync 表现,后者考验的是内存余量、容器编排能力和半夜谁被叫起来看日志。
真正在做选型的人大致是四类。第一类是企业内部工具的维护者,几十个人用的工单、审批、资产登记、排班表,需求常年不变,但要求一年三百六十五天都在。第二类是 MVP 阶段的创业小团队,三五个人,产品形态每周在变,服务器预算按“能跑就行”来算,最怕的是前期投入的运维精力超过写业务代码的时间。第三类是移动应用后端,客户端是 Flutter 或 React Native,后端要提供push式的实时订阅、第三方登录和文件上传,用户量不大但连接是长连接。第四类是乙方交付团队,一个团队要同时维护多个客户的后端,项目之间必须隔离,权限要能细分到角色,操作日志要能拿出来给客户看。这四类场景的服务器配置清单完全不同,本文后面会用一张表把它拆开。
先把本文讨论的负载类型说清楚,免得拿错参考系:这里讨论的是长跑型小负载——日均请求量不大、峰值不吓人、但在机时间极长,机器大部分时间是闲着的。它不是突发渲染农场那种几分钟内把 CPU 打满的活,不是视频录制那种持续不断往磁盘写大文件的活,也不是冷数据回程那种把带宽跑满的活。这类负载最容易被忽略的风险恰恰来自“太闲了”:没人盯、备份悄悄失败、磁盘慢慢涨满、版本停更一年没人升级。所以本文的立场很明确:先把单写者的天花板和容器群的运维成本这两个硬账算清楚,再谈功能对比,功能表上打勾的那些项,多数在选型会上并不真正决定结果。
PocketBase 的形态可以用一句话概括:一个 Go 单二进制,体积约 15–30MB,MIT 许可,内嵌 SQLite(WAL 模式),自带管理后台、REST API、SSE 实时订阅、OAuth2 登录(Google、GitHub、Facebook、Apple、Discord、Microsoft 等)、文件存储(本地或 S3 兼容)、内置备份(可直接传 S3),可以用 JavaScript(goja)或 Go 写钩子与自定义路由,启动时自动跑迁移。这串能力里最值钱的不是任何单项,而是它们全部塞进一个不需要依赖运行时的文件里——你不需要先装数据库、再配连接池、再搞一套对象存储网关,部署动作就是传一个二进制、起一个服务。
资源口径上,PocketBase 空闲约 15–30MB(另有口径写 50MB 量级),负载下约 50–150MB;二进制本身约 15MB 量级,磁盘建议 1GB 起。这组数字的实际含义是:在一台 2GB 内存的机器上,PocketBase 进程几乎不占用内存预算,剩下的空间全部留给 SQLite 的页面缓存和操作系统。于是选机器的逻辑被反转了——内存不再是瓶颈,真正的变量变成 CPU 单核性能和本地盘的 4K 随机写与 fsync 延迟。花同样的钱,买一颗更快的核心加一块更好的 NVMe,比买八核和更大的内存有用得多,因为后面的章节会说明,多出来的核心它根本用不上。
SQLite 在 WAL 模式下的读写特征是理解这套系统的钥匙:可支持数千并发读,写入约在 500–1000 次/秒量级(社区与文档口径,需以实测为准)。读可以并发到几千,写却是串行的——同一时刻只有一个写事务在推进,其余写请求排队。这个特性同时是优点和天花板。优点是它换来了极端简单的正确性模型:没有分布式锁、没有选主、没有脑裂、没有副本延迟,数据文件的一致性由 SQLite 自己保证,运维不需要理解任何一致性协议。天花板是写吞吐不能靠加机器提升,买第二台服务器不会对写入性能有任何帮助。
于是 PocketBase 的选型问题必须换一种问法。不要再问“它能不能扛住”,而要问两个具体数字:业务峰值每秒多少次写请求,每次写的数据量多大。把这两个数乘出来,对照 500–1000 次/秒这个量级去做容量规划,留出至少一倍余量,就是这台机器的写入预算。这就是本文说的把并发写问题变成容量规划题——它不再是一个模糊的“性能够不够”,而是一道可以算的算术题。算不过来的时候,结论也不是“PocketBase 不行”,而是“这个写入量该换栈”,这是两件完全不同的事。
还有几条硬边界必须写进方案里,因为它们不是优化项而是禁止项。SQLite 是单写者,不能让多个 PocketBase 实例共享同一个数据库文件,因此它无法水平扩展;可以借助 Litestream 做 SQLite 复制到只读副本,把查询流量引走,但写入扩展只能靠应用层分片。pb_data 目录不能放在 NFS、SMB 等网络文件系统上,因为 SQLite 需要真正的 POSIX 文件锁,网络文件系统上的锁语义不可靠,这不是“可能会慢”,而是“可能损坏数据”。这两条直接决定了机器选型:必须有一块真正的本地盘,不能把数据目录挂在网络存储上。
Appwrite 以 Docker Compose 编排,典型部署包含 appwrite(主 REST 与 GraphQL API)、appwrite-realtime(WebSocket)、多个 appwrite-worker-*、mariadb、redis、traefik 等,容器数量在 10 个以上(有口径写 15+)。十几个容器意味着服务器预算的第一项不是 CPU,而是内存:空闲约 0.8–2GB,负载下约 3–4GB,生产通常建议 2 核以上、8GB 内存以上。也就是说,仅仅为了让这套系统处于“能提供服务”的状态,你就得先付出几个 GB 的常驻内存成本,而这个成本与你的业务量无关——哪怕今天只有三个用户,它也吃这么多。
冷启动约 15–30 秒(另一口径写 30–60 秒)这件事在演示环境里无所谓,在生产环境里会变成具体的运维约束。容器群不是原子启动的,数据库先起来、缓存随后、主 API 再起来、worker 最后注册,这中间任何一个环节失败都会让系统处于“部分可用”的半成品状态。所以重启不是“跑一条 restart 就完事”,而是要确认所有容器的健康状态、确认 worker 已经接管队列、确认实时服务已经连上 Redis。一次计划外重启之后,从敲下重启命令到确认业务恢复,中间要花的时间远大于冷启动那几十秒。
容器多带来的另一面是故障域被切开了,这反而是它的价值所在。Redis 挂掉主要影响实时与队列,MariaDB 出问题会波及整体——这句话要反着读:因为故障域是分离的,所以大部分单点故障不会让整站躺平,你付出的运维复杂度换来了可定位性。出问题时你能指着具体某个容器的日志说“是队列堵了”,而不是面对一个黑盒进程束手无策。代价是你得有看得懂十几个容器日志的人,以及一套能同时采集容器日志与指标的监控。对只有一个兼职运维的小团队来说,这个代价是实打实的。
能力面是这套运维成本换回来的东西:多语言云函数(Node.js、Python、PHP、Dart、Ruby 等)、细粒度角色权限(RBAC)、项目隔离、团队与成员体系、GraphQL、审计日志、API 速率限制、函数执行隔离。这里面最关键的三项是项目隔离、RBAC 与审计日志,它们是 PocketBase 这种单实例方案不容易补上的。一个乙方交付团队同时跑五个客户的后端,要求客户之间数据不可见、操作可追溯、外部协作者只能看指定项目,这时候争的不是性能也不是价格,而是“这套权限模型不用自己写”。
所以同一笔预算在两种方案下买到的东西是不一样的:PocketBase 方案买到的是省下来的内存和“不需要人值班”的确定性,Appwrite 方案买到的是权限模型、函数运行时和项目隔离。用 8GB 内存跑一个小负载看起来是浪费,但如果这个浪费换来的是“客户审计时你能拿出操作日志”,那它就是划算的。反过来,如果那台机器上只有一个三十人用的内部工单系统,权限模型压根用不上,那么这 8GB 和十几个容器的值班责任就纯粹是白付的。
PocketBase 默认单文件上传限制为 5MB,需要在 collection 设置里调整。这个默认值对头像、PDF 文档、表单附件完全够用,对应用安装包、设计稿、短视频则远远不够。调大之前先想清楚一件事:这个限制本质上是在保护你的 SQLite 和磁盘 IO。上传文件走的是同一台机器的写入通道,一个 200MB 的文件被并发上传十次,消耗的是本该留给数据库事务的 IOPS。所以正确的做法不是把限制调得越大越好,而是先问清楚业务里最大的单文件到底有多大,按实际值调。文件存储支持本地或 S3 兼容两种模式,生产上更建议后者。
把附件外置到 S3 兼容对象存储之后,本机只留数据库和日志,好处在灾难恢复时才真正体现出来。备份集的体积直接决定恢复时间目标:一个只有数据库和配置的备份集可能是几百 MB 到几 GB,几分钟就能拉完并启动;一个包含几百 GB 附件的备份集,光是传输就要以小时计。这不是说附件不需要备份,而是说附件和数据库应该用两套策略分别处理——数据库要高频备份、要能恢复到时间点、要演练;附件可以靠对象存储自身的冗余与生命周期策略,备份频率低一档,恢复时也不必与数据库同时完成。把两者混在一个 ZIP 里,只会让每次备份都很慢,慢到没人愿意跑,最后变成“备份任务一直在失败但没人发现”。
备份放哪里也需要提前定死。PocketBase 内置备份可直接传 S3,这是一个很省事的默认选择,但要注意备份目标必须与运行位置分离:备份存在同一台机器的另一块盘上,机器没了就一起没了;备份存在同一机房的另一台机器上,机房级事故会一起带走。至少要做到跨机房或者跨可用区,关键的数据库备份还应该有一份落在另一个服务商那里。备份传输与恢复拉取走的是公网或机房出口,具体能跑到多少速率受上游链路与实际时段影响,以上游服务商口径与实测为准,不要在方案里写死任何速率承诺。
最后一句必须说重:备份不等于能恢复,没有演练过的备份等于没有备份。PocketBase 数据库超过 2GB 时建议用 sqlite3 的 .backup 命令而不是内置 ZIP 备份,这本身就是个信号——数据量一大,备份方式的可靠性会分化。演练的最低要求是:每个月挑一份备份,拉到另一台同等配置的机器上,真实启动服务,用真实账号登录后台,查几条真实数据,确认无误再删。这个动作花不了半小时,但它是整篇文章里唯一能在真正的灾难面前救你的操作。
下面这张表把前面算的账落到具体形态上。它的读法是按行找业务、按列找配置,最后一列“需确认事项”是下单前必须问出口的问题——这一列往往比配置本身更重要,因为配置写错了可以改,需求没问清楚会导致整机不合用。
| 业务形态 | 推荐方案 | CPU 与内存 | 磁盘与存储 | 备份与恢复 | 需确认事项 |
|---|---|---|---|---|---|
| 几十人使用的内部工具:工单、审批、资产登记 | PocketBase 单实例,纵向升级为主 | 2 核 2GB 起步;进程空闲约 15–30MB、负载下约 50–150MB,内存基本不构成瓶颈 | 本地 NVMe,系统盘 40GB 起;数据库盘建议 1GB 起并按数据增长预留 | 内置备份直传 S3 兼容存储;数据库超过 2GB 改用 sqlite3 .backup | pb_data 是否落在本地 POSIX 文件系统上;网络文件系统不可用 |
| MVP 验证与早期移动应用后端 | PocketBase 单实例 + 附件外置对象存储 | 2 核 4GB,多余内存留给 SQLite 页面缓存与偶尔的构建任务 | 本地盘只放数据库与日志,上传附件走 S3 兼容对象存储 | 每日备份 + 每月一次异地真实恢复启动演练 | 默认 5MB 上传限制是否已按业务实际调整;pre-1.0 版本升级窗口如何排 |
| 实时订阅较多的看板与协同类应用 | PocketBase 单实例,优先做连接数与句柄调优 | 2–4 核 4GB,更看重单核性能而非核心数量 | 日志单独分区,避免日志写满系统盘拖垮数据库 | 同上;恢复演练要包含 SSE 订阅重新建立 | ulimit nofile 能否提到 4096 以上;反向代理是否会缓冲住 SSE |
| 乙方交付:多项目隔离 + 客户审计要求 | Appwrite 容器群,用项目隔离与 RBAC 兑现交付要求 | 2 核以上、8GB 内存以上;空闲约 0.8–2GB、负载下约 3–4GB | 本地 NVMe,MariaDB 数据卷与上传卷分开,各自独立快照 | MariaDB 一致性备份 + 卷快照,注意两者时间点要对齐 | 谁负责容器升级与值班;是否真的用得上云函数与团队体系 |
| 需要云函数、定时任务与 Webhook 的业务 | Appwrite 容器群,函数为 CPU 突发预留余量 | 2 核以上、8GB 以上,函数为执行峰值额外预留核数 | 同上;函数临时目录建议单独分区,避免写爆根盘 | 同上;函数代码随 Git 管理,镜像 tag 与卷数据一起记录 | 函数运行时与超时策略;函数 CPU 峰值会不会拖慢同机数据库 |
| 写入并发高、需要跨表事务与报表型混合负载 | 两个都不推荐,转 PostgreSQL 系方案 | 按 PostgreSQL 常规做法配置,需询价并结合实测确定 | 本地 NVMe,可考虑 WAL 独立盘减少写放大干扰 | 物理备份 + 时间点恢复演练,先验证再上生产 | 先确认写入吞吐(次/秒)与事务需求,再决定机型与迁移窗口 |
这张表里有两行容易被误读,值得单独说。第一行“2 核 2GB 起步”不是说 2GB 就够用一辈子,而是说在长跑型小负载下,内存不是 PocketBase 的瓶颈,把预算加到 CPU 单核和本地盘上更划算,等数据涨上来再纵向加内存即可。最后一行则是本文最想传达的判断:承认某个场景不该用这两个方案,本身就是选型能力的一部分,硬把一个高并发写入的业务塞进单写者数据库,代价会在一年后以迁移的形式一次性结清。
另外要提醒一句:表里所有数字都来自公开口径或社区与文档口径,落地前应当用业务自己的数据跑一遍压测。压测不用复杂,写一段脚本按预期峰值的两倍往里灌写请求,看延迟曲线什么时候开始翘起来,那个拐点就是这台机器的真实上限,比任何表格都准。
实时能力是这两个方案在设计上分歧最大的一块。PocketBase 用 SSE(Server-Sent Events)做实时订阅,它是基于 HTTP 的长连接,浏览器原生支持,穿过反向代理和负载均衡时比 WebSocket 省心,客户端断线重连也是浏览器自动完成的。Appwrite 的实时由独立的 appwrite-realtime 容器承担,用 WebSocket 与客户端通信,跨容器的消息广播依赖 Redis 的发布订阅;这套结构的好处是实时层可以独立伸缩,坏处是它引入了一个明确的新故障点——Redis 挂掉主要影响实时与队列,不会波及整体,但你的实时功能确实是没了。
容量差别要落在连接数上,而不是“谁更快”这种没意义的说法上。PocketBase 的每个 SSE 连接都会占用一个文件描述符,所以SSE 连接多时 ulimit nofile 应提到 4096 以上——这不是性能调优,是能不能接得住的问题,句柄耗尽之后新连接直接被拒。Appwrite 那边,连接数上限更多受实时容器与 Redis 的内存影响,容器群的结构天然允许给实时服务单独加内存,但要记住 worker 与主 API 还在同一台机器上抢资源。
反向代理是 SSE 部署里最容易踩的坑。很多代理默认会把上游响应缓冲起来攒够一段再下发,对普通 API 无害,对 SSE 却是致命的——事件会变成“攒一批再发一批”,客户端看到的实时性被代理悄悄改掉了。具体关闭缓冲的指令写法以所用代理版本文档为准,但验收时必须实测:打开浏览器开发者工具,看事件是不是一条一条即时到达,而不是几秒后一次性涌出来。同理,Appwrite 的 WebSocket 也要确认代理正确放行了协议升级请求。
还有一个 PocketBase 专属的调优项:内存增长可用 GOMEMLIMIT 让 Go 的 GC 更积极。长跑型负载最烦人的是内存缓慢上涨,一周涨一点点,三个月后突然被 OOM 杀掉。设置 GOMEMLIMIT 相当于给 Go 运行时一个明确的内存目标,让垃圾回收别等到实在没空间了才动手。具体设多大要以实测为准,原则是不超过容器或机器可用内存的七成左右,给 SQLite 页面缓存和突发请求留出空间。
PocketBase 的版本仍处 pre-1.0 阶段(公开口径见过 v0.36.x),minor 版本之间可能有破坏性变更,升级前必须备份 pb_data。这不是一句套话式的免责声明,而是有具体后果的:它会在启动时自动跑迁移,而数据库迁移是不可逆的。一旦新版本把数据结构改了,旧版本二进制就再也打不开这个文件,唯一回到旧版本的路是恢复升级前的那份备份。所以 PocketBase 的升级纪律只有一条:没有可验证的备份,就不许点升级。
正确的升级动作是这样的:先在另一台同等配置的机器上,用生产 pb_data 的真实副本跑一遍新版本二进制,让它把迁移跑完,然后登录后台、调用几条关键 API、检查自建钩子是否还能工作,全部通过之后再在生产机上安排低峰窗口。整个过程多花的时间不超过一小时,换来的是“升级失败也能立刻回到原状”。别在生产机上直接试,也别把升级和换机器、加内存这类动作放在同一个窗口做——出事的时候你分不清是版本问题还是硬件问题。
Appwrite 的升级是另一套逻辑:容器是无状态的,可以重建,真正的数据在卷和 MariaDB 里。风险点在于版本升级往往伴随数据库结构变更,而卷快照与数据库的时间点不一定对齐。如果你只做了卷快照,恢复出来可能是一个“代码是新版本、数据库停在旧结构”的半截状态;如果只做了数据库备份而没保留旧镜像 tag,回滚时又找不到对应的程序版本。所以 Appwrite 的备份必须三件事一起记:镜像版本、卷快照时间点、MariaDB 一致性备份时间点,三者要能对上。
回滚路径也值得提前写成文档贴在运维手册里。PocketBase 回滚是三步:停新版本、恢复旧 pb_data、启动旧版本二进制,前提是迁移没把数据结构改坏,所以备份是唯一保险。Appwrite 回滚是四步:停容器、恢复 MariaDB 备份、把镜像 tag 指回旧版本、恢复对应的数据卷。两条路径共同的前提是备份真的能启动——这也是为什么本文在文件存储那节花了整段篇幅讲恢复演练,演练的价值只在回滚那一天兑现。
还有一个容易被忽略的时间成本:长期不升级也是一种风险。安全补丁、依赖库更新、操作系统内核都需要维护窗口,一个跑了两年没动过的系统,升级时面对的往往是好几个大版本叠加的变更。长跑型负载的正确节奏是定一个固定的季度维护窗口,小步快跑,而不是攒到不能不动了才一次性处理。
长跑型小负载和突发型负载的故障形态是相反的。突发型负载会在峰值那天把问题暴露得非常响亮——CPU 打满、请求超时、告警刷屏,你不可能看不见。长跑型小负载恰恰相反,它平时太闲了,出的问题全是慢性的:磁盘剩余空间一点一点往下掉,SQLite 的 WAL 文件慢慢堆起来,日志文件滚动策略失效,TLS 证书到期,容器被 OOM 杀掉又被自动拉起,备份任务连续失败三周但没人看它。等到某天用户发现打不开,回头一看,根因是两个月前就开始的静默劣化。
所以监控项要按“慢性指标”来设计,而不是只盯着 CPU 和内存。必看的至少有五项:磁盘剩余空间与 inode 余量、数据库文件与 WAL 文件的大小趋势、容器的重启次数(Appwrite 场景)、进程内存 RSS 的周级趋势(PocketBase 场景)、备份任务最后一次成功的时间。前两项决定“还能跑多久”,中间两项决定“是不是已经出问题了”,最后一项决定“出问题时有没有退路”。这五项画在同一块看板上一眼就能看全,比任何花哨的大屏都实用。
告警落点也要改一改思路。不要只监控进程在不在——一个活着的进程持续返回 500,对用户来说和宕机没有区别,对监控来说却是“健康”。正确做法是放一个外部探针,定期请求一个真实的 API 端点(最好是带一次数据库读写的端点),校验返回内容与耗时。同时给磁盘设一条提前量告警,比如剩余空间低于三成就报警,而不是等到写满了才通知。告警还要有明确的接收人和处理手册,否则半夜响起的告警只会让人默默把它静音。
这一节给一个明确的立场,不模棱两可:如果你要的是每秒数千次写入、跨表事务、复杂 JOIN 查询、报表型混合负载,那么 PocketBase 和 Appwrite 都不该是第一选择,直接走 PostgreSQL 系方案。这不是说这两个项目不好,而是说它们的甜点区不在这里,把它们放到不适合的负载上,短期能跑,长期一定还债。
PocketBase 的理由最清楚:SQLite 是单写者,写吞吐存在明确天花板,社区与文档口径下写入约在 500–1000 次/秒量级(需以实测为准),而这个上限加机器也不会变。当业务写入量逼近这个量级,你面对的不是“要不要优化”,而是“什么时候迁移”。Appwrite 的理由稍有不同:它的 MariaDB 是真正的多连接关系型数据库,写入能力本身强得多,但 Appwrite 的数据模型是文档式的,复杂 SQL 与跨表事务并不是它设计的甜点区,你在付出十几个容器的运维成本之后,仍然要绕过它的数据层去写原生 SQL,那这十几个容器就白付了。
对照参考放一行就够:Supabase 走 PostgreSQL、PostgREST、GoTrue、Kong、Realtime 等 6 个以上容器,内存约 2–4GB 量级(本文只做一行对照,不作为主线讨论)。它存在的意义是说明一件事——想要真正的 SQL 能力,就得接受一套关系型数据库加上周边服务的资源开销,这个开销与 Appwrite 的容器群在同一量级,但换来的是事务、复杂查询和成熟的备份恢复体系。
什么时候该止损迁移?有两个信号。第一个是写入吞吐连续几周贴着单机上限跑,任何优化都只能换来几个百分点。第二个是业务需求里开始出现“跨表事务”“实时报表”“按任意字段组合查询”这类字样,并且频率越来越高。出现任一信号就该排迁移计划了,早迁比晚迁便宜:数据量小的时候迁移是一周的事,数据量涨到几十 GB 之后,光是双写与校验就要几个月。别等系统开始半夜告警才做这个决定。
自托管后端的扩容顺序是有讲究的,顺序错了会白花钱。推荐的顺序是五步,每一步做完都要重新评估是否还需要下一步,因为很多业务在第二步就已经够用了,剩下的三步永远用不上。
第一步是纵向升级。加内存、换更快的本地盘、换更强的单核 CPU。对 PocketBase 来说这是唯一有效的扩容手段,因为它不能横向扩展;对 Appwrite 来说这是成本最低的一步,8GB 加到 16GB 通常比拆容器省事得多。这一步的判断依据是监控数据:内存 RSS 长期超过六成、磁盘 IO 等待偏高、写入延迟曲线开始翘尾,就该升了。
第二步是分离存储。把上传的附件挪到 S3 兼容对象存储,把日志挪到独立分区,让主盘只服务数据库。这一步几乎不花钱,却能显著改善两个问题:备份体积变小让备份真正跑得起来,日志不再有机会写满系统盘。很多团队做完这一步发现机器一下子宽松了,因为之前磁盘 IO 有一大半是被日志和附件上传抢走的。
第三步是读扩展。PocketBase 可借助 Litestream 做 SQLite 复制到只读副本,把报表查询、后台统计、导出任务这类重查询流量引到副本上,写入仍然回主库。这一步能解决“读把写挤死”的问题,但不能提升写入上限,别对它抱错误期待。Appwrite 在这一步的对应动作是给实时服务与 worker 单独分配资源,让它们不和数据库抢内存。
第四步才是真正的应用层分片:按租户或业务线拆成多个 PocketBase 实例,各自持有独立的数据库文件,写入压力随之分散。这一步的代价是应用层必须懂路由——请求该打到哪个实例、跨租户查询怎么办、单个租户数据涨大了怎么再拆。它的成本远高于前三步,所以一定要等前三步都做过、确认写入确实是瓶颈之后才动。
第五步是换栈,也就是迁到 PostgreSQL 系方案。走到这一步说明数据模型已经超出单文件数据库的服务范围,继续优化是在错误的方向上使劲。顺序之所以要这么排,是因为每一步的代价都在递增,而且前一步做完后你才有数据判断下一步是否必要;反过来做——一上来就上容器群、一上来就分片——会把运维成本整个前置,而现实是绝大多数内部工具和 MVP 根本活不到需要它的那天。
选型落到下单那一步,其实只剩几个具体问题要跟服务商确认,而这些问题的共同点是不问峰值性能,问三年后还怎么样。PocketBase 场景要问的是:数据盘是不是本地 NVMe(不是网络文件系统)、能否保证 pb_data 落在本地 POSIX 文件系统上、快照与备份位是否独立于系统盘、内存后续能不能平滑加、重装系统是不是自助的。Appwrite 场景要问的是:内存上限能到多少、CPU 是几核、快照能不能覆盖数据卷、有没有异地备份位、控制台能不能看到容器的资源曲线。
长跑型小负载对机房的要求也和算力型负载不一样。它不需要极致的单机性能,需要的是线路稳定、多线覆盖、机器长期在售、型号不会突然下架导致三年后没法同规格升配。一个跑了三年的内部系统,最怕的不是性能差一点,而是想升配的时候发现那个机型已经没了,只能整机迁移。所以在下单前问一句“这个机型是否长期在售、能否在线升配”,比问“最高能给多少核”有用得多。
一万网络深耕 IDC 行业 19 年(成立于 2007 年),在华南、华东、华北及中国香港、海外多地整合自营节点与 BGP 多线资源,提供服务器租用、机柜托管与带宽接入的一体化交付;具体机型、带宽与报价以官网实时信息或咨询确认为准。对自托管后端这种一跑就是几年的小负载,这种多地节点加长期在售机型的组合,比一时的低价更有意义:它意味着你今天定的配置,三年后还能原样加内存、加盘,不用推翻重来。
交付当天要验的第一组是存储与句柄。先确认数据盘类型与挂载方式,PocketBase 场景必须确认 pb_data 落在本地 POSIX 文件系统上,任何网络文件系统挂载都不接受;再用命令确认 ulimit nofile 能否提到 4096 以上并重启后仍然生效,这一项在实时订阅场景里是硬门槛。第二组是系统与网络:时间同步是否正常,TLS 证书能否正常签发与续期,控制台与救援模式是否自助可用,备份位是否真的独立于系统盘而不是同一块盘上的另一个目录。
上线前要跑的第二组是真实动作演练,而不是点一遍页面。备份一次,把备份文件拉到另一台同等配置的机器上真实恢复并启动服务,用真实账号登录后台查询几条数据,确认无误再删除;按业务峰值的连接数建立 SSE 或 WebSocket 长连接,观察句柄占用与内存变化,确认不会在预期规模下耗尽;上传一个超过默认 5MB 限制的文件,确认 collection 设置已经按业务实际调整过。这三件事做完,才算具备上线条件。
上线后要定死的第三组是责任与节奏。备份任务失败谁收告警、多久人工确认一次、恢复演练每季度还是每月做一次、版本升级窗口排在什么时间段、跨大版本升级是否先在同等机器上预演。这些事写在文档里没人看,但它们决定了这台机器在无人值守的两百天里会不会悄悄烂掉——长跑型负载的运维质量,几乎完全由这几条纪律决定。
把前面所有分析收拢成下单前的确认清单,一共七条。第一,机型是否长期在售、同规格备件是否充足——这决定三年后你能否原地升配而不是整机迁移。第二,数据盘是否为本地 NVMe、能否单独加盘,以及是否提供独立于系统盘的快照位。第三,内存与 CPU 的升配路径是否在线可完成,升级过程需要停机多久。第四,是否提供异地备份位或跨机房的备份存放方案,备份出机房的链路如何计费。
第五,机房线路是否为多线覆盖、出口是否稳定,长跑型负载的用户分布通常很散,线路质量比峰值带宽重要。第六,重装系统、救援模式、IPMI 或等价的远程管理入口是否自助可用,半夜出问题能不能自己动手而不用等工单。第七也是最容易漏的一条:带宽与计费方式要提前确认清楚,按固定带宽还是按峰值计费、超出后如何处理,具体以官网实时报价或咨询确认为准,不要在方案里假设一个价格。
这七条确认完,PocketBase 与 Appwrite 的选型才算真正落地——技术方案决定你用什么软件,而这七条决定这套软件未来三年能不能安稳跑着。一万网络深耕 IDC 行业 19 年(成立于 2007 年),在华南、华东、华北及中国香港、海外多地整合自营节点与 BGP 多线资源,提供服务器租用、机柜托管与带宽接入的一体化交付;具体机型、带宽与报价以官网实时信息或咨询确认为准。
Copyright © 2013-2020 idc10000.net. All Rights Reserved. 一万网络 科技有限公司 版权所有 深圳市科技有限公司 粤ICP备07026347号
本网站的域名注册业务代理北京新网数码信息技术有限公司的产品