在微服務架構下,建置開發環境需要整合多項技術,包含 Docker 容器化、測試框架以及依賴管理。本文將以 FlixTube 應用程式為例,說明如何使用 Docker 建立開發與正式環境,並利用 Jest 和 Playwright 進行測試,最後透過 GitHub Actions 實作 CI/CD 流程。首先,我們會分別建立 Dockerfile.dev 和 Dockerfile.prod 檔案,以區隔開發測試與正式環境的設定。接著,使用 Jest 設定單元測試,並以 Playwright 進行端對端測試,確保各個微服務的功能正確性。最後,整合 GitHub Actions,自動化建置、測試和佈署流程,提升開發效率。

微服務開發環境設定

在進行微服務開發時,設定適當的開發環境是非常重要的。這涉及到使用Docker容器化技術、組態測試框架以及管理專案依賴等。

Dockerfile 組態

為了區分開發測試環境和生產環境,我們需要建立兩個不同的Dockerfile:

  • Dockerfile.dev:用於開發和測試階段,包含了開發所需的所有依賴和工具。
  • Dockerfile.prod:用於生產環境,最佳化了容器大小和安全性,僅包含生產環境所需的最小依賴集。

Jest 組態

Jest是一個流行的JavaScript測試框架。透過建立一個Jest組態檔案(通常命名為jest.config.js),我們可以定製測試行為,例如指定測試檔案的位置、設定測試環境等。

依賴管理

在專案根目錄下的package.json檔案中,我們管理專案的依賴和指令碼。這包括了開發依賴(如測試框架)、生產依賴以及可以執行的指令碼(如啟動應用、執行測試等)。

原始碼組織

  • src/:這個目錄包含了微服務的原始碼。它可能包括了應用邏輯、模型定義、API路由等。
  • index.js:作為微服務的入口檔案,負責啟動應用。

測試

  • tests/:這個目錄包含了微服務的自動化測試。這些測試可以是單元測試,也可以是整合測試,確保應用的各個部分正確地一起工作。

Mermaid 圖表:微服務開發流程

  flowchart TD
    A[需求分析] --> B[設計]
    B --> C[開發]
    C --> D[測試]
    D --> E[佈署]
    E --> F[維護]

圖表翻譯:

上述Mermaid圖表描述了微服務從需求分析到維護的完整生命週期。每個階段都對應著微服務開發中的關鍵步驟:首先進行需求分析,以確定專案的目標和範圍;然後設計系統架構和資料模型;接著進行開發,實作功能和寫測試;隨後進行測試,以確保系統的品質和可靠性;完成測試後,佈署系統到生產環境;最後,進入維護階段,不斷迭代和最佳化系統,以滿足使用者的變化需求。

內容解密:

在微服務開發中,使用Docker容器化可以提高開發效率和環境的一致性。Jest組態檔案使得測試工作更加方便和可靠。透過package.json管理依賴,可以保持專案的可維護性。原始碼的組織和測試的撰寫都是保證微服務品質的關鍵步驟。

微服務概覽

在本章中,我們將探討微服務的概念及其在實際應用中的運用。首先,我們來看一下微服務的基本結構。

微服務結構

一個典型的微服務專案通常包含多個獨立的服務,每個服務負責特定的業務邏輯。以下是微服務專案的基本結構:

- 服務1
  - 服務1程式碼
  - 服務1組態
- 服務2
  - 服務2程式碼
  - 服務2組態
...

在這個結構中,每個服務都是獨立的,並且可以獨立佈署和管理。

FlixTube 概覽

FlixTube 是一個簡單的微服務專案,旨在展示微服務的基本概念。FlixTube 由多個微服務組成,每個微服務負責特定的業務邏輯。以下是 FlixTube 的基本結構:

- gateway
  - gateway 程式碼
  - gateway 組態
- metadata
  - metadata 程式碼
  - metadata 組態
- video-streaming
  - video-streaming 程式碼
  - video-streaming 組態
...

FlixTube 的每個微服務都是獨立的,並且可以獨立佈署和管理。

獨立佈署

