CloudWatch 儀錶板提供 Serverless 應用監控所需的視覺化與警示功能,能有效追蹤 Lambda、API Gateway 和 DynamoDB 等服務的效能指標,協助 DevOps 團隊識別瓶頸並最佳化成本。除了預設指標,還能自定義儀錶板以滿足不同角色的需求,並整合日誌分析功能,提供更全面的應用程式洞察。同時,文章也逐步引導讀者設計與實作一個根據 Serverless 架構的天氣資訊系統,從需求分析、架構設計到程式碼實作,完整呈現 Serverless 應用開發流程。透過整合 OpenWeatherAPI、Lambda、API Gateway、DynamoDB 和 MySQL 等服務,讀者能學習如何運用 Python 建立 Lambda 函式,處理資料轉換與儲存,並透過 API Gateway 暴露安全介面,最後透過 CloudWatch 監控系統效能。

CloudWatch 儀錶板在 Serverless 應用監控的實務應用

CloudWatch 儀錶板在多種情境下對於 serverless 應用的監控與管理極具價值。DevOps 團隊能夠利用 CloudWatch 儀錶板即時監控 Lambda 函式、API Gateway 端點以及 DynamoDB 表格的效能。這對於追蹤資源利用率、識別效能瓶頸以及最佳化 serverless 架構的成本至關重要。該儀錶板也非常適合為不同的利害關係人建立自定義檢視,例如需要高層級概覽的執行者或需要詳細效能指標的開發人員。此外,它還非常適合設定主動式警示和視覺化應用程式行為的長期趨勢,使團隊能夠就擴充套件和資源分配做出明智的決策。

CloudWatch 儀錶板的關鍵組成部分

CloudWatch 儀錶板由多個基本元件構成,共同提供全面的監控解決方案:

  1. 小工具(Widgets):這些是儀錶板的基本構建塊,代表各種型別的視覺化,如折線圖、條形圖和數字顯示。小工具可以調整大小並排列以建立自定義佈局。

  2. 指標(Metrics):從 AWS 服務和自定義應用程式收集的核心資料點。指標提供了資源效能和健康狀況隨時間變化的量化資訊。

  3. 警示(Alarms):可組態的閾值,當指標超過指定限制時觸發通知或自動化操作。警示有助於主動監控和問題解決。

  4. 日誌(Logs):來自各種 AWS 服務和應用程式的日誌資料匯總,可以在儀錶板內直接視覺化和分析,用於故障排除和洞察。

使用範例程式碼

import boto3

# 初始化 CloudWatch 使用者端
cloudwatch = boto3.client('cloudwatch')

# 建立一個新的儀錶板
dashboard_name = 'ServerlessApplicationDashboard'
dashboard_body = {
    "widgets": [
        {
            "type": "metric",
            "x": 0,
            "y": 0,
            "width": 6,
            "height": 6,
            "properties": {
                "view": "timeSeries",
                "metrics": [
                    ["AWS/Lambda", "Invocations", "FunctionName", "MyLambdaFunction"]
                ],
                "region": "us-west-2",
                "title": "Lambda Invocations"
            }
        }
    ]
}

response = cloudwatch.put_dashboard(
    DashboardName=dashboard_name,
    DashboardBody=str(dashboard_body)
)

print(response)

內容解密:

上述 Python 程式碼演示瞭如何使用 boto3 程式函式庫建立一個 CloudWatch 儀錶板。首先,我們初始化了一個 CloudWatch 使用者端。然後,我們定義了一個包含單一指標(Lambda 呼叫次數)的儀錶板主體。最後,我們使用 put_dashboard 方法將此儀錶板上傳到 AWS CloudWatch。

CloudWatch 儀錶板的特點

CloudWatch 儀錶板提供了多項強大的功能以增強監控和分析:

  1. 跨區域和跨帳戶監控:此功能允許您建立顯示來自多個 AWS 區域和帳戶的指標和警示的儀錶板,提供對整個基礎設施的全面檢視。

  2. 自動重新整理和時間範圍選擇:儀錶板可以設定為按指定間隔自動重新整理,確保您始終擁有最新的資訊。您還可以輕鬆調整所有小工具的時間範圍。

  3. 分享和許可權:儀錶板可以與團隊成員或外部利害關係人分享,並具有細粒度的許可權控制。這促進了協作並確保相關資訊到達正確的人員。

  4. 自定義小工具:除了預建的小工具外,您還可以使用數學表示式、文字甚至 Lambda 函式建立自定義小工具,以顯示符合您需求的複雜指標或業務特定 KPI。

使用 Plantuml 圖示說明 CloudWatch 儀錶板的架構

@startuml
skinparam backgroundColor #FEFEFE
skinparam sequenceArrowThickness 2

title Serverless 應用監控與實作

actor "客戶端" as client
participant "API Gateway" as gateway
participant "認證服務" as auth
participant "業務服務" as service
database "資料庫" as db
queue "訊息佇列" as mq

client -> gateway : HTTP 請求
gateway -> auth : 驗證 Token
auth --> gateway : 認證結果

