「非同期処理の設計で後から変えられなくなった」
AWS環境で非同期処理や分散アーキテクチャを設計するとき、SQS(Simple Queue Service)とSNS(Simple Notification Service)のaws sqs sns 使い分けで迷うエンジニアは多い。
名前が似ているうえに、ユースケースが重なって見える部分もあるので、「とりあえずSQS」「なんとなくSNS」という選び方をしてしまいがちだ。
この記事では、aws sqs sns 使い分けの判断軸を根本から整理し、疎結合アーキテクチャを正しく設計する方法を解説する。
ファンアウトキューイングパターン、VPCエンドポイントとの連携、実務上の注意点とアンチパターンまでカバーする。
この記事のポイント
・SQSは1対1のキューイング、SNSは1対多のファンアウト配信
・SNS+SQSの組み合わせでメッセージの蓄積とファンアウトを両立できる
・VPCエンドポイントでSQS/SNS通信をAWSネットワーク内に閉じセキュリティを強化する
・FIFOトピックとFIFOキューは必ずセットで使う(混在不可)
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
SQSとSNSの役割の違い:キューイングとパブサブを混同しない
1. Amazon SQSとは(メッセージキューイング)
SQSは、送信者(プロデューサー)と受信者(コンシューマー)の間にキューを挟むポイント・ツー・ポイント型のメッセージサービスだ。「送った側はキューに入れるだけ」「受け取る側は自分のペースで取り出す」という仕組みで、両者の処理速度の差を吸収する。
コンシューマーが一時的に落ちていても、キューにメッセージが蓄積されるため、復旧後に処理を再開できる。
# SQSへのメッセージ送信(プロデューサー側) aws sqs send-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/MyQueue --message-body "注文ID:20260717-001の処理依頼" # メッセージ受信(コンシューマー側) aws sqs receive-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/MyQueue # 出力例: # { # "Messages": [{ # "MessageId": "abc123-def456", # "Body": "注文ID:20260717-001の処理依頼", # "ReceiptHandle": "AQEBxxx..." # }] # }
2. Amazon SNSとは(パブリッシュ・サブスクライブ)
SNSは、発行者(パブリッシャー)が「トピック」にメッセージを送ると、そのトピックを購読している複数のサブスクライバーに同時配信されるサービスだ。サブスクライバーには、SQSキュー・Lambda・HTTPエンドポイント・メールアドレス・SMS・モバイルプッシュ通知など、多様なターゲットを設定できる。
# SNSトピックへのパブリッシュ aws sns publish --topic-arn arn:aws:sns:ap-northeast-1:123456789012:OrderEvents --message "注文ID:20260717-001の決済完了" # 出力例: # { # "MessageId": "xyz789-abcd-efgh-ijkl-012345678901" # } # 購読しているSQS・Lambda・メール全てに即時配信される
3. SQSとSNSの違いを一覧で整理する
| 項目 | SQS(キューイング) | SNS(パブサブ) |
|---|---|---|
| 配信先 | 1対1(コンシューマー1つ) | 1対多(サブスクライバー複数) |
| メッセージの蓄積 | 蓄積される(最長14日間) | 蓄積しない(プッシュ型・即時配信) |
| 受信の仕組み | ポーリング(Pull型) | プッシュ(Push型) |
| 主な用途 | 非同期ワーカー・順次処理・バックログ | イベント通知・ファンアウト・マルチサービス連携 |
| 処理失敗時の対応 | デッドレターキュー(DLQ)で保持・再処理 | 再送ポリシーあり(回数制限あり) |
疎結合アーキテクチャとは何か
1. 密結合が引き起こす問題
密結合アーキテクチャでは、サービスAが直接サービスBのAPIを同期的に呼び出す。このとき、BがダウンするとAも処理できなくなる。BがレスポンスするまでAは待機しなければならず、BのレスポンスタイムがそのままAのレスポンスタイムに影響する。
ECサイトで言えば、「注文処理」が「在庫サービス」「決済サービス」「配送サービス」を全て同期的に呼び出している状態だ。どれか1つが遅くなると注文全体が止まる。スケーリングも全サービスを同時に対応させなければならず、コストが跳ね上がる。
2. SQS/SNSが疎結合を実現する仕組み
SQSを挟むことで、注文処理サービスはキューにメッセージを投げるだけで処理完了となる。在庫・決済・配送の各サービスは自分のペースでキューからメッセージを取り出して処理する。・注文処理サービスは各下流サービスの存在を知らなくてよい(疎結合)
・下流サービスが一時的にダウンしても、キューにメッセージが蓄積されるため注文は失われない
・下流サービスのスケーリングを独立して行える
・処理量の急増(バースト)にも、キューがバッファの役割を果たして対応できる
これが疎結合アーキテクチャの本質だ。SQSとSNSはこの疎結合を実現するための核となるサービスだ。
SQSを使うべきケース:ワーカーキューと順次処理
1. 非同期ワーカー処理
画像のリサイズ、メールの一括送信、CSVのバッチ処理など、時間のかかる処理をバックグラウンドで行う場合はSQSが最適だ。Webアプリケーションはリクエストを受け取ったらSQSキューにジョブを追加して即座にレスポンスを返す。EC2やLambdaで動くワーカーが非同期でキューからジョブを取り出して処理する。ユーザーは処理完了を待たずにレスポンスを受け取れるため、UXが大きく改善する。
2. デッドレターキューによる失敗管理
SQSにはデッドレターキュー(DLQ)という機能がある。処理に失敗したメッセージを指定回数リトライした後、別のキュー(DLQ)に移動させる仕組みだ。# デッドレターキューの設定(RedrivePolicy) aws sqs set-queue-attributes --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/MainQueue --attributes '{ "RedrivePolicy": "{\"deadLetterTargetArn\":\"arn:aws:sqs:ap-northeast-1:123456789012:DLQueue\",\"maxReceiveCount\":\"3\"}" }' # maxReceiveCount=3 : 3回処理失敗でDLQへ移動 # DLQのメッセージ数を確認 aws sqs get-queue-attributes --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/DLQueue --attribute-names ApproximateNumberOfMessages # 出力例: # {"Attributes": {"ApproximateNumberOfMessages": "2"}} # 0以外ならCloudWatchアラームで通知する運用が鉄則
3. スタンダードキュー vs FIFOキュー
・スタンダードキュー:スループット優先。メッセージが重複して配信される場合があり、順序は保証されない・FIFOキュー(First-In-First-Out):順序保証と重複排除が必要な場合に使う。スループットはスタンダードより低い
金融取引・ログの順次書き込み・ステート遷移管理のようにメッセージの順序が重要な場合はFIFOキューを選ぶ。それ以外はスタンダードキューでスループットを優先する方が実践的だ。
Linuxの実践力を体系的に身につけたい方は、AWSコース紹介ページもご覧ください。
>> AWSの設計・構築を体系的に学ぶ(詳細はこちら)
SNSを使うべきケース:ファンアウトとマルチサブスクライバー
1. 複数サービスへの同時配信(ファンアウト)
「注文が完了したとき、在庫管理・メール通知・ポイント付与の3つを同時に動かしたい」というケースでは、SNSのファンアウトパターンが力を発揮する。注文サービスがSNSトピックにパブリッシュするだけで、購読している3つのシステムが同時にイベントを受け取る。注文サービスは下流3つのエンドポイントを知る必要がない。
2. Lambda・SQS・メールを並列実行する
SNSのサブスクライバーとして設定できる主なターゲットは以下の通りだ。・AWS Lambda:イベントドリブンな処理の即時実行
・Amazon SQS:非同期ワーカーキューへの転送(ファンアウトキューイングパターン)
・HTTPエンドポイント:外部WebhookやAPIへの通知
・Amazon SES/メール:メール通知の自動送信
・モバイルプッシュ:iOSおよびAndroidアプリへのプッシュ通知
1つのイベントでこれだけ多くのターゲットを並列に動かせるのが、SNSの最大の強みだ。
SQS+SNSを組み合わせたファンアウトキューイングパターン
1. アーキテクチャの構造を理解する
「SNS単体」ではメッセージが蓄積されないため、下流サービスがダウンしているとメッセージが失われる。「SQS単体」では1つのコンシューマーにしか配信できない。
この両方の問題を解決するのがファンアウトキューイングパターンだ。SNSトピックの各サブスクライバーとしてSQSキューを配置することで、ファンアウト(1対多配信)と蓄積(キューイング)を両立する。
# ファンアウトキューイングパターン 構成イメージ # # [プロデューサー(注文サービス)] # | # v # [SNSトピック: OrderEvents] # | | | # v v v # [SQS:在庫] [SQS:決済] [SQS:メール] # | | | # v v v # [在庫Worker] [決済Worker] [メールWorker]
2. AWS CLIでファンアウト構成を設定する
# 1. SNSトピックの作成 aws sns create-topic --name OrderEvents # 出力例: {"TopicArn": "arn:aws:sns:ap-northeast-1:123456789012:OrderEvents"} # 2. SQSキューの作成(在庫管理用) aws sqs create-queue --queue-name InventoryQueue # 出力例: {"QueueUrl": "https://sqs.ap-northeast-1.amazonaws.com/123456789012/InventoryQueue"} # 3. SQSキューにSNSからの送信を許可するポリシーを設定(必須) # 注意: このポリシーがないとSNSからのメッセージがサイレントに失敗する aws sqs set-queue-attributes --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/InventoryQueue --attributes '{"Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"},\"Action\":\"sqs:SendMessage\",\"Resource\":\"arn:aws:sqs:ap-northeast-1:123456789012:InventoryQueue\",\"Condition\":{\"ArnEquals\":{\"aws:SourceArn\":\"arn:aws:sns:ap-northeast-1:123456789012:OrderEvents\"}}}]}"}' # 4. SNSトピックにSQSをサブスクライブ aws sns subscribe --topic-arn arn:aws:sns:ap-northeast-1:123456789012:OrderEvents --protocol sqs --notification-endpoint arn:aws:sqs:ap-northeast-1:123456789012:InventoryQueue # 出力例: {"SubscriptionArn": "arn:aws:sns:ap-northeast-1:123456789012:OrderEvents:xxxxxxxx"} # 5. テストパブリッシュ aws sns publish --topic-arn arn:aws:sns:ap-northeast-1:123456789012:OrderEvents --message "注文完了イベント 注文ID=20260717-001" # 6. SQSキューで受信確認 aws sqs receive-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/InventoryQueue # メッセージが届いていれば設定成功
VPC設計・セキュリティ(VPCエンドポイント)との連携
1. なぜVPCエンドポイントが必要か
デフォルトでは、EC2やLambdaからSQS/SNSへの通信はインターネット経由(パブリックエンドポイント)となる。プライベートサブネット内のリソースからSQS/SNSを使う場合、インターネットゲートウェイかNATゲートウェイが必要になる。NATゲートウェイはコストが高く、通信がインターネットを経由するためセキュリティ上のリスクがある。
VPCエンドポイント(インターフェイス型)を使えば、SQS/SNSへの通信をAWSネットワーク内に閉じることができる。
・インターネットを経由しないため、セキュリティポリシーの要件を満たしやすい
・NATゲートウェイのデータ処理コストを削減できる
・プライベートサブネットのリソースからSQS/SNSに直接アクセスできる
2. SQS/SNS用VPCエンドポイントの設定
# SQS用VPCエンドポイントの作成(インターフェイス型) aws ec2 create-vpc-endpoint --vpc-id vpc-0a1b2c3d4e5f67890 --vpc-endpoint-type Interface --service-name com.amazonaws.ap-northeast-1.sqs --subnet-ids subnet-0a1b2c3d subnet-0e5f6a7b --security-group-ids sg-0a1b2c3d4e5f67890 # 出力例: {"VpcEndpoint": {"VpcEndpointId": "vpce-0a1b2c3d4e5f67890", "State": "pending"}} # SNS用VPCエンドポイントの作成 aws ec2 create-vpc-endpoint --vpc-id vpc-0a1b2c3d4e5f67890 --vpc-endpoint-type Interface --service-name com.amazonaws.ap-northeast-1.sns --subnet-ids subnet-0a1b2c3d subnet-0e5f6a7b --security-group-ids sg-0a1b2c3d4e5f67890 # エンドポイントの状態確認(available になれば使用可能) aws ec2 describe-vpc-endpoints --filters "Name=vpc-id,Values=vpc-0a1b2c3d4e5f67890" --query "VpcEndpoints[*].{ID:VpcEndpointId,Service:ServiceName,State:State}" # 出力例: # [ # {"ID": "vpce-0a1b2c3d", "Service": "com.amazonaws.ap-northeast-1.sqs", "State": "available"}, # {"ID": "vpce-1e2f3g4h", "Service": "com.amazonaws.ap-northeast-1.sns", "State": "available"} # ]
VPCエンドポイント設定後の実際の疎通確認には、Linuxのポート確認ツールが有効だ。
・Linux ポート確認の全コマンド(ss・lsof・netstat)
設計時の注意点とアンチパターン
1. アンチパターン:SNSだけで全てを解決しようとする
SNSはメッセージを蓄積しない。下流のサービス(Lambda・SQSキュー)が処理できない状態のとき、SNSはメッセージを破棄する(プロトコルによっては再送するが上限がある)。高負荷時のバーストトラフィックに対応するには、SNS+SQSの組み合わせでバッファを設けることが必須だ。SQSトリガーのLambdaなら、バッチサイズとコンカレンシーを明示的にコントロールできる。
2. メッセージの重複とべき等性
SQSのスタンダードキューは、ネットワーク障害時などに同じメッセージが複数回配信されることがある(At-least-once配信)。コンシューマーは「同じメッセージを複数回受け取っても結果が変わらない(べき等な)」実装にする必要がある。実務上の対策として、処理済みのメッセージIDをDynamoDBなどに記録して重複検知する方法が現場でよく使われる。
3. FIFOトピックとFIFOキューは必ずセットにする
FIFOキューは順序保証と重複排除を提供するが、スループットが制限される。また、FIFOキューにSNSからメッセージを配信するには、SNSトピックもFIFOトピックにする必要がある。スタンダードSNSトピックはFIFOキューをサブスクライバーとして登録できない。
・スタンダードSNS + スタンダードSQS:高スループット・重複あり・順序不保証
・FIFO SNS + FIFO SQS:順序保証・重複排除・低スループット
この2つを混在させることはできない点を設計初期に把握しておくことが要注意だ。
よくあるエラーとトラブルシュート
1. SNSからSQSにメッセージが届かない
最も多いトラブルだ。症状は「SNS publishは成功しているのにSQSキューが空のまま」というもの。原因のほぼ全てはSQSのキューポリシー未設定だ。SNS側にエラーは出ないままサイレントに失敗する。
対処法: SQSキューのポリシーに `sqs:SendMessage` をSNSに許可する設定を追加する(前述のAWS CLI設定例を参照)。
2. VPCエンドポイント設定後も接続できない
エンドポイントの状態が `available` になっていても接続できない場合、セキュリティグループのインバウンドルール(ポート443)が不足していることが多い。# セキュリティグループのインバウンドルール確認 aws ec2 describe-security-groups --group-ids sg-0a1b2c3d4e5f67890 --query "SecurityGroups[*].IpPermissions" # ポート443(HTTPS)のインバウンドがEC2/Lambdaのセキュリティグループから許可されているか確認 # エンドポイントのDNS名を確認(プライベートDNS有効化が必要な場合がある) aws ec2 describe-vpc-endpoints --filters "Name=vpc-id,Values=vpc-0a1b2c3d4e5f67890" --query "VpcEndpoints[*].DnsEntries"
Linuxホスト上でのNTPによる時刻同期もAWS環境では重要だ。SNSやSQSの認証に使うAWS署名には正確な時刻が必要なため、時刻ずれは認証エラーの原因になる。
・Amazon Linux環境でのchrony・ntpd 時刻同期設定
まとめ:aws sqs sns 使い分けの判断基準
| やりたいこと | 選択すべき構成 |
|---|---|
| 1つのコンシューマーに非同期でジョブを渡したい | SQS(スタンダードキュー) |
| 処理の順序を保証したい・重複排除したい | SQS FIFOキュー |
| 複数サービスに同時にイベントを届けたい | SNSトピック+複数サブスクライバー |
| ファンアウト配信しつつ各先でキューイングしたい | SNS+SQS(ファンアウトキューイングパターン) |
| 処理失敗したメッセージを保持・再処理したい | SQS デッドレターキュー(DLQ) |
| プライベートVPC内でSQS/SNSを使いたい | VPCエンドポイント(インターフェイス型) |
| SNS+FIFOキューで順序保証したい | FIFO SNSトピック+FIFO SQSキュー |
AWSでの実践的な設計・構築スキルをさらに深めたい方はこちらも参考にしてほしい。
>> AWSの設計・構築を体系的に学ぶ(詳細はこちら)
>> AWSをはじめて学ぶ方はこちら(入門LP)
AWS SQSとSNSの使い分けを「なぜこの設計か」まで説明できる力は、Linuxサーバー構築の「型」から生まれます
クラウドのマネジメントサービスを使いこなせても、「なぜこの構成にするか」を説明できるかどうかで現場での信頼が変わります。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 前のページへ:AWS LambdaとEventBridgeでEC2運用を自動化する方法|夜間自動停止・スナップショット取得のサーバーレス設計
- この記事の属するカテゴリ:AWS(Amazon Linux)へ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます