在分散式系統中,微服務佈署至關重要。本文以 DC/OS 叢集為例,詳細說明如何佈署產品目錄微服務。首先,透過 Marathon 平台,利用 JSON 檔案定義服務的 Docker 映像、網路設定、埠對映、資源分配和健康檢查等引數,提交任務到 Mesos 叢集。Marathon-lb 作為負載平衡器,自動發現服務例項並進行流量分發,確保服務的高用性。此外,文章也探討了微服務架構與 DevOps 的密切關係,分析微服務如何促進 DevOps 文化的形成,並以幫助台應用程式為例,說明其在微服務架構下的運作流程、使用者角色和程式碼實作,展現微服務架構的優勢。

在DC/OS叢集中佈署目錄微服務

在開始佈署之前,讓我們先回顧一下第9章「容器協調」中關於Mesos和Marathon的內容,以便更好地理解我們的佈署過程:

  • Mesos是一個開源的Apache專案,用於管理叢集中機器上的CPU和記憶體等資源。像產品目錄和票務這樣的任務或服務將在Mesos叢集中執行。
  • Marathon是另一個與Mesos緊密合作的開源框架,用於在叢集中排程任務。在我們的案例中,如果需要在Mesos叢集中執行目錄服務,就需要在Marathon UI中提供有關產品目錄服務的詳細資訊(例如,服務的Docker映像、監聽埠),然後點選提交。
  • Marathon-lb是一個根據流行的負載平衡器HAProxy的負載平衡器,它透過自動生成HAProxy組態來工作。以下是它的工作原理:
    • 它透過API與Marathon通訊,以取得Marathon在Mesos叢集中排程的任務和服務列表。
    • 從Marathon的回應中,它找出叢集中執行的服務、它們執行的位置(即叢集中的哪台機器)、服務執行的埠等。
    • 它生成一個HAProxy組態,這是一個請求對映。該組態具有詳細資訊;例如,「如果請求到達伺服器端點/abc」,則該請求可能由伺服器a、b或c處理,其中a、b和c是執行服務以處理請求/abc的機器。
    • 外部應用程式將始終透過Marathon-lb存取Mesos叢集中執行的服務。

現在我們的叢集已經準備好了,讓我們來佈署我們的微服務。我們在這裡佈署產品目錄服務,並將其他兩個服務留給您以類別似的方式自行佈署。

佈署目錄微服務

我們首先佈署產品目錄微服務的單個例項,然後根據需要擴充套件或縮減它。

要將服務佈署到叢集中,我們需要建立一個包含有關服務和我們需求的所有詳細資訊的任務。然後透過Marathon將此任務提交到叢集。

向Marathon提交任務

讓我們來描述一下產品目錄服務的任務。有兩種方法可以向Marathon提交任務:

  • 使用簡單的命令,您可以直接提交Docker命令 - 例如,Docker run -P -d nginx。簡單、小型的任務不需要太多組態,可以直接提交。
  • 當我們想要更詳細地描述服務時,可以使用JSON檔案。JSON檔案是一種眾所周知、標準的檔案格式,它使用人類可讀的文字來描述資料。它使用鍵值對來描述資料,就像我們接下來會看到的那樣。

我們使用JSON檔案來詳細描述我們的目錄服務,然後透過Marathon提交任務。以下是我們的目錄微服務組態檔案(JSON):

{
  "id": "catalog-external",
  "container": {
    "type": "DOCKER",
    "docker": {
      "image": "kocher/catalog-svc:1.1",
      "network": "BRIDGE",
      "portMappings": [
        { "hostPort": 0, "containerPort": 8080, "servicePort": 10000 }
      ],
      "forcePullImage": false
    }
  },
  "instances": 1,
  "mem": 1024,
  "healthChecks": [{
    "protocol": "HTTP",
    "path": "/",
    "portIndex": 0,
    "timeoutSeconds": 20,
    "gracePeriodSeconds": 10,
    "intervalSeconds": 10,
    "maxConsecutiveFailures": 10
  }],
  "labels":{
    "HAPROXY_GROUP":"external",
    "HAPROXY_0_VHOST":"ec2-52-207-255-252.compute-1.amazonaws.com"
  }
}

