> For the complete documentation index, see [llms.txt](https://ayakaleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ayakaleaf-pro.ayaka.space/on-premises/zh-tw/kai-shi-shi-yong/microservices.md).

# 微服務

建議使用 Toolkit 來部署和管理 Overleaf Server CE 與 Overleaf Pro 執行個體。

Toolkit 透過一些自訂腳本簡化 Overleaf 執行個體的建立，這些腳本將所需微服務的協調工作抽象化。只要執行隨附的初始化腳本，提供幾個設定選項，例如你的持久性儲存路徑，Toolkit 就會負責佈建並連接構成你的 Overleaf Server CE 或 Pro 執行個體的微服務。

這讓你可以專心自訂使用者體驗，以及實作構成你內部部署執行個體的特定功能。Toolkit 在幕後處理所有複雜性，讓你的 Overleaf 執行個體能夠以更簡化的方式部署。

{% hint style="info" %}
基於舊有原因，主要的 Overleaf 容器稱為 `sharelatex`，並以 `sharelatex/sharelatex` Docker 映像為基礎。這是因為該技術建立在 ShareLaTeX 程式碼基礎上，而該程式碼基礎已合併至 Overleaf。請參閱 [這篇部落格文章arrow-up-right](https://www.overleaf.com/blog/518-exciting-news-sharelatex-is-joining-overleaf) 以了解更多細節。未來的某個時間，這將會重新命名以符合 Overleaf 的命名規則。
{% endhint %}

#### 架構

在 Overleaf 容器內，軟體以一組微服務執行，由 `runit`管理。容器內一些較有趣的檔案包括：

* `/etc/service/`：微服務的初始化檔案。
* `/var/log/overleaf/`：各個微服務的日誌。
* `/overleaf/services/`：各種微服務的程式碼。
* `/var/lib/overleaf/`：持久性資料的掛載點（對應於主機上由 `OVERLEAF_DATA_PATH` 所指定的目錄）。

#### MongoDB 和 Redis 容器

Overleaf 依賴兩個外部資料庫：MongoDB 和 Redis。預設情況下，Toolkit 會為這兩個資料庫各建立一個容器，此外還會建立 Overleaf 容器，總共三個 Docker 容器。

{% hint style="info" %}
如果你偏好連接到現有的 MongoDB 或 Redis 執行個體，可以在 [overleaf.rc](https://ayakaleaf-pro.ayaka.space/on-premises/zh-tw/kai-shi-shi-yong/pages/c66b68bf29f648389701bb70ed6cfe3650e9f9b1#the-overleaf.rc-file) 組態檔中設定適當的選項。
{% endhint %}

#### 編輯器與編譯流程

本節概述文件處理與編譯流程。

{% hint style="info" %}
本頁說明僅在 Overleaf Pro 中提供的隔離式編譯之編譯流程。在 Server CE 中，編譯流程使用簡單的子程序——請將引用一個 **容器內啟動 shell** 的項目替換為單一項目 **在子程序中執行編譯**.
{% endhint %}

元件 / 角色：

* `使用者` — 應用程式的使用者
* `編輯器` — 在瀏覽器中執行的用戶端應用程式
* `clsi` — 用於編譯 PDF 的微服務
* `document-updater` — 用於處理文件更新的微服務
* `filestore` — 用於處理二進位檔案的微服務
* `real-time` — 用於處理 Web Socket 的微服務
* `web` — 用於處理 API 請求的（不那麼）微服務

**Redis 快取**

* **使用者**：載入編輯器頁面
* **編輯器**：開啟 Web Socket
* **編輯器**：透過 Web Socket 傳送開啟文件的請求
  * **real-time** -> **document-updater**：文件從 MongoDB 載入至 Redis
* **編輯器**：透過 Web Socket 傳送文件更新
  * **real-time** -> **document-updater**：文件在 Redis 中更新
* **編輯器**：傳送更多編譯請求
  * 距離上次刷新已過 5 分鐘後（每份文件）：
    * **document-updater**：將文件從 Redis 刷新到 MongoDB
* **編輯器**：傳送更多更新
  * 每 100 次更新（每份文件）：
    * **document-updater**：將文件歷史從 Redis 刷新到 MongoDB
* **使用者**：離開編輯器／關閉瀏覽器分頁
  * 5 分鐘後
    * **real-time**：檢查是否有其他協作者，如果沒有：
      * **real-time** -> **document-updater**：將文件從 Redis 刷新到 MongoDB

**從 MongoDB 讀入 Redis**

* **document-updater** -> **web** -> **docstore**：從 MongoDB 讀取

**從 Redis 刷新至 MongoDB**

* **document-updater** -> **web** -> **docstore**：寫入 MongoDB

**編譯 — 「full」同步模式**

* **編輯器**：傳送同步模式設為「full」的編譯請求
* **web** -> **document-updater**：任何文件都會從 Redis 刷新到 MongoDB
* **web** -> **docstore**：所有文件都會從 MongoDB 下載
* **web** -> **clsi**：編譯請求會傳送到 `clsi`，包括：
  * 同步模式
  * 檔案樹的雜湊值 -> 「專案狀態」
  * 所有文件及其內容 -> 受限於 7MB 的請求主體大小限制
  * 供單獨下載的二進位檔案 URL
* **clsi**：以同步模式和「專案狀態」檢查磁碟上的狀態
  * 這是完整同步，因此可以忽略先前的磁碟狀態
* **clsi**：清理編譯目錄
* **clsi**：將所有文件寫入編譯目錄
* **clsi**：將所有二進位檔案寫入編譯目錄
  * `clsi` 從每個專案的本機快取複製檔案
  * 在快取未命中時：
    * **clsi** -> **filestore**：下載檔案
* **clsi**：寫入「專案狀態」
* **clsi**：確保存在符合所需設定的 docker 容器
  * 建構容器選項，包括 texlive 版本
  * 雜湊選項
  * 容器名稱： `project-<project-id>-<user-id>-<hash>`
* **clsi**：啟動容器並將 stdout/stderr 串流到記憶體中 -> 限制為 2MB
* **clsi**：保留已停止的容器 -> 24 小時後清理
* **clsi**：將 stdout/stderr 寫入磁碟
* **clsi**：將輸出檔案複製到唯一的輸出目錄
  * 由 8 個隨機位元組加上毫秒精度時間戳組成的 build-id
  * 刪除除最後 3 個（匿名）／最後 1 個（已登入使用者）以外的所有建置資料夾
* **clsi**：編譯失敗／逾時
  * 刪除編譯快取 — 它可能包含部分檔案／損毀的快取
* **編輯器**：下載 output.log 和 output.pdf

**編譯 — 「incremental」同步模式**

* **編輯器**：傳送同步模式設為「incremental」的編譯請求
* **web** -> **document-updater**：從 Redis 取得任何文件
  * 「專案狀態」雜湊也儲存在 Redis 中
  * **web** 將檔案樹的雜湊傳送到 `document-updater` 以及 `document-updater` 在不匹配時可將增量編譯轉為完整編譯
    * 請參閱編輯器要求「full」編譯時所執行的編譯流程
* **web** -> **clsi**：編譯請求會傳送到 `clsi`，包括：
  * 同步模式
  * 檔案樹的雜湊值 -> 「專案狀態」
  * 來自 Redis 的所有文件及其內容 -> 受限於 7MB 的請求主體大小限制
  * 沒有二進位檔案
* **clsi**：以同步模式和「專案狀態」檢查磁碟上的狀態
  * 這是增量同步，因此「專案狀態」必須相符
  * 不匹配時：回應 409，讓網頁以「full」同步重試
    * 請參閱編輯器要求「full」編譯時所執行的編譯流程
* **clsi**：將更新後的文件寫入編譯目錄
* **clsi**：確保存在符合所需設定的 docker 容器
  * 建構容器選項，包括 texlive 版本
  * 雜湊選項
  * 容器名稱： `project-<project-id>-<user-id>-<hash>`
* **clsi**：啟動容器並將 stdout/stderr 串流到記憶體中 -> 限制為 2MB
* **clsi**：保留已停止的容器 -> 24 小時後清理
* **clsi**：將 stdout/stderr 寫入磁碟
* **clsi**：將輸出檔案複製到唯一的輸出目錄
  * 由 8 個隨機位元組加上毫秒精度時間戳組成的 build-id
  * 刪除除最後 3 個（匿名）／最後 1 個（已登入使用者）以外的所有建置資料夾
* **clsi**：編譯失敗／逾時
  * 刪除編譯快取 — 它可能包含部分檔案／損毀的快取
* **編輯器**：下載 output.log 和 output.pdf

**編譯 — 在模式之間切換**

* **編輯器**：觀察到編譯失敗，下一次編譯為「full」編譯
* **編輯器**：觀察到編譯成功，下一次編譯為「incremental」編譯


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ayakaleaf-pro.ayaka.space/on-premises/zh-tw/kai-shi-shi-yong/microservices.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
