分布式隊列的組成部分
- 生產者,向隊列發送消息的組件
- 消費者,接受隊列消息
- 隊列,多個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:"
}