我们使用 Java 从 SNS/SQS 发送/接收消息。当我们发布消息时,我们正在这样做:
final var req = PublishRequest.builder()
.topicArn(topicArn)
.message(payload)
.subject(subject)
.build();
final var response = snsClient.publish(req);
请注意,我们在这里设置
subject
——这很重要,因为我们用它来驱动接收端的逻辑。当我们收到消息时,我们将 JSON 解析为一个对象并正确地得到一个 subject
。但是,我们现在也使用 Python SDK 来接收消息,在这种情况下,API 调用不会发送回“主题”属性:
queue_name = "..."
sqs = boto3.resource("sqs")
queue = sqs.get_queue_by_name(QueueName=queue_name)
messages = queue.receive_messages(
MaxNumberOfMessages=1,
WaitTimeSeconds=10,
AttributeNames=["All"],
MessageAttributeNames=["All"],
)
for message in messages:
print("Got message:")
print(f"Queue URL: {message.queue_url}")
if message.attributes != None:
print(f"Attributes:\n{json.dumps(message.attributes, indent=2)}")
if message.message_attributes != None:
print(f"Message Attributes:\n{json.dumps(message.message_attributes, indent=2)}")
print(f"Body:\n{json.dumps(json.loads(message.body), indent=2)}")
结果:
Got message:
Queue URL: https://...
Attributes:
{
"SenderId": "...",
"ApproximateFirstReceiveTimestamp": "1737570929119",
"ApproximateReceiveCount": "5",
"SentTimestamp": "1737535740136"
}
Body:
{
...
}
请注意,没有顶级“主题”属性,并且 https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs/queue/receive_messages.html 没有提及根本就是“主题”。
我是否遗漏了什么,或者两个 SDK 的输出根本不一样?请注意,我还尝试在 Python 中使用 SQS 客户端(而不是“资源”)。如何让 Python SDK 包含“主题”?
我还配置了电子邮件订阅,主题作为独立属性显示在电子邮件主题以及电子邮件的 JSON 正文中。
Java AWS 开发工具包:29 年 2 月 29 日 蟒蛇:3.10.2 Python AWS 开发工具包:1.33.13
SNS 到 SQS 的一个令人困惑的方面是原始 SNS 消息被“包装”在 SQS 消息内。 没有任何方法可以从 SNS 消息中提取主题等信息。 此外,虽然 SQS 消息允许添加最多 10 个任意字段作为消息属性,但没有预定义的“主题”字段。 要获取 SNS 主题,您需要解开 SQS 消息中的消息正文并解析 SNS 消息正文。 无论您使用什么语言 - SQS 有效负载都是相同的。
在Python中,你最终会做类似的事情:
response = sqs.receive_message(
QueueUrl=queue_url,
MaxNumberOfMessages=1,
WaitTimeSeconds=20
)
sqs_message = response['Messages'][0]
body = json.loads(sqs_message['Body'])
message = json.loads(body['Message'])
(如果有多个,则需要循环
Messages
)
在此示例中,message
现在将包含 SNS 消息。 现在您需要从中获取数据,其中包括 SNS 消息的主题。