使用 Elastic 进行 Amazon MQ 可观察性:通过实时洞察解密消息流

作者:来自 Elastic Agi K Thomas 及 Udayasimha Theepireddy (Uday)

由 Amazon MQ 管理的 RabbitMQ 在分布式架构中启用异步通信,但带来了操作风险,例如重试、处理延迟和队列积压。Elastic 的 Amazon MQ 集成对于 RabbitMQ 提供了对代理健康、队列性能、消息流和资源使用的深度可观察性,通过 Amazon CloudWatch 指标和日志进行监控。本文概述了与 RabbitMQ 相关的主要操作风险,并解释了 Elastic 可观察性如何帮助保持系统可靠性并优化大规模消息传递。

使用 Elastic 的 Amazon MQ 可观察性:通过实时洞察解密消息流

管理消息驱动架构中的隐藏复杂性

Amazon MQ 是一项托管的消息代理服务,支持 Apache ActiveMQ Classic 和 RabbitMQ,负责消息代理的设置、操作和维护。像 RabbitMQ 这样的消息系统,由 Amazon MQ 管理,在现代解耦的事件驱动应用程序中发挥着关键作用。作为服务之间的中介,RabbitMQ 通过消息排队、路由和可靠交付促进异步通信,使其成为微服务、实时数据流和事件驱动架构的理想选择。然而,这种灵活性也带来了操作挑战,例如重试、处理延迟、消费者失败和队列积压,这些问题会逐渐影响下游性能和系统可靠性。

通过 Elastic 的 Amazon MQ 集成,用户可以深入了解消息流模式、队列性能和消费者健康状况。该集成使得能够主动检测瓶颈,帮助优化系统行为,并确保大规模的可靠消息传递。

在这篇博客中,我们将深入探讨 RabbitMQ 在现代架构中的操作挑战,同时审视常见的漏洞和应对策略。

为什么在 Amazon MQ 上对 RabbitMQ 进行可观察性至关重要?

RabbitMQ 代理在分布式系统中至关重要,负责订单处理、支付流程和通知发送等任务。任何中断都可能引发严重的下游问题。对 RabbitMQ 的可观察性有助于回答关键的运维问题,例如:

  • CPU 和内存使用率是否在持续上升?

  • 消息发布率和确认率的趋势如何?

  • 是否有消费者未确认消息?

  • 哪些队列出现了异常增长?

  • 死信消息数量是否在不断增加?

通过 Amazon MQ 集成实现增强的可观察性

Elastic 为 RabbitMQ 提供了专用的 Amazon MQ 集成,利用 Amazon CloudWatch 的指标和日志来提供全面的可观察性数据。此集成支持采集与连接、节点、队列、交换机及系统日志相关的指标。

部署带有此集成的 Elastic Agent 后,用户可以监控以下内容:

  • 队列性能和死信队列(DLQ)指标,包括总消息数(MessageCount.max)、准备交付的消息数(MessageReadyCount.max)以及未确认的消息数(MessageUnacknowledgedCount.max)。其中 MessageCount.max 指标跟踪队列中的消息总数,包括已被标记为死信的消息,长期监控此指标可识别消息堆积趋势,提示潜在死信问题。

  • 消费者行为,例如消费者数量(ConsumerCount.max)和确认速率(AckRate.max),有助于识别性能较差的消费者或潜在的积压问题。

  • 消息吞吐量,通过实时跟踪发布速率(PublishRate.max)、确认速率(ConfirmRate.max)和确认消息速率,深入了解应用的消息流模式。

  • 代理和节点级别的健康状态,包括内存使用(RabbitMQMemUsed.max)、CPU 利用率(SystemCpuUtilization.max)、磁盘可用空间(RabbitMQDiskFree.min)和文件描述符使用(RabbitMQFdUsed.max)。这些指标对于诊断资源饱和情况和避免服务中断非常关键。

将 Amazon MQ 指标集成到 Elastic Observability 中

Elastic 的 Amazon MQ 集成支持将 CloudWatch 指标和日志导入 Elastic Observability,提供近乎实时的 RabbitMQ 可见性。预构建的 Amazon MQ 仪表板可视化这些数据,集中展示代理健康状况、消息活动和资源使用,帮助用户快速检测并解决问题。Elastic 的 Observability 告警功能可根据自定义条件触发主动通知,而其 SLO 能力则允许用户定义并跟踪关键性能目标,从而增强系统可靠性和服务承诺。

Elastic 将来自 Amazon MQ 的日志和指标与 AWS、本地部署或多云环境中的其他服务和应用数据整合在一起,实现统一平台上的可观察性。

前提条件

要按步骤操作,请确保你具备以下条件:

架构图

从 RabbitMQ 到 AWS Lambda 的审计流程追踪