組態檔案解密:

  • id是用於標識我們的目錄服務的識別符號,用於識別叢集中執行的服務。
  • container部分描述了產品目錄服務的Docker容器,具有以下組成部分:
    • type表示容器的型別,預設為DOCKER。另一個選項是MESOS,未來Marathon框架可能會支援其他容器型別。
    • image表示啟動任務時應該使用的Docker映像。
    • network表示網路型別,我們使用的是BRIDGE。還有其他型別的網路,如第8章「容器網路」中所述。
    • portMappingshostPort表示應該在容器執行的主機上暴露的埠。containerPort是容器內部暴露的埠。servicePort是透過Marathon-lb負載平衡器存取目錄服務的埠。
    • forcePullImage如果設為TRUE,則會強制Marathon在啟動任務之前從Docker倉函式庫提取最新映像。預設值為false
  • instances表示需要在叢集中啟動的目錄服務例項數量。
  • mem表示需要分配給目錄服務的記憶體量。
  • healthChecks區塊中的引數指示Marathon按照組態的間隔對目錄服務執行健康檢查。
  • labels部分具有以下標籤:
    • HAPROXY_GROUP:外部標籤指示Marathon負載平衡器,此微服務必須可供外部世界存取。如果設為內部,則相同的微服務將只能從DC/OS叢集內部存取,而無法從外部存取。
    • HAPROXY_0_VHOST指示Marathon負載平衡器為服務建立虛擬主機。設定此標籤的服務將可透過servicePort以及埠80和443存取。

現在讓我們前往Marathon UI並提交此JSON檔案,以啟動我們在DC/OS叢集中的第一個微服務。從DC/OS UI,前往「Services」並點選Marathon連結。然後點選「Open Service」以啟動Marathon UI,如圖13.9所示:

圖13.9:DC/OS UI中的Marathon連結

此圖示說明瞭如何在DC/OS UI中找到Marathon連結並開啟Marathon UI。

圖表說明:

此圖表展示了從DC/OS UI進入Marathon UI的操作流程。首先進入「Services」,然後點選Marathon連結,最後點選「Open Service」開啟Marathon UI。

接下來,我們需要在Marathon UI中提交我們的JSON組態檔案,以佈署目錄微服務。這將使我們的服務在DC/OS叢集中執行,並可供外部存取。

在DC/OS叢集中佈署目錄微服務

佈署微服務是現代軟體架構中的一個關鍵步驟,特別是在使用容器化和微服務架構的應用程式中。本章節將詳細介紹如何在DC/OS叢集中佈署目錄微服務,並探討相關的組態和擴充套件。

建立應用程式

首先,我們需要在DC/OS叢集中建立一個新的應用程式。這個過程涉及幾個步驟,包括選擇適當的埠和服務發現機制。具體步驟如下:

  1. 登入DC/OS叢集的管理介面。
  2. 點選「Create Application」以建立新的應用程式。
  3. 選擇「Ports」和「Service Discovery」選項。
  4. 切換到JSON模式,並提供目錄微服務的JSON組態檔案。

JSON組態範例

{
  "id": "/catalog-svc",
  "instances": 1,
  "cpus": 0.1,
  "mem": 128,
  "portDefinitions": [
    {
      "port": 10000,
      "protocol": "tcp",
      "name": "catalog-svc"
    }
  ],
  "container": {
    "type": "DOCKER",
    "docker": {
      "image": "your-docker-image-name",
      "network": "BRIDGE",
      "portMappings": [
        {
          "containerPort": 8080,
          "hostPort": 0,
          "protocol": "tcp"
        }
      ]
    }
  }
}

內容解密:

  • "id" 指定了微服務的唯一識別符號。
  • "instances" 定義了初始執行的例項數量。
  • "cpus""mem" 分別指定了每個例項所需的CPU和記憶體資源。
  • "portDefinitions" 定義了服務的埠組態。
  • "container" 部分指定了容器相關的組態,包括Docker映像和網路設定。

檢查和擴充套件服務

一旦應用程式被建立並執行,我們就可以檢查其狀態並根據需要進行擴充套件。

  1. 檢查服務狀態:點選應用程式連結可以檢視其詳細資訊,包括例項數量、狀態、日誌和版本號等。
  2. 擴充套件服務:透過點選「Scale Application」並輸入所需的例項數量,可以輕鬆地擴充套件或縮減服務。

