從單體式應用程式轉換到微服務架構時,首要之務是找出適合遷移的功能,並規劃遷移路線。考量規模、效能、技術選項和儲存方案等準則,能幫助團隊決定哪些功能需要優先轉換。修改頻率高的功能、佈署複雜的功能,以及關鍵的協助服務,都是適合優先轉換的目標。微服務的設計應著重單一功能,並考量程式語言、資料函式庫選型和版本控制等導向。Docker 容器技術則能簡化微服務的佈署和擴充套件,透過封裝應用程式及其所有依賴項,確保應用程式在不同環境中的一致性。相較於虛擬機器,Docker 容器更輕量、啟動更快,且資源利用率更高。Docker Compose 則能有效管理多容器應用程式,透過單一設定檔定義和執行多個容器。

將單體式應用程式遷移至微服務的關鍵準則

在決定將現有的單體式應用程式遷移至微服務架構時,首要任務是確定哪些元件應該優先被遷移,或甚至是否應該被遷移。這就引出了「微服務準則」的概念。這些準則是一套規則,用於根據組織當前的需求,決定哪些功能應該被遷移至微服務。

微服務準則的重要性

隨著時間的推移,組織的需求可能會發生變化,因此可能需要重新評估哪些元件適合被遷移至微服務。換言之,隨著需求的變化,單體式應用程式中的其他元件可能會符合遷移的條件。

微服務準則的最佳實踐

在轉換過程中,可以考慮以下最佳實踐作為微服務準則:

規模

首先需要確定哪些功能被高度使用。優先將這些高使用率的服務或應用程式功能轉換為微服務。記住,微服務應該只執行一個明確定義的服務。遵循這一原則,將應用程式相應地進行劃分。

效能

某些元件可能效能不佳,而其他替代方案已經準備就緒。例如,可能有開源外掛可用,或者從頭開始構建一個服務。設計微服務時,關鍵是要確保它只做好一件事。確定微服務的邊界通常很困難,但隨著實踐經驗的積累,會變得更容易。評估微服務邊界的一個方法是考慮是否能夠在幾週內重寫整個微服務,而不是花費數月的時間。

更好的技術替代方案或多語言程式設計

可以使用特定領域的程式語言來幫助解決特定的問題領域。這對於過去收到許多增強請求的元件尤其適用。如果認為不僅可以使用新的語言或市場上的新功能簡化元件的實作,而且未來的維護和更新也會變得更容易,那麼現在就是實施這些變更的最佳時機。在某些情況下,可能會發現另一種語言提供了比當前使用的語言更容易的平行抽象。可以針對特定的微服務利用新語言,而應用程式的其他部分仍然可以使用不同的語言。

儲存替代方案或多語言持久化

隨著大資料的興起,應用程式中的某些元件可能會透過使用NoSQL資料函式庫而不是關係型資料函式庫來提供價值。如果應用程式中的任何元件可以從這種替代方案中受益,那麼現在可能是切換到NoSQL的最佳時機。

優先考慮轉換的專案

在評估單體式應用程式中的每個服務或功能時,需要優先考慮這些專案的轉換。一旦從高優先順序專案中獲得了價值,就可以應用其他規則。

修改請求

在任何軟體生命週期中,跟蹤新的增強請求或變更非常重要。具有較多變更請求的功能可能適合採用微服務,因為這樣可以減少構建和佈署的時間。將這些服務分離出來,可以減少構建和佈署的時間,因為不需要重新構建整個應用程式,只需要重新佈署變更的微服務,這也可能增加應用程式其他部分的可用性時間。

佈署

在單體式應用程式中,總是存在一些部分會增加佈署複雜度的情況。即使某個特定功能沒有被修改,也仍然需要經歷完整的構建和佈署過程。如果存在這種情況,將這些部分切割出來並替換為微服務是有益的,這樣可以減少單體式應用程式其他部分的整體佈署時間。

協助服務

在大多數應用程式中,核心或主要服務依賴於一些協助服務。這些協助功能的不可用性可能會影響核心服務的可用性。例如,在幫助台應用程式中,票務系統依賴於產品目錄服務。如果產品目錄服務不可用,使用者將無法提交票據。如果存在這種情況,應該將協助服務轉換為微服務,並適當地使其具有高用性,以便更好地為核心服務提供支援。這些也被稱為斷路器服務。