在傳統的單體式應用中,所有的業務邏輯都集中在一個單一的應用中。然而,在微服務架構中,每個服務都是獨立的,並且可以獨立佈署和管理。這樣可以帶來以下優點:

  • 靈活性:每個服務可以獨立佈署和管理,這樣可以提高整個系統的靈活性。
  • 可擴充套件性:每個服務可以獨立擴充套件,這樣可以提高整個系統的可擴充套件性。
  • 容錯性:如果一個服務出現問題,不會影響其他服務的正常執行。

GitHub Actions

GitHub Actions 是一個連續整合和連續佈署(CI/CD)工具,可以幫助我們自動化微服務的佈署和管理。以下是 GitHub Actions 的基本組態:

name: Build and deploy
on:
  push:
    branches:
      - main
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Build and deploy
        run: |
          # Build and deploy code here

在這個組態中,我們定義了一個名為 Build and deploy 的工作流程,當程式碼推播到 main 分支時,會觸發這個工作流程。工作流程會在 ubuntu-latest 環境中執行,並執行 Build and deploy 步驟。

內容解密

在上面的例子中,我們定義了一個名為 Build and deploy 的工作流程,當程式碼推播到 main 分支時,會觸發這個工作流程。工作流程會在 ubuntu-latest 環境中執行,並執行 Build and deploy 步驟。在這個步驟中,我們可以執行任意程式碼,例如建構和佈署微服務。

圖表翻譯

以下是微服務架構的圖表:

  graph LR
    A[客戶端] -->|請求|> B[Gateway]
    B -->|路由|> C[Metadata]
    C -->|處理|> D[Video Streaming]
    D -->|傳回|> B
    B -->|傳回|> A

在這個圖表中,我們可以看到客戶端傳送請求給 Gateway,Gateway 路由請求給 Metadata,Metadata 處理請求並傳回結果給 Gateway,Gateway 傳回結果給客戶端。這個圖表展示了微服務架構中的請求流程。

圖表翻譯

以下是 GitHub Actions 的圖表:

  graph LR
    A[程式碼推播] -->|觸發|> B[GitHub Actions]
    B -->|執行|> C[Build and deploy]
    C -->|建構和佈署|> D[微服務]
    D -->|傳回|> B
    B -->|傳回|> A

在這個圖表中,我們可以看到程式碼推播觸發 GitHub Actions,GitHub Actions 執行 Build and deploy 步驟,Build and deploy 步驟建構和佈署微服務,微服務傳回結果給 GitHub Actions,GitHub Actions 傳回結果給客戶端。這個圖表展示了 GitHub Actions 的工作流程。

在開發環境中執行 FlixTube

在開始佈署 FlixTube 之前,我們需要先確保它可以在我們的開發電腦上執行。下面是 FlixTube 在開發環境中的架構概覽。

專案結構

FlixTube 的專案結構如下:

  • docker-compose.yml:用於定義和執行多個 Docker 容器的檔案,適用於開發和測試環境。
  • package.json:包含指令碼和依賴項的檔案,對於 Node.js 專案至關重要。
  • test/fixtures:包含測試資料的資料夾,用於測試應用程式。
  • mock-storage:一個模擬儲存微服務的專案,用於方便測試。
  • microservices:每個微服務的子專案。
  • deploy:包含佈署指令碼和 Kubernetes 組態的資料夾。

執行個別微服務

在執行整個應用程式之前,讓我們先了解如何啟動個別的微服務。當我們開發新的微服務或專注於現有的微服務時,我們經常需要在應用程式的正常上下文之外獨立執行它。以下是啟動 metadata 微服務的步驟:

  1. 切換目錄:進入 metadata 微服務的專案目錄。

    cd chapter-10/metadata
    
  2. 安裝依賴項:在執行 Node.js 專案之前,必須先安裝其依賴項。

    npm install
    
  3. 執行微服務:使用 Node.js 直接執行微服務。

    node index.js
    

使用 Docker Compose 執行應用程式

除了執行個別微服務外,我們也可以使用 Docker Compose 來執行整個 FlixTube 應用程式。這涉及到建立一個 docker-compose.yml 檔案,定義所有微服務及其之間的依賴關係。