使用curl命令檢查服務

curl http://10.0.0.79:15973/catalog-svc/rest/CatalogService/getCatalog/pkocher | python -m json.tool

內容解密:

  • 此命令用於檢查目錄微服務是否正常執行,並傳回目錄資料。
  • python -m json.tool 用於格式化輸出的JSON資料,使其更易讀。

存取服務

在DC/OS叢集中,Marathon-lb負責發現和負載平衡服務。要存取目錄微服務,需要知道Marathon-lb的主機名和服務埠。

  1. 查詢Marathon-lb主機名:在AWS CloudFormation中,選擇相應的堆積疊並檢視輸出標籤頁,找到PublicSlaveDnsAddress
  2. 存取服務:使用以下格式的URL存取目錄微服務:http://<Marathon-lb主機名>:10000/catalog-svc/rest/CatalogService/getCatalog/<userid>

更新單體式應用程式

為了讓單體式應用程式使用新的目錄微服務,需要更新其組態檔案中的端點URL。

  1. 修改組態檔案:編輯/usr/share/tomcat7/lib/Application.properties檔案,將endPoints.getCatalog屬性的值更新為Marathon-lb的URL。

範例組態

endPoints.getCatalog=http://ec2-52-207-255-252.compute-1.amazonaws.com:10000/catalog-svc/rest/CatalogService/getCatalog

內容解密:

  • 此步驟使單體式應用程式能夠透過Marathon-lb存取目錄微服務。
  • 無論目錄微服務有多少個例項在執行,Marathon-lb都能自動發現並負載平衡流量。

什麼是 DevOps?

在本文的開頭章節中,我們探討了微服務和容器對組織的影響,但並未深入討論它們對另一個當前熱門話題——DevOps 的潛在影響。如今,許多軟體組織正朝著 DevOps 模式邁進,而微服務和容器將是這一旅程中的關鍵推動因素。

DevOps 是軟體開發和(IT)維運這兩種軟體工程實踐的混合術語。其重點是加強這兩種實踐之間的協作,以實作以下目標:

  • 加快軟體釋出速度
  • 以更快的速度提高產品品質
  • 自動化這兩個領域的各個方面,例如程式碼構建、測試、封裝、釋出和佈署

毫不意外的是,整個科技行業都在爭相跳上 DevOps 的列車,以取得所有潛在的好處。那麼,究竟是什麼阻礙了他們?是什麼挑戰讓矽谷最優秀的人才無法開發出所謂的「金蛋」?最大的挑戰是變革。許多工具和實踐已經在這些組織中到位,用於管理軟體開發、測試或釋出,而所有這些都必須改變。不僅如此,組織變革也可能影響現有的團隊結構,這反過來可能需要招募新的技能組合。這些挑戰聽起來與圍繞微服務的挑戰相似。

接下來,如果你看看 DevOps 背後的目標,你會發現微服務顯然能夠實作這種軟體工程實踐的結合。單體架構的複雜性被分解成可管理的部分,每個部分提供單一功能。這些部分可以分配給多個團隊,以便每個團隊可以專注於自己的部分。結果是縮短了開發週期,簡化了佈署流程,減少了上市時間。這些優勢反過來又創造了對維運敏捷性和自動化的需求。微服務需要這種敏捷文化來維持,因此推動或實作了 DevOps 環境。

DevOps 的優勢