alt 認證成功
    gateway -> service : 轉發請求
    service -> db : 查詢/更新資料
    db --> service : 回傳結果
    service -> mq : 發送事件
    service --> gateway : 回應資料
    gateway --> client : HTTP 200 OK
else 認證失敗
    gateway --> client : HTTP 401 Unauthorized
end

@enduml

圖表翻譯: 此圖示展示了 CloudWatch 儀錶板的架構,包括其主要元件(小工具、指標、警示、日誌)以及它們之間的關係。小工具可以用於視覺化不同型別的資料,如 Lambda 呼叫次數和 API Gateway 請求數。

建立第一個無伺服器應用程式:設計與實作

介紹

本章將指導您從零開始建立第一個無伺服器應用程式。透過本章的學習,您將能夠在AWS雲端上佈署一個功能齊全、可擴充套件且具成本效益的解決方案。

本章的目標是引導您完成無伺服器應用程式的整個生命週期,從理解問題陳述到監控已佈署的解決方案。我們將利用各種AWS服務,包括Lambda、API Gateway、DynamoDB、CloudWatch等,來構建一個強壯且高效的應用程式。

理解問題陳述

您將設計一個無伺服器天氣資訊系統,該系統根據郵政編碼(PIN/ZIP程式碼)提供天氣資料。該系統將作為AWS無伺服器架構的實際演示。

該系統由幾個關鍵元件組成,這些元件共同工作:

  1. OpenWeatherAPI整合:用於取得當前天氣資料
  2. Lambda函式:處理和轉換天氣資訊
  3. 資料函式庫:用於持久化儲存
  4. S3儲存桶:用於檔案儲存
  5. 安全的API Gateway:為客戶端提供存取介面
  6. CloudWatch:用於監控和日誌記錄

設計解決方案

在設計我們的無伺服器天氣應用程式時,我們將遵循一個結構化的方法,強調可擴充套件性和效率。解決方案架構的核心是一個Lambda函式,它作為核心處理器,與OpenWeatherAPI互動以取得根據縣名(或城市名)的天氣資料。如圖6-1所示,該設計結合了各種必要的AWS服務。

系統架構元件

  1. OpenWeatherAPI整合:作為檢索近實時天氣資訊的外部資料來源。
  2. Lambda函式:處理傳入請求並處理資料轉換,作為系統的核心處理單元。
  3. RDS MySQL資料函式庫:提供持久化儲存和高效的資料檢索能力。
  4. CloudWatch:用於對整個系統的操作進行全面的監控和日誌記錄。
  5. S3儲存桶:用於維護城市列表CSV檔案。
  6. DynamoDB:用於儲存城市列表,Lambda函式將從中列出城市並請求OpenWeatherAPI的天氣報告。
  7. API Gateway:透過安全的端點為客戶端提供存取介面。
  8. 安全組態:透過安全群組、IAM角色、政策、子網組態和VPC設定來確保適當的存取控制和網路隔離。

資料流

  1. csvprocessing Lambda函式從Amazon S3檢索CSV資料,並隨後將「城市程式碼」和「城市名稱」屬性儲存在Amazon DynamoDB表中。

    import boto3
    import csv
    
    s3 = boto3.client('s3')
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('CityList')
    
    def lambda_handler(event, context):
        # 從S3下載CSV檔案
        s3.download_file('your-bucket-name', 'citylist.csv', '/tmp/citylist.csv')
    
        # 處理CSV檔案並上傳到DynamoDB
        with open('/tmp/citylist.csv', 'r') as file:
            reader = csv.DictReader(file)
            for row in reader:
                table.put_item(Item=row)
        return {
            'statusCode': 200,
            'statusMessage': 'OK'
        }
    

    內容解密:

    • 該Lambda函式使用boto3函式庫與S3和DynamoDB互動。
    • s3.download_file方法用於從S3下載CSV檔案到Lambda的臨時儲存。
    • 使用csv.DictReader讀取CSV檔案,並將每一行作為字典處理,便於將資料寫入DynamoDB。
    • table.put_item方法用於將CSV中的每一行資料寫入DynamoDB表中。
  2. fetchweatherdata Lambda函式從DynamoDB表中檢索城市名稱。隨後,它利用OpenWeatherAPI取得相應的天氣資料,並將其持久化在MySQL資料函式庫表中。

    import requests
    import boto3
    import mysql.connector
    
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('CityList')
    
    def lambda_handler(event, context):
        # 從DynamoDB取得城市列表
        response = table.scan()
        cities = response['Items']
    
        # 對每個城市呼叫OpenWeatherAPI取得天氣資料
        for city in cities:
            city_name = city['CityName']
            weather_data = requests.get(f'http://api.openweathermap.org/data/2.5/weather?q={city_name}&appid=YOUR_API_KEY').json()
    
            # 將天氣資料儲存在MySQL資料函式庫中
            cnx = mysql.connector.connect(user='your_user', password='your_password',
                                          host='your_host', database='your_database')
            cursor = cnx.cursor()
            query = ("INSERT INTO weather_data (city_name, weather) VALUES (%s, %s)")
            cursor.execute(query, (city_name, weather_data['weather'][0]['description']))
            cnx.commit()
            cursor.close()
            cnx.close()
        return {
            'statusCode': 200,
            'statusMessage': 'OK'
        }
    

    內容解密:

    • 該Lambda函式首先掃描DynamoDB表以取得城市列表。
    • 對每個城市,使用OpenWeatherAPI取得其天氣資料。
    • 將取得的天氣資料儲存在MySQL資料函式庫中,使用mysql-connector-python函式庫進行資料函式庫操作。

