#Background
現在、とあるベンダー製品の運用をしている。そのベンダー製品というのが、今どき珍しく、single instanceでしか動かないという仕様で、そのくせにトラブりまくるという感じである。そのトラブルに対応するために、threaddumpやらheapdumpやら、自動再起動などの、様々な運用を自動化するスクリプトをたくさん作って対応していた
そうしたら、最近になって複数台構成にできるようにアップデートしてきた。自動化スクリプト群はsingle instance用に書かれているものばかりなので、複数台での運用の自動化の際に、それぞれが持っているsingle instance用のスクリプトを、なんらかのコマンドで同時に叩く、ということをしたかった。
#Serf
そこでSerfさんですよ。Serfをつかって、eventが送られた際に、任意のスクリプトをすべてのサーバで叩くという構成をつくった。
#serf-handler.sh
#!/bin/sh
HANDLER_DIR="/path/to/scripts"
if [ "$SERF_EVENT" = "user" ]; then
EVENT="tarr-$SERF_USER_EVENT"
elif [ "$SERF_EVENT" = "query" ]; then
case ${SERF_QUERY_NAME} in
"uptime")
uptime;;
* )
EVENT="tarr-$SERF_QUERY_NAME";;
esac
else
EVENT=$SERF_EVENT
fi
HANDLER="$HANDLER_DIR/$EVENT"
[ -f "$HANDLER" -a -x "$HANDLER" ] && exec "$HANDLER" || :
/path/to/scripts/
というdirectoryに自動化スクリプトが置かれていて、prefixがtarr-
になっている。例えば、tarr-autosnapshot.sh
のような感じだ。serfのイベントがきたら、ここのスクリプトを叩けるようにした。
#agentの起動
$ /path/to/serf/serf agent -node=cdc-node1 -bind=xxx.xxx.64.7 -event-handler=/path/to/scripts/serf-handler.sh > /path/to/serf/log/serf.log.`date +%Y%m%d%H%M%S` 2>&1 &
[1] 6118
$ /path/to/serf/serf agent -node=cdc-node2 -bind=xxx.xxx.64.8 -event-handler=/path/to/scripts/serf-handler.sh > /path/to/serf/log/serf.log.`date +%Y%m%d%H%M%S` 2>&1 &
[1] 27281
こんな感じで、必要なサーバでそれぞれ立ち上げていく。その後、joinしておく。
$ ./serf members
cdc-node1 xxx.xxx.64.7:7946 alive
$ ./serf join xxx.xxx.64.8
Successfully joined cluster by contacting 1 nodes.
$ ./serf members
cdc-node1 xxx.xxx.64.7:7946 alive
cdc-node2 xxx.xxx.64.8:7946 alive
event/queryの発行
好きなサーバに入って、serfにイベントを発行したら、すべてのサーバに伝播されて、スクリプトが実行される。
$ ./serf query status
Query 'status' dispatched
Ack from 'cdc-node1'
Response from 'cdc-node1': hogehoge201: alive: 19304
Ack from 'cdc-node2'
Response from 'cdc-node2': hogehoge202: alive: 13417
Total Acks: 2
Total Responses: 2
応答時間の短いスクリプトは、queryで投げると結果が帰ってきて便利。
$ ./serf event threaddump-long
Event 'threaddump-long' dispatched! Coalescing enabled: true
裏で長時間動くようなスクリプトはeventとして発行する。これで、これまで一台構成用に動かしていた自動化スクリプトを複数台でも動くようにできた。