分布式队列的组成部分
- 生产者,向队列发送消息的组件
- 消费者,接受队列消息
- 队列,多个sqs服务器存储冗余存储消息
sqs自动删除超过最大留存时间的消息(默认4天),可以通过SetQueueAttributes调整为(60 s to 1,209,600 s (14 天) )
消息的生命周期
-
生产者向sqs发送消息,在多个服务器上冗余存储
-
消费者请求消费,可见性超时开始计时,消息并未删除但不接受后续消费请求
-
消费者消费完毕删除消息,避免可见性超时后重复消费
队列类型
标准队列
由于分布式存储,sqs副本服务器可能故障导致消费和删除消息失败,导致重复消费。需要将application设置为幂等的
fifo队列
- 发送消息时消息本身带有不重复id,sqs按照发送顺序处理
- 如果多个生产者向同一个消息组id发送,则在消费组中按照先后顺序处理
- 消息仅在同一个消息组中有序,不同消息组的消息无序
- 队列中的消息组数量没有上限
- 无法接收指定消费组的消息
- 接受具有多个消息组id的队列时,sqs首先尝试返回尽可能多的具有相同消息组 ID 的消息
- fifo队列允许重试逻辑
- fifo在标准队列的基础上引入了exactonce,需要配置基于内容的重复数据删除(使用SHA-256 hash生成去重id)或者显示提供去重id
- 不能将现有的标准队列转换为 FIFO 队列,必须为应用程序创建一个新的 FIFO 队列
- fifo队列不支持每个消息延迟,只支持每个队列延迟
- fifo的数据在分片中存储,请求接近或超过分片上限会自动添加新分片,分片的利用率较低可能会减少分片,此操作对用户透明
- 消息所处的分片取决于消息组id的hash,建议大量使用消息组id区分分片
- sqs异步缓冲客户端不支持fifo队列
- 不兼容fifo队列的服务包括,s3事件通知,asg生命周期钩子,iot规则行动,lambda死信队列
队列比较
队列类型 | 标准队列 | FIFO 队列 |
---|---|---|
吞吐量 | 无限吞吐量,支持每个 API 操作每秒几乎无限次的 API 调用 | 高吞吐量 ,如果使用批处理,则每个 API 方法(发送,接受,删除),FIFO 队列每秒最多支持 3,000 条消息。每秒 3000 条消息指可能 300 个 API 调用,每个调用都包含10 条消息。可以提限 不使用批处理,FIFO 队列的每个 API 方法(发送,接受,删除)每秒最多支持 300 个 API 调用 |
数据重复 | at least once | exact once |
数据有序 | 尽力排序 ,可能乱序 | 先进先出传送 — 严格保留消息的发送和接收顺序。 |
使用场景 | 当吞吐量很重要时 | 当事件的顺序重要时 |
队列参数
可见超时
- 可见性超时设置从队列接收的消息(由一个使用者接收)对其他消息使用者不可见的时间长度
- 如果消息必须只接收一次,则使用者必须在可见性超时期间删除该消息
- 默认的可见性超时设置为30秒
- 为了获得最佳性能,将可见性超时设置为大于 AmazonWebServicesSDK 读超时
消息保留期
-
保留不会被删除的消息的时间量
-
默认4天,保留时间从60秒到1,209,600秒(14天)不等
-
消息的过期时间总是基于其原始的队列时间戳。当消息移动到死信队列时,队列时间戳保持不变。例如,如果一条消息在被移动到死信队列之前在原始队列中停留1天,并且死信队列的保留期被设置为4天,那么该消息将在3天后从死信队列中删除
延迟时间
- 适用于使用者需要额外的时间来处理消息。发送到队列的任何消息在延迟期间对使用者都是不可见的
- 队列的默认(最小)延迟为0秒,最多15分钟
- 对于标准队列该设置不可回溯的(不会影响队列中已有消息的延迟)。对于 FIFO 队列是可追溯的
最大消息大小
- 支持的最小消息大小为1字节,最大大小为262,144字节(256 KB)
- 要发送大于256kb 的消息,可以使用 sqs 扩展的 Java 客户端库。该消息包含对 AmazonS3中消息有效负载的引用。最大有效载荷大小为2G
接收消息等待时间
- 接收消息等待时间是轮询等待消息可用以接收的最长时间
- 最小值为0秒,最大值为20秒
- 在服务端(设置上限),如果将接收消息等待时间设置为0,则接收请求使用短轮询
- 在客户端(实际轮询时间),当 ReceiveMessage 请求的 WaitTimeSecond 参数设置为0时,将发生短轮询
Redrive allow
- 定义哪些源队列可以使用此队列作为死信队列
- 通过 ARN 指定最多10个源队列的列表
- 源队列必须由相同的帐户拥有,并且必须与死信队列驻留在相同的区域中
死信队列
-
MaxReceiveCount 是使用者在移动到死信队列之前尝试从队列接收消息而不删除消息的次数
-
DLQ 队列类型(标准或 FIFO)必须与源队列匹配
-
源队列和死信队列必须由相同的帐户拥有,并且必须与死信队列驻留在相同的区域中
队列权限
授权其他账户访问sqs权限的示例
{"Sid": "__sender_statement","Effect": "Allow","Principal": {"AWS": ["12323112441"]},"Action": ["SQS:SendMessage"],"Resource": "arn:aws-cn:sqs:cn-north-1:xxxxxxxxxxx:"
},
{"Sid": "__receiver_statement","Effect": "Allow","Principal": {"AWS": ["12323112441"]},"Action": ["SQS:ChangeMessageVisibility","SQS:DeleteMessage","SQS:ReceiveMessage"],"Resource": "arn:aws-cn:sqs:cn-north-1:xxxxxxxxxxx:"
}