容器化技術的遷移與實作:微服務與Docker的整合應用

在現代軟體開發中,微服務架構已成為提升系統可擴充套件性和維護性的重要策略。隨著應用程式的複雜度增加,傳統的單體式架構逐漸暴露出其侷限性。因此,將現有的單體式應用程式遷移到微服務架構成為許多企業的重要任務。本章節將重點探討微服務的遷移與實作,並介紹Docker容器技術如何解決佈署和擴充套件的挑戰。

微服務的遷移步驟

  1. 識別可遷移的功能:首先,需識別哪些功能適合遷移到微服務。這需要根據應用的具體情況,決定是否需要轉換大部分服務。目標是簡化轉換過程,以便優先排序並定義遷移到根據微服務架構的路線圖。

  2. 重新設計服務:一旦確定了要遷移的功能,就需要根據最佳實踐重新設計所選的服務。需考慮以下幾個方面:

    • 微服務定義:為每個功能定義合適的微服務,包括通訊機制(API)、技術定義等。需考慮現有功能的資料使用情況,或為微服務規劃資料策略。
    • 程式碼重構:儘可能重用現有程式碼,但需考慮儲存/資料函式庫層是共用還是專用、記憶體還是外部儲存。目標是重新封裝現有程式碼並暴露所需的API,而非新增新功能。
    • 版本控制:在開始編碼之前,決定原始碼控制和版本控制機制,並確保遵循這些標準。每個微服務都是一個獨立的專案,並作為獨立的應用程式佈署。
  3. 資料遷移:如果決定建立新的資料函式庫,則需要遷移舊資料。通常透過編寫簡單的SQL指令碼來處理,具體取決於源和目標資料函式庫。

  4. 獨立構建、佈署和管理:每個微服務都獨立構建和佈署。在推出新版本的微服務時,可以再次將流量拆分到舊版本和新版本之間。這意味著可能在生產環境中執行相同微服務的兩個或多個版本。

混合式方法

在開發全新的應用程式時,開發人員可以直接遵循微服務架構原則來構建軟體應用程式。然而,在某些情況下,開發人員可能會採用微服務和單體式架構的混合式方法。這種方法允許開發人員根據特定標準,將部分應用程式開發為微服務,而其他部分則遵循標準的SOA/MVC實踐。

Docker容器技術

隨著企業規模的擴大,軟體佈署和擴充套件性成為日益嚴峻的挑戰。Docker容器技術透過將應用程式與基礎設施依賴項分離,解決了這些問題。Docker容器允許將應用程式及其所有依賴項(包括目錄結構、中繼資料、處理空間、連線埠集等)封裝,從而確保應用程式在所有機器和環境中以相同的方式執行。

Docker與虛擬機器的比較

Docker容器與虛擬機器(VM)的主要區別在於,Docker提供了更輕量級和高效的虛擬化解決方案。虛擬機器模擬整個作業系統,而Docker容器則分享主機作業系統核心,從而減少了資源佔用並提高了啟動速度。

Docker容器的優勢

  • 一致性和可移植性:Docker容器確保了開發、測試和生產環境之間的一致性,從而簡化了應用程式的佈署和管理。
  • 高效的資源利用:與虛擬機器相比,Docker容器佔用更少的資源,從而提高了硬體利用率。
  • 快速佈署和擴充套件:Docker容器可以快速啟動和停止,使得應用程式的佈署和擴充套件更加靈活高效。

虛擬機器與容器技術的演進

在探討容器技術之前,我們需要了解虛擬機器的基本架構及其運作原理。虛擬機器是一種自包含的系統,包含了從作業系統到應用程式環境及其本身的所有元件。多個虛擬機器可以透過管理軟體(Hypervisor)安裝在一台主機或實體機器上。Hypervisor扮演著硬體代理的角色,讓虛擬機器上的作業系統覺得自己執行在獨立的硬體上。

虛擬機器的優勢

虛擬機器提供了多項優勢,包括:

  • 效率:虛擬機器可以有效利用資源並提供安全隔離。
  • 彈性:資源可以根據需求進行分配,例如CPU、記憶體等。
  • 備份與復原:虛擬機器可以儲存為單一檔案,方便備份和復原。
  • 作業系統自由度:不同的虛擬機器可以執行不同的作業系統。
  • 效能與遷移:虛擬機器可以輕易地從一台主機遷移到另一台主機。

