[アップデート] Amazon SQS で AWS JSON プロトコルがプレビューとして利用出来るようになったので何が変わるのかを確認してみた

2023.07.29

いわさです。

今朝、Amazon SQS に関する次のアナウンスがありました。

「なんだかよくわからないがパフォーマンスが向上するのか?」という感じだったので、少し掘り下げてみてみました。

AWS JSON プロトコルに Amazon SQS の API が対応した(プレビュー)

上記のアナウンスに色々書いてあるのですが、変更点としては SQS を AWS API 経由で呼び出す際に、従来の方法(クエリプロトコル)の他に、AWS JSON プロトコルと呼ばれる形式もサポートとしたよという点があります。

この形式を使うことで HTTP 経由で API を呼び出す際のリクエストとレスポンスの形式がより効率的な形式になり、処理レイテンシーの削減やクライアントのリソース使用量の削減が期待出来るようです。

なお、AWS JSON 1.0 protocol に関しての詳細情報は以下がドキュメントとなっています。

AWS JSON プロトコルを体験してみた

やはりよくわからんので cURL を叩いてみるしかない。
SQS の標準キューを作成し、そこにメッセージを送信してみましょう。

普段 SDK や CLI 経由で AWS の API が HTTP 経由で呼び出されているわけですが、これを生で呼び出す場合は色々と面倒です。特に署名が。
そこで、今回は awscurl を使わせてもらいましょう。

従来のリクエスト・レスポンス

SQS での従来形式での API の使用方法は次のドキュメントに記載されています。

リクエスト時にはapplication/x-www-form-urlencoded形式でデータを送信し、XML 形式でレスポンスを受信しています。
実際に試してみると次のようになります。

% awscurl "https://sqs.ap-northeast-1.amazonaws.com/123456789012/hoge0729json" \          
-X POST \
--service sqs \          
--region ap-northeast-1 \                                             
-H "Content-Type: application/x-www-form-urlencoded" \                             
-d "Action=SendMessage&MessageBody=hoge111&Version=2012-11-05" | xmllint --format -
<?xml version="1.0"?>
<SendMessageResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
  <SendMessageResult>
    <MessageId>406a7de3-b9b6-4cb0-be39-52ebd8786090</MessageId>
    <MD5OfMessageBody>e0a085c1cc8a35b521d5ed2e59f2c4ee</MD5OfMessageBody>
  </SendMessageResult>
  <ResponseMetadata>
    <RequestId>a2c12efc-49b3-5468-9694-73c2269a589e</RequestId>
  </ResponseMetadata>
</SendMessageResponse>

なるほど、SDK からメッセージ送信した際のリクエスト・レスポンスはこのような感じになっていたのか。

レスポンスのメッセージ ID でメッセージが送信されていることがコンソールからも確認出来ました。

AWS JSON プロトコルでのリクエスト・レスポンス

SQS での AWS JSON プロトコルの仕様は次のドキュメントに記載されています。
アナウンスにも記載がありますが、「プレビュー」という点に注意が必要です。ドキュメントにも記載されていますね。

リクエストもレスポンスも JSON です。
ちょっと手間取ったのですが、実際に使ってみると次のような感じです。

% awscurl "https://sqs.ap-northeast-1.amazonaws.com/" \
-X POST \
--service sqs \
--region ap-northeast-1 \
-H "X-Amz-Target: AmazonSQS.SendMessage" \
-H "Content-Type: application/x-amz-json-1.0" \
-d '{"QueueUrl": "https://sqs.ap-northeast-1.amazonaws.com/123456789012/hoge0729json", "MessageBody": "hoge222"}' | jq
{
  "MD5OfMessageBody": "ec7a95f6d49f691c3232cdc3cedb8f87",
  "MessageId": "9a4965cc-4c49-42ce-91a2-c56c0090c621"
}

こちらもレスポンスのメッセージ ID でメッセージが送信されていることがコンソールからも確認出来ました。

このようにリクエストとレスポンスの形式が変わるので、サイズが小さくなってよりレイテンシーが改善され、それぞれ発生するシリアライズ・逆シリアライズ処理も効率的になりクライアントパフォーマンスが向上するということを、アップデートアナウンスで言っているようですね。

AWS SDK のバージョンアップで自動適用される

実際のところ、AWS API に直接 HTTP リクエストを送信するシーンはそう多く無いのではと思います。
通常は AWS CLI あるいは AWS SDK を使用することが大半ではないでしょうか。

AWS SDK 側で AWS JSON プロトコルを使ってリクエストとレスポンスを処理するためにはどうしたら良いのか、ですが特定バージョンで自動適用されるようです。
アプリケーションコードの変更は不要で、AWS SDK 側で吸収してくれます。

SDK 別の対応バージョンは次のドキュメントにて記載されています。

例えば、.NET だと3.7.540.0以上に AWS SDK をバージョンアップすることで、自動で AWS JSON プロトコルが SQS クライアントで使用されるようになるということです。
ただし、.NET SDK の場合だと NuGet の最新版は本日時点で3.7.200.7なので、パッケージマネージャ以外から導入が必要そうです。
このあたりの対応状況はランタイムごとに違っていそうなので、個別にご確認頂いたほうが良いです。

また、「既存のプロトコル使えなくなるのか?アップデート必須か?」というところも気になると思いますが、従来方式も引き続きサポートされるので廃止はされないそうです。
ただし、今後は AWS JSON プロトコルが AWS SDK のデフォルトになるしパフォーマンス上がるだろうから切り替え(SDK のアップグレード)が推奨されています。

まだプレビューということもあって品質面など気になるところですが、上記の FAQ ドキュメント上ではテスト環境での事前テストは推奨されていますが、本番環境でも使用可能との記述があります。
テストの観点としては、AWS SDK を使わずにカスタムクライアントで呼び出していたり、手を加えたカスタム SDK を使っている場合は特に注意が必要です。
HTTP レイヤーでのレスポンス形式などが変わっているため、そのあたりに介入する処理を行っている場合は気をつける必要がありそうです。
.NET だと HttpHandler あたりでリクエストやレスポンスにカスタム処理で SDK に介入しようとしていたりすると、ちょっと影響ありそうですね。

なお SDK 側の具体的な変更点としては、このあたりのコミットを眺めてみると、把握出来ます。

さいごに

本日は Amazon SQS で AWS JSON プロトコルがプレビューとして利用出来るようになったので何が変わるのかを確認してみました。

あまり意識するところではないですが、SDK を介して実際にリクエストしている内容、受信するレスポンス内容が特定バージョンから変わるということで知っておくと良さそうなのと、アプリケーション側で特殊な実装をしている場合は影響が出る可能性もあるので、事前テストが推奨されていますので覚えておきましょう。

プレビューという点が少し気になりますが、GitHub を眺めた限りではapplication/x-amz-json-xx自体は SQS 以外でも既に使用されているようなので「やはり従来形式に戻しました」となる可能性自体は低そうです。