> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kasoftware.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 架構

> 知行之橋訊息驅動整合平臺的設計原則、核心概念和實現細節。

export const companyName = "知行軟件";

export const siteNameShort = "知行之橋";

export const siteName = "知行之橋";

{siteName} 是一個用於整合業務流程的訊息驅動平臺。它提供了一個集中的通訊中心，使應用程式、資料庫和外部訊息系統能夠相互通訊。

## 設計原則與實現

{siteNameShort} 的架構決策源於一套核心設計原則。本節重點介紹 {siteNameShort} 設計的三個方面：

* 優先考慮的原則和價值
* 深入理解 {siteNameShort} 所需的核心概念
* 架構決策及其如何符合設計原則

[核心原則](#核心原則)和[概念](#概念)部分適用於技術和非技術使用者。其餘實現部分旨在幫助工程師瞭解如何利用 {siteNameShort} 架構。

### 核心原則

下圖展示了 {siteNameShort} 設計的核心原則：

<img src="https://mintcdn.com/qiao/U-KEZ9JbQY4Wqs1D/public/images/architecture_core_principles.png?fit=max&auto=format&n=U-KEZ9JbQY4Wqs1D&q=85&s=1a87ce1b29416b51c7b9d4b5286c8398" alt="Core principles diagram" width="600" data-path="public/images/architecture_core_principles.png" />

{siteNameShort} 架構並不是在整合平臺中實現上述設計原則的唯一方式。以下是對實現選擇及其如何符合設計原則的說明。

## 概念

從高層看，{siteNameShort} 的實現由三個元素組成：

* 工作流程 (Flows)
* 端口 (Connectors)
* 訊息 (Messages)

下圖展示了這些元素之間的關係：

<img src="https://mintcdn.com/qiao/U-KEZ9JbQY4Wqs1D/public/images/architecture_data_processing.png?fit=max&auto=format&n=U-KEZ9JbQY4Wqs1D&q=85&s=0a12dfc757ac09eae98d2aaf0867b03d" alt="Data processing relationships" width="800" data-path="public/images/architecture_data_processing.png" />

### 工作流程 (Flows)

{siteNameShort} [工作流程](../flows)是配置好的工作流程程，用於執行一組自動化的資料處理任務。工作流程由多個端口組成，這些端口相互連線，使一個端口處理的資料會自動傳遞給工作流程中的下一個端口。

在 UI 中，工作流程位於**工作流程**頁面的工作區內。端口被新增到空白畫布上，並在此進行配置和相互連線。下圖展示了一個由兩個端口（AS2 和 File）組成的簡單工作流程。

<img src="https://mintcdn.com/qiao/U-KEZ9JbQY4Wqs1D/public/images/architecture_flow.png?fit=max&auto=format&n=U-KEZ9JbQY4Wqs1D&q=85&s=11034f807db5a81d8b217255fb8362e5" alt="Simple flow with two connectors" width="800" data-path="public/images/architecture_flow.png" />

端口之間的藍色箭頭表示 AS2 端口接收的資料會自動傳遞給 File 端口。透過將一個端口右側的藍點拖動到另一個端口的左側，即可建立這種關係。

工作流程中的一系列端口建立了邏輯資料處理鏈，因此工作流程的設計應旨在完成特定的業務任務。這些任務的複雜度各不相同，從簡單下載檔案到根據接收到的業務單據同步多個後端應用程式。

可以在 {siteNameShort} 中配置多個工作流程來完成不同的任務。除非透過藍色工作流程箭頭顯式連線，否則工作流程之間相互獨立。

### 端口 (Connectors)

[端口](../connectors)是工作流程的單個構建塊，作用於應用程式資料或訊息。每個端口對訊息執行特定操作，並將其傳遞給工作流程中的下一個端口，或傳遞給外部物件（如 FTP 目的地）。

操作主要分為三類：觸發 (Trigger)、轉換 (Transform) 和終結 (Terminal)。

* 觸發端口透過**接收自動化**拉取或建立檔案來啟動工作流程；對於支援被動接收的端口，則是在端口從外部用戶端接收檔案時啟動。範例包括 [AS2](../connectors/as2)、[Email Receive](../connectors/email-receive) 或 [SFTP](../connectors/sftp)。
* 轉換端口位於工作流程中間，負責對訊息執行操作（以某種方式對其進行修改）。範例包括 [X12](../connectors/x12)、[XML Map](../connectors/xml-map/xml-map) 或 [CSV](../connectors/csv)。
* 終結端口是工作流程的終點，此時 {siteNameShort} 將訊息移交給底層磁碟，或者訊息在端口執行傳送操作期間被消耗且不生成輸出。範例包括 [File](../connectors/file)、[MySQL](../connectors/mysql/mysql)，或任何配置為 Upsert 的資料庫端口。

端口每次執行上述操作之一時，都在處理一個*交易*。

在**工作流程**頁面的工作區中，將端口新增到畫布時，其配置設定面板會開啟：

<img src="https://mintcdn.com/qiao/U-KEZ9JbQY4Wqs1D/public/images/architecture_connector.png?fit=max&auto=format&n=U-KEZ9JbQY4Wqs1D&q=85&s=2ce3075a236ce6afbd6d729163bd67de" alt="Connector configuration panel" width="800" data-path="public/images/architecture_connector.png" />

端口根據其型別（AS2、SQL Server、XML 等）具有不同的配置設定集。

某些端口（如 AS2 和 SFTP）既可以從外部物件或伺服器接收資料，也可以將資料傳送到外部物件或伺服器（或兩者兼有）。這些端口通常位於工作流程的開始或結束，因為這是資料進入或離開應用程式的位置。

其他端口（如 XML Map 和 X12）在應用程式本地處理資料。這些端口通常位於工作流程的中間，因為它們只能從其他端口接收資料（不能從外部源接收），並且只能將資料傳送到其他端口（不能傳送到外部目的地）。

### 訊息 (Messages)

當資料在工作流程中的端口之間傳遞時，它以訊息的形式傳遞。訊息主要由檔案有效載荷資料（{siteNameShort} 正在處理的資料）和中繼資料（{siteNameShort} 用於跟蹤應用程式中資料流向的資訊）組成。

訊息在[訊息實現](#訊息實現)中有更詳細的解釋，但高層核心點是：訊息是標準 RFC822（網際網路訊息）格式的檔案。當一個端口將資料傳遞給工作流程中的另一個端口時，它將資料寫入檔案，然後將該檔案傳遞給下游的下一個端口，如下圖所示。

<img src="https://mintcdn.com/qiao/U-KEZ9JbQY4Wqs1D/public/images/architecture_message_flow.png?fit=max&auto=format&n=U-KEZ9JbQY4Wqs1D&q=85&s=ccdeee4fedf069d7544aec25dc7d94eb" alt="Message flow between connectors" width="800" data-path="public/images/architecture_message_flow.png" />

在工作流程的每個步驟中，訊息（檔案）透過觸發端口被接收或下載到應用程式中，透過轉換端口在應用程式本地進行轉換，或者透過終結端口被傳送或上傳出應用程式。這些操作中的每一個都稱為一個*交易*。

{siteNameShort} 是透明的：可以透過檢視檔案系統、觀察訊息如何從一個資料夾複製到另一個資料夾，以及使用常規文字編輯器或其他工具檢視訊息內容，來觀察平臺內部發生的情況。

## 實現概觀

本節提供有關 {siteNameShort} 對上述核心概念（[工作流程](#工作流程-flows)、[端口](#端口-connectors)和[訊息](#訊息-messages)）實現的技術細節，並解釋為什麼這種實現滿足我們的[核心原則](#核心原則)。

#### 基於檔案的架構

{siteNameShort} 將所有資料儲存在檔案系統的檔案中，因此應用程式中的所有內容都會持久化到磁碟。例如：

* 應用程式資料（訊息）
* 配置資料（[個人設定](./administration/profiles)和工作流程）
* 日誌（詳見[日誌](./administration/activity)）

配置好的工作流程中的端口從**交易索引標籤**讀取和寫入檔案（訊息）。當資料從一個端口傳遞到下一個端口時，這些訊息檔案將從第一個端口的 Receive 資料夾移動到下一個端口的 Send 資料夾。

{siteNameShort} 在這種基於檔案系統的基礎架構之上提供了 Web UI，以便輕鬆構建和配置工作流程。{siteNameShort} 的 [Admin API](../admin-api) 和 UI 是管理配置的推薦方法。這些方法會直接修改磁碟上的配置檔案。基於檔案的架構還使 {siteNameShort} 易於與基礎設施即程式碼 (IaC) 工具和 Git 等版本控制系統整合。

## 訊息實現

{siteNameShort} 中的訊息是磁碟上的簡單檔案，包含應用程式處理的原始資料。訊息由兩部分組成：

* 正文：應用程式資料有效載荷
* 標頭：訊息中繼資料

標頭和正文的組合儲存在符合 RFC2822 標準且副檔名為 `.eml` 的檔案中，可以使用任何標準文字編輯器或郵件用戶端開啟。標頭是由 `newline` 字元分隔的 `name: value` 標頭簡單清單，正文透過兩個 `newline` 字元與標頭分隔。

<Warning>為確保 {siteNameShort} 執行可靠，請勿在應用程式執行時直接與這些檔案互動。外部程式對這些檔案加鎖可能會導致效能和可靠性問題。</Warning>

### 訊息正文

訊息正文或有效載荷是應用程式處理的實際檔案資料。這是從遠端源接收、由轉換端口處理的資料等。雖然訊息標頭主要由 {siteNameShort} 用於跟蹤訊息，但訊息有效載荷包含了使用者最關心的資料。

接收資料時，{siteNameShort} 會生成一條訊息（在磁碟上寫入一個新的訊息檔案），並將傳入的資料作為訊息正文。例如，當 SFTP 端口從遠端伺服器下載檔案時，該遠端檔案的內容將成為新訊息的正文。

當資料在應用程式本地處理時（例如將 EDI 翻譯為 XML，或將檔案對映到新格式），執行操作的端口讀取輸入訊息的正文，在記憶體中處理資料，並將結果寫入輸出訊息的正文。

當資料離開應用程式時（例如上傳檔案到遠端伺服器、傳送檔案給夥伴或插入資料庫），僅傳送輸入訊息的正文。

### 訊息標頭

訊息標頭幫助 {siteNameShort} 跟蹤資料在應用程式中的進度。標頭包括唯一的 MessageId（幫助 {siteNameShort} 瞭解訊息的完整生命週期，即使檔名被更改）、端口處理訊息時的時間戳、處理過程中可能發生的任何錯誤以及其他中繼資料。

標頭以 *headerName: headerValue* 語法列在訊息頂部，由換行字元分隔。將滑鼠懸停在訊息上並點選**檢視詳情**，可以顯示其關聯的標頭，並允許下載訊息檔案內容。

訊息標頭還用於儲存 {siteNameShort} 在工作流程中需要了解的各種輔助值。例如，從遠端 FTP 伺服器的子資料夾下載檔案時，{siteNameShort} 使用[子資料夾標頭](../connectors/ftp#subfolder-headers)來跟蹤訊息的資料夾路徑，以便在本地系統上需要重建此資料夾路徑時使用。

{siteNameShort} 為原始資料檔案增補了描述應用程式如何處理該檔案的中繼資料。以下是一些最常見的標頭：

* 唯一且持久的 MessageId，在整個工作流程中標識該檔案
* 檔案被處理的時間戳
* 處理該檔案的任何端口的 ConnectorId
* 任何由於錯誤導致檔案處理失敗的記錄

應用程式永遠不會編輯或覆蓋訊息標頭。新的標頭總是附加到現有清單的末尾，以便保留完整的處理歷史。

### 工作流程中的訊息

雖然 {siteNameShort} 在內部使用訊息標頭來跟蹤和理解應用程式處理的資料，但除非檢查訊息，否則會對使用者隱藏這些細節。例如，{siteNameShort} 使用內部 MessageId 來標識訊息，但在**交易索引標籤**和**訊息**頁面上顯示公共檔名。

要檢查訊息上的標頭，請懸停在訊息上並選擇**檢視訊息詳情**。下圖顯示了**交易索引標籤**上的訊息。

<img src="https://mintcdn.com/qiao/U-KEZ9JbQY4Wqs1D/public/images/architecture_headers.png?fit=max&auto=format&n=U-KEZ9JbQY4Wqs1D&q=85&s=8aef9c105fba5b0adb9c6edbaa2dee88" alt="Messages on the Transactions tab" width="800" data-path="public/images/architecture_headers.png" />

無論訊息處於工作流程的哪個位置，當訊息被寫入端口的內部 Receive 資料夾時，{siteNameShort} 都會以 `.eml` 格式儲存。但是，當訊息傳送到外部系統（例如資料庫或 SFTP 伺服器）時，{siteNameShort} 僅上傳檔案內容，不包括 `.eml` 標頭。同樣，在使用 [File 端口](../connectors/file)的傳送操作將檔案寫入磁碟時，{siteNameShort} 會省略 `.eml` 結構，以便輸出符合外部程式的預期。換句話說，`.eml` 標頭是 {siteNameShort} 內部檔案格式的一部分，但在向外部目的地交付資料時不被包含。

### 批次組和批次訊息

訊息可以包含多個有效載荷，在這種情況下，它們被視為*批次組*。批次組中的每個單獨有效載荷被視為一條*批次訊息*，如下圖所示。

<img src="https://mintcdn.com/qiao/U-KEZ9JbQY4Wqs1D/public/images/architecture_batch_processing.png?fit=max&auto=format&n=U-KEZ9JbQY4Wqs1D&q=85&s=b481fddf1b4476226458522385b25d41" alt="Batch groups and batch messages" width="800" data-path="public/images/architecture_batch_processing.png" />

#### 批次組

訊息可以分批組成批次組，以提高效能並使大型訊息組更易於管理。批次組是 MIME 格式的檔案，其中每個 MIME 部分是一條單獨的批次訊息。批次組使用與基本訊息相同的標頭方案維護有關批次的中繼資料。這些標頭跟蹤整個批次的處理，而不是批次的各個部分。

#### 批次訊息

批次組中的每條批次訊息都是一個包含應用程式處理的檔案有效載荷資料的 MIME 部分。每條批次訊息都包含與有效載荷（而非批次組）關聯的中繼資料。批次訊息具有多組中繼資料：一組標頭用於跟蹤整個批次組，另一組單獨的標頭用於跟蹤批次中的每條訊息。

### 存取和檢視訊息

由於訊息只是磁碟上的簡單檔案，使用者和外部系統可以存取和檢視當前處於 {siteNameShort} 管道中的訊息。要使用外部應用程式存取訊息，需要了解在檔案系統的何處查詢訊息 `.eml` 檔案。請參閱[資料夾層級](#資料夾層級)瞭解訊息檔案的確切位置。

<Warning>為確保 {siteNameShort} 執行可靠，請勿在應用程式執行時直接與訊息檔案互動。外部程式對這些檔案加鎖可能會導致效能和可靠性問題。</Warning>

也可以在 {siteNameShort} UI 和 {siteNameShort} [Admin API](../admin-api) 中檢視訊息。訊息顯示在處理過該訊息的任何端口的**交易索引標籤**中，以及[日誌](./administration/activity)頁面上。點選**檢視詳情**開啟**訊息資訊**頁面：

<img src="https://mintcdn.com/qiao/U-KEZ9JbQY4Wqs1D/public/images/architecture_message_headers.png?fit=max&auto=format&n=U-KEZ9JbQY4Wqs1D&q=85&s=86c8e11c0c2484d57c6ee2f3a4f10ad2" alt="Message Information panel showing headers" width="800" data-path="public/images/architecture_message_headers.png" />

此面板中顯示的值是訊息標頭。點選**下載**按鈕存取訊息正文。點選**下載日誌**下載與訊息關聯的[日誌](#訊息跟蹤與日誌)。

### 訊息跟蹤與日誌

訊息包含一個 MessageId 標頭，作為訊息的唯一識別碼。當檔案透過工作流程時，即使檔案本身被重新命名，該 MessageId 仍保持不變。因此，可以透過參考其 MessageId 來追蹤任何檔案在整個工作流程中的進度。該值還允許使用者查詢與特定交易關聯的日誌資料。

{siteNameShort} 以兩種格式儲存日誌資料：

* [應用程式資料庫](#應用程式資料庫)
* 磁碟上的[詳細日誌檔案](#詳細日誌檔案)

這些格式及其關係詳見下文。

#### 應用程式資料庫

\_應用程式資料庫\_是一個關係型資料庫，{siteNameShort} 用它來：

* 儲存有關應用程式處理的每個交易的中繼資料
* 儲存不屬於任何特定交易的應用程式操作日誌
* 儲存某些端口的狀態（例如，當端口正在等待確認或回執時）

{siteNameShort} 捆綁了 SQLite (Windows/.NET) 或 H2 (Java) 資料庫，但也可以配置為使用外部資料庫，如 SQL Server、PostgreSQL 或 MySQL。{siteNameShort} 負責處理應用程式資料庫中所有相關表的建立和維護。

要使用外部資料庫，必須在託管應用程式的伺服器配置檔案中配置資料庫連接字串（請參閱 [.NET 版](./installation/windows-edition)中的[配置應用程式資料庫](./installation/windows-edition#configuring-the-application-database)，以及[跨平臺版](./installation/cross-platform-edition) `arc.properties` 檔案中的 [cdataappdb](./installation/arc-properties-configuration#cdata-app-db) 設定）。

應用程式資料庫中有一個表用於跟蹤訊息並查詢日誌。它儲存應用程式處理的每個交易的中繼資料，中繼資料包括所處理訊息的 MessageId。使用 UI 中的**日誌**頁面查詢訊息和交易日誌。可以在**日誌**頁面上搜尋交易中繼資料（如時間戳、ConnectorId 和狀態）。為了最大限度地減少資料庫佔用空間，詳細日誌資料不包含在**日誌**頁面中，而是儲存在磁碟上的日誌檔案中。

#### 詳細日誌檔案

每當 {siteNameShort} 處理一條訊息時，它都會生成一個與 MessageId 同名的日誌資料夾。此資料夾包含詳細日誌檔案，具體日誌內容取決於傳送和/或接收檔案的端口型別。例如，AS2 端口除了記錄代表訊息本身的 `.eml` 檔案外，還會記錄 MDN 回執、原始請求和回應以及連線日誌。

這些日誌檔案對於僅在工作流程中跟蹤訊息並非必需；儲存在應用程式資料庫中的中繼資料足以跟蹤訊息。但是，為了查詢有關特定交易的詳細資訊（特別是在偵錯時），需要根據訊息的 MessageId 和處理該訊息的端口在磁碟上找到相應的檔案。

使用者在知道 MessageId 後可以手動導航到磁碟上相應的日誌資料夾；但是，使用應用程式資料庫查詢這些詳細日誌檔案通常更方便。詳情請參閱[應用程式資料庫與日誌檔案之間的關係](#應用程式資料庫與日誌檔案之間的關係)。

#### 應用程式資料庫與日誌檔案之間的關係

儲存在應用程式資料庫中的中繼資料包含了查詢與特定交易關聯的日誌檔案所需的所有資訊。{siteNameShort} UI 和 [Admin API](../admin-api) 利用這種關係來提供對任何交易日誌檔案的便捷存取。

* **日誌**頁面包含所有交易中繼資料。懸停在任何交易項目上並點選**檢視詳情**以存取關聯的日誌檔案；在底層，{siteNameShort} 正在使用 MessageId 查詢磁碟上相應的日誌檔案。

* 同樣，端口配置面板上的**交易索引標籤**提供了存取由該特定端口處理的任何交易的入口。展開這些交易以檢視和下載詳細日誌檔案。

* 應用程式資料庫對於手動導航到存放交易日誌檔案的相應資料夾也很有幫助。通常，使用者知道交易的檔名但不知道內部 MessageId。**日誌**頁面上的**訊息**頁面是可搜尋的，因此搜尋特定檔名會顯示與該檔名關聯的任何交易的 MessageId。有關知道 MessageId 和端口後如何查詢日誌資料夾的更多資訊，請參閱[資料夾層級](#資料夾層級)。

### 訊息實現背後的設計決策

我們希望應用程式資料對使用者和外部系統保持透明，因此訊息是透過檔案系統上的簡單資料檔案傳遞的，而不是透過不透明的內部資料通道。因此，{siteNameShort} 不是一個在處理過程中隱藏資料的黑匣子。這意味著 {siteNameShort} 可以有效地嵌入到任何從檔案系統特定資料夾提取或放置檔案的系統中。

我們還希望無需專門的工具或程式即可存取訊息。訊息儲存在符合 RFC2822 標準的檔案中，因此任何文字編輯器都可以開啟該檔案。由於訊息具有 `.eml` 副檔名，雙擊檔案即可開啟訊息並在系統預設郵件用戶端中顯示其內容。

為了使訊息和日誌可存取且透明，我們提供了一個可搜尋的交易中繼資料資料庫。此資料庫可用於直接存取訊息有效載荷和詳細日誌檔案，同時保持較小的資料庫佔用空間。

## 端口實現

端口代表[工作流程](../flows)中的一個步驟。複雜的工作流程是透過將多組端口連線在一起來執行邏輯資料處理鏈而建立的。

端口執行三種型別的操作：

* 接收資料並寫入輸出訊息（例如透過 SFTP 下載遠端檔案）
* 讀取輸入訊息並將資料傳送給外部物件（例如透過 AS2 傳送檔案）
* 讀取輸入訊息，在本地進行處理，並寫入輸出訊息（例如將 EDI 檔案翻譯為 XML）

大多數端口可以執行前兩個操作（向遠端端點傳送資料和從遠端端點接收資料）或最後一個操作（在本地轉換資料）。端口執行的每個操作都稱為一個\_交易\_。

端口從**交易索引標籤**讀取和寫入輸入和輸出訊息。當端口在工作流程中連線時，{siteNameShort} 會自動將訊息從第一個端口的**交易索引標籤**移動到下一個端口的**交易索引標籤**資料夾。（在磁碟上，輸入資料夾標記為 Send，輸出資料夾標記為 Receive。）

### 端口檔案和資料夾

端口的每個例項在磁碟上都作為一個以 ConnectorId（工作流程中的顯示名稱）命名的單個資料夾存在。每個端口資料夾包含以下內容：

* 包含配置設定的 [port.cfg](#port-cfg) 檔案
* [Send](#輸入訊息) 子資料夾中待傳送或處理的訊息（如輸入訊息）
* [Receive](#輸出訊息) 子資料夾中已接收的訊息（如輸出訊息）
* 由端口處理的訊息的[日誌檔案](#日誌檔案)
* [端口特定檔案](#其他配置檔案)，如對映、範本和指令碼

以下部分解釋了這些資料夾內容在應用程式中的功能。[資料夾層級](#資料夾層級)解釋了端口資料夾及其子資料夾的確切位置。

#### Port.cfg

每個端口的 `port.cfg` 檔案包含管理端口行為的設定（出現在端口**設定**和**高階**索引標籤中的設定）。該檔案為 INI 格式：端口設定以 `SettingName = SettingValue` 語法列出，每行一個設定。在 UI 中編輯端口設定在功能上等同於直接在 `port.cfg` 檔案中編輯設定。

`port.cfg` 檔案支援\_間接值\_，這意味著設定可以使用引用而不是字串字面量。這在概念上類似於在應用程式的其他部分設定變數，並在 `port.cfg` 檔案中引用該變數名。有關如何設定間接值的詳細資訊，請參閱[資料目錄](#資料目錄)。

#### 輸入訊息

**交易索引標籤**資料夾存放輸入訊息，即排隊等待端口處理的訊息。

在每個時鐘滴答（預設每半秒）處，{siteNameShort} 檢查每個端口的 Send 資料夾是否有更改，並向任何有可用訊息的端口分派工作執行緒。處理訊息時，{siteNameShort} 會向該訊息附加一個包含處理嘗試時間戳的標頭。

{siteNameShort} 根據最後修改時間對輸入訊息進行排序，以便優先處理較舊的檔案。由於 {siteNameShort} 在每次嘗試期間都會附加標頭，這確保了導致錯誤的訊息不會因重複重試而不必要地阻塞端口。

請注意，端口必須啟用 *Send* 自動化，才能在每個時鐘滴答處處理輸入訊息。

#### 輸出訊息

Receive 資料夾存放輸出訊息，即已被端口接收、下載和/或處理的訊息。

某些端口在完成輸入訊息處理後立即寫入輸出訊息（例如翻譯資料格式的端口）。其他端口在未先讀取輸入訊息的情況下寫入輸出訊息。範例包括輪詢遠端伺服器以下載檔案的 SFTP 端口，以及被動監聽傳入檔案的 AS2 端口。

當端口在工作流程中連線到另一個端口時，輸出訊息不會留在 Receive 資料夾中。它們會被傳遞到下一個端口的 Send 資料夾。

#### 日誌檔案

端口處理的每個交易都會生成一組日誌檔案。有關交易的中繼資料會被新增到日誌中，[詳細日誌](#詳細日誌檔案)資訊以檔案形式儲存在磁碟上。日誌檔案始終包含 `.eml` 格式的訊息本身以及任何端口特定的日誌檔案。

預設情況下，所有端口日誌檔案按周組織在資料夾中，如下面的資料夾結構所示：

<img src="https://mintcdn.com/qiao/U-KEZ9JbQY4Wqs1D/public/images/architecture_logs_folder_hierarchy.png?fit=max&auto=format&n=U-KEZ9JbQY4Wqs1D&q=85&s=57e58a4fb885a3539eadd90f41a7faee" alt="Log folder hierarchy" width="400" data-path="public/images/architecture_logs_folder_hierarchy.png" />

要更改預設的每週資料夾組織方式，請將任何端口的**日誌子資料夾方案**欄位設定為不同的時間間隔（如\_每日\_或\_每月\_）。這意味著在該時間間隔內生成的所有日誌都存放在一個子資料夾中。這可以透過減少單個子資料夾的大小來提高磁碟 I/O 效能。

可以使用[訊息索引標籤](./administration/activity#messages-tab)查詢相應的日誌資料夾，可以透過查詢 MessageId 或使用**下載日誌**。

#### 保留已處理檔案的副本

保留成功處理檔案副本的推薦方式是：在工作流程中右鍵單擊端口，選擇**顯示成功路徑**，然後將成功路徑連線到 [File 端口](../connectors/file)。File 端口會將已處理的有效負載寫入所選的本地目錄。透過成功路徑路由的檔案在應用程式內傳輸時受 {siteNameShort} 的靜態加密保護；寫入 File 端口的目標目錄後，將以明文形式儲存。

<Note>
  **儲存到已傳送資料夾**設定會將已處理檔案複製到每個端口資料夾內的 Sent 子資料夾；此設定自 v26.3 起已棄用，且預設停用。對於之前已啟用該設定的端口，它仍然可見並可用，但不建議用於新配置。Sent 資料夾中的檔案不受靜態加密保護。
</Note>

#### 其他配置檔案

根據端口型別，某些端口資料夾包含其他配置檔案。這些額外檔案包括：

* `map.json`
* `script.rsb`
* 範本 XML 檔案

這些檔案儲存對映關係、自定義指令碼行為以及端口輸入和輸出的結構。手動編輯這些檔案等同於編輯相關的端口 UI 設定。

<Warning>手動編輯這些檔案可能存在風險。雖然佈局易於理解且透明，但不正確地修改這些配置檔案可能會導致意外後果。</Warning>

### 端口實現背後的設計決策

我們希望工作流程完全模組化，這意味著每個端口都應以可預測且直觀的方式提供直接的功能。{siteNameShort} 執行複雜任務的能力來自於組合任意端口集的能力，而端口介面保持簡單。由於端口鏈被分解為離散的步驟，複雜的工作流程仍然易於理解。

我們希望與端口相關的所有資料（配置資料、應用程式資料、日誌資料等）都易於存取。因為資料都儲存在特定於端口的資料夾中，存取資料只需知道在何處找到該資料夾即可。配置資料以透明的 INI 格式儲存，因此它與訊息資料一樣，可以使用簡單的工具輕鬆檢視和編輯。

這種基於資料夾的端口方法還使理解資料如何在端口之間傳遞變得容易：對訊息檔案進行簡單的檔案移動操作，即可將一個端口的輸出變為另一個端口的輸入。{siteNameShort} 包含內建工具來自動建立這些檔案移動關係。

<Warning>為確保 {siteNameShort} 執行可靠，請勿在應用程式執行時直接與任何配置檔案互動。外部程式對這些檔案加鎖可能會導致效能和可靠性問題。</Warning>

## 工作流程和工作區實現

[工作流程](../flows)在檔案系統上由一個 `flow.json` 檔案表示，該檔案包含工作流程中每個端口的位置和連線關係。有關此檔案的位置，請參閱[資料夾層級](#資料夾層級)。

工作流程中端口的位置純粹是裝飾性的，僅在 UI 中配置工作流程時使用。端口之間的連線在資料處理級別是相關的：端口寫入輸出訊息後，它會查詢應用程式引擎以檢視是否需要將輸出訊息傳遞給另一個端口的 Send 資料夾。應用程式使用 `flow.json` 檔案來確定將檔案交給哪個端口（如果有）。

可以在同一個工作流程畫布上配置多個工作流程，{siteNameShort} UI 允許拖動畫布在工作流程之間導航。這類似於線上導航地理地圖（如 Google Maps）。

[工作區](../flows/workspaces)提供了工作流程之間的邏輯分離。每個工作區提供一個新的畫布，用於在其中將端口配置為邏輯工作流程。延續 Google Maps 的類比，工作區相當於獨立的\_星球\_。

按交易夥伴或整合專案分離工作區是常見的做法。然而，是否在獨立的工作區配置新工作流程取決於個人偏好。有關更多資訊，請參閱[將工作流程組織到工作區中](../flows/designing-a-flow#organize-flows-into-workspaces)。

#### 檔案系統上的工作區

引入新的（非預設）工作區時，{siteNameShort} 會在資料夾層級中新增一組新資料夾。`workspaces` 目錄包含在非預設工作區中配置的所有端口的資料夾。`workspaces` 資料夾是[資料目錄](#資料目錄)的同級資料夾。

### 工作流程和工作區背後的設計決策

我們認為，保持工作流程中端口之間簡單模組化關係的最好方法是將工作流程視為純粹的邏輯概念。確定邏輯資料處理序列所需的所有資訊都已包含在端口實現中。

我們希望工作區能夠提供在更實質層面上分離端口的能力。獨立的工作區使用獨立的資料夾來存放端口，以便檔案系統級別的操作（如權限和目錄清單）可以輕鬆地與特定工作區隔離。

## 資料夾層級

由於所有 {siteNameShort} 資源都可在檔案系統上存取，從底層理解 {siteNameShort} 需要學習應用程式的資料夾結構以及檔案和資料夾在磁碟上的組織方式。

為了理解該層級，檢視 {siteNameShort} 安裝的目錄檢視會很有幫助。以下是資料夾結構的視覺呈現。結構的詳細資訊將在以下部分中解釋。

<img src="https://mintcdn.com/qiao/U-KEZ9JbQY4Wqs1D/public/images/architecture_folder_hierarchy.png?fit=max&auto=format&n=U-KEZ9JbQY4Wqs1D&q=85&s=02191726cb97e29de91ffab1c612deb5" alt="Folder hierarchy" width="400" data-path="public/images/architecture_folder_hierarchy.png" />

<Note>
  * 此層級結構假設工作流程僅在預設工作區中配置。有關其他工作區的詳細資訊，請參閱[工作流程和工作區](#工作流程和工作區實現)。
  * 如果**設定 > 高階**頁面的[清理設定](./administration/settings/cleanup-settings)部分中的**本地存檔資料夾**為空，則每個端口還包含一個 **Archive** 資料夾。
</Note>

### 根安裝目錄

所有 {siteNameShort} 資源都在安裝目錄中，預設位置如下：

* **Windows**: `C:\Program Files\CData\CData Arc`
* **Linux**: `/opt/arc`

對於 Java 版安裝，{companyName} 提供了一個 zip 檔案，可以將其解壓到選擇的安裝目錄（例如 `/opt/arc`）。

當 Java 版 {siteNameShort} 託管在 Tomcat 等外部 Java Servlet 上時，{siteNameShort} 資源駐留在 `~/cdata/arc` 中。在此路徑中，`~` 解析為託管 Java Servlet 的使用者的家目錄。

在上面的[資料夾層級](#資料夾層級)中，根安裝目錄是樹頂部的 `Arc` 資料夾。

### 資料目錄

`data` 目錄包含以下內容：

* 為在[工作流程](../flows)頁面上配置的每個端口（在預設工作區中）準備的一個子資料夾
* 一個 [profile.cfg](#profile-cfg) 檔案
* 一個 [flow.json](#flow-json) 檔案
* 一個 [roles.json](#roles-json) 檔案
* 一個 [settings.json](#settings-json) 檔案
* 一個 [users.json](#users-json) 檔案
* 所有[憑證](#憑證)檔案

#### Profile.cfg

`profile.cfg` 檔案包含應用程式範圍的設定，例如配置的本地[個人設定](./administration/profiles)（例如 AS2 個人設定）。該檔案為 INI 格式：應用程式設定以 `SettingName = SettingValue` 語法列出，每行一個設定。

`profile.cfg` 設定分為若干部分：用於常規應用程式設定的 `Application` 部分，以及為每個個人設定準備的專用部分（例如，AS2 個人設定有一個 `AS2` 部分，本地 SFTP Server 設定有一個 `SFTPServer` 部分）。

在 UI 的**個人設定**頁面上編輯應用程式設定在功能上等同於直接在 `profile.cfg` 檔案中編輯設定。

#### Flow\.json

`flow.json` 檔案包含已配置工作流程的結構：每個端口例項的位置和連線關係。直接編輯 `flow.json` 與在**工作流程**頁面上移動或重新連線端口的效果相同。

#### Roles.json

`roles.json` 檔案包含與所有自定義[使用者角色](./administration/settings/user-roles)相關的詳細資訊。直接編輯 `roles.json` 與在**角色**頁面上新增和配置角色的效果相同。

#### Settings.json

`settings.json` 檔案包含一系列設定，可以透過使用引用名稱而非具體值在應用程式的其他位置引用這些設定。這使得能夠以不在應用程式中顯示的方式儲存安全值（如密碼）。還可以使用引用名稱來集中配置跨多個例項部署的工作流程。

支援這種集中引用語法的設定在 UI 中有一個鑰匙圖示，可以點選它來檢視 `settings.json` 檔案中定義的引用清單。有關更多資訊，請參閱[全域設定庫](./administration/settings/global-settings-vault)。

#### Users.json

`users.json` 檔案包含與所有 {siteNameShort} [使用者](./administration/settings/users)相關的詳細資訊。直接編輯 `users.json` 與在**使用者**頁面上新增或編輯使用者的效果相同。

#### 憑證

在應用程式中建立或上傳的所有憑證都儲存在 `data` 目錄中。通常，憑證以公開金鑰/私密金鑰對的形式出現，檔名相同但副檔名不同：`.pfx` 為私密金鑰，`.cer` 為公開金鑰。上傳到應用程式的其他格式憑證會按原樣儲存。

{siteNameShort} 列舉 `data` 目錄中的憑證，以確定在 UI 中配置憑證時的可用選項。將憑證檔案新增到 `data` 目錄與在 UI 中上傳憑證的效果相同。

### 端口資料夾

每個配置的端口例項在 `data` 目錄中都有一個專用資料夾。資料夾名稱與工作流程中每個端口的 ConnectorId 值（顯示名稱）匹配。在上述範例資料夾結構中，兩個配置的端口是 AS2\_Amazon 和 Database\_MySQL。

端口資料夾的內容在[端口檔案和資料夾](#端口檔案和資料夾)中進行了說明。以下是端口資料夾中子資料夾結構的概觀：

* Logs：由端口處理的每條訊息的詳細日誌檔案
  * Received：端口接收的訊息日誌；每條訊息都有自己的資料夾，與 MessageId 匹配
  * Sent：端口傳送的訊息日誌；每條訊息都有自己的資料夾，與 MessageId 匹配
* Receive：端口已接收或處理的訊息
* Send：端口應傳送或處理的訊息
* Sent：成功處理的訊息副本（原始資料檔案格式）。僅當啟用已棄用的**儲存到已傳送資料夾**設定時存在。

根據端口型別，某些端口可能具有其他子資料夾：

* Pending：等待另一方確認的已處理訊息
* Public：應作為應用程式中公共端點釋出的檔案
* Schemas：特定於特定端口的架構檔案（如 EDI 架構）
* Templates：端口輸入和輸出資料的 XML 表示

### 資料夾層級背後的設計決策

由於我們希望 {siteNameShort} 中的資料透明且易於存取，應用程式中的特定檔案應當易於查詢。簡單的分層資料夾結構有助於確保使用者和外部系統知道在何處查詢 {siteNameShort} 資料檔案。

我們希望 {siteNameShort} UI 為配置和使用應用程式提供便捷的介面，但同時也希望應用程式保持完全可嵌入到其他解決方案中。瞭解 {siteNameShort} 資料夾結構是將這些其他解決方案指向任何相關 {siteNameShort} 資料所需的全部內容。

## 自動化

{siteNameShort} 自動化服務處理每個端口**交易索引標籤**資料夾中的檔案。自動化服務以半秒一個\_時鐘滴答\_的頻率執行，訊息在每個滴答時在工作流程中向前推進一步。

{siteNameShort} 透過向每個端口分配多個執行緒來支援平行處理，每個執行緒可以處理該端口中的多個檔案。分配的工作執行緒具體數量和每個工作執行緒處理的檔案數由[個人設定](./administration/profiles)和特定端口設定中的效能設定決定。

### 時鐘滴答 (Clock Ticks)

以預定義的時間間隔（預設 500 毫秒），{siteNameShort} 檢查每個配置端口的 Send 資料夾內容，如果發現新檔案，則根據端口設定分配工作執行緒來處理它們。

應用程式不保證首先列舉哪個端口的輸入。當單個端口的 Send 資料夾中有多個檔案時，它們根據最後修改時間排序處理（最早修改的檔案優先處理）。

當 {siteNameShort} 嘗試處理檔案時，它會新增一個包含處理時間戳的訊息標頭，這會更改檔案的最後修改時間。這意味著如果檔案處理失敗（導致錯誤），與 Send 資料夾中的其他檔案相比，它將變成優先順序最低的檔案。這防止了單個檔案因重複拋錯並立即重試而阻塞端口的執行。

### 平行處理

啟用平行處理後，{siteNameShort} 可以在單個時鐘滴答期間向同一個端口分配多個工作執行緒。這些工作執行緒的數量和行為由**設定**頁面的**高階**索引標籤上的三個設定決定（其中一些可以在特定端口的**高階**索引標籤中為單個端口覆蓋）：

* **工作執行緒池 (Worker Pool)**：建立應用程式可以同時分配給所有端口（總計）的全域最大執行緒數。當執行緒完成在特定端口中的分配任務後，它會被回收回執行緒池。主機上可用的硬體資源決定了此設定的上限。
* **每個端口最大工作執行緒數 (Max Workers per Connector)**：建立同時分配給單個端口的最大執行緒數。分配給端口的每個執行緒會逐個處理該端口 Send 資料夾中的檔案，直到資料夾為空（或達到**每個端口最大檔案數**）。達到此條件後，分配給端口的執行緒在完成處理後會被回收回工作執行緒池。可以在單個端口的**高階**索引標籤上覆蓋此設定。
* **每個端口最大檔案數 (Max Files per Connector)**：建立在單個時鐘滴答內，單個端口處理的檔案數量限制。例如，如果此設定設為 5，那麼分配給端口的執行緒在（共同）處理了 5 個檔案後將被回收回工作執行緒池，即使該端口的 Send 資料夾中仍有檔案。可以在單個端口的**高階**索引標籤上覆蓋此設定。當設定為 0 時，端口會嘗試處理分配執行緒時端口中存在的所有檔案。

執行緒以輪詢方式分派給各個端口，因此調整這些值（全域或針對特定端口）可以幫助緩解吞吐量問題，或防止某些端口佔用過多系統資源。下圖展示了平行處理設定是如何協同工作的。

<img src="https://mintcdn.com/qiao/U-KEZ9JbQY4Wqs1D/public/images/architecture_parallel_processing.png?fit=max&auto=format&n=U-KEZ9JbQY4Wqs1D&q=85&s=c1ac41e26e35904544117bbfec5b2b97" alt="Parallel processing settings diagram" width="800" data-path="public/images/architecture_parallel_processing.png" />

#### 最大化效能

可以在單個端口中調整**每個端口最大工作執行緒數**和**每個端口最大檔案數**設定，以在某些端口需要比其他端口更多或更少資源時，幫助最大化 {siteNameShort} 效能。

增加特定端口的**每個端口最大工作執行緒數**會告訴應用程式在處理該端口的輸入檔案時分配更多系統資源。當特定端口成為工作流程吞吐量的瓶頸時，這非常有用。然而，由於執行緒是以輪詢方式分配的，為許多不同的端口增加此設定可能會導致應用程式耗盡**工作執行緒池**中的執行緒。發生這種情況時，應用程式必須等待其他執行緒完成並被回收，然後才能將它們分配給剩餘的端口。

減小特定端口的**每個端口最大工作執行緒數**可以防止該端口在處理檔案時嚴重消耗工作執行緒池。這有助於避免應用程式在輪詢分配期間耗盡可分派執行緒的問題。但是，如果端口的 Send 資料夾有很多檔案，那麼較少數量的執行緒可能需要很長時間才能完成檔案處理並回收回池中（除非同時調整了**每個端口最大檔案數**，如下文所述）。

增加特定端口的**每個端口最大檔案數**（或設定為 `0` 以處理所有檔案）有助於確保檔案不會在端口的 Send 資料夾中停留多個時鐘滴答。這有助於提高高業務量端口的吞吐量。然而，這也可能增加分配給該端口的執行緒長時間不被回收回工作執行緒池的可能性（可能會導致執行緒短缺）。

減小特定端口的**每個端口最大檔案數**有助於確保分配給該端口的執行緒能夠及時回收回池中。然而，如果 Send 資料夾中的檔案數量超過了每滴答處理的最大值，這可能意味著檔案並不總是在單個時鐘滴答內被處理。

最大化效能取決於具體環境和用例。通常，需要處理或傳送大量檔案的端口應當分配更多工作執行緒，並且應當允許這些工作執行緒在回收前處理更多檔案。為了防止執行緒池耗盡，其他端口應當分配較少的工作執行緒，並限制這些工作執行緒處理較少的檔案。

### 接收自動化

在 {siteNameShort} 中，上述對輸入檔案的自動處理稱為 *Send* 自動化。{siteNameShort} 還支援 *Receive* 自動化，它描述了端口根據預定間隔自動將檔案拉取到 {siteNameShort} 工作流程中的過程。

接收操作分為兩類：

* 從遠端主機/伺服器（如 FTP、SFTP 或 S3）下載檔案
* 從後端系統（如資料庫、ERP 系統或 CRM）提取資料並將其作為 XML 寫出

接收自動化始終與排程間隔掛鉤，該間隔決定了端口嘗試下載檔案或從外部系統提取資料的頻率。

每個時鐘滴答，自動化服務都會檢查是否有任何端口的接收間隔已到期。如果是，端口會立即建立出站連線並根據端口設定提取資料。

某些端口（如 AS2 端口）被動監聽傳入資料以進行接收。這些端口不支援接收自動化，因為它們無法主動輪詢外部系統以取得資料。

## 投入使用

開始使用 {siteNameShort} 並不需要完全理解其底層架構。然而，剝開應用程式的層層外衣可以帶來一系列重要的好處：

* [評估](#評估-arc-技術特性) {siteNameShort} 的方法是否符合更具體的技術要求
* 以更透徹的理解和控制力來[操作](#充滿信心操作-arc)和配置應用程式
* 瞭解如何將 {siteNameShort} [嵌入](#將-arc-嵌入到更大的解決方案中)到更大的資料處理解決方案中

#### 評估知行之橋技術特性

{siteNameShort} 是訊息驅動整合框架的輕量級實現。對其底層的瞭解有助於工程師判斷這種方法是否適合其特定的業務需求。

閱讀本文件後，我們希望指導設計決策的原則已清晰明瞭，因為這些原則將繼續塑造應用程式的成長和發展。瞭解應用程式設計背後的“為什麼”有助於使用者在決定其是否適合自己時做出明智的選擇。

#### 充滿信心操作知行之橋

{siteNameShort} UI 提供了一個易於操作和配置應用程式的介面。對底層架構更好的理解可以幫助使用者進行更高階的“引擎蓋下”的工作，例如在特定資料夾上設定權限，以實現對使用者存取的細粒度控制。

此外，我們相信對工作流程、端口及其與應用程式資料之間關係的概念性掌握，可以幫助使用者快速輕鬆地配置最佳業務流程。我們優先考慮讓使用者能夠以最小的配置開銷利用 {siteNameShort} 的功能集。

#### 將知行之橋嵌入到更大的解決方案中

一旦瞭解了 {siteNameShort} 的資料夾結構，將 {siteNameShort} 嵌入到另一個資料處理系統的過程就會變得簡單。由於 {siteNameShort} 透過磁碟上一組定義明確的資料夾與系統互動，任何讀寫指定資料夾的應用程式都可以無縫地與 {siteNameShort} 交換資料。{companyName} 建議在與外部系統互動時使用 [File 端口](../connectors/file)。有關配置詳情，請參閱[與本地檔案系統互動](../flows/designing-a-flow#interacting-with-the-local-file-system)。

#### 輕鬆使用知行之橋

最後，我們相信工程師普遍渴望瞭解他們所使用系統的底層機制。即使上述好處都不適用於實際實現，我們也希望本文件能提供額外的舒適感和熟悉感，幫助你使用 {siteNameShort} 構建自己的資料集成工作流程。如果對本文件內容有任何疑問或需要進一步指導，請聯絡專門的支援團隊 **[support@kasoftware.cn](mailto:support@kasoftware.cn)**，我們將很樂意為你提供幫助。
