跳到主要内容

连接 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。

  1. 重启 ONLYOFFICE 文档,并检查 DocService 日志(Linux 上为 /var/log/onlyoffice/documentserver/docservice/out.log)。
    • RabbitMQ 连接错误记录为 [AMQP] connect error,并附带尝试次数和距下次重试的时间。
    • Redis 错误包含 redisClient。
  2. 在两个浏览器中打开同一文档并共同编辑。
  3. 在文档打开期间,停止一个 RabbitMQ 节点。检查编辑是否可以继续,以及关闭文档后文档是否已保存。
  4. 再次启动该 RabbitMQ 节点,然后对一个 Redis 主节点重复此测试。测试完成后,再次启动该 Redis 节点。