然而,虛擬機器也存在一些問題,例如:

  • 資源消耗:每個虛擬機器都需要一個完整的作業系統,消耗大量資源。
  • 備份檔案龐大:由於包含了完整的作業系統,備份檔案通常非常龐大。
  • 效能開銷:應用程式需要透過Guest OS、Hypervisor和Host OS才能存取硬體資源,增加了效能開銷。

容器技術的出現

為瞭解決虛擬機器的問題,容器技術應運而生。容器提供了一個虛擬環境,將應用程式的流程、元資料和檔案系統封裝在一起,讓應用程式可以在獨立的環境中執行。與虛擬機器不同的是,容器不需要自己的作業系統,而是直接與核心溝通以請求和利用資源。

容器技術的優勢

容器技術具有以下優勢:

  • 輕量級:容器不需要完整的作業系統,因此非常輕量級。
  • 高效利用資源:容器可以直接存取核心資源,提高了資源利用率。
  • 快速佈署:容器可以快速佈署和遷移。

虛擬機器與容器的比較

虛擬機器容器
作業系統需要完整的作業系統不需要完整的作業系統
資源消耗資源消耗大資源消耗小
備份檔案大小備份檔案龐大備份檔案較小
效能開銷效能開銷大效能開銷小
隔離性提供較好的隔離性提供較差的隔離性

總而言之,虛擬機器和容器技術各有其優缺點。虛擬機器提供了較好的隔離性和安全性,但資源消耗大、效能開銷大。容器技術則提供了輕量級、高效利用資源和快速佈署的優勢,但隔離性較差。在選擇使用虛擬機器還是容器技術時,需要根據具體的需求和場景進行評估。

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title 虛擬機器與容器的比較

rectangle "安裝" as node1
rectangle "建立" as node2
rectangle "包含" as node3
rectangle "執行" as node4

node1 --> node2
node2 --> node3
node3 --> node4

@enduml

此圖示展示了虛擬機器的基本架構。實體機器上安裝了Host OS,Host OS上安裝了Hypervisor,Hypervisor建立了多個虛擬機器,每個虛擬機器包含了自己的Guest OS和應用程式。

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title 虛擬機器與容器的比較

rectangle "安裝" as node1
rectangle "執行" as node2
rectangle "建立" as node3

node1 --> node2
node2 --> node3

@enduml

此圖示展示了容器技術的基本架構。實體機器上安裝了Host OS,Host OS上執行了Docker,Docker建立了多個容器,每個容器執行了自己的應用程式。

內容解密:

以上兩個Plantuml圖表,分別展示了虛擬機器和容器技術的基本架構。第一個圖表展示了虛擬機器的架構,包括實體機器、Host OS、Hypervisor、虛擬機器、Guest OS和應用程式。第二個圖表展示了容器技術的架構,包括實體機器、Host OS、Docker和容器。每個圖表都清晰地展示了各自技術的架構和元件之間的關係。

在第一個圖表中,實體機器是基礎,其上安裝了Host OS。Host OS上安裝了Hypervisor,Hypervisor負責建立和管理虛擬機器。每個虛擬機器都包含了自己的Guest OS和應用程式。這種架構提供了較好的隔離性和安全性,但也增加了資源消耗和效能開銷。

在第二個圖表中,實體機器上同樣安裝了Host OS,但其上執行的是Docker。Docker建立了多個容器,每個容器執行了自己的應用程式。這種架構相比虛擬機器,更為輕量級和高效,但隔離性較差。

這兩個圖表透過視覺化的方式,有助於讀者更好地理解虛擬機器和容器技術的基本原理和架構差異。

Docker容器技術深度解析

Docker容器技術是目前軟體開發與佈署領域的重要革新,它根據Linux容器(LXC)技術並進行了多項關鍵性的改進,使其更具可移植性、易用性和靈活性。與傳統虛擬機器(VM)相比,Docker容器具備更輕量、啟動更快、資源利用率更高的特點。

Linux容器與Docker容器的微妙差異