version: '3'
services:
  metadata:
    build:./metadata
    ports:
      - "3001:3001"
    depends_on:
      - db
    environment:
      - DATABASE_URL=postgres://user:password@db:5432/database

  db:
    image: postgres
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=database

然後,使用以下命令執行整個應用程式:

docker-compose up

這樣就可以在開發環境中執行 FlixTube 應用程式,並對其進行測試和除錯。

圖表翻譯:

  graph LR
    A[Metadata Microservice] -->|依賴|> B[Database]
    B -->|提供資料|> A
    C[Docker Compose] -->|管理|> A
    C -->|管理|> B

這個圖表展示了 metadata 微服務、資料函式庫和 Docker Compose 之間的關係。Docker Compose 用於管理和啟動這些服務,確保它們之間的正確依賴關係。

開發環境設定

在開始開發FlixTube應用之前,我們需要設定好開發環境。這包括安裝必要的套件和設定Docker Compose。

安裝套件

首先,我們需要安裝必要的套件,包括dockerdocker-compose。然後,我們可以使用以下命令安裝其他必要的套件:

npm install

Docker Compose設定

接下來,我們需要設定Docker Compose以便在開發環境中執行FlixTube應用。Docker Compose是一個工具,允許我們定義和執行多個容器的應用。

FlixTube應用

FlixTube是一個影片串流應用,使用微服務架構設計。它包括多個微服務,例如影片上傳、元資料儲存等。

Mock-storage微服務

在開發環境中,我們使用一個模擬版本的儲存微服務(Mock-storage)。這允許我們在不需要真正儲存系統的情況下測試應用。

載入模擬資料

我們需要載入模擬資料(database fixtures)到模擬儲存微服務中,以便測試應用。

影片上傳和元資料

FlixTube應用包括影片上傳和元資料儲存功能。影片上傳允許使用者上傳影片,而元資料儲存則負責儲存影片的相關訊息,例如標題、描述等。

執行FlixTube應用

現在,我們可以使用Docker Compose執行FlixTube應用了。執行應用後,我們可以使用Web瀏覽器存取它。

內容解密:

以下是執行FlixTube應用的步驟:

  flowchart TD
    A[安裝套件] --> B[設定Docker Compose]
    B --> C[載入模擬資料]
    C --> D[執行FlixTube應用]
    D --> E[存取應用]

圖表翻譯:

上述流程圖顯示了執行FlixTube應用的步驟。首先,我們需要安裝必要的套件。然後,我們設定Docker Compose以便執行應用。接下來,我們載入模擬資料到模擬儲存微服務中。最後,我們執行FlixTube應用並使用Web瀏覽器存取它。

FlixTube 的開發與測試

10.5.1 啟動 FlixTube 的個別微服務

要啟動 FlixTube 的個別微服務,需要使用 npm start 指令,這會啟動微服務的開發模式。然而,在啟動之前,需要設定環境變數,例如 PORTDBHOSTDBNAMERABBIT。這些變數用於設定微服務的連線埠、資料函式庫連線字串、資料函式庫名稱和 RabbitMQ 連線字串。

在開發模式下,微服務會自動重啟以反映程式碼的變化。要啟動微服務的開發模式,可以使用 npm run start:dev 指令。

10.5.2 啟動整個 FlixTube 應用程式

要啟動整個 FlixTube 應用程式,可以使用 Docker Compose。Docker Compose 是一個方便的工具,允許您定義和執行多個容器。FlixTube 的 docker-compose.yaml 檔案定義了所有微服務和依賴項,包括資料函式庫和 RabbitMQ。

要啟動 FlixTube,可以執行以下指令:

cd chapter-10
docker compose up --build

這會建立和啟動所有微服務和依賴項。等待 “online” 訊息出現在終端機中,表示應用程式已經啟動並執行中。

10.6 測試 FlixTube

要測試 FlixTube,可以開啟瀏覽器並導航到 http://localhost:3000。您可以上傳影片、觀看影片和檢視歷史記錄。

當您完成開發和測試後,別忘了關閉 FlixTube 以節省資源。可以使用以下指令關閉 FlixTube:

