SQSを公式ドキュメントから読み解く

## モチベーション
- 業務で最近良く使用している非同期の王道パターンなのでついでに深い知識を得たいため
- この人にSQS + Lambdaを聞けば安心だよねという状態に持っていきチームに頼られるようになりたい
## 前提レベル
- 業務ですでに基盤に乗っているSQSとLambdaを触ったことがあるレベル
- オライリーラーニングのAWS Sandboxで軽くSQS + Lambdaの環境を構築したレベル
    - https://github.com/yuuttana1223/sqs-lambda
## 学習につかうもの
基本的には公式ドキュメントを参照しつつ、Chat GPTとかに投げていく
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html

## 利点
### 1. セキュリティ
- 誰がメッセージを送受信できるかを制御できる
    - アクセス制御(IAMポリシー)
        - 例えば、EC2 から SQS にメッセージを送れるけど、外部ユーザーは送れないように設定可能。
- メッセージを暗号化して安全に保管できる
    - 暗号化（SSE：Server-Side Encryption）
        - 例えば、ユーザーの個人情報（名前、住所など）をメッセージに含める場合、暗号化して第三者が内容を見られないようにできる。
### 2. 耐久性
- メッセージは複数のサーバーに保存されるので、データが消えにくい
    - サーバーが1台ダウンしても、別のサーバーでメッセージを保持
        - 例えば、EC2 インスタンスが処理中に落ちても、メッセージは SQS 上に残るので、別のインスタンスが処理を引き継げる。
### 3. 可用性
- SQS は冗長化されたインフラを使っているので、落ちにくい
    - 複数のサーバーがメッセージの送受信を支えるので、AWS 側で障害が発生しても問題が起こりにくい。
- 大量のメッセージを同時に送受信できる
    - 例えば、数百人のユーザーが Web アプリで注文を送った場合、すべてのメッセージが SQS に保存され、サーバーが処理できるようになる。
 ### 4. スケーラビリティ
 - SQS は負荷が増えても自動でスケールするので、事前にサーバーを増やす必要がない
    - 例えば、ブラックフライデーのセールで注文が急増しても、SQS はメッセージを受け取る処理を自動的にスケールするので、処理遅延が起こりにくい。
### 5. 信頼性
- メッセージが処理されている間、他のコンシューマが同じメッセージを処理しないようにロックされる
    - 例えば、ECサイトで「購入処理」のメッセージを SQS に送ったとき、処理中のメッセージは他のサーバーが誤って受け取らないようにロックされる。（可視性タイムアウト（Visibility Timeout））
### 6. カスタマイズ
- 遅延メッセージを設定（例：「注文確定後 10 秒後に通知を送る」）
- メッセージを Amazon S3 や DynamoDB に保存してリンクを SQS に送れる
    - 256KB を超えるメッセージを S3 に保存し、そのURLを SQS に保存（例：「大きなデータの処理をスムーズに行う」）

## 仕組み
### 分散メッセージングシステム
- 非同期でシステム間のデータ転送を行うための仕組み
- 3つの主要コンポーネント で構成
#### 1. 分散システムのコンポーネント
- プロデューサー（Producer）: メッセージをキューに送信するシステム（例: Webアプリ、マイクロサービス）。
- コンシューマー（Consumer）: メッセージをキューから受信して処理するシステム（例: Lambda関数、EC2インスタンス）。
#### 2. キュー（Queue）
- メッセージを一時的に保存する場所。
- Amazon SQS サーバーに分散配置され、冗長化 されているため、耐障害性が高い
#### 3. メッセージ（Message）
- プロデューサーが送信し、コンシューマーが処理するデータ。
- SQSの複数のサーバーに冗長的に保存 されるため、システム障害時もメッセージが失われにくい。
--- 
### メッセージのライフサイクル
| ステップ | アクション | 説明 |
|---------|----------|------|
| **1. 送信** | `SendMessage` | プロデューサーが SQS にメッセージを送信 |
| **2. 冗長保存** | SQS サーバー | メッセージは Amazon SQS の複数のサーバーに冗長保存 |
| **3. 受信 & 可視性タイムアウト開始** | `ReceiveMessage` | コンシューマーがメッセージを取得し、一定時間他のコンシューマーから見えなくなる（可視性タイムアウト） |
| **4. 処理成功 → 削除** | `DeleteMessage` | コンシューマーが処理成功時、SQS からメッセージを削除 |
| **5. 処理失敗 → 再試行** | 可視性タイムアウト後に再取得 | 処理失敗すると、可視性タイムアウト終了後に再取得可能 |
| **6. リトライ回数超過** | `maxReceiveCount` (例: 5) | 指定回数のリトライ後、デッドレターキュー（DLQ）に移動 |
| **7. 保持期間超過** | `MessageRetentionPeriod` | 最大 14 日間メッセージが保持され、超過すると自動削除 |

具体例で書いてみた
```mermaid
sequenceDiagram
    participant OrderSystem as Order System (注文システム)
    participant SQS as Amazon SQS (注文キュー)
    participant PaymentService as Payment Service (決済サービス)
    participant DLQ as Dead Letter Queue (デッドレターキュー)

    OrderSystem->>SQS: 1. 注文データを送信 (SendMessage)
    SQS-->>SQS: 2. メッセージを冗長的に分散
    SQS->>PaymentService: 3. 注文データを返す (ReceiveMessage)
    PaymentService-->>PaymentService: 4. 決済処理実行
    
    alt 決済成功
        PaymentService->>SQS: 5. メッセージ削除 (DeleteMessage)
    else 決済失敗
        SQS-->>SQS: 6. 可視性タイムアウト後、メッセージを再取得可能
        SQS->>PaymentService: 7. 別のサービスがリトライ
    end
    
    alt 最大リトライ回数超過
        SQS->>DLQ: 8. メッセージをデッドレターキューへ移動
    end
    
    alt メッセージが長期間未処理
        SQS-->>SQS: 9. 設定された保持期間を超過した場合、自動削除
    end

```