儘管 DevOps 具有諸多優勢,但似乎並非每位開發人員、架構師或組織都願意轉向微服務正規化。正如我們之前所討論的,它並不適合每個人。微服務最適合用於複雜的架構——即具有多種功能和終端使用者、快速佈署和可擴充套件性的軟體。在不久的將來,大多數公司,包括許多中小型組織,都將採用這一趨勢。為什麼?有五個主要原因:

  • 軟體行業未來將更加複雜。軟體定義網路、軟體定義儲存、軟體即服務、物聯網,以及處理數百萬使用者和裝置之間複雜通訊的平台,都是軟體行業發展方向的一些例子。許多大大小小的公司正在進入這些領域,隨著它們的發展,它們將意識到需要根據微服務的架構與敏捷文化相結合。
  • 新客戶型別產生新的需求。最具創新性的公司正在開發支援各種新裝置和全球的解決方案。每類別裝置都有不同的資源集可供使用。記憶體、處理速度和儲存空間在某些裝置上有限,但在其他裝置上卻很豐富。當所有這些具有不同限制的裝置試圖存取相同的軟體時,軟體必須透過隱藏客戶端的複雜性來支援它們的請求。這種複雜性將隱藏在哪裡?在軟體本身!這意味著軟體將變得更加複雜——因此需要能夠支援與不同客戶端通訊的微服務架構,正如我們在前面的章節中所討論的那樣。
  • 使用者驅動的複雜性。Amazon 和 Netflix 的產品由於其在簡化和增強使用者經驗方面的創新而變得複雜。如果他們的使用者數量保持可控,他們可能會繼續使用單體正規化。事實上,他們在初期繼續沿用了這條道路。隨著新興市場趕上已開發市場,它們的數百萬(或數十億!)使用者上線,軟體將繼續變得更加複雜,以滿足不同使用者的可擴充套件性、效能和需求。這將導致越來越多的公司感受到對微服務的需求,這些服務可以解決這些問題。
  • 工作滿意度。單體意味著一個由一個或多個開發團隊共同開發的平台,有時按工作型別劃分(例如,前端、後端、使用者經驗)。這種模式的一個問題是,一個後端工程團隊可能負責構建所需的所有後端程式碼,例如計費、產品目錄、購物車等服務(以電子商務網站為例)。當程式碼和使用案例變得複雜時,團隊進一步分裂,並在後端系統內部劃分工作(常見功能等)。隨著複雜性的增加,他們增加了更多人員並建立了新的團隊,複雜性不斷增長,直到任何小的功能更新都需要長週期和佈署時間。隨著時間的推移,團隊變得沮喪。失敗的構建、回復和耗時的除錯成為常態,而不是偶爾的障礙。溝通不暢和缺乏協作會發生,在特別棘手的情況下,甚至可能導致指責、謾罵,甚至人才流失。如果實施得當,DevOps 和微服務可以促進角色和責任的明確分離,從而增強團隊之間的協作。協作反過來又提高了生產力,直接影響了底線。結果呢?工作滿意度全面提升。

微服務與 DevOps 的未來

綜上所述,微服務和 DevOps 將在未來發揮越來越重要的作用。它們將幫助公司應對日益增長的複雜性,提高開發效率,並最終提升使用者經驗。因此,瞭解和掌握這些技術對於任何希望在未來保持競爭力的組織來說都是至關重要的。

內容解密:

此結論段落主要闡述了微服務和容器技術對軟體開發和維運(DevOps)的深遠影響。首先,回顧了本文的主要內容,並強調了微服務和容器技術的重要性。接著,詳細介紹了 DevOps 的概念、目標和優勢,以及微服務如何推動 DevOps 的實作。此外,還分析了企業採用微服務和 DevOps 的五大驅動力,包括軟體行業未來將更加複雜、新客戶型別產生新的需求、使用者驅動的複雜性增加、工作滿意度的提升等。

本段落還強調了微服務和 DevOps 在未來的重要性,並指出瞭解和掌握這些技術對於任何希望在未來保持競爭力的組織來說都是至關重要的。透過詳細分析,我們可以看到,微服務和 DevOps 將成為未來軟體開發和維運的主流趨勢,企業需要積極採用和適應這些新技術,以保持競爭優勢。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title DCOS叢集中佈署微服務與DevOps實踐

package "微服務架構" {
    component [API Gateway] as gateway

    package "核心服務" {
        component [用戶服務] as user
        component [訂單服務] as order
        component [商品服務] as product
        component [支付服務] as payment
    }

    package "基礎設施" {
        component [服務發現] as discovery
        component [配置中心] as config
        component [鏈路追蹤] as trace
    }

    queue "訊息佇列" as mq
    database "各服務資料庫" as db
}

gateway --> user
gateway --> order
gateway --> product
gateway --> payment

user --> mq : 事件發布
order --> mq : 事件發布
product --> mq : 事件發布
payment --> mq : 事件發布

user --> discovery : 註冊/發現
order --> discovery
product --> discovery
payment --> discovery

user --> db
order --> db
product --> db
payment --> db

@enduml