以财务审计跟踪为例,每个用户操作(如资金转账)都会发布到 RabbitMQ。一个基于 Python 的 AWS Lambda 函数消费这些消息,使用 id 字段去重,并记录结构化的审计事件供下游分析使用。

通过 RabbitMQ 发送的示例负载:

{
  "id": "txn-849302",
  "type": "audit",
  "payload": {
    "user_id": "u-10245",
    "event": "funds.transfer",
    "amount": 1200.75,
    "currency": "USD",
    "timestamp": "T14:20:15Z",
    "ip": "192.168.0.8",
    "location": "New York, USA"
  }
}

你现在可以将 RabbitMQ 的消息发布活动与 AWS Lambda 的调用日志进行关联,追踪处理延迟,并为消费者吞吐量下降或 RabbitMQ 队列深度意外激增等情况配置告警。

AWS Lambda 函数:处理来自 RabbitMQ 的消息

这个基于 Python 的 AWS Lambda 函数处理从 RabbitMQ 接收到的审计事件。它基于 id 字段对消息去重,并记录结构化事件数据,供下游分析或合规使用。将以下代码保存为名为 app.py 的文件。

import json
import logging
import base64
# Configure logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# In-memory set to track processed message IDs for deduplication
processed_ids = set()
def lambda_handler(event, context):
    logger.info("Lambda triggered by RabbitMQ event")
    if 'rmqMessagesByQueue' not in event:
        logger.warning("Invalid event: missing 'rmqMessagesByQueue'")
        return {'statusCode': 400, 'body': 'Invalid RabbitMQ event'}
    for queue_name, messages in event['rmqMessagesByQueue'].items():
        logger.info(f"Processing queue: {queue_name}, Messages count: {len(messages)}")
        for msg in messages:
            try:
                raw_data = msg['data']
                decoded_json = base64.b64decode(raw_data).decode('utf-8')
                message = json.loads(decoded_json)
                logger.info(f"Decoded message: {json.dumps(message)}")
                message_id = message.get('id')
                if not message_id:
                    logger.warning("Message missing 'id', skipping.")
                    continue
                if message_id in processed_ids:
                    logger.warning(f"Duplicate message detected: {message_id}")
                    continue
                payload = message.get('payload', {})
                logger.info(f"Processing message ID: {message_id}")
                logger.info(f"Event Type: {message.get('type')}")
                logger.info(f"User ID: {payload.get('user_id')}")
                logger.info(f"Event: {payload.get('event')}")
                logger.info(f"Amount: {payload.get('amount')} {payload.get('currency')}")
                logger.info(f"Timestamp: {payload.get('timestamp')}")
                logger.info(f"IP Address: {payload.get('ip')}")
                logger.info(f"Location: {payload.get('location')}")
                processed_ids.add(message_id)
            except Exception as e:
                logger.error(f"Error processing message: {str(e)}")
    return {'statusCode': 200, 'body': 'Messages processed successfully'}

设置 AWS Secrets Manager

为了安全地存储和管理你的 RabbitMQ 凭证,请使用 AWS Secrets Manager。

创建新密钥:

  • 进入 AWS Secrets Manager 控制台

  • 选择 “Store a new secret”。

  • 选择 “Other type of secret”。

  • 输入以下键值对:

    • username: 你的 RabbitMQ 用户名

    • password: 你的 RabbitMQ 密码

配置密钥:

  • 提供一个有意义的名称,例如 RabbitMQAccess

  • 可选:添加标签并设置自动轮换(如有需要)。

存储密钥:

  • 检查设置并存储密钥。记录你创建的密钥的 ARN。

设置 Amazon MQ 上的 RabbitMQ

要开始在 Amazon MQ 上使用 RabbitMQ,请按照以下步骤设置你的代理:

  • 打开 Amazon MQ 控制台

  • 使用 RabbitMQ 引擎创建一个新代理。

  • 选择你偏好的部署选项 —— single-instance clustered

  • 使用你之前在 AWS Secrets Manager 中存储的相同用户名和密码。

  • 在 “Additional settings” 中启用 CloudWatch Logs,以实现可观测性。

  • 配置访问和安全设置,确保该代理可以被你的 AWS Lambda 函数访问。
  • 在代理创建完成后,记录以下重要信息:
    • RabbitMQ 代理的 ARN。

    • RabbitMQ Web 控制台的 URL。

  • 你需要 RabbitMQ 日志组的 ARN 来设置 Elastic 的 Amazon MQ 集成。请按照以下步骤找到它:
    • 前往代理的 General – Enabled Logs 部分。
    • 复制 CloudWatch 日志组的 ARN。

创建 RabbitMQ 队列

现在 RabbitMQ 代理已配置好,使用管理控制台创建一个消息将被发布到的队列。

  • 使用 web 控制台 URL 访问 RabbitMQ 管理控制台。
  • 创建一个新队列(例如: myQueue)来接收消息。