docker compose down

圖表翻譯:

以下是 FlixTube 的架構圖:

  graph LR
    A[Gateway] --> B[Metadata]
    A --> C[Video Streaming]
    A --> D[Database]
    A --> E[RabbitMQ]
    B --> D
    C --> D
    C --> E

這個圖表顯示了 FlixTube 的架構,包括 Gateway、Metadata、Video Streaming、Database 和 RabbitMQ。每個微服務都有其依賴項和連線埠。

內容解密:

FlixTube 的開發和測試涉及多個微服務和依賴項。要啟動整個應用程式,需要使用 Docker Compose 定義和執行所有微服務和依賴項。每個微服務都有其環境變數和連線埠,需要設定和管理。

10.6 測試 FlixTube

測試是軟體開發中的一個重要環節。雖然手動測試很重要,但自動化測試更能夠提供效率、可靠性和重複性。在第 9 章中,我們探討了使用 Jest 和 Playwright 進行測試的多種方法。在本章中,我們將重新審視這些測試,並在 FlixTube 專案中執行它們。

10.6.1 使用 Jest 測試微服務

FlixTube 中的資料函式庫微服務包含了第 9 章中的 Jest 單元測試。在執行測試之前,需要安裝相依套件:

cd chapter-10/metadata
npm install

然後,執行測試使用傳統的 npm 指令碼:

npm test

這會執行與 metadata 微服務的 package.json 檔案中組態的命令列。圖 10.6 顯示了成功執行測試的結果。

我們也可以在 live reload 模式下執行測試,這意味著我們可以編輯程式碼,測試將自動重新執行。使用另一個名為 test:watch 的 npm 指令碼可以實作此功能:

npm run test:watch

10.6.2 使用 Playwright 測試應用程式

我們也可以執行第 9 章中的 Playwright 端對端測試對 FlixTube 應用程式。為了執行此測試,需要安裝 FlixTube 專案的相依套件:

cd chapter-10
npm install

確保啟動整個 FlixTube 應用程式,如果尚未啟動:

docker compose up --build

等待閘道器微服務線上的訊息(執行測試之前必須等待此訊息)。

然後,開啟新的終端視窗,執行常規的 npm 測試指令碼:

cd chapter-10
npm test

這會執行 Playwright 並顯示結果,如圖 10.7 所示。

10.7 深入探索 FlixTube

在本文中,我們將更深入地探索 FlixTube 的各個方面,包括:

  • 資料函式庫固定資料(database fixtures)
  • 模擬儲存微服務(mocking the storage microservice)
  • 閘道器(the gateway)
  • FlixTube 使用者介面(the FlixTube UI)
  • 影片串流(video streaming)
  • 影片上傳(video upload)

10.7.1 資料函式庫固定資料

資料函式庫固定資料是指在資料函式庫中載入真實的資料集,以便於進行自動化測試。在第 9 章中,我們使用了資料函式庫固定資料來載入資料函式庫中的資料。在單元測試中,我們不需要資料固定資料,因為我們模擬了 MongoDB 資料函式庫函式庫,並使用模擬版本的資料函式庫函式庫提供假資料。

以下是資料函式庫固定資料的範例(chapter-10/fixtures/two-videos/videos.js):

const { ObjectId } = require("mongodb");
module.exports = [
  {
    _id: new ObjectId("5ea234a1c34230004592eb32"),
    name: "SampleVideo_1280x720_1mb.mp4"
  },
  {
    _id: new ObjectId("5ea234a5c34230004592eb33"),
    name: "Another video.mp4"
  }
];

這個固定資料包含兩個影片的資料,並將其載入 videos 集合中。

資料函式庫ID的建立和資料匯出

為了能夠有效地管理和識別資料函式庫中的記錄,我們需要建立資料函式庫ID。這些ID可以用於唯一地標識每個記錄,從而方便我們進行資料查詢、更新和刪除等操作。

資料函式庫ID的重要性

在資料函式庫設計中,ID是一個非常重要的概念。它可以幫助我們快速地定位到特定的記錄,從而提高資料函式庫的查詢效率。同時,ID也可以用於建立資料之間的關係,從而實作資料的聯結和查詢。

