# 部署指引

> 按规模为 Server SDK 应用选择部署形态：单机、拆分导入导出、多协同节点。

- Human documentation: [https://docs.univer.ai/zh-CN/server/deployment](https://docs.univer.ai/zh-CN/server/deployment)

- Agent Markdown: [https://docs.univer.ai/zh-CN/server/deployment.md](https://docs.univer.ai/zh-CN/server/deployment.md)

- Requested language: `zh-CN`

- Content language: `zh-CN`

- Documentation version: `1.2.0`

- Source: [deployment.zh-CN.mdx](https://github.com/dream-num/documentation/blob/dev/content/server/deployment.zh-CN.mdx)

---

本页按规模介绍 Server SDK 应用的三种部署形态。先阅读 [Collaboration SDK](https://docs.univer.ai/zh-CN/server/collaboration/overview.md)、
[导入导出](https://docs.univer.ai/zh-CN/server/import-export.md)和[示例](https://docs.univer.ai/zh-CN/server/collaboration/examples.md)，了解模块如何组装；部署是把同一套
组装放到一个或多个节点上。

| 形态                | 协同   | 导入导出 | 推荐规模             |
| ----------------- | ---- | ---- | ---------------- |
| [单机](#单机)         | 一个节点 | 同一节点 | 本地应用、开发测试、少量内部用户 |
| [拆分导入导出](#拆分导入导出) | 一个节点 | 独立节点 | 多人线上服务，单节点容量以内   |
| [多节点](#多协同节点)     | 多个节点 | 独立节点 | 超出单节点容量，或需要故障切换  |

## 单机

所有功能部署在一个 Node.js 进程里，浏览器直接连接。

```mermaid
%%{init: {"themeVariables": {"fontSize": "14px"}, "flowchart": {"nodeSpacing": 24, "rankSpacing": 40, "padding": 12}}}%%
flowchart LR
    Browser(["浏览器"]) --> App["协同 + 导入导出"]
    App --> DB[("数据库")]
    classDef default rx:8,ry:8,stroke-width:1px
    classDef actor fill:transparent,stroke:none
    class Browser actor
```

* Database Adapter 实现 `IDatabaseAdapter` 契约，见 [Database Adapter](https://docs.univer.ai/zh-CN/server/collaboration/database-adapters.md)。
* 导入导出的任务与文件存储、超时和下载链接见[文件交换集成](https://docs.univer.ai/zh-CN/server/import-export.md)。
* 一次转换是 CPU 密集型的，大文件会拖慢协同。

导入导出影响协同响应，或要面向多人持续服务时，拆分导入导出。

## 拆分导入导出

导入导出放到独立节点；协同仍是一个节点；网关分别路由两类路径；两者连同一个数据库。

```mermaid
%%{init: {"themeVariables": {"fontSize": "14px"}, "flowchart": {"nodeSpacing": 24, "rankSpacing": 40, "padding": 12}}}%%
flowchart LR
    Browser(["浏览器"]) --> Gateway["网关"]
    Gateway -->|"协同请求"| Node["协同节点"]
    Gateway -->|"导入导出请求"| Exchange["导入导出节点"]
    Node --> DB[("数据库")]
    Exchange --> DB
    classDef default rx:8,ry:8,stroke-width:1px
    classDef actor fill:transparent,stroke:none
    class Browser actor
```

导入导出节点组装 Database Adapter、`UniverCollabService` 和转换模块，直接访问数据库，注入点与单机相同。

协同单节点能服务的文档数受进程内存限制。超出容量或需要故障切换时进入多节点。

## 多协同节点

多个协同节点运行同一份代码，连同一个数据库。pub/sub adapter 在节点间中继 Room、Presence 和广播，
ticket store 共享 Session Ticket，`@univerjs-pro/collaboration-cluster-redis` 提供 Redis 实现。参考示例：[Multi-node](https://docs.univer.ai/zh-CN/server/collaboration/examples.md#multi-node)。

```mermaid
%%{init: {"themeVariables": {"fontSize": "14px"}, "flowchart": {"nodeSpacing": 24, "rankSpacing": 40, "padding": 12}}}%%
flowchart LR
    Browser(["浏览器"]) --> Gateway["网关"]
    subgraph Nodes["协同节点"]
        direction TB
        A["节点 A"]
        B["节点 B"]
    end
    Gateway -->|"协同请求"| A
    Gateway --> B
    subgraph Exchange["导入导出节点"]
        direction TB
        X1["节点 A"]
        X2["节点 B"]
    end
    Gateway -->|"导入导出请求"| X1
    Gateway --> X2
    A --- PubSub[("pub/sub + ticket store")]
    B --- PubSub
    A --> DB[("数据库")]
    B --> DB
    X1 --> DB
    X2 --> DB
    classDef default rx:8,ry:8,stroke-width:1px
    classDef actor fill:transparent,stroke:none
    class Browser actor
```

每个协同节点把 Redis 的 pub/sub adapter 和 ticket store 传给 Endpoint，其余组装保持原样：

```ts
import { createClient } from "redis";
import { RedisPubSubAdapter, RedisSessionTicketStore } from "@univerjs-pro/collaboration-cluster-redis";
import { UniverCollabEndpoint } from "@univerjs-pro/collaboration-endpoint";

const client = createClient({ url: process.env.REDIS_URL });
const subClient = client.duplicate();
await Promise.all([client.connect(), subClient.connect()]);

const pubSub = new RedisPubSubAdapter({ pubClient: client, subClient });
const ticketStore = new RedisSessionTicketStore({ client });
const endpoint = new UniverCollabEndpoint(service, { pubSub, ticketStore });
```

## 进一步

一个节点上同时处理超大文档会拖慢同节点上小文档的请求。可以按文档规模划分节点池，由网关把大文档路由到
单独的节点池处理；路由键仍是 unit ID，各池共享数据库和 pub/sub。
