# 배포 가이드

> 규모에 따라 Server SDK 애플리케이션의 배포 형태를 선택합니다. 단일 머신, 가져오기와 내보내기 분리, 여러 협업 노드.

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

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

- Requested language: `ko-KR`

- Content language: `ko-KR`

- Documentation version: `1.3.0`

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

---

이 페이지는 Server SDK 애플리케이션의 세 가지 배포 형태를 규모 순으로 소개합니다. 먼저 [Collaboration SDK](https://docs.univer.ai/ko-KR/server/collaboration/overview.md), [가져오기와 내보내기](https://docs.univer.ai/ko-KR/server/import-export.md), [예제](https://docs.univer.ai/ko-KR/server/collaboration/examples.md)를 읽고 모듈이 어떻게 조립되는지 확인하세요. 배포는 같은 조립을 하나 이상의 노드에 배치하는 일입니다.

| 형태 | 협업 | 가져오기와 내보내기 | 권장 규모 |
| --- | --- | --- | --- |
| [단일 머신](#단일-머신) | 노드 1개 | 같은 노드 | 로컬 애플리케이션, 개발과 테스트, 소수의 내부 사용자 |
| [가져오기와 내보내기 분리](#가져오기와-내보내기-분리) | 노드 1개 | 별도 노드 | 다중 사용자 온라인 서비스, 노드 1개 용량 이내 |
| [여러 노드](#여러-협업-노드) | 여러 노드 | 별도 노드 | 노드 1개 용량을 넘거나 노드 장애 조치가 필요한 경우 |

## 단일 머신

모든 기능을 하나의 Node.js 프로세스에 배포하고 브라우저가 직접 연결합니다.

```mermaid
%%{init: {"themeVariables": {"fontSize": "14px"}, "flowchart": {"nodeSpacing": 24, "rankSpacing": 40, "padding": 12}}}%%
flowchart LR
    Browser(["브라우저"]) --> App["협업 + Exchange"]
    App --> DB[("데이터베이스")]
    classDef default rx:8,ry:8,stroke-width:1px
    classDef actor fill:transparent,stroke:none
    class Browser actor
```

- Database Adapter는 `IDatabaseAdapter` 계약을 구현합니다. [데이터베이스 어댑터](https://docs.univer.ai/ko-KR/server/collaboration/database-adapters.md)를 참고하세요.
- 가져오기와 내보내기의 작업과 파일 저장, 시간 제한, 다운로드 링크는 [파일 교환 통합](https://docs.univer.ai/ko-KR/server/import-export.md)을 참고하세요.
- 변환은 CPU 집약적이며 큰 파일은 협업을 느리게 합니다.

변환이 협업 응답에 영향을 주거나 많은 사용자에게 지속적으로 서비스해야 할 때 가져오기와 내보내기를 분리합니다.

## 가져오기와 내보내기 분리

가져오기와 내보내기를 별도 노드로 옮깁니다. 협업은 노드 1개를 유지하고, 게이트웨이가 두 종류의 경로를 나누어 라우팅하며, 둘 다 같은 데이터베이스에 연결합니다.

```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`, 변환 모듈을 조립하고 데이터베이스에 직접 접근합니다. 주입 지점은 단일 머신과 같습니다.

협업 노드 1개가 처리할 수 있는 문서 수는 프로세스 메모리로 제한됩니다. 용량을 넘거나 장애 조치가 필요하면 여러 노드로 넘어갑니다.

## 여러 협업 노드

여러 협업 노드가 같은 코드를 실행하고 같은 데이터베이스에 연결합니다. pub/sub 어댑터가 노드 간에 Room, Presence, 브로드캐스트를 중계하고 ticket store가 Session Ticket을 공유하며 `@univerjs-pro/collaboration-cluster-redis`가 Redis 구현을 제공합니다. 참고 예제: [Multi-node](https://docs.univer.ai/ko-KR/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 어댑터와 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를 공유합니다.