實作無伺服器天氣應用程式:API Gateway 與 Lambda 函式的整合

規劃實作架構

圖 6-2 展示了本實作的整體基礎設施架構。首先,使用您的憑證登入 AWS 控制檯。登入後,您需要根據基礎設施架構為此實作提供所有必要的 AWS 資源。建立這些資源有兩種選擇:使用 CloudFormation 範本或直接透過 AWS 控制檯使用者介面。在本案例中,我們將結合兩種方法來高效地設定必要的資源。

實作步驟

準備工作

  1. 安裝並組態最新版本的 Python 在您的本地機器上。
  2. 具備基本的 Python 知識,因為您的 Lambda 函式將使用 Python 語言實作。
  3. 使用 MySQL Workbench 作為客戶端連線到 AWS RDS MySQL 例項;您也可以根據自己的習慣使用其他工具。

建立 API Gateway

  1. 登入 AWS 管理控制檯,進入 API Gateway 控制檯並開始建立 API 的過程,選擇「REST API」選項,如圖 6-3 所示。
  2. 將 API 名稱指定為「weatherreport」,選擇「Regional」作為 API 端點型別,然後點選「Create API」選項。
  3. 成功建立 REST API 後,在 API Gateway 控制檯中點選「Create Resource」按鈕來建立資源。將資源名稱指定為「countryweather」,然後點選「Create Resource」。這將成功建立資源,如圖 6-4 所示。

建立 readweather Lambda 函式

  1. 導航到 Lambda 控制檯並開始建立一個新的函式。將函式名稱指定為「readweather」,並選擇「Python 3.13」作為執行環境。
  2. 點選「Create function」按鈕。這將生成一個具有基本 Python 程式的 Lambda 函式,如圖 6-5 所示。然後,對函式主體內的預設程式碼進行必要的修改。
  3. 佈署 Lambda 函式並建立測試事件以驗證其功能。

將 readweather Lambda 函式與 API Gateway 整合

  1. 傳回 API Gateway 控制檯,選擇「weatherreport」API,導航到資源,然後點選「Create method」選項。
  2. 選擇「GET」作為方法型別,並將整合型別組態為「Lambda」。選擇「readweather」Lambda 函式的 ARN,然後點選「Create method」以完成流程。

佈署 API

  1. 從資源頁面,點選「Deploy API」按鈕。選擇「New Stage」作為佈署階段,並指定階段名稱為「Dev」。點選「Deploy API」以佈署 API。
  2. 成功佈署後,系統將自動重定向到階段頁面。

建立 Authorizer Lambda 函式以增強安全性

  1. 使用 AWS 控制檯頁面為 API Gateway 建立 Authorizer Lambda 函式,命名為「authorizer」,並選擇 Python 作為執行環境。
  2. 將預設程式碼替換為以下程式碼:
import json

def generate_policy(principal_id, effect, resource):
    auth_response = {
        'principalId': principal_id
    }
    if effect and resource:
        policy_document = {
            'Version': '2012-10-17',
            'Statement': [
                {
                    'Action': 'execute-api:Invoke',
                    'Effect': effect,
                    'Resource': resource
                }
            ]
        }
        auth_response['policyDocument'] = policy_document
    return auth_response

def lambda_handler(event, context):
    token = event['authorizationToken']
    valid_token = "apressweatherapi"
    if token == valid_token:
        return generate_policy('countryweather', 'Allow', event['methodArn'])
    else:
        return generate_policy('countryweather', 'Deny', event['methodArn'])

程式碼解析:

此程式碼定義了一個 Lambda 函式,用於授權存取 Weather API。它檢查傳入的授權令牌是否與預設的有效令牌匹配。如果匹配,則生成一個允許策略,否則生成一個拒絕策略。

測試 Invoke URL

  1. 您可以在新的瀏覽器標籤頁中開啟 Invoke URL,或使用 Postman 等 API 測試工具進行測試。

圖表說明:

此圖示展示了 Weather API 的整體架構,包括 API Gateway、Lambda 函式和 RDS MySQL 例項之間的互動關係。

圖表翻譯: 此圖表詳細描述了 Weather API 的工作流程。首先,使用者透過 API Gateway 傳送請求。API Gateway 將請求轉發給 Authorizer Lambda 函式進行驗證。如果驗證成功,則呼叫 readweather Lambda 函式從 RDS MySQL 例項中檢索天氣資料。最後,將格式化後的資料傳回給使用者。