雖然Docker容器源自Linux容器,但兩者在設計理念和實際應用上存在一些關鍵差異:

  1. 行程管理:LXC允許在單一容器中執行多個行程,而Docker容器則被設計為單一行程執行。這種設計帶來了管理的複雜性,但也提供了對應用系統的極高靈活性。對於微服務架構而言,這種一容器一行程的模式是理想的,因為它允許對每個服務進行獨立管理和更新。

  2. 永續性儲存:Docker容器本質上是無狀態的,不支援永續性儲存。要實作資料持久化,需要將外部儲存掛載為Docker資料卷。這種設計確保了容器的可移植性和一致性。

  3. 可移植性:Docker透過抽象化作業系統、網路和儲存細節,提供了比LXC更高的可移植性。這意味著開發人員可以在開發環境中建立一個Docker映像,並保證它在生產環境中能夠平滑執行,無需擔心環境差異導致的問題。

Docker架構與元件

Docker採用客戶端-伺服器架構,其中客戶端與Docker守護程式(daemon)互動,由後者提供主要服務。以下是構成Docker生態系統的核心元件:

  • Docker伺服器或守護程式:執行在主機系統上,負責管理所有容器。
  • Docker容器:一個獨立的虛擬系統,包含執行中的行程、所需檔案、依賴項、行程空間和連線埠。由於每個容器都有所有連線埠可用,因此需要在Docker層級進行連線埠對映。
  • Docker客戶端:用於與Docker守護程式進行通訊的使用者介面或命令列介面。
  • Docker映像:Docker容器的唯讀範本檔案,可以被傳輸和分發。與虛擬機器映像不同,Docker映像可以進行版本控制,並且可以透過docker diff命令檢視兩個映像之間的差異。
  • Docker註冊中心:用於分享和儲存Docker容器映像的倉函式庫。最知名的註冊中心是Docker Hub,它允許使用者提取或推播具有公有或私有存取許可權的容器映像。
  • Dockerfile:一個簡單的文字檔案,用於指定建置Docker映像的命令。透過Dockerfile,可以設定安裝軟體、環境變數、工作目錄和進入點等指令,從而建立自訂的軟體映像。
  • Docker Machine:允許使用者在本機或公有/私有雲上建立Docker主機,並透過Docker Machine命令進行管理。
  • Docker Swarm:提供開箱即用的叢集功能,讓一組Docker節點像一個大型Docker主機一樣運作。Swarm模式支援負載平衡和服務發現,是一個功能完整的協調引擎。

Docker Compose:多容器應用的管理利器

對於具有多個元件的應用程式,Docker提供了Compose工具來定義和執行多容器應用。透過在單一docker-compose.yml檔案中定義服務,可以自動建立所需的容器,並透過單一命令管理應用服務。

Docker Compose 的使用範例

version: '3'
services:
  web:
    build: .
    ports:
      - "80:80"
    depends_on:
      - db
  db:
    image: postgres
    environment:
      - POSTGRES_USER=myuser
      - POSTGRES_PASSWORD=mypassword
此設定定義了一個包含兩個服務(web和db)的應用程式
  • web服務根據當前目錄的Dockerfile建置,並將主機的80連線埠對映到容器的80連線埠。它依賴於db服務。
  • db服務使用PostgreSQL映像,並設定了環境變數來組態資料函式庫使用者和密碼。

內容解密:

  1. version: '3' 指定了Docker Compose檔案的版本。
  2. services 定義了組成應用的服務。
  3. build: . 指示Docker Compose根據當前目錄下的Dockerfile建置web服務的映像。
  4. ports 設定了主機與容器之間的連線埠對映。
  5. depends_on 指定了服務之間的依賴關係。在此例中,web服務依賴於db服務,因此db服務會在web服務之前啟動。
  6. image: postgres 指定了db服務使用的映像。
  7. environment 設定了傳遞給db服務容器的環境變數,用於組態PostgreSQL資料函式庫。

Docker 容器技術的優勢與實務應用

Docker 技術的邏輯架構與優勢

Docker 容器技術提供了一個輕量級且可攜式的虛擬環境,能夠有效地解決傳統虛擬機器的許多問題。圖 5.3 展示了 Docker 的邏輯架構,包括 Docker 使用者端、伺服器和註冊中心(Registry)之間的互動關係。Docker 客戶端透過命令與 Docker 伺服器互動,從註冊中心提取(Pull)映象(Images),並執行容器(Containers)。