此圖示展示了微服務如何推動 DevOps 的實作,並進一步提高開發效率、增強協作,從而縮短上市時間、提升工作滿意度,最終提高企業的競爭力。

內容解密:

此 Plantuml 圖表清晰地展示了微服務與 DevOps 之間的關係,以及它們如何共同作用以提升企業的競爭力。首先,微服務推動了 DevOps 的實作,而 DevOps 又進一步提高了開發效率並增強了團隊之間的協作。隨後,這些改進帶來了上市時間的縮短和工作滿意度的提升,最終使企業在市場中更具競爭力。透過這樣的視覺化呈現,我們可以更直觀地理解微服務和 DevOps 之間的相互關係及其對企業發展的重要性。

微服務架構下的幫助台應用程式流程分析

在現代化的商業環境中,技術的不斷革新促使企業必須隨時調整策略以保持競爭優勢。微服務架構作為一種新型的軟體開發模式,為企業提供了更靈活、更高效的解決方案。本文將探討幫助台應用程式的流程,並分析其在微服務架構下的運作機制。

幫助台應用程式概述

幫助台應用程式是企業用於管理客戶問題和技術支援的重要工具。該應用程式通常與訂單管理和客戶管理系統整合,以實作資料的自動化處理。然而,在本案例中,我們將重點放在獨立的幫助台應用程式上,並手動建立所需的資料以闡述其功能。

使用者角色

幫助台應用程式中有三種主要的使用者角色:

  1. 管理員(Administrator):具有最高許可權,可以建立和修改帳戶、使用者、服務等,並可存取後端系統如資料函式庫。
  2. 客戶(Customers):購買了產品或服務的使用者,可以建立、修改和查詢工單,並檢視自己提交的工單狀態。
  3. 支援工程師(Support desk engineer):負責處理客戶提交的工單,並可檢視所有工單。

管理員流程

登入與首頁面

管理員透過輸入使用者名稱和密碼登入應用程式。成功驗證後,管理員將進入首頁面,該頁面包含頂部選單中的所有模組。

管理功能

管理員可以執行以下操作:

  • 新增使用者(客戶和支援工程師)
  • 新增支援產品
  • 新增已售產品

例如,管理員可以新增支援產品,如圖A.3所示。該功能允許管理員新增新的支援產品或過期現有的產品。

新增使用者與產品

管理員可以手動新增客戶使用者,例如建立一個名為Bob Black的使用者,如圖A.5所示。同時,管理員還需要將該使用者與其購買的產品關聯起來,例如新增一筆iPhone 7s的銷售記錄,如圖A.6所示。

客戶流程

登入與首頁面

客戶使用管理員提供的憑證登入後,可以在首頁面上看到可用的選項,如圖A.7所示。

客戶功能

客戶可以執行以下操作:

  • 檢視已購買的產品(My Products)
  • 建立工單(Create an Incident)
  • 檢視工單狀態(View Incident)
  • 使用留言板(Message Board)

例如,客戶可以建立一個新的工單,如圖A.9所示。客戶需要填寫相關資訊,如標題、問題嚴重性、手機型號和問題類別等。

重點分析與技術洞察

幫助台應用程式在微服務架構下的運作,展現了多項技術優勢。首先,其模組化的設計使得各個服務可以獨立開發和佈署,提高了整體的靈活性和可擴充套件性。其次,透過使用容器化技術(如Docker),應用程式的佈署和維運變得更加高效和可靠。

程式碼解析

以下是一個簡單的範例,展示如何使用微服務架構實作幫助台應用程式中的工單建立功能:

from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///tickets.db"
db = SQLAlchemy(app)

class Ticket(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text, nullable=False)

@app.route("/tickets", methods=["POST"])
def create_ticket():
    data = request.get_json()
    ticket = Ticket(title=data["title"], description=data["description"])
    db.session.add(ticket)
    db.session.commit()
    return jsonify({"message": "Ticket created successfully"}), 201

if __name__ == "__main__":
    app.run(debug=True)

內容解密:

  1. Flask應用程式初始化:首先,我們初始化了一個Flask應用程式,並組態了資料函式庫連線。
  2. 資料函式庫模型定義:定義了一個Ticket模型,用於表示工單資料表。
  3. 建立工單API:實作了一個用於建立工單的API端點,接收JSON格式的請求資料,並將其存入資料函式庫中。