簡體   English   中英

使用 AWS lambda 將自定義指標數據寫入 CloudWatch 時超時

[英]Timeout when writing custom metric data to CloudWatch with AWS lambda

我正在運行一個香草 AWS lambda function 來計算我的 RabbitMQ 任務隊列中的消息數量:

import boto3
from botocore.vendored import requests


cloudwatch_client = boto3.client('cloudwatch')


def get_queue_count(user="user", password="password", domain="<my domain>/api/queues"):
    url = f"https://{user}:{password}@{domain}"
    res = requests.get(url)
    message_count = 0
    for queue in res.json():
        message_count += queue["messages"]
    return message_count


def lambda_handler(event, context):
    metric_data = [{'MetricName': 'RabbitMQQueueLength', "Unit": "None", 'Value': get_queue_count()}]
    print(metric_data)
    response = cloudwatch_client.put_metric_data(MetricData=metric_data, Namespace="RabbitMQ")
    print(response)

在測試運行時返回以下 output :

Response:
{
  "errorMessage": "2020-06-30T19:50:50.175Z d3945a14-82e5-42e5-b03d-3fc07d5c5148 Task timed out after 15.02 seconds"
}

Request ID:
"d3945a14-82e5-42e5-b03d-3fc07d5c5148"

Function logs:
START RequestId: d3945a14-82e5-42e5-b03d-3fc07d5c5148 Version: $LATEST
/var/runtime/botocore/vendored/requests/api.py:72: DeprecationWarning: You are using the get() function from 'botocore.vendored.requests'.  This dependency was removed from Botocore and will be removed from Lambda after 2021/01/30. https://aws.amazon.com/blogs/developer/removing-the-vendored-version-of-requests-from-botocore/. Install the requests package, 'import requests' directly, and use the requests.get() function instead.
  DeprecationWarning
[{'MetricName': 'RabbitMQQueueLength', 'Value': 295}]
END RequestId: d3945a14-82e5-42e5-b03d-3fc07d5c5148

您可以看到我能夠與 RabbitMQ API 進行交互就好了 - function 在嘗試發布指標時掛起。

lambda function 使用 IAM 角色put-custom-metric ,該角色使用此處推薦的策略,以及CloudWatchFullAccess以獲得良好的衡量標准。

我的內部負載均衡器上的資源(我的 RabbitMQ 服務器所在的位置)受 VPN 保護,因此我有必要將此 function 與適當的 VPC/安全組相關聯。 這是它現在的設置方式(我知道這是有效的,否則與 RabbitMQ 的通信將失敗): 在此處輸入圖像描述 我閱讀了這篇文章,其中多個貢獻者建議增加 function memory 和超時設置。 我已經完成了這兩項,並且超時仍然存在。

我可以毫無問題地在本地運行它,在不到 5 秒的時間內在 CloudWatch 上創建指標。

您可能想要使用 Lambda function 來實現您的目標的唯一原因是,如果您不擁有 RabbitMQ 集群。 您的邏輯在通信期間掛起的事實表明網絡問題主要是由於安全組配置錯誤造成的。

如果您可以更改集群配置,我建議您安裝和配置CloudWatch 指標導出器插件,該插件為您完成大部分繁重的工作。

如果您的集群在 Docker 上運行,我相信自定義 Docker 文件是最佳解決方案。 如果您通過 ECS/Fargate 在 AWS 中運行 Docker 實例,插件應該能夠通過ExAws任務角色自動推斷憑證。 否則,只需按照關於如何自己設置憑據的 README 說明進行操作。

@noxdafox 編寫了一個出色的插件,讓我大部分時間都在那里,但最終我最終還是選擇了一個純基於 lambda 的解決方案。 讓雲監視插件與 docker 一起運行非常棘手,並且在我遇到容器關閉其服務並停止處理消息隊列時遇到問題。 此外,我希望能夠通過我的 ECS 集群中的工作服務數量來標准化隊列計數,因此無論如何我都需要從我的 VPC 中連接到至少一個 AWS 資源。 我想最好把一切都簡單地放在同一個地方。

import os
import boto3
from botocore.vendored import requests

USER = os.getenv("RMQ_USER")
PASSWORD = os.getenv("RMQ_PASSWORD")

cloudwatch_client = boto3.client(service_name='cloudwatch', endpoint_url="https://MYCLOUDWATCHURL.monitoring.us-east-1.vpce.amazonaws.com")
ecs_client = boto3.client(service_name='ecs', endpoint_url="https://vpce-MYECSURL.ecs.us-east-1.vpce.amazonaws.com")


def get_message_count(user=USER, password=PASSWORD, domain="rabbitmq.stockbets.io/api/queues"):
    url = f"https://{user}:{password}@{domain}"
    res = requests.get(url)
    message_count = 0
    for queue in res.json():
        message_count += queue["messages"]
    print(f"message count: {message_count}")
    return message_count


def get_worker_count():
    worker_data = ecs_client.describe_services(cluster="prod", services=["worker"])
    worker_count = worker_data["services"][0]["runningCount"]
    print(f"worker_count count: {worker_count}")
    return worker_count


def lambda_handler(event, context):
    message_count = get_message_count()
    worker_count = get_worker_count()
    print(f"msgs per worker: {message_count / worker_count}")
    metric_data = [
        {'MetricName': 'MessagesPerWorker', "Unit": "Count", 'Value': message_count / worker_count},
        {'MetricName': 'NTasks', "Unit": "Count", 'Value': worker_count}
    ]
    cloudwatch_client.put_metric_data(MetricData=metric_data, Namespace="RabbitMQ")

創建 VPC 終端節點比我想象的要容易。 對於 Cloudwatch,您希望在創建步驟期間搜索“監控”VPC 端點(而不是“cloudwatch”或“日志”。搜索“ecs”可以獲得 ECS 連接所需的內容。

一旦您的 lambda 成為我們,您需要配置指標和隨附的警報,然后將它們與自動縮放策略相關聯,但這可能超出了本文的 scope。 如果您對我的解決方法有疑問,請發表評論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM