You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS SQS Java SDK与Python SDK/CLI返回结果不一致,Python端无法获取消息Subject字段

AWS SQS Java SDK与Python SDK/CLI返回结果不一致,Python端无法获取消息Subject字段

这个问题我之前排查过,核心原因是SNS向SQS传递消息时有两种不同的模式,而Java和Python端的处理逻辑对应了不同的模式,导致你在Python里找不到Subject字段。咱们一步步来理清楚:

首先明确SNS→SQS的两种消息传递模式

SNS把消息发到SQS时,有两种核心模式,直接决定了Subject字段的位置:

1. 默认模式(RawMessageDelivery=false)

这是SNS订阅SQS的默认配置,此时SQS收到的消息body是一个完整的SNS消息结构,里面直接包含Subject、Message(你的原始 payload)、TopicArn等元数据。比如body解析后会是这样:

{
  "Type": "Notification",
  "MessageId": "xxxx-xxxx-xxxx",
  "TopicArn": "arn:aws:sns:xxx:xxx:your-topic",
  "Subject": "你设置的主题内容",
  "Message": "你的原始消息payload",
  "Timestamp": "2024-01-22Txx:xx:xx.xxxZ",
  ...
}

你的Java端能拿到Subject,大概率是这种模式——Java代码解析了这个SNS消息结构,直接取了Subject字段。

2. 原始消息模式(RawMessageDelivery=true)

如果手动开启了这个配置,SQS收到的消息body就是你发布的原始payload,而SNS的元数据(包括Subject)会被放到SQS的Message Attributes里,键为Subject,类型是字符串。

为什么Python里拿不到Subject?

结合你的代码和输出来看,可能有两种情况:

情况1:你用了默认模式,但Python代码没找对位置

你的Python代码里解析了message.body,但输出里没看到Subject,这可能是你没注意到——默认模式下Subject是在body的SNS消息结构里,而不是SQS的Attributes或Message Attributes里。

修正代码:直接从解析后的body里取Subject:

import json

for message in messages:
    sns_message = json.loads(message.body)
    # 从SNS消息结构里拿Subject
    subject = sns_message.get("Subject")
    if subject:
        print(f"Subject: {subject}")
    # 你的其他打印逻辑...

情况2:你开启了原始消息模式,但没正确读取Message Attributes

如果你的SNS订阅SQS时开了RawMessageDelivery=true,那Subject会出现在message_attributes里,但需要注意boto3返回的Message Attributes是嵌套结构,要取StringValue字段:

修正代码:

import json

for message in messages:
    subject = None
    if message.message_attributes and "Subject" in message.message_attributes:
        # 原始模式下Subject在Message Attributes里,要取StringValue
        subject = message.message_attributes["Subject"]["StringValue"]
    if subject:
        print(f"Subject: {subject}")
    # 你的其他打印逻辑...

关键:检查并修正SNS订阅SQS的配置

不管哪种情况,先确认你的SNS订阅SQS的RawMessageDelivery设置:

  1. 打开AWS控制台→进入对应的SNS主题→找到订阅列表里的SQS订阅
  2. 点击订阅的ARN→查看RawMessageDelivery属性是true还是false
  3. 如果需要修改,直接在控制台修改,或者用boto3代码修改:
import boto3

sns_client = boto3.client("sns")
# 替换成你的订阅ARN
subscription_arn = "arn:aws:sns:region:account-id:topic-name:subscription-id"
# 设置为false回到默认模式,或者true用原始模式
sns_client.set_subscription_attributes(
    SubscriptionArn=subscription_arn,
    AttributeName="RawMessageDelivery",
    AttributeValue="false"
)

额外验证:邮件订阅的情况

你说邮件订阅里能看到Subject,这是因为SNS给邮件订阅的消息默认会把Subject放到邮件主题,同时在邮件的JSON附件里也会包含完整的SNS消息结构,和默认模式的SQS消息结构一致,这也侧面说明你发布SNS消息时Subject是正常传递的。


备注:内容来源于stack exchange,提问作者Josh M.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 14:54:37