构建并部署 AWS Lambda 函数

本节将使用 AWS SAM 设置 Lambda 函数,添加消息处理逻辑,并将其部署到 AWS。此 Lambda 函数将负责从 RabbitMQ 消费消息并记录审计事件。

继续之前,请确保你已完成以下前提条件。

接下来,按照以下步骤继续设置:

  • 在命令行中,进入你选择的目录并运行命令 sam init
  • AWS SAM CLI 会引导你完成设置流程。
    • 选择 AWS Quick Start Templates
    • 选择 Hello World Example
    • 使用 Python 运行时和 zip 打包类型。
    • 使用默认选项继续。
    • 将你的应用命名为 sample-rabbitmq-app
    • AWS SAM CLI 会下载起始模板并创建应用项目的目录结构。
  • 在命令行中进入新创建的 sample-rabbitmq-app 目录。
    • hello_world/app.py 文件的内容替换为用于处理 rabbitmq 消息的 lambda 函数代码。
    • template.yaml 文件中,使用以下提供的值更新文件内容。
Resources:
 SampleRabbitMQApp:
   Type: AWS::Serverless::Function
   Properties:
     CodeUri: hello_world/
     Description: A starter AWS Lambda function.
     MemorySize: 128
     Timeout: 3
     Handler: app.lambda_handler
     Runtime: python3.10
     PackageType: Zip
     Policies:
       - Statement:
           - Effect: Allow
             Resource: '*'
             Action:
               - mq:DescribeBroker
               - secretsmanager:GetSecretValue
               - ec2:CreateNetworkInterface
               - ec2:DescribeNetworkInterfaces
               - ec2:DescribeVpcs
               - ec2:DeleteNetworkInterface
               - ec2:DescribeSubnets
               - ec2:DescribeSecurityGroups
     Events:
       MQEvent:
         Type: MQ
         Properties:
           Broker: <ARN of the Broker>
           Queues:
             - myQueue
           SourceAccessConfigurations:
             - Type: BASIC_AUTH
               URI: <ARN of the secret>
  • 运行命令 sam deploy --guided 并等待确认消息。这将部署所有资源。

发送审计事件到 RabbitMQ 并触发 Lambda

为了测试端到端设置,通过使用 RabbitMQ 的 Web UI 将审计事件数据发布到 RabbitMQ。一旦消息被发送,它将触发 Lambda 函数。

  • 导航到 Amazon MQ 控制台并选择你新创建的代理。
  • 找到并打开 Rabbit Web 控制台 URL。

  • 在 "Queues and Streams" 标签下,选择目标队列(例如:myQueue)。
  • 输入消息负载,然后点击 "Publish message" 将其发送到队列。

以下是通过 RabbitMQ 发布的示例负载:

{
  "id": "txn-849302",
  "type": "audit",
  "payload": {
    "user_id": "u-10245",
    "event": "funds.transfer",
    "amount": 1200.75,
    "currency": "USD",
    "timestamp": "T14:20:15Z",
    "ip": "192.168.0.8",
    "location": "New York, USA"
  }
}
  • 导航到之前创建的 AWS Lambda 函数。
  • 在 "Monitor" 标签下,点击 "View CloudWatch logs"。
  • 检查最新的日志流,确认 Lambda 函数是否被 Amazon MQ 触发,并且消息是否成功处理。

配置 Amazon MQ 集成以收集指标和日志

Elastic 的 Amazon MQ 集成简化了从由 Amazon MQ 管理的 RabbitMQ 经纪人收集日志和指标的过程。日志通过 Amazon CloudWatch Logs 获取,而指标则从指定的 AWS 区域按定义的时间间隔提取。

Elastic 提供了默认的指标收集配置。你可以接受这些默认设置,或者根据你的需求调整设置,如收集周期(Collection Period)。

启用日志收集:

  • 导航到 Amazon MQ 控制台并选择新创建的经纪人。

  • 在 "General – Enabled Logs" 部分,点击 Logs 超链接以打开详细的日志设置页面。

  • 从此页面复制 CloudWatch log group ARN

  • 在 Elastic 中,设置 Amazon MQ integration 并粘贴 CloudWatch 日志组 ARN。

  • Accept Defaults or Customize Settings– Elastic 提供了日志收集的 default configuration。你可以接受这些默认设置,也可以调整如 collection intervals 等设置,以更好地满足你的需求。

通过预构建的 Amazon MQ 仪表板可视化 RabbitMQ 工作负载

你可以通过以下方式访问 RabbitMQ 仪表板:

  1. 导航到仪表板菜单 – 在 Elastic 中选择仪表板菜单选项,搜索 [Amazon MQ] RabbitMQ 概览以打开仪表板。

  2. 导航到集成菜单 – 打开 Elastic 中的 Integrations 菜单,选择 Amazon MQ,转到 Assets 选项卡,选择 [Amazon MQ] RabbitMQ Overview 以从仪表板资产中查看。