Docker 技術的優勢

  • 輕量級:Docker 容器不需要獨立的作業系統,因此體積較小。同時,容器可以儲存為映象,這些映象只是簡單的檔案,可以進行版本控制和輕鬆分發。
  • 可攜性:Docker 容器將應用程式及其所有依賴項封裝在一起,無論佈署模型、作業系統版本等,都能保持一致性。這種容器可以輕易地轉移到其他主機上,以映象的形式執行而無任何問題。只需構建一次,即可在任何地方執行。
  • 重用性:Docker 映象是多層結構,連續的命令會在原有映象上建立新的層來形成最終的映象。一旦映象構建完成,Docker 會重用它來進行新的構建,這使得構建速度更快,映象更小,因為它們重用了或分享了這些層。
  • 快速佈署:Docker 容器是完全自足的、輕量級的軟體包,易於分發,並在測試週期中得到充分測試。同樣的容器可以在生產環境中佈署,幾乎無需或只需極少的更改,從而加快了佈署速度並減少了因環境依賴而導致的回復。這一特性對於持續開發至關重要。
  • 資源的高效利用:與虛擬機器類別似,Docker 能夠高效地利用資源,甚至可能比虛擬機器做得更好,因為 Docker 容器的重量更輕。同時,它提供了可接受的隔離度。由於其體積小,相較於虛擬機器,同一台主機上可以安裝更多的容器。

Docker 與虛擬機器的比較

雖然在許多情況下,Docker 容器比虛擬機器更受青睞,但必須明確的是,Docker 並不會取代虛擬機器。事實上,典型的佈署往往同時利用兩者的優勢,在虛擬機器內執行 Docker,使得資源利用變得非常高效。

Docker 的實務應用範例:建立 WordPress 網站

假設需要建立一個基本的 WordPress 網站,該網站包含三個部分:執行 WordPress 應用程式的網頁伺服器、關係型資料函式庫(如 MySQL)以及儲存資料的儲存體。在虛擬機器的世界裡,可以在一台或多台虛擬機器上設定這些元件。

使用 Docker 佈署

  1. 資料容器(Data Container):首先,從 Docker Hub 提取一個基本 Linux 映象(如 Ubuntu)並執行它,用於建立本地儲存,相當於建立一個目錄結構來儲存資料。命令如下:

docker create –name mysql_data_container -v /var/lib/mysql ubuntu

2.  **MySQL 容器**:接著,從 Docker Hub 提取最新的 MySQL 映象並在本地主機上執行。在相同的執行命令中,可以對映在前一步驟中建立的卷(Volume)。命令如下:
    ```bash
docker run --volumes-from mysql_data_container -v /var/lib/mysql:/var/lib/mysql -e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_DATABASE=test -e MYSQL_ROOT_PASSWORD=test -it -p 3306:3306 -d mysql
#### 內容解密:
*   `--volumes-from mysql_data_container`:掛載來自 `mysql_data_container` 的卷,用於持久化 MySQL 資料。
*   `-v /var/lib/mysql:/var/lib/mysql`:將主機的 `/var/lib/mysql` 目錄掛載到容器的 `/var/lib/mysql`,確保資料持久化。
*   `-e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_DATABASE=test -e MYSQL_ROOT_PASSWORD=test`:設定 MySQL 的環境變數,包括使用者名稱、密碼、資料函式庫名稱和 root 使用者的密碼。
*   `-it`:以互動模式執行容器,但由於後面有 `-d`,實際上是讓容器在背景執行。
*   `-p 3306:3306`:將主機的 3306 連線埠對映到容器的 3306 連線埠,使得外部可以透過主機的 3306 連線埠存取 MySQL 服務。
*   `-d mysql`:在背景執行 MySQL 映象,並指定使用的映象名稱為 `mysql`。
  1. WordPress 容器:最後,從 Docker Hub 提取最新的 WordPress 映象並執行。在相同的執行命令中,可以連結(Link)之前建立的 MySQL 資料函式庫。命令如下:

docker run -d –name wordpress –link mysql:mysql wordpress

    #### 內容解密:
    *   `-d`:在背景執行容器。
    *   `--name wordpress`:將容器命名為 `wordpress`。
    *   `--link mysql:mysql`:將 `mysql` 容器連結到 `wordpress` 容器,使得 `wordpress` 可以透過 `mysql` 的名稱存取 MySQL 資料函式庫。
    *   `wordpress`:指定要執行的映象名稱。

透過上述三個步驟,可以在短短不到 10 分鐘的時間內完成一個個人 WordPress 網站的設定,如圖 5.5 所示。