どうも、AWS で好きなサービスは SQS と言いたいけど、言える程に修行が足りてないかっぱ@inokara)です。

はじめに

fluentd にログを捌かせる仕事ではなく Amazon SQS の Consumer として利用してみたいと思います。そして、メッセージがキューインされたことをトリガーにしてインスタンス上の Apache を起動してみたいと思います。


やりたいこと

  1. Amazon SQS のキューにメッセージをキューイング(今回は Amazon SNS から通知)
  2. fluentd + fluent-plugin-sqs でキューをポーリング
  3. キューにメッセージがあったら out_exec で別のコマンドを実行( Apache を起動する)

以下、動作イメージです。

01


設定

Amazon SQS

とりあえずキューを作っておきましょう。

02

fluentd + fluent-plugin-sqs

尚、設定は全て fluentd-ui から設定しています。

fluentd

fluentd-ui からさくっとインストールしてみます。

fluent-plugin-sqs

fluentd から SQS を扱う fluent-plugin-sqs をインストールしてます。fluentd-ui ならプラグインのインストールも簡単ですね。

03

fluent-plugin-sqs に必要な設定は下記の通りです。

<source>
  type sqs
  aws_key_id AKxxxxxxxxxxxxxxxxxx
  aws_sec_key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  sqs_url https://sqs.ap-northeast-1.amazonaws.com/123456789012/xxxxxxxxxxxx
  sqs_endpoint sqs.ap-northeast-1.amazonaws.com
  receive_interval 60
  tag hogehuga
</source>

メッセージが存在していたら hogehuga タグをつけて exec アウトプットプラグインに渡します。

exec アウトプットプラグインの設定

exec アウトプットプラグインを利用してキューにメッセージが存在していたら command で指定されたスクリプトを実行するように設定します。

04

以下、コピペ用。

<match hogehuga>
  type copy
  <store>
    type file
    path /tmp/sqs
  </store>
  <store>
    type exec
    command /usr/bin/ruby /opt/bin/test.rb
    format json
    buffer_path /tmp/exec_filter
    tag_key result
    log_level debug
    flush_interval 5s
  </store>
</match>

exec アウトプットプラグインから利用するスクリプト

スクリプトはとっても簡単。スクリプト内でシステムコマンドを実行して結果を /tmp/script.log に書いています。

test.rb
#!/usr/bin/ruby

output = `/usr/bin/sudo /etc/init.d/httpd start`
open("/tmp/hoge.txt","w"){|f|
  f.write output
}

尚、exec アウトプットプラグインについては以下のサイトが参考になりました。

sudo の設定変更

残念ながら Amazon Linux では(他の OS やディストーションでも)sudo を利用する場合には tty が必要となるようでして、上記のスクリプトをexec アウトプットプラグインから実行させることが出来ませんでした。ということで /etc/sudoers を以下のように修正しました。

--- sudoers.original    2014-08-04 14:54:24.715511653 +0000
+++ sudoers     2014-08-04 14:54:00.307926083 +0000
@@ -53,7 +53,7 @@
 # Disable "ssh hostname sudo <cmd>", because it will show the password in clear.
 #         You have to run "ssh -t hostname sudo <cmd>".
 #
-Defaults    requiretty
+#Defaults    requiretty

 #
 # Refuse to run if unable to disable echo on the tty. This setting should also be gz_log = 

やってみる

CLI でキューイン

AWS CLI で SQS にメッセージを送ってみましょう。

aws sqs send-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxx/hoge-test --message-body 'apache start'

以下のように出力される。

{
    "MD5OfMessageBody": "1fae1672eff635e11c40fb8f48975b1e",
    "MessageId": "18e9e559-9612-4d6b-b68e-bc6bdce3d922"
}

fluent-plugin-sqs は初期設定ではキューを 1 秒毎にポーリングしていますが、今回は receive_interval 60 としているので 60 秒毎にポーリングします…と言っても…ほぼ間髪入れずに…。

結果を見守る

暫くすると test.rb に書かれている通り /tmp/hoge.txt には以下のように Apache 起動の文字。

05

プロセスも恐る恐る確認してみる。

06

Apache が起動しました。


まとめ(まとまってないけど)

  • SQS と fluentd を組み合わせることでキューによる非同期処理が出来ることを確認しました
  • fluentd に Consumer 的な動きをさせる意味があるか?と問いに関しては、最近ではデフォルトで fluentd はインストールする状況においては敢えて Consumer 的な動きをするツールを自作したり導入する手間は省けます
  • fluentd-ui を使えばデバッグも Web ブラウザ経由で出来て捗りました
  • 但し、sudo の設定を修正しなければいけないなど実際の導入に際しては検討が必要です
  • また、exec アウトプットプラグインから実行するスクリプトのデバッグ方法をよく解ってないので苦労しました…
  • キューインされたメッセージを解析して処理を分けるようなこともしてみたいと思います

元記事は、こちら