建立資料函式庫ID

為了建立資料函式庫ID,我們可以使用MongoDB的ObjectId類別。這個類別可以自動地生成一個唯一的ID,從而確保每個記錄都有一個唯一的標識。

const mongoose = require('mongoose');
const ObjectId = mongoose.Types.ObjectId;

// 建立一個新的ObjectId
const id = new ObjectId();
console.log(id);

資料匯出

除了建立資料函式庫ID外,我們還需要匯出已經插入到資料函式庫中的資料。這可以透過使用MongoDB的find()方法來實作。

const mongoose = require('mongoose');

// 匯出所有的資料
mongoose.model('Video').find().then((videos) => {
  console.log(videos);
});

測試資料的建立

為了方便地進行測試,我們需要建立一些測試資料。這些資料可以用於模擬真實的使用場景,從而幫助我們測試和驗證系統的功能。

測試資料的重要性

測試資料對於系統的測試和驗證是非常重要的。它可以幫助我們模擬真實的使用場景,從而發現系統中的問題和缺陷。

建立測試資料

為了建立測試資料,我們可以使用JavaScript或JSON格式來定義資料。下面是一個例子:

// 建立測試資料
const videos = [
  {
    title: 'Video 1',
    description: 'This is video 1',
  },
  {
    title: 'Video 2',
    description: 'This is video 2',
  },
];

// 匯出測試資料
module.exports = videos;

Mocking儲存微服務

為了方便地進行開發和測試,我們可以使用Mocking技術來替換掉真實的儲存微服務。這可以幫助我們模擬真實的儲存場景,從而提高開發和測試的效率。

Mocking儲存微服務的重要性

Mocking儲存微服務對於開發和測試是非常重要的。它可以幫助我們模擬真實的儲存場景,從而提高開發和測試的效率。

建立Mocking儲存微服務

為了建立Mocking儲存微服務,我們可以使用Docker Compose來定義一個Mocking儲存容器。下面是一個例子:

version: '3'
services:
  mock-storage:
    image: mock-storage:latest
    volumes:
      -./mock-storage:/mock-storage
    ports:
      - "8080:8080"

圖表翻譯:

  graph LR
    A[開發電腦] -->|分享檔案|> B[Mock儲存容器]
    B -->|提供Mock儲存服務|> C[FlixTube]
    C -->|使用Mock儲存服務|> B

這個圖表展示了開發電腦、Mock儲存容器和FlixTube之間的關係。開發電腦分享檔案到Mock儲存容器,Mock儲存容器提供Mock儲存服務給FlixTube,FlixTube使用Mock儲存服務來進行儲存操作。

開發環境下的微服務替換

在開發過程中,我們可以用一個「mock」微服務來替換外部檔案儲存微服務,以便使用本地檔案系統進行儲存。這樣做的好處是可以去除外部依賴,將整個應用程式限制在單一開發者的電腦上,從而使開發變得更加容易,並防止不同的開發者意外地幹擾彼此的工作。

Gateway 和 Docker Volume

在開發環境下,我們可以使用 Docker Volume 來實作微服務之間的資料分享。例如,我們可以建立一個名為 video-storage 的 Docker Volume,將其掛載到 mock-storage 微服務的容器中。這樣,mock-storage 微服務就可以存取和操作本地檔案系統中的資料。

Mock-Storage 微服務

mock-storage 微服務不是一個完全的假設微服務,它仍然負責儲存資料,但使用本地檔案系統而不是雲端儲存。這樣做的主要原因不是為了測試,而是為了開發的方便性和效能。透過限制儲存到本地檔案系統,我們可以使開發設定變得更加容易,並提高效能,因為資料不需要被傳送到雲端。

替換複雜微服務

能夠替換複雜微服務以簡單的 mock 版本,不僅方便,而且可能在未來某個時候是必要的。當 FlixTube 成長為一個世界級的串流媒體服務時,它可能會變得太大,無法在單一電腦上執行。屆時,我們需要使用每一個技巧來使其適應於開發電腦。這包括刪除不需要的微服務,例如歷史記錄微服務。

