给 OnlyOffice 配服务器这件事,十个团队里有八个第一步就走岔了。常见的做法是打开后台看一眼注册人数:哦,两千多号人,那得来个大点的机器吧。两万块砸下去,上线后发现 CPU 常年趴在百分之十几睡觉。反过来,一个几十人的小团队,每周五下午全员挤在一个共享表格里填数据,机器直接跪给他们看。差别在哪?OnlyOffice 的资源消耗压根不跟着"用户数"走,它跟着"同时打开几个编辑会话"走。这篇就把这条主线掰开,从单个会话的真实开销,一路讲到 converter 的 CPU 突发、WebSocket 的连接数账、临时目录的盘位规划、NFS 的坑、以及保存回调那条藏在 CPU 内存曲线背后的丢数据链路。
OnlyOffice Docs,习惯叫它 Document Server,本质上是一个文档处理与协同引擎。浏览器打开一个 docx,请求打到它这里,它把文件取过来、转成内部格式、推送渲染数据给前端、接住每个人敲进去的键盘事件、做操作转换(也就是常说的 OT)、再把改完的内容吐回去。整条链路里,它扮演的是 CPU 和内存的消费者,而不是文件的长期保管者。
文件的长期保管另有其人:可以是 Nextcloud、Seafile 这类自带接口的网盘系统,可以是自建的对象存储,可以是简单的 WebDAV 服务,也可以是你自己写的一个带 API 的业务系统。搞清楚这一层,配置就顺了一半——因为你至少知道,"文档多、文档大"这件事,压力主要落在存储后端和转换那一瞬间的 CPU上,而不是落在日常运行的内存里。
顺手列一下容易被错算的部分:用户登录、组织架构、权限审批、文件版本界面、全文检索。这些属于对接的业务系统。把它们和文档编辑混在一台机器上估算,结果一定是 CPU 和内存双双虚高。不是说不能部署在一台机器上——小团队完全可以——但估算的时候必须拆开算,部署的时候再决定合不合,顺序不能反。
举个不刻意的例子。一个两千人规模的机构,文档协作的实际画面很可能是:日常几十个人在系统里查资料、看文件,真正同时把文档打开进编辑态的,往往就是十几个人,而且分散在一天的不同时间段。这中间的绝大多数请求是静态文件下载和页面渲染,跟 Document Server 的协同引擎半点关系没有。
换成另一个场景:一个五十人的商务团队,每周五下午四点交周报,全员同时打开同一批模板表格往里填数。同一时刻五十个活跃编辑会话,且集中在同一批文件上——同一个文件上的协同人数越多,服务端要维护的操作转换状态就越复杂。五十个人同时改同一批表格带来的服务端压力,远超两千人组织里那十几个零散会话。这就是"用户数估配置"失效的地方,它不是大致不好使,是完全不对。
所谓一个编辑会话,指的就是一个浏览器标签页把文档打开在可编辑状态。这里有几个容易漏算的细节:同一个人开三个标签页,就是三个会话;只读预览和一个正在敲字的会话开销完全不同,只读一般不会进协同状态;手机端、平板端各算一路;开着没操作但没关页面的,连接还在,状态还在内存里。
所以真正该做的是拿业务系统的数据说话——查过去一两个月的访问记录,统计"最大同时处于编辑态的连接数",而不是查"活跃用户数"。如果你手头没有这类日志,那就问业务部门一个问题:最挤的那一天那个钟头,最多会有多少人同时在线改东西。这个答案哪怕粗糙,也比用户总数靠谱十倍。
普通的 Web 请求是"来,处理,走",连接用完就还了。协同编辑不是这个模式——浏览器打开文档的那一刻起,会和 Document Server 建立一条WebSocket 长连接,这条连接在整个编辑过程中一直挂着,直到用户关闭或长时间断连。中间的每一次击键、每一次光标移动、每一次别人的改动广播,都从这条连接上走。
长连接的账要从两个方向算:横向是连接数量,纵向是每条连接的存活时长。一个短请求哪怕每秒来一万次,峰值过去资源就释放了;一条挂着两小时的长连接,占用的那份内存和那个文件描述符在这两个小时里是不释放的。这就是为什么"看着没多少人在用,内存却一路往上走"——人数没涨,单条连接的寿命拉长了。
光一条连接本身开销有限,真正吃内存的是连接背后的协同状态。多人同时改一个文件时,服务端必须维护一份权威版本,处理每个人提交上来的操作、做转换、广播给其他人,还要处理并发冲突。这份东西必须常驻内存,没法写出去。
单个会话大致吃多少内存,网上流传的数字五花八门。按官方给出的量级估算,一个活跃编辑会话的内存占用在百兆级别这个量级上浮动,文档越小越省,几十兆到两三百兆的区间都在合理范围内。但这个数字受文档体量、协同人数、插件、版本差异影响巨大,官方给的是参考量级而非精确值,实际到你的环境里必须自己压一遍才有数——拿你们真实的最大尺寸文档,按真实的同时编辑人数跑一次,看常驻内存涨多少,这才是有用的数。
这一点最容易被低估。一个三页的会议纪要和一个塞了几百张图、几十个图表联动的产品手册,占用的资源完全不是一个量级。大文档的页数多、样式多、对象多,加载时要一次性解析进内部表示,协同时的操作树也更复杂。配置样按"平均文档大小"估,遇到那几个超规格的老文件时就会很难看——不是慢,是可能直接触发内存上限。建议是按你们最大的那批文件去留出余量,而不是按平均值。
很多人以为装完 OnlyOffice 就是"一个服务",实际上它一跑起来是个小集群。默认安装包会顺手带上 Nginx 作为前端入口负责静态资源与反向代理,RabbitMQ 承担协同过程中的消息传递,Redis 扛缓存,PostgreSQL 或 MySQL 可选用于存储部分元信息。这几位就算完全空闲的状态下也是常驻进程,各自有各自的内存基线。
所以你看到的整机内存占用,永远是 Document Server 协同进程叠上这几个中间件的总和。有些团队觉得"我并发会话才十来个,怎么占了这么多内存",答案往往就在 RabbitMQ 和 Redis 的默认配置上——中间件的默认内存上限在容器环境下经常失效,它按照宿主机可见内存去算,一不留神就占出一大块。
CPU 侧的麻烦在于峰值对齐。转换文档的时候,converter 要吃 CPU;同时来几个编辑会话的 OT 计算要吃 CPU;RabbitMQ 的消息处理、Nginx 的 TLS 握手,统统要吃 CPU。这些峰值一旦叠在同一个瞬间,单机的小核数就会瞬间见底,表现是页面转圈、击键延迟、视图不同步。
所以核数这件事不能只看平均占用率。要看的是峰值那一刻能同时跑几个胖线程。低核数的大内存机型在这种场景下会很难受,因为它的短板在突发而不在容量。
用户拖一个几十兆的 docx 到浏览器里,前端把它交给 Document Server,接下来服务端要做的事远比"复制一份"复杂:接收文件落到临时位置,调用 converter 把它解析成一个内部交换格式(本质是拆成一堆结构化描述加资源文件),建立索引以便后续渲染,再把这些东西推送给前端。整个解析过程是纯 CPU 密集的活,而且为了快,会尽量并行把能开的核都吃上。
一个几十兆的复杂 docx 转换要保持几十秒才出现在屏幕上并不稀奇;格式特别复杂的 Excel 更夸张,公式、图表、条件格式、外部链接,每一项都要重算。这几十秒里,那台机器对外服务的编辑会话是肉眼可见地卡——因为 CPU 被转换吃光了。
这类负载特征是典型的脉冲式:日间大部分时间 CPU 在低水位,一旦有上传或批量转换就开始拉满。用平均值去规划必然低估。应对的办法是限流而不是一味加配置——限制同时进行的转换任务数,把大文件的转换排队而不是并发冲锋,让编辑态的请求始终有 CPU 富余。真要加大批量转换的处理能力,可以额外部署独立的转换实例,把转换这一路剥出去,让它和业务会话互不干扰。
回到长连接的账。一条 TCP 连接在 Linux 上就是一个文件描述符,Nginx 侧的 worker_connections 决定了它总共能吃下多少路连接,进程级的文件描述符上限决定了硬性天花板。平时跑 HTTP 短请求,这两项几乎用不完,因为连接复用厉害;换成几千条挂着的 WebSocket,情况就变了。
症状很好认:到某个量之后新用户打不开文档,但机器的 CPU 和内存都还很空,连接就是建立不上。这时候查什么都不如查 Nginx 的 active connections 和系统的 fd 占用直接。这是典型的"资源没占满却服务不了"的瓶颈。处理方式两头:调大 worker_connections 和系统级的 fd 上限,同时在前端时间段上做疏导——比如给文档编辑这类入口单独一套代理配置,别和静态资源下载挤在一起。
反向代理如果要转发 WebSocket,必须显式打开协议升级支持,HTTP/1.1 的 Upgrade 和 Connection 头一个都不能少。这一层没配好,轻则连接退化成长轮询勉强能用,重则频繁掉线。而这事往往不一开始就暴露,因为短连接态看着完全正常。
另一个高频坑是超时。代理层如果沿用默认读超时,一条挂着半小时没人敲字的会话会被静默掐断,客户端的心跳还来不及把它救回来。用户那边看到的就是写着写着跳出"文档已修改,请重新加载"或者干脆转圈。判定要点很直接:如果掉线总是集中在停顿几分钟后的第 N 分钟,那就别查 CPU 了,直接去改代理的读写超时和心跳间隔。
下面这张表把上面几节的内容收成一张横向对照。用法是:先看"瓶颈信号"那一列能不能对上你遇到的现象,再回去看对应的那一两个组件,别一上来就想着加机器。
| 组件/环节 | 消耗的主要资源 | 典型瓶颈信号 | 配置与调优动作 | 常见误判 |
|---|---|---|---|---|
| 协同编辑会话 | 内存为主,CPU 为辅 | 会话数上去后常驻内存持续抬升,扩容前先看这条曲线的斜率 | 按最大并发会话数估内存,再叠加中间件基线并留三成以上余量 | 拿注册用户总数去套 |
| 转换服务 converter | CPU 突发,短时吃满多核 | 上传大文件时 CPU 瞬间拉满,其他会话同段卡住 | 限制并发转换数、排队处理,规模大时拆出独立转换实例 | 看平均 CPU 占用以为是闲置机 |
| 反向代理层 | 连接数、文件描述符 | CPU 内存都空,新建的连接就是建立不上 | 开 WebSocket 升级,调大 worker_connections 与系统 fd 上限 | 只看 worker 进程数不看 fd 天花板 |
| Nginx 读写超时 | 连接存活时长 | 停顿几分钟后提示文档已修改需要重新加载 | 放宽代理读写超时,对齐客户端心跳间隔,避免静默掐断 | 当作程序 bug 去重启服务 |
| RabbitMQ 消息队列 | 内存 + 队列落盘空间 | 协同指令滞后、消息堆积、队列所在分区写报警 | 给队列独立落盘位置,设堆积告警阈值,别让它和系统盘抢空间 | 装完就默认没问题,堆积才被发现 |
| Redis 缓存 | 内存 | 内存持续上涨不回落,打开同样文档依然慢 | 显式设 maxmemory 与淘汰策略,不要和业务缓存共用 | 以为容器内存限制对它天生生效 |
| 临时文件目录 | 磁盘空间 + 瞬时写 IO | 批量上传时磁盘占用短时间暴涨,个别转换直接失败 | 独立分区或独立数据盘,清理策略加额度告警 | 扔在根分区,跟系统盘共用空间 |
| 持久化存储后端 | IOPS、读写时延、内网带宽 | 文档打开慢、保存慢,业务日志里有回调超时记录 | 优先本地 NVMe 或对象存储,走内网直连,避开高小文件并发的网络文件系统 | 认为挂载上了就等于读写本地盘 |
| 保存回调链路 | 网络往返时延、重试次数 | CPU 内存全正常,用户反馈改完的内容偶发丢失 | 拉长回调超时,链路走内网,补重试与失败记日志 | 指标全绿就判定不是自己的问题 |
表格里九行看着多,落到实际的采购清单上就三件事——CPU 给突发留核、内存按并发会话给上限、磁盘分清楚谁是临时、谁是缓存、谁是持久。下一节专门讲存储这层。
重复一遍这个容易被忘的事实:Document Server 本身不承担长期存储职责。文档在它被编辑的时候会出现在它的缓存和临时目录里,但"这份文件属于谁、在哪一层目录、有几个历史版本"这些信息,由对接的后端系统说了算。所以你在做容量规划时,至少要把三块地方分开盘算:临时目录(短期、可清)、缓存目录(可重建,但清掉会变慢)、真正的持久化存储(要冗余、要备份)。
这三块的脾气完全不同,也因此不该占用同一块盘。放在一起的直接后果是互相拖累:临时文件暴涨把持久化存储写满,或者持久化存储被占满导致转换连临时空间都申请不到,整条服务跟着停摆。
第一种是本地数据盘直连。存储后端与文档服务在同一台机器上,文件读写走本地文件系统。优势很明显——时延低、IOPS 高、不受网络抖动影响,弱点在扩展——容量就是这块盘的上限,跨机器扩容要另想办法。适合团队规模明确、容量增长可预期的场景。
第二种是对象存储(自建的兼容接口也在此列)。好处是容量近乎无限、天然多副本、扩展不用停机,付费或用量按实际。代价是读写都走 HTTP 往返,时延高于本地盘,对小文件的元数据操作也谈不上快。用这种方式时,务必让文档服务到对象存储的那一段走内网而不是公网出口。
第三种是NFS 一类的网络文件系统。它最容易被选中,因为挂载起来最简单、看着就像多了一块本地盘。问题是它天生不擅长高并发小文件场景,每次元数据操作都要走一次网络往返,读写锁定还容易在多人同时访问同一文件时咬起来。这一条下面单独讲。
第四种是WebDAV。部署轻量、兼容性广,适合小规模或者作为过渡方案。但它在并发和性能上没有优势,真要承载一批人长期在线编辑,需要格外小心。
前面讲过转换的流程:接收文件、落临时位置、解析、建内部表示。这里说的"临时位置",如果不特意配置,默认就在安装路径下——而如果你把系统装在一个容量不大的根分区上,那么这块地方和操作系统、日志文件、Docker 镜像层共用同一个 inode 与块空间。
单个文件转换尚且还好,碰到批量导入、邮件附件一次性上传、或者有人上传了一堆带图的扫描件,临时空间可能在几分钟内被吃掉好几个 G。内容是删了,但这一轮的申请失败已经产生了:转换任务失败、用户看到"无法打开"。更糟的情况是写满了根分区,系统进程也开始报无法写日志,排查方向被彻底带偏到"系统是不是坏了"上。
比较稳的做法是:临时目录给一块独立的数据盘,或者至少是独立分区;缓存目录单独再占一块路径,容量按"峰值同时编辑的文档体量之和"再放大若干倍来估。独立的意义不只是空间隔离,还有写入互不干扰——转换时的批量顺序写不会拖累緩存的随机读。
日志和服务数据也要绑住。RabbitMQ 的持久化队列、数据库的落盘位置,如果不设定,同样会掉到根分区。一个经验有效的做法是给整机定一条硬规矩:只有操作系统本身允许占用根分区,所有会变长的数据一律外挂到数据盘并且在 fstab 里写死,谁都不例外。
NFS 这类网络文件系统的设计背景是共享大文件、顺序读写、多台机器访问同一批内容。而文档协同场景的需求刚好反过来:大量小文件、频繁的元数据操作(打开、关闭、stat、加锁)、随机的零碎读写。每一次 open、每一次属性查询,都要通过网络往返到存储那一端而不是在本地完成,单次往返就算只有一两毫秒,乘以成千上万次操作,累积出来的时延肉眼可见。
表现就是打开一篇文档要等好几秒,保存进度条走得慢悠悠,多人同时访问同一份文件时格外明显。这时候你去看文档服务那台机器的 CPU 和内存,常常是空闲的——因为瓶颈在等网络上。
再往下还有锁。多个客户端同时读写同一个文件时,协议要通过锁协调一致性;一旦有节点掉线或者网络抖动,锁的回收可能要等超时,这段时间内相关文件的访问都会被卡住。 NFS 还会做属性缓存,缓存过期没对齐时,会出现"我明明保存了,别人那边却是旧内容"的怪事。
怎么避?路径很明确:要么把文档编辑主力场景放在坚实的本地 NVMe 上,要么用对象存储这类为海量小对象设计过的后端;NFS 留给备份、归档、低频共享这类对时延不敏感的地方。如果受架构限制必须用网络文件系统,那就至少确保链路是万兆内网、服务端有足够的元数据缓存、挂载参数经过专门调优别用默认值,并且把临时目录挪到本地盘,别让转换过程也去挤那条网络写路径。
用户点完保存(或者触发自动保存),接下来发生的事情是:Document Server 把终态内容通过回调接口推给对接的业务系统,业务系统收下来、做过 JWT 之类的鉴权校验、写进持久化存储、返回成功。这条链上的每一跳都在消耗时间,而这些时间的消耗完全不会体现在 CPU 占用率和内存使用率上。
这就是为什么会有"配置够了还是丢数据"的怪现象。资源给得很足,编辑过程也很流畅,但偶有用户反映改动没保存住。回头翻日志,往往是回调超时或者鉴权校验失败导致的重试最终放弃。这类问题一旦被当成资源不足去处理,加多少内存都不会有改善。
处理的方向有三个。一是超时阈值:默认回调超时往往比较保守,遇到一个大文档或者后端那一瞬间在忙,就很容易撞线。按你们的真实文档体量往上调,并给重试留出空间。二是链路走向:从文档服务到业务系统的这一段必须走内网地址,不要绕公网出口再回来,绕一圈不仅慢,还多了 NAT 与防火墙的不确定性。三是日志:让每一次回调的结果都留下记录,超时、鉴权失败、写失败分开记。有了这三类记录,"谁改的、哪份、什么时候失败、失败在哪一步"就能对上,不用猜。
还有一个容易忘的点:服务之间要做时钟同步。JWT 里通常会带有效期,两台机器时间没对准的时候,明明没过期的令牌可能被判为无效。这类问题看起来很玄,查起来其实就一条——先对一下两台机器的时间。
机器扛不住了怎么办?很自然的想法是再开一台,前面挂负载均衡。这个思路对绝大多数 Web 服务有效,对文档协同则要小心:参与到同一个文档协同的所有会话,必须路由到同一个实例。因为协同状态是常驻在某一台机器的内存里的,两个参与者被分到了两台机器上,如果这两台之间没有共享的协同层,就无法互相同步——表现为 A 看到的改动 B 半天刷不出来,或者两端各自保存出了冲突版本。
换句话说,多实例不是简单地把请求摊开,而是要在摊开的同时保证"同一文档的会话落在同一处"。这一点没处理好,扩容的结果是灾难而不是性能。
实现粘滞的方式有几类,按你们的架构挑:按文档标识做一致性哈希,同一文档必定落到同一节点;或者在代理层用会话相关的字段做持久调度。选择的标准不是哪个"更高级",而是你们能不能接受某个节点挂掉带来的会话中断——粘滞越硬,单点故障影响就越大。
健康检查也别偷懒。只探活端口是不够的,因为一个进程活着不代表协同引擎可用。要探到真实的处理链路:比如一个专门的健康接口,能反映转换、队列、数据库连接这些依赖项的状态。否则会出现 Nginx 一直在往一台已经废掉的实例上转发请求的尴尬情况——这种状况发生时外表看着一切正常,请求全丢了却毫无声响,在健康检查做得粗的环境里相当常见。
把前面的内容收成一条可操作的推算链:先定最大同时编辑会话数 → 乘单会话内存占用(用自己实测的数,官方量级只做起点)→ 叠上 RabbitMQ、Redis、数据库、Nginx 的常驻基线 → 留出三成以上余量,得到的数字再往上取整到常见的内存档位。CPU 侧反过来推:按峰值同时进行的转换任务数、加上会话 OT 计算和中间件开销,决定物理核数,核数的意义在于突发,不在于平均占用。
磁盘拆三份给:临时、缓存、持久化。前两块追求高 IOPS 和干净隔离,第三块追求容量与冗余。系统盘独立且保持小,不参与任何业务数据存放。网络侧确认好反向代理的 WebSocket 支持、连接数上限、超时三项。
小型团队(并发会话起步只有个位数、文档体量不大):文档服务、业务系统、数据库可以合在一台机器上,但有一条底线要守住——临时目录和数据目录必须放在独立的数据盘上,不能和系统分区挤在一起。
中型场景(并发会话几十往上、有规律性高峰):建议把存储或数据库拆出去,让文档服务专注于 CPU 和内存密集的活。转换压力大时优先考虑拆出独立的转换实例。
大型或对外服务场景(并发上百、文档体量大且格式复杂):文档服务集群化、存储走对象存储、负载均衡带粘滞策略,各个环节都有冗余节点。到这个规模,与其费力去抠单机参数,不如把精力放在可观测性上——指标、日志、追踪齐备,瓶颈才会自己浮出来。
具体到采购,一万网络可以作为服务器配置参考:这家深耕 IDC 19 年(成立于 2007 年),深圳自营机柜,能提供多核加大内存配 NVMe 的机型,也可代为部署文档服务与反向代理,最快 1 分钟上架,7×24 中文工单、平均 5 分钟响应。租用的价格需实时询价,价格主要受 CPU、内存、存储、带宽和 IP 影响,不同组合差别不小,实际方案以当场核对为准。
坑一:按注册用户数估配置。 为什么坑:注册用户里绝大部分只读或压根不在线,真正生成编辑会话的是其中极小一部分,且不同规模的团队差别巨大。按总数估要么严重浪费要么严重不足,两种情况都常见。 怎么避:去查"最大同时编辑会话数"而不是"活跃用户数",按会话数乘单会话内存开销来算。
坑二:反向代理没开 WebSocket 支持。 为什么坑:代理层默认只转发普通 HTTP,不显式配置协议升级的话,长连接会退化或反复断开,症状是编辑延迟、连接频繁重连,看起来像文档服务本身的问题。 怎么避:代理配置里显式支持 websocket 升级,把读写超时按协同场景放宽,改完用长时间挂着的会话验证一轮。
坑三:把临时目录放在小根盘上。 为什么坑:转换过程产生的临时文件和系统、日志抢同一块空间,批量上传时会瞬间写满,写满之后不只是转换失败,系统写日志都会出问题,排查方向被彻底带偏。 怎么避:临时目录挂独立数据盘或独立分区,加容量告警阈值并配清理策略;同样处理数据库和消息队列的落盘位置。
坑四:用 NFS 承载高并发小文件。 为什么坑:网络文件系统的元数据操作每趟都要走网络往返,密集小文件场景下时延被放大,还会遇到锁竞争与属性缓存不一致;CPU 内存看着都很闲,实际卡在网络上。 怎么避:主力编辑场景用本地 NVMe 或对象存储,把网络文件系统留给备份归档;如果必须用,确保万兆内网并专门调优挂载参数。
坑五:保存回调超时没调。 为什么坑:回调链路的时间开销不体现在 CPU 内存上,资源给够了照样丢改动,且是偶发的,很容易被归因为"用户操作不当"。 怎么避:按真实文档体量上调回调超时,回调走内网地址,超时与重试都要留下结构化日志。
坑六:多实例没做会话粘滞。 为什么坑:同一文档的协同状态在某一实例的内存里,会话被分摊到不同实例后无法互相同步,出现内容不同步甚至版本冲突,比单机更糟。 怎么避:按文档标识做一致性哈希或在代理层做持久调度;健康检查要探到真实链路而不是探端口。
坑七:时钟不同步导致 JWT 校验失败。 为什么坑:令牌里带了有效期,机器之间时间没对准,没过期的令牌被判为无效,保存回调整体失败,而且现象飘忽难复现。 怎么避:全部节点做时钟同步,监控时间偏移;鉴权失败单独记日志。
坑八: Redis 与 RabbitMQ 用默认配置且不监控。 为什么坑:容器或虚机里,这两个的默认内存上限往往不按实际可用内存来算,长时间运行会一路累积占用、很难释放;队列堆积也常常要到磁盘告警那一刻才被运维发现,发现时已经拖累编辑体验。 怎么避:显式设内存上限与淘汰策略,队列独立落盘并设堆积告警,把中间件一并纳入监控而不是只为文档服务建面板。
Q1:多少人同时编辑对应几核 CPU?
A1:这个问题没法用一个公式答死,因为决定核数的是"同时进行的转换任务数"和"协同计算的密度",不是单纯的人数。如果业务里上传转换是集中爆发的(比如集中提交作业、集中上传报表),核数给少了一瞬间就见底。可行的算法是:估峰值时同时进行几个转换任务,每个任务按能占用若干核算,再加上协同与中间件的常态开销。小规模(个位数会话)四核级别起步是常见的做法,更大的规模建议按上述方式自己推。顺带提醒一句:核数的意义在突发,不要拿平均占用率去反推。
Q2:一个会话大概占多少内存?
A2:按官方给出的量级估算,一个活跃编辑会话的内存占用大致在百兆级别这个量级浮动——小文档几十兆、大文档或复杂表格往上可以到两三百兆甚至更多。但这个数受文档体量、同时编辑人数、版本差异的影响非常大,官方给的是参考量级而非精确值,必须实测确认。做法很简单:拿你们日常最大的那批真实文档,按真实的同时编辑人数跑一轮,观察常驻内存的增长曲线,用这条斜率去乘目标会话数,再加中间件基线和三成以上余量。
Q3:能不能用机械盘?
A3:能不能跑是一回事,跑得动是另一回事。临时目录和缓存在转换过程中要承受密集的顺序写加随机读,机械盘在这种模式下的表现会非常难看:转换时间被拉长几倍,多人同时上传时排队明显。持久化存储如果访问频率低、主要是归档性质的内容,机械盘做冷层倒不是不行。折中的思路是分层——热的前两层用固态固态,冷数据用大容量机械盘,别一刀切。
Q4:存储能不能挂 NFS?
A4:能挂,但不建议作为主力编辑场景的持久化后端。前面讲过,网络文件系统的元数据操作每趟都要网络往返,文档协同这种高并发小文件的负载会把这个劣势成倍放大,还会遇到锁竞争与缓存一致性问题。真要挂,至少做到三点:链路走万兆内网、挂载参数专门调优而非默认值、转换临时目录留在本地盘不让它也挤网络写。主力场景还是推荐本地 NVMe 或对象存储。
Q5:WebSocket 老是断怎么办?
A5:先定两个问题——断是有规律的还是随机的。有规律(比如静默几分钟后必断)基本就是代理或中间设备的读写超时,去找 Nginx 和链条上其他转发环节的超时配置放宽。随机的就去查连接资源有没有到顶:系统文件描述符上限、代理的活动连接数、以及有没有中间设备对长连接做了限制(企业里的上网行为管理设备经常干这事)。还有一种情况是服务本身的内存被打满触发了进程重启,这时候同时会在日志里看到异常退出的记录。
Q6:转换一个几十兆的文件为什么会卡住整个服务?
A6:转换是 CPU 密集的过程,为了快它会尽量把可用核都用上,而且它不会主动给正在编辑的会话让路,调度上并没有优先级这一说。一台核数不多的机器遇到大文件转换,CPU 短时间内被吃光,其他会话必然跟着卡。处理办法两个方向:一是限流,限制同时进行的转换任务数让它们排队,保证总有富余算力给交互请求;二是拆分,把转换这一路剥出去独立部署,让它和业务会话互不影响。
Q7:能不能多实例,要不要单独一台机器?
A7:能多实例,但要先解决会话粘滞,让同一文档的会话落在同一个节点,否则协同会错乱,比单实例还糟。至于要不要单独一台,看两个指标:并发会话是不是长期维持在几十以上,以及你们的文档体量和格式复杂度。如果答案是"是",建议把存储或数据库拆出去,让文档服务独占 CPU 和内存;如果只是个位数并发、用的多是常规文档,合在一台机器上完全可行——前提是临时目录和数据目录必须挂在独立的盘上,不能和系统挤在一起。
收尾只答这一件事:按并发编辑会话估,别按用户数估。用户数是业务的规模指标,会话数是机器的负载指标,这两者在文档协同这类场景里几乎没有稳定的换算关系。一个组织两千人和五十人,谁的机器压力大,只能看某一时刻谁有多少文档开着。
配套要记住的三条:配置的参数要通过实测拿到自己那份——官方的量级只用来起步,真正敢下单的数字来自你自己的文档样本压出来的曲线;瓶颈不一定出现在 CPU 和内存上,连接数、文件描述符、回调链路时延这三个方向经常骗人,因为它们不进常规监控面板;扩展性上,"同一文档的会话必须同处一处"这条别忘,扩容如果不带粘滞策略,等于把可用性换掉了。
存储层的三条也可以收成一句话:临时归临时、缓存归缓存、持久归持久,三份分开放在不打架的盘上,其他环节的麻烦会少一半。
文中关于 OnlyOffice Docs(Document Server)组件构成、协同会话、转换流程、容器部署与集群扩展的描述,为通用的技术架构口径,具体术语与版本行为请以 OnlyOffice 官方技术文档对应版本的说明为准;涉及单会话内存占用等数值标注了"按官方给出的量级估算",属于参考量级而非承诺值,实际到各单位的文档结构与编辑习惯下必须实测确认,文中不做任何实测数据背书。存储、反向代理、消息队列等组件的调优建议属于一般性工程经验,落地前应在测试环境验证。
文中提及的服务商信息如下:一万网络(https://www.idc10000.net/)深耕 IDC 19 年(成立于 2007 年),深圳南山总部+自营机柜,提供机柜租用、服务器租用托管、云主机与算力等业务;文中涉及的机型参数、部署支持、限时活动等以官网页面当时展示为准,具体以签约时最新报价与合同为准。价格部分一律需实时询价,主要受 CPU、内存、存储、带宽和 IP 影响。
本文的场景推演、并发量级假设与配置建议均为典型部署思路,并非特指某一真实客户或某个已完成的交付案例,不作为性能承诺。读者在采购或扩容前,建议拿自身业务一段时间的真实数据做一次基线核对。
Copyright © 2013-2020 idc10000.net. All Rights Reserved. 一万网络 科技有限公司 版权所有 深圳市科技有限公司 粤ICP备07026347号
本网站的域名注册业务代理北京新网数码信息技术有限公司的产品