Elastic 集成中的 Amazon MQ RabbitMQ 仪表板提供了对代理健康和消息活动的全面概览。它提供了关于代理资源利用、队列和主题性能、连接趋势和消息吞吐量的实时洞察。该仪表板帮助用户跟踪系统行为,检测性能瓶颈,并确保跨分布式应用程序的可靠消息传递。

代理指标 - Broker Metrics

此部分提供了 RabbitMQ 代理总体健康和性能的集中视图。可视化展示了已配置的交换和队列数量、活动代理连接、生产者、消费者和飞行中的总消息。系统级别的指标,如 CPU 利用率、内存消耗和可用磁盘空间,帮助评估代理是否有足够的资源来处理当前的工作负载。

消息流量指标,如发布速率、确认速率和确认率,显示了消息如何通过代理进行处理。监控这些值的趋势有助于检测消息传递问题、吞吐量下降或在负载下可能导致代理饱和的情况。

节点指标 - Node Metrics

节点级的可视化有助于识别集群式 RabbitMQ 设置中各节点之间的资源不平衡情况。此部分包括每个节点的 CPU 使用率、内存消耗和可用磁盘空间,提供对底层基础设施是否能支持代理操作的洞察。

队列指标 - Queue Metrics

特定队列的洞察对于理解消息传递模式和积压情况至关重要。此部分详细说明了按代理、虚拟主机和队列细分的总消息数、准备好的消息数和未确认的消息数。

通过观察这些计数如何随时间变化,用户可以识别慢消费者、消息积压或交付问题,这些问题可能会影响应用程序性能或在压力下导致消息丢失。

日志 - Logs

此部分显示日志级别、进程 ID 和原始消息内容。这些日志提供了对连接失败、资源阈值被触发或队列行为异常等事件的即时可视化。

使用警报规则检测队列积压

Elastic 的警报框架允许你定义规则,监控关键的 RabbitMQ 指标,并在特定阈值被突破时自动触发操作。

警报:队列积压(消息就绪或未确认的消息)

此警报帮助通过评估两个指标来检测 Amazon MQ 中的队列积压:

  • MessageUnacknowledgedCount.max

  • MessageReadyCount.max

如果以下条件持续超过 10 分钟,则触发警报:

  • MessageUnacknowledgedCount.max 超过 5,000

  • MessageReadyCount.max 超过 7,000

这些阈值应根据典型的消息量和消费者吞吐量进行调整。持续的高值可能表明消费者跟不上,或者消息传递管道出现拥塞,这可能导致延迟或丢失消息。如果不处理,持续的高值可能导致处理延迟或丢失消息。

跟踪资源利用率以维持 RabbitMQ 性能

Elastic 的服务级目标(Service-level objectives - SLOs)功能允许你使用关键指标(如延迟、可用性和错误率)定义和监控性能目标。一旦配置,Elastic 会实时评估这些 SLO,提供直观的仪表板、超出阈值的警报以及错误预算消耗的洞察。这使得团队能够提前识别问题,确保服务可靠性和一致的性能。

SLO: 节点资源健康(CPU、内存、磁盘)

此 SLO 关注确保 RabbitMQ 代理和节点具有足够的资源来处理消息,而不会导致性能下降。它跟踪 RabbitMQ 代理和节点的 CPU、内存和磁盘使用情况,以防资源耗尽导致服务中断。

目标阈值

  • SystemCpuUtilization.max 始终保持在 85% 以下,持续时间为 99%。

  • RabbitMQMemUsed.max 始终保持在 RabbitMQMemLimit.max 的 80% 以下,持续时间为 99%。

  • RabbitMQDiskFree.min 始终保持在 RabbitMQDiskFreeLimit.max 的 25% 以上,持续时间为 99%。

CPU 或内存使用率的持续高值可能表明资源竞争,这可能导致消息处理变慢或停机。磁盘可用性低可能导致代理停止接受消息,存在丢失消息的风险。这些阈值旨在捕捉资源饱和的早期迹象,并确保 RabbitMQ 部署中平稳、无中断的消息流动。

结论

随着基于 RabbitMQ 的消息架构的扩展和复杂化,深入了解系统性能和潜在问题的需求也在增加。Elastic 的 Amazon MQ 集成将这种可见性呈现到前端 —- 帮助你超越基本的健康检查,实时了解消息吞吐量、队列积压趋势以及代理和消费者之间的资源饱和情况。

通过利用预构建的仪表板、配置警报和 SLO,你可以主动检测异常,优化消费者性能,并确保在事件驱动的应用程序中可靠地交付消息。

原文:Observability for Amazon MQ with Elastic: Demystifying Messaging Flows with Real-Time Insights — Elastic Observability Labs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值