Docker Compose 檔案

以下是 docker-compose.yaml 檔案中 mock-storage 微服務的設定:

video-storage:
  image: mock-storage
  build:
    context:./mock-storage
    dockerfile: Dockerfile-dev
  container_name: video-storage
  volumes:
    - /tmp/mock-storage/npm-cache:/root/.npm:z
    -./mock-storage/src:/usr/src/app/src:z
    -./mock-storage/storage:/usr/src/app/storage:z
  ports:
    - "4005:80"
  environment:
    - PORT=80
  restart: "no"

這個設定與 azure-storage 微服務的設定相似,但有一些不同之處。例如,storage 子目錄被分享於主機作業系統和容器之間,這樣我們就可以在主機作業系統上檢查上傳的影片,以測試微服務是否正常工作。

測試真實的 Azure 儲存微服務

如果需要測試真實的 Azure 儲存微服務,可以簡單地在 docker-compose.yaml 檔案中替換 mock-storage 微服務的設定。以下是真實的 Azure 儲存微服務的設定:

# video-storage:
#   image: azure-storage
#   build:
#     context:./azure-storage
#   environment:
#     - STORAGE_ACCOUNT_NAME=
#     - STORAGE_ACCESS_KEY=

需要在終端中設定 STORAGE_ACCOUNT_NAMESTORAGE_ACCESS_KEY 環境變數,以提供 Azure 儲存帳戶的驗證詳細訊息。然後,重新構建和重新啟動 FlixTube,即可在開發環境中測試真實的 Azure 儲存微服務。

Dockerfile-dev 檔案設定

在 Dockerfile-dev 檔案中,我們定義了微服務的容器設定。這包括設定容器名稱、環境變數以及重啟策略。

# 使用 Dockerfile-dev 檔案
FROM node:14

# 設定容器名稱
container_name: video-storage

# 設定環境變數
ENV PORT=80
ENV STORAGE_ACCOUNT_NAME=${STORAGE_ACCOUNT_NAME}
ENV STORAGE_ACCESS_KEY=${STORAGE_ACCESS_KEY}

# 設定重啟策略
restart: "no"

模擬儲存微服務

模擬儲存微服務(mock-storage)是一個用於開發環境的替代品,模擬了真實的 Azure 儲存微服務。它使用本地檔案系統來儲存和提供視訊檔案。

// 模擬儲存微服務(mock-storage)
const express = require('express');
const app = express();
const path = require('path');

const storagePath = path.join(__dirname, "../storage");

// 導向視訊上傳路由
app.post('/video', (req, res) => {
  // 將視訊檔案儲存到本地檔案系統
  const videoFile = req.body;
  const filePath = path.join(storagePath, 'video.mp4');
  fs.writeFileSync(filePath, videoFile);
  res.send('視訊檔案上傳成功');
});

// 導向視訊下載路由
app.get('/video', (req, res) => {
  // 從本地檔案系統讀取視訊檔案
  const filePath = path.join(storagePath, 'video.mp4');
  const videoFile = fs.readFileSync(filePath);
  res.set("Content-Type", "video/mp4");
  res.send(videoFile);
});

真實的 Azure 儲存微服務

真實的 Azure 儲存微服務(azure-storage)使用 Azure 儲存帳戶來儲存和提供視訊檔案。

// 真實的 Azure 儲存微服務(azure-storage)
const express = require('express');
const app = express();
const { AzureStorage } = require('azure-storage');

const accountName = process.env.STORAGE_ACCOUNT_NAME;
const accountKey = process.env.STORAGE_ACCESS_KEY;
const blobService = AzureStorage.createBlobService(accountName, accountKey);

// 導向視訊上傳路由
app.post('/video', (req, res) => {
  // 將視訊檔案上傳到 Azure 儲存帳戶
  const videoFile = req.body;
  const blobName = 'video.mp4';
  blobService.createBlockBlobFromText('videos', blobName, videoFile, (err) => {
    if (err) {
      res.status(500).send('上傳視訊檔案失敗');
    } else {
      res.send('視訊檔案上傳成功');
    }
  });
});

// 導向視訊下載路由
app.get('/video', (req, res) => {
  // 從 Azure 儲存帳戶下載視訊檔案
  const blobName = 'video.mp4';
  blobService.getBlobToText('videos', blobName, (err, videoFile) => {
    if (err) {
      res.status(404).send('視訊檔案不存在');
    } else {
      res.set("Content-Type", "video/mp4");
      res.send(videoFile);
    }
  });
});

容器間通訊

為了讓微服務之間可以通訊,我們需要設定容器間的網路連線。這可以透過 Docker Compose 來完成。

version: '3'
services:
  video-storage:
    build:.
    ports:
      - "80:80"
    environment:
      - STORAGE_ACCOUNT_NAME=${STORAGE_ACCOUNT_NAME}
      - STORAGE_ACCESS_KEY=${STORAGE_ACCESS_KEY}
    volumes:
      -./storage:/app/storage

這樣設定後,微服務就可以透過 http://video-storage:80/video 來存取視訊檔案了。

儲存影片於本地檔案系統

在 FlixTube 的架構中,儲存影片於本地檔案系統是一個重要的功能。以下是實作此功能的 Express.js 程式碼:

const express = require('express');
const app = express();
const path = require('path');
const fs = require('fs');

// 定義儲存影片的路徑
const storagePath = './videos';

// HTTP GET 路由處理器,串流影片從本地檔案系統
app.get("/video", (req, res) => {
  const videoId = req.query.id;
  const localFilePath = path.join(storagePath, videoId);
  res.sendFile(localFilePath);
});

// HTTP POST 路由處理器,上傳影片到本地檔案系統
app.post("/upload", (req, res) => {
  const videoId = req.headers.id;
  const localFilePath = path.join(storagePath, videoId);

  const fileWriteStream = fs.createWriteStream(localFilePath);
  req.pipe(fileWriteStream)
   .on("error", err => {
      console.error("上傳失敗.");
      console.error(err && err.stack || err);
    })
   .on("finish", () => {
      res.sendStatus(200);
    });
});

閘道(Gateway)

FlixTube 有一個單一的閘道微服務,負責提供前端 UI 和 REST API,以便使用者與應用程式互動。目前,閘道是整個應用程式的唯一入口。在未來,閘道可能需要升級以支援使用者驗證,讓使用者在與後端其他微服務互動之前必須先登入。

多閘道模式(Backends for Frontends)

如果 FlixTube 需要支援多個前端應用程式,每個前端都有不同的需求(例如,網頁和行動應用程式的驗證方式不同),則可以使用多閘道模式。這意味著每個前端都有一個對應的閘道,例如,有一個閘道供網頁版 FlixTube 使用,另一個供行動應用程式使用,還有一個供管理員入口使用。

優點和挑戰

使用單一閘道的優點是簡單易於維護,但如果不同前端有不同的需求,可能需要採用多閘道模式以滿足各自的安全性和驗證需求。然而,這也增加了系統的複雜度,因此需要仔細評估是否需要採用多閘道模式。

從技術架構視角來看,FlixTube 微服務應用程式示範了現代軟體開發的最佳實務,包含 Docker 容器化、Jest 測試框架、以及清晰的程式碼組織結構。深入剖析其核心架構,可以發現每個微服務的獨立性設計,例如 metadata 與 video-streaming,有效提升了系統的靈活性和可擴充套件性。然而,目前的單一閘道設計在未來大型應用場景下可能面臨瓶頸,需要考慮匯入 Backends for Frontends 的多閘道模式以滿足不同前端的需求。同時,mock-storage 微服務雖然簡化了開發流程,但在實際佈署時仍需仔細評估與真實 Azure 儲存服務的整合策略以及潛在的效能差異。玄貓認為,FlixTube 的架構設計展現了微服務的優勢,但也需要持續關注技術演進,例如 Service Mesh 技術,以進一步提升系統的彈性和可管理性。對於追求高擴充套件性和高可靠性的串流媒體應用,採用更進階的容器協調和監控工具將是未來的發展方向。