AWS SQSのFIFOキューを試してみた

# 背景

2018年11月にAWSの東京リージョンで、SQS(Simple Queue Service)のFIFOキューを作成できることになったので、試しに使ってみた。
今までのキューはアプリ側でSQSの特徴をカバーして上げる必要があったからちょっと困ったちゃんだった。

# FIFOキューとは？

標準キューとの大きな違いは

* メッセージを　first in first out　で処理する
* メッセージは1回だけ配信される（重複がない）

って感じですかね。
[詳しくは公式さんで](https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html)

# 使ってみた

## SQSでキューを作成する

と言っても、ちょー簡単なので割愛します。（新幹線のチケット買うより簡単・・・）
基本はそのままで使えるのですが、標準キュート違う設定が必要なところだけ説明します。

**キュー名の最後には```.fifo```が必要**

|<img width="1602" alt="queue_name.png" src="https://qiita-image-store.s3.amazonaws.com/0/198158/d737cf37-06c7-4092-359d-142e21e62e30.png">|
|:-:|

**コンテンツに基づく重複排除のチェックボックスをONにする**
ONにしておかないとメッセージ登録に失敗します。

|<img width="1563" alt="duprication.png" src="https://qiita-image-store.s3.amazonaws.com/0/198158/47423040-6fd0-b926-eb14-b34d15c6b426.png">|
|:-:|

## aws-sdkを使ってメッセージ登録する

今回はrubyのaws-sdkを使用してメッセージ登録を行いました。
特に言語は気にしませんが、大量に登録したかっただけ。

```ruby:send_message.rb
require 'aws-sdk'
sqs = Aws::SQS::Client.new(
    region: 'ap-northeast-1', # 東京リージョン
    access_key_id: 'access_key_id',
    secret_access_key: 'secret_access_key',
    )
url = 'url' # FIFOキューのURL(マネージメントコンソールで確認するやつ)
for num in 1..1000 do
  response = sqs.send_message({
    queue_url: url,
    message_body: 'standard queue message ' + num.to_s, # 登録した順番がわかるようにナンバリング
    message_attributes: { # message_attributesは特にこだわらない
      'Title' => {
       string_value: 'title',
       data_type: 'String'
      },
      'Author' => {
        string_value: 'author',
        data_type: 'String'
      },
      'WeeksOn' => {
        string_value: '6',
        data_type: 'Number'
      }
    },
    message_group_id: 'b-group', # 標準キュート違ってmessage_group_idが必須
  })
end
```

標準キューの場合との違いは```message_group_id```が必須だということです。
message_group_idに基づいて順序性を保ってくれるらしいですね。
複数のホストからメッセージを登録するときは、message_group_idを設定する必要がありそうです。

## キューメッセージを取得する

1000件のメッセージを取得してみます。
これもaws-sdkで取得します。

```ruby:receive_message.rb
require 'aws-sdk'
sqs = Aws::SQS::Client.new(
    region: 'ap-northeast-1', # 東京リージョン
    access_key_id: 'access_key_id',
    secret_access_key: 'secret_access_key',
    )
url = 'url' # FIFOキューのURL(マネージメントコンソールで確認するやつ)
loop do
  # メッセージ受信
  res = sqs.receive_message(queue_url: url,
      max_number_of_messages: 1,
      visibility_timeout: 60,
      wait_time_seconds: 1)
  # 0件だったらループから抜ける
  break if !res || !res.respond_to?(:messages) || res.messages.count.zero?
  # メッセージ出力
  puts res.messages[0].body 
  # メッセージ削除
  handle = res.messages[0].receipt_handle
  delete_res = sqs.delete_message({
    queue_url: url,
    receipt_handle: handle,
  })
end
```

こちらは標準キューとやることは変わりませんね。
```message_group_id```を指定する方法とかあるのかな？ないのかな？

ということで、結果はこちら

```sh:
standard queue message 1
standard queue message 2
standard queue message 3
・
・
・
standard queue message 998
standard queue message 999
standard queue message 1000
```

このように登録した順番で取得できることがわかります。

※標準キューの場合は順序性が保たれないことからこんな感じです。

```sh:
standard queue message 6
standard queue message 5
standard queue message 9
・
・
・
standard queue message 998
standard queue message 995
standard queue message 999
```

#　感想
今までは標準キューのみだったから、順序性が保たれないという点をアプリ側の機能でカバーしていた。（順序性が大事なデータや計算があったから。だいたい重要だよねって話もあるよねｗ）
FIFOキューが東京リージョンにきて素直に嬉しいと思ったし、標準キューと同じように使えるのはすごい良かった！
あとはFIFOキューに移行するってした時の影響範囲調査か・・・（つらたん）