连接 RabbitMQ 和 Redis 集群
介绍
本指南仅适用于 ONLYOFFICE 文档企业版和开发者版。
如需将 ONLYOFFICE 文档连接到 RabbitMQ 集群和 Redis Cluster,请使用本指南。如需将 ONLYOFFICE 文档本身作为集群运行,请参阅适用于 Kubernetes 的 ONLYOFFICE 文档。
ONLYOFFICE 文档社区版不使用 Redis。从 9.4.0 版本开始,也不使用 RabbitMQ。
编辑配置
以下设置需在 local.json 文件中进行:
- Linux:
/etc/onlyoffice/documentserver/local.json - Windows:
%ProgramFiles%\ONLYOFFICE\DocumentServer\config\local.json
将参数添加到文件的现有部分中,然后重启 ONLYOFFICE 文档服务。
连接 RabbitMQ 集群
ONLYOFFICE 文档连接到单个 RabbitMQ URL。rabbitmq.url 参数只接受一个字符串,不支持代理 URL 列表。请确保 RabbitMQ 集群可通过一个端点访问:
- TCP 负载均衡器,例如 HAProxy,并配有高可用地址(keepalived 或 VRRP);
- 解析到正在运行的节点的 DNS 名称。
在 local.json 中指定此端点:
{
"rabbitmq": {
"url": "amqp://<user>:<password>@rabbitmq.example.com:5672"
}
}
对于 Docker,请在 AMQP_URI 环境变量中传递相同的 URL。
当某个 RabbitMQ 节点宕机时,ONLYOFFICE 文档会自动重新连接。对于经典队列,会在拥有队列的节点重启后重新开始消费消息。
心跳
ONLYOFFICE 文档启用 TCP keepalive,并使用 RabbitMQ 提供的 AMQP 心跳超时(默认为 60 秒)来检测断开的连接。请将 RabbitMQ 负载均衡器的空闲超时设置为大于心跳超时。如需请求其他超时值,请在 rabbitmq.url 中以秒为单位设置 heartbeat:
{
"rabbitmq": {
"url": "amqp://<user>:<password>@rabbitmq.example.com:5672?heartbeat=30"
}
}
仲裁队列
默认情况下,ONLYOFFICE 文档使用经典队列。您可以切换到仲裁队列,RabbitMQ 会在集群节点之间复制这类队列。为以下四个队列将 x-queue-type 设置为 quorum:
{
"rabbitmq": {
"queueconverttask": {"options": {"arguments": {"x-queue-type": "quorum"}}},
"queueconvertresponse": {"options": {"arguments": {"x-queue-type": "quorum"}}},
"queueconvertdead": {"options": {"arguments": {"x-queue-type": "quorum"}}},
"queuedelayed": {"options": {"arguments": {"x-queue-type": "quorum"}}}
}
}
请将 queuepubsub 保留为经典队列:它是独占的自动删除队列,而仲裁队列不允许这种类型。
仲裁队列在 RabbitMQ 4.0 至 4.2 中支持两个优先级,从 RabbitMQ 4.3 开始支持 32 个优先级。更早的版本不支持优先级,因此转换任务将不再按优先级处理。
RabbitMQ 无法更改现有队列的类型。在使用新设置重启 ONLYOFFICE 文档之前,请停止它,并删除 ds.converttask6、ds.convertresponse、ds.convertdead 和 ds.delayed 队列,或在这些队列的 name 参数中设置新名称。请在维护窗口期间执行此操作:已删除队列中剩余的消息将会丢失。
连接 Redis Cluster
ONLYOFFICE 文档内置的两个 Redis 客户端,node-redis(默认)和 ioredis,均支持 Redis Cluster。请在 local.json 的 services.CoAuthoring.redis 部分中指定集群节点。
对于 node-redis,请使用 optionsCluster:
{
"services": {
"CoAuthoring": {
"redis": {
"name": "redis",
"optionsCluster": {
"rootNodes": [
{"url": "redis://192.168.0.150:7000"},
{"url": "redis://192.168.0.150:7001"},
{"url": "redis://192.168.0.150:7002"}
],
"defaults": {"username": "default", "password": "<password>"}
}
}
}
}
}
对于 ioredis,请使用 iooptionsClusterNodes 和 iooptionsClusterOptions:
{
"services": {
"CoAuthoring": {
"redis": {
"name": "ioredis",
"iooptionsClusterNodes": [
{"host": "192.168.0.150", "port": 7000},
{"host": "192.168.0.150", "port": 7001},
{"host": "192.168.0.150", "port": 7002}
],
"iooptionsClusterOptions": {"redisOptions": {"password": "<password>"}}
}
}
}
}
Redis Cluster 仅支持 0 号数据库。
映射节点地址
集群节点会将自己的地址告知客户端。如果 ONLYOFFICE 文档无法访问这些地址(例如由于 NAT 或 Docker 网络),日志中会出现 MOVED ... 或 Cannot read properties of undefined (reading 'master') 等错误。
请将每个通告的地址映射到 ONLYOFFICE 文档可以访问的地址。对于 node-redis,请将 nodeAddressMap 添加到 optionsCluster:
"optionsCluster": {
"rootNodes": [{"url": "redis://redis1.example.com:7000"}],
"nodeAddressMap": {
"10.0.0.5:7000": {"host": "redis1.example.com", "port": 7000},
"10.0.0.6:7000": {"host": "redis2.example.com", "port": 7000},
"10.0.0.7:7000": {"host": "redis3.example.com", "port": 7000}
}
}
对于 ioredis,请将 natMap 添加到 iooptionsClusterOptions:
"iooptionsClusterOptions": {
"natMap": {
"10.0.0.5:7000": {"host": "redis1.example.com", "port": 7000},
"10.0.0.6:7000": {"host": "redis2.example.com", "port": 7000},
"10.0.0.7:7000": {"host": "redis3.example.com", "port": 7000}
}
}
检查设置
第 3 步和第 4 步需要在至少三个 RabbitMQ 节点之间复制的仲裁队列,以及为每个主节点配置一个副本的 Redis Cluster。
- 重启 ONLYOFFICE 文档,并检查 DocService 日志(Linux 上为
/var/log/onlyoffice/documentserver/docservice/out.log)。- RabbitMQ 连接错误记录为
[AMQP] connect error,并附带尝试次数和距下次重试的时间。 - Redis 错误包含
redisClient。
- RabbitMQ 连接错误记录为
- 在两个浏览器中打开同一文档并共同编辑。
- 在文档打开期间,停止一个 RabbitMQ 节点。检查编辑是否可以继续,以及关闭文档后文档是否已保存。
- 再次启动该 RabbitMQ 节点,然后对一个 Redis 主节点重复此测试。测试完成后,再次启动该 Redis 节点。