前書き
NATSは、オープンソースの高性能メッセージングシステムであり、「クラウドの中枢神経系」と呼ばれることがよくあります。 毎秒数百万のメッセージをルーティングできるため、マイクロサービスとIoT(モノのインターネット)デバイスの接続に最適です。
NATSはPubSub messaging systemです。 この種のシステムでは、1つ以上のpublishersが特定の件名のメッセージをmessage brokerに送信し、メッセージブローカーはこれらのメッセージを任意のクライアントまたは特定の件名のsubscribersに配信します。 パブリッシャーはサブスクライバーを知りませんし、気にしません。その逆も同様です。 このアーキテクチャにより、システムの残りの部分に影響を与えることなくパブリッシャーとサブスクライバーを追加できるため、システムのスケーリングと新しい機能の追加が容易になります。 このタイプのシステムは、サーバーとデバイスの監視に最適です。デバイスはメッセージを送信でき、電子メールまたはその他の手段で通知を送信するためにそれらのメッセージを購読できます。
このチュートリアルでは、公式のNATSサーバーであるgnatsd
をサービスとしてインストールし、安全な方法でアクセスできるようにします。 また、gnatsd
をメッセージブローカーとして使用して、サーバーの負荷が高くなりすぎたときに電子メールを送信する基本的なサーバー過負荷警告システムを作成します。
前提条件
このチュートリアルを完了するには、次のものが必要です。
-
新しいUbuntu 16.04サーバー。
-
sudo
権限を持つ標準ユーザーアカウント。 Initial Server Setup with Ubuntu 16.04に従うことで、標準アカウントを設定できます。
[[step-1 -—- downloading-the-nats-server]] ==ステップ1—NATSサーバーのダウンロード
まず、gnatsd
サーバーをダウンロードして、問題なくシステム上で実行できることを確認しましょう。
このチュートリアルが書かれた時点での最新の安定したgnatsd
リリースはバージョン0.9.4です。 新しいバージョンを使用する場合は、the NATS download pageで新しいバージョンを確認し、必要に応じて以下のコマンドを適用できます。
最初に、非ルートアカウントでサーバーにログインします。
ssh sammy@your_server_ip
次に、ユーザーのホームディレクトリにいることを確認します。
cd
次に、wget
を使用してgnatsd
をサーバーにダウンロードします。
wget https://github.com/nats-io/gnatsd/releases/download/v0.9.4/gnatsd-v0.9.4-linux-amd64.zip
ダウンロードしたアーカイブは圧縮アーカイブであるため、ファイルを抽出するにはunzip
をインストールする必要があります。 apt
でインストールできます:
sudo apt-get install -y unzip
次に、unzip
を使用してgnatsd
を抽出します。
unzip -p gnatsd-v0.9.4-linux-amd64.zip gnatsd-v0.9.4-linux-amd64/gnatsd > gnatsd
次に、gnatsd
を実行可能にして、実行できるようにします。
chmod +x gnatsd
現在のディレクトリから実行することでgnatsd
を実行できることをテストしてみましょう。 次のコマンドを使用して、gnatsd
を開始します。
./gnatsd --addr 127.0.0.1 --port 4222
表示される出力は、次の例のようになります。
Output[1851] 2016/09/23 05:20:02.247420 [INF] Starting nats-server version 0.9.4
[1851] 2016/09/23 05:20:02.248182 [INF] Listening for client connections on 127.0.0.1:4222
[1851] 2016/09/23 05:20:02.248626 [INF] Server is ready
デフォルトでは、gnatsd
は、すべてのインターフェイスに対応するアドレス0.0.0.0
のポート4222
でリッスンします。 --port
引数を使用すると、ポートを変更でき、--addr
を使用すると、リッスンするアドレスを変更できます。 gnatsd
を--addr 127.0.0.1
で実行したため、サーバー内でのみ使用可能であり、外部クライアントからはアクセスできません。 チュートリアルの後半で、gnatsd
を保護し、それを世界に公開します。
CTRL+C
を押して、gnatsd
をシャットダウンします。
動作することがわかったので、より正式な方法で設定してみましょう。
[[step-2 -—- createing-the-directory-structure-and-configuration-file]] ==ステップ2—ディレクトリ構造と構成ファイルの作成
Linuxでは、サードパーティのサービス関連ソフトウェアが/srv
ディレクトリに保存されることがよくあります。 その規則に従い、NATS関連のファイルを/srv/nats
未満に保ちます。 gnatsd
実行可能ファイルを/srv/nats/bin
に配置します。
まず、/srv/nats/bin
フォルダーを作成します。
sudo mkdir -p /srv/nats/bin
次に、gnatsd
を/srv/nats/bin
フォルダーに移動します。
sudo mv ~/gnatsd /srv/nats/bin
サーバーは、その構成をファイルからロードできます。これは、チュートリアルの後半でサーバー設定を変更する必要がある場合に便利です。 ファイル/srv/nats/gnatsd.config
を作成します。
sudo nano /srv/nats/gnatsd.config
そして、次の内容をファイルに追加します。
/srv/nats/gnatsd.config
port: 4222
net: '127.0.0.1'
この構成ファイルは、以前と同様に、gnatsd
サーバーにアドレス127.0.0.1
のポート4222
でリッスンするように指示しますが、今回はコマンドラインでこれらのオプションを指定する必要はありません。
サーバーを再度実行して、設定が正しいことを確認します。 次のコマンドを実行して、新しい構成ファイルを使用してgnatsd
を起動します。
/srv/nats/bin/gnatsd -c /srv/nats/gnatsd.config
出力は、前に見たものに似ています。
Output[1869] 2016/06/18 05:30:55.988856 [INF] Starting nats-server version 0.9.4
[1869] 2016/06/18 05:30:55.989190 [INF] Listening for client connections on 127.0.0.1:4222
[1869] 2016/06/18 05:30:55.989562 [INF] Server is ready
もう一度、CTRL+C
を押してgnatsd
をシャットダウンし、プロンプトに戻ります。 次に、このサービスを実行するユーザーを作成しましょう。
[[step-3 -—- creating-the-service-user]] ==ステップ3—サービスユーザーの作成
サービスが侵害された場合の損害を制限するために、独自のユーザーアカウントで各サービスを実行することは、セキュリティ上の良い習慣です。 NATSサービスとNATS関連のファイルを所有するユーザーとグループを作成しましょう。
まず、nats
というシステムユーザーとグループを作成しましょう。
sudo adduser --system --group --no-create-home --shell /bin/false nats
OutputAdding system user `nats' (UID 106) ...
Adding new group `nats' (GID 114) ...
Adding new user `nats' (UID 106) with group `nats' ...
Not creating home directory `/home/nats'.
/bin/false
シェルをnats
システムユーザーに割り当てて、このユーザーのログインを無効にし、ホームディレクトリの作成を抑制しました。 また、nats
グループを作成しました。
/srv
ディレクトリの所有者をnats
ユーザーとグループに変更しましょう。
sudo chown -R nats:nats /srv
nats
ユーザーとグループを作成したので、NATSサービスの作成を続けましょう。
[[step-4 -—- running-gnatsd-as-a-service]] ==ステップ4—gnatsdをサービスとして実行する
システムの起動時にgnatsd
を開始し、クラッシュした場合は再起動します。 これを処理するためにsystemdを使用します。
systemdは、Linuxシステムのサービスマネージャーです。 起動時にサービスを開始し、必要に応じてサービスを再起動し、システムのシャットダウン時に制御された方法でサービスを停止します。
NATSサービスをいつどのように開始するかを定義するために、service configurationを作成する必要があります。 ユーザーが作成したサービスファイルは/etc/systemd/system
にあるため、ファイル/etc/systemd/system/nats.service
を作成します。
sudo nano /etc/systemd/system/nats.service
そして、ファイルに次のスクリプトを配置して、gnatsd
の起動方法を定義します。
/etc/systemd/system/nats.service
[Unit]
Description=NATS messaging server
[Service]
ExecStart=/srv/nats/bin/gnatsd -c /srv/nats/gnatsd.config
User=nats
Restart=on-failure
[Install]
WantedBy=multi-user.target
-
[Unit]
セクションには、サービスを説明するDescription
など、サービスに関する一般的な情報が含まれています。 -
[Service]
セクションには、サービス関連の構成が含まれています。ExecStart
は、サーバーを実行するためのコマンドです。 ここでは、gnatsd
実行可能ファイルの絶対パスを使用します。Restart=on-failure
は、サービスがクラッシュしたり、失敗して終了したりした場合に、サービスを再起動する必要があることを意味します。 systemdによって停止された場合、再起動されません。 -
[Install]
セクションには、サービスに関するインストール情報が含まれています。WantedBy=multi-user.target
は、multi-user.target
の開始時にサービスを開始するようにsystemdに指示します。 これは、システム起動時にサービスを開始する一般的な方法です。
サービスの説明を作成したら、次のコマンドで開始できます。
sudo systemctl start nats
PING
メッセージを送信して、gnatsd
が実行されていることを確認しましょう。
printf "PING\r\n" | nc 127.0.0.1 4222
gnatsd
と通信するためにnc
を使用しました。 nc
は、TCPまたはUDPサーバーと通信するためのコマンドラインユーティリティです。 使用したコマンドは、次のような出力を出力します。
OutputINFO {"server_id":"Os7xI5uGlYFJfLlfo1vHox","version":"0.9.4","go":"go1.6.3","host":"127.0.0.1","port":4222,"auth_required":false,"ssl_required":false,"tls_required":false,"tls_verify":false,"max_payload":1048576}
PONG
応答PONG
は、サーバーが期待どおりにリッスンして動作していることを示します。 NATSサーバーをブート時に起動するには、最後の1つのコマンドを実行する必要があります。
sudo systemctl enable nats
サービスがインストールされたことを確認する次の出力が表示されます。
OutputCreated symlink from /etc/systemd/system/multi-user.target.wants/nats.service to /etc/systemd/system/nats.service.
gnatsd
をサービスとして実行するように正常に構成しました。 次に、セキュリティを確保して、外部クライアントがアクセスできるようにします。
[[step-5 -—- securing-connections-to-the-nats-service]] ==ステップ5—NATSサービスへの接続の保護
gnatsd
で使用するすべてのパブリッシャーとサブスクライバーが同じサーバーで実行されている場合、それを完了と呼んで先に進むことができますが、最近はめったにありません。 外部クライアントが安全な方法でgnatsd
に接続してメッセージを公開できるようにする必要があります。
gnatsd
はTLSトランスポートをサポートしているため、これを使用してgnatsd
とNATSクライアント間の通信を保護します。
まず、証明書が必要です。 商用証明書を購入するか、Let’s Encryptから証明書を取得するか、自己署名証明書を生成できます。 証明書の取得はこの記事の範囲外であるため、後者のアプローチを使用します。
証明書を一時的に保持するディレクトリを作成します。
mkdir ~/priv
次に、次のコマンドで自己署名証明書を作成します。
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout priv/gnatsd.key -out priv/gnatsd.crt \
-subj "/C=US/ST=Texas/L=Austin/O=AwesomeThings/CN=www.example.com"
このコマンドは、2048ビットで有効期間が10年のRSA証明書を作成します。 この記事ではgnatsd
サーバーのTLS検証を有効にしないため、任意のドメイン名を使用していることに注意してください。
これで、ファイルgnatsd.key
とgnatsd.crt
が~/priv
ディレクトリにあるはずです。 これらのファイルを/srv/nats/
ディレクトリ構造の下に移動して、すべてが1か所にあるようにします。 次のコマンドを実行してください。
sudo mv ~/priv /srv/nats
ここで、nats
のユーザーとグループだけが/srv/nats/priv
にアクセスできるようにします。
sudo chmod 440 /srv/nats/priv/*
sudo chmod 550 /srv/nats/priv
sudo chown -R nats:nats /srv/nats/priv
次に、/srv/nats/gnatsd.config
を更新して、作成したばかりの証明書とキーを含めます。 構成ファイルを再度開きます。
sudo nano /srv/nats/gnatsd.config
そして、次のセクションを追加して、gnatsd
に証明書とキーを使用するように指示します。
/srv/nats/gnatsd.config
. . .
tls {
cert_file: "/srv/nats/priv/gnatsd.crt"
key_file: "/srv/nats/priv/gnatsd.key"
timeout: 1
}
ファイルを保存し、エディターを終了します。 次に、サービスを再起動して、変更を反映できるようにします。
sudo systemctl restart nats
証明書が機能することをテストしてみましょう。 このコマンドを実行してください。
printf "PING\r\n" | nc localhost 4222
今回、コマンドは次のメッセージを出力します。
OutputINFO {"server_id":"npkIPrCE5Kp8O3v1EfV8dz","version":"0.9.4","go":"go1.6.3","host":"127.0.0.1","port":4222,"auth_required":false,"ssl_required":true,"tls_required":true,"tls_verify":false,"max_payload":1048576}
-ERR 'Secure Connection - TLS Required'
サーバーは、新しい構成が取得され、安全な接続が必要であることを確認するメッセージ-ERR 'Secure Connection - TLS Required'
を返しましたが、nc
はその方法を知りません。
本格的なNATSクライアントをインストールせずにNATSサービスと通信できるようにするために、catnatsというツールを使用します。 最初にダウンロードしましょう:
wget https://github.com/yuce/catnats/raw/0.1.2/catnats.py
実行可能にします。
chmod +x catnats.py
最後に、catnats.py
を/srv/nats/bin
フォルダーに移動し、名前をcatnats
に変更します。
sudo mv catnats.py /srv/nats/bin/catnats
以前に送信したものと同じPING
メッセージを送信して、catnats
を使用してNATSサービスと通信できることを確認しましょう。
printf "PING\r\n" | /srv/nats/bin/catnats --addr 127.0.0.1:4222
接続が安全であることを示す次の出力が表示されます。
OutputINFO {"server_id":"npkIPrCE5Kp8O3v1EfV8dz","version":"0.9.4","go":"go1.6.3","host":"127.0.0.1","port":4222,"auth_required":false,"ssl_required":true,"tls_required":true,"tls_verify":false,"max_payload":1048576}
PONG
通信を保護したので、認証を有効にして、NATSへの接続にユーザー名とパスワードが必要になるようにします。
[[step-6 -—- requiring-authentication]] ==ステップ6—認証を要求する
NATSサービスはデフォルトで認証を必要としません。 これは、サービスがプライベートネットワークでのみアクセス可能な場合は問題ありませんが、認証を有効にする必要があるため、インターネットでNATSサービスにアクセスできるようにする必要があります。 gnatsd
はユーザー名とパスワードの認証をサポートしており、簡単に有効にできます。
/srv/nats/gnatsd.config
ファイルを開きます。
sudo nano /srv/nats/gnatsd.config
資格情報を指定する新しいauthorization
セクションを追加します。 このチュートリアルでは、ユーザー名としてuser1
を使用し、パスワードとしてpass1
を使用します。 実稼働環境では、より長く複雑なパスワードを使用する必要があります。
/srv/nats/gnatsd.config
. . .
authorization {
user: user1
password: pass1
}
ファイルを保存してから、/srv/nats/gnatsd.config
の所有者をnats
に変更し、システム上の他のユーザーからユーザー名とパスワードを保護するために、そのユーザーが読み取れるようにします。
sudo chown nats /srv/nats/gnatsd.config
sudo chmod 400 /srv/nats/gnatsd.config
次に、変更を有効にするためにサービスを再起動します。
sudo systemctl restart nats
PING
メッセージをgnatsd
に送信して、すべてが正常かどうかを確認しましょう。 もう一度、catnats
を使用してメッセージを送信します。
printf "PING\r\n" | /srv/nats/bin/catnats --addr 127.0.0.1:4222
次の出力が表示されます。
OutputNFO {"server_id":"sY0SSJBNbEw53HxzS9mH1t","version":"0.9.4","go":"go1.6.3","host":"127.0.0.1","port":4222,"auth_required":true,"ssl_required":true,"tls_required":true,"tls_verify":false,"max_payload":1048576}
-ERR 'Authorization Violation'
これにより、変更が正常に適用され、サービスに接続するために正しいユーザー名とパスワードを送信する必要があることがわかります。 もう一度試してみましょう。今回は、ユーザー名user1
とパスワードpass1
を指定します。
printf "PING\r\n" | /srv/nats/bin/catnats --addr 127.0.0.1:4222 --user user1 --pass pass1
今回は、次の出力からわかるように機能しました。
OutputINFO {"server_id":"sY0SSJBNbEw53HxzS9mH1t","version":"0.9.4","go":"go1.6.3","host":"127.0.0.1","port":4222,"auth_required":true,"ssl_required":true,"tls_required":true,"tls_verify":false,"max_payload":1048576}
+OK
PONG
ユーザー名とパスワードを知っているクライアントにこのサービスを制限したので、外部クライアントが接続できるようにサービスを再構成できます。
[[step-7 --- open-the-service-to-the-world]] ==ステップ7—サービスを世界に開く
ローカルインターフェースである127.0.0.1
をリッスンするようにNATSサーバーを構成しました。 0.0.0.0
でリッスンさせると、世界中で利用できるようになります。 最後にもう一度/srv/nats/gnatsd.config
を更新しましょう。
sudo nano /srv/nats/gnatsd.config
次に、net
設定に関連付けられているIPアドレスを変更します。
/srv/nats/gnatsd.config
. . .
net: '0.0.0.0'
. . .
ファイルを保存して、サービスを再起動します。
sudo systemctl restart nats
これで、NATSサービスは外部クライアント接続の準備ができました。 使い方を学ぶために、NATSサーバーをメッセージブローカーとして使用する簡単な監視サービスを作成しましょう。
[[step-8 -—- optional-configuring-notifications-on-server-overload]] ==ステップ8—(オプション)サーバーの過負荷に関する通知の構成
このセクションでは、NATSサービスを利用する簡単な過負荷監視システムを作成します。 システムは、サーバーの平均負荷を受け取り、サーバーのいずれかが過負荷になった場合に管理者にメールを送信します。
サンプルプロジェクトは、次のコンポーネントで構成されます。
-
構成したばかりのNATSサービス。
-
monitorは、サーバーのホスト名、負荷平均、およびプロセッサー数を60秒ごとに
stats.loadaverage
サブジェクトに公開します。 負荷を監視するサーバーでこのコンポーネントを実行する必要があります。 -
stats.loadaverage
サブジェクトにサブスクライブし、サーバーのホスト名、負荷平均、およびプロセッサー数を受け取るnotifier。 ホストの負荷平均が特定のしきい値を超えている場合、通知者はSMTPサーバーを介して事前定義されたアドレスに電子メールを送信します。
簡単にするためにこれらすべてのコンポーネントを同じサーバーで実行しますが、このチュートリアルを完了したら、各サーバーを異なるサーバーで実行してみてください。
モニターのセットアップ
Linuxシステムの平均負荷は/proc/loadavg
から読み取ることができます。 このプロジェクトでは、出力の最初のフィールドである直前の負荷平均のみに関心があります。 この値を取得するには、次のコマンドを使用します。
cat /proc/loadavg | cut -f1 -d" "
次の出力が表示されます。
Output0.11
/proc/loadavg
を読み取ることで得られる負荷平均はプロセッサの数に依存するため、負荷平均をプロセッサの数で割って正規化する必要があります。 次のコマンドを使用して、サーバーのプロセッサカウントを取得できます。
getconf _NPROCESSORS_ONLN
端末に結果が表示されます:
Output1
サーバーのデフォルトシェルは浮動小数点演算を処理できないため、メッセージのペイロードとしてホスト名とともに負荷平均とプロセッサ数の両方を送信し、後で通知機能で分割を行います。 ペイロードを構築するために使用するコマンドは次のとおりです。
echo $(hostname) `cat /proc/loadavg | cut -f1 -d" "` `getconf _NPROCESSORS_ONLN`
このコマンドは、ホスト名、負荷平均、およびプロセッサ数をそれぞれ表示します。
Outputyour_hostname 0.28 1
ホスト名、負荷平均、プロセッサ数を件名stats.loadaverage
でNATSサーバーに公開するシェルスクリプトを作成しましょう。 このスクリプトを定期的に実行するようにシステムを構成します。 ~/publish_load_average.sh
という名前の新しいファイルを作成します。
nano ~/publish_load_average.sh
ファイルに次のスクリプトを追加します。
~/publish_load_average.sh
NATS_ADDR=127.0.0.1:4222
LOADAVG=$(cat /proc/loadavg | cut -f1 -d" ")
NPROC=$(getconf _NPROCESSORS_ONLN)
SUBJECT="stats.loadaverage"
PAYLOAD=$(echo $(hostname) $LOADAVG $NPROC)
MESSAGE="PUB $SUBJECT ${#PAYLOAD}\r\n${PAYLOAD}\r\n"
printf "$MESSAGE" | /srv/nats/bin/catnats -q --raw --addr $NATS_ADDR --user user1 --pass pass1
このスクリプトはメッセージを作成し、それをcatnats
にパイプします。これにより、メッセージがNATSサービスに公開されます。 catnats
を-q
スイッチで実行して出力を抑制し、--raw
スイッチを使用して、catnats
が入力の内容を解釈しようとしないようにします。 NATSサービスが異なるサーバー上にある場合は、$NATS_ADDR
変数の値を変更できます。
スクリプトが負荷平均をNATSに送信することをテストしてみましょう。
次のコマンドは、5秒ごとに~/publish_load_average.sh
を実行します。 行末で&
文字を使用して、バックグラウンドでコマンドを実行することに注意してください。
while true; do sh ~/publish_load_average.sh; sleep 5; done &
コマンドがプロセスIDでバックグラウンドで実行されていることを示す出力が表示されます。
Output[1] 14123
[.note]#Note:後でコマンドを停止するためにIDを使用する必要があるため、プロセスIDをどこかに書き留めます。
#
次に、NATSに接続し、サブジェクトstats.loadaverage
にサブスクライブして、負荷平均を取得します。
printf "SUB stats.loadaverage 0\r\n" | /srv/nats/bin/catnats --raw --no-exit --pong --user user1 --pass pass1
--no-exit
フラグを使用して自動終了を無効にし、--pong
を使用してNATSへの接続を維持します。 すべてが正しい場合、5秒ごとに更新される次のような出力を取得する必要があります。
OutputINFO {"server_id":"A8qJc7mdTy8AWBRhPWACzW","version":"0.8.1","go":"go1.6.2","host":"0.0.0.0","port":4222,"auth_required":true,"ssl_required":true,"tls_required":true,"tls_verify":false,"max_payload":1048576}
+OK
+OK
MSG stats.loadaverage 0 27
your_hostname 0.08 1
CTRL+C
を押して、catnats
を終了します。 publish_load_average.sh
を実行するためのより良い方法があるので、publish_load_average.sh
を呼び出すループも停止しましょう。
kill 14123
私たちが今採用したアプローチはテストには最適ですが、永続的に使用したいものではありません。 システムでpublish_load_average.sh
を実行して毎分実行するようにします。 これを実現するために、crontabエントリを追加できます。 Linuxシステムは、指定したスケジュールでコマンドまたは「ジョブ」を実行できるシステムであるcron
を使用します。 crontab
コマンドを使用すると、これらのジョブを管理できます。 チュートリアルHow To Use Cron To Automate Tasks On a VPSでCronのすべてを学ぶことができます。
新しいエントリを作成するには、次のコマンドを実行します。
crontab -e
上記のコマンドを実行したことがない場合は、次のプロンプトが表示され、エントリを管理するためのテキストエディターを選択するよう求められます。
Outputno crontab for demo - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/ed
2. /bin/nano <---- easiest
3. /usr/bin/vim.basic
4. /usr/bin/vim.tiny
Choose 1-4 [2]:
最も使いやすいエディターに対応する番号を入力し、ENTER
を押します。 選択したエディターにファイルが表示されます。
開いたファイルの最後に次の行を追加しますが、sammy
以外のものを使用した場合は、ユーザー名に置き換えてください。
*/1 * * * * bash /home/sammy/publish_load_average.sh
上記のエントリは、cron
にpublish_load_average.sh
スクリプトを毎分実行するように指示しています。 ファイルを保存し、エディターを閉じます。
次に、負荷平均の定期的な発行が機能していることをテストしてみましょう。
printf "SUB stats.loadaverage 0\r\n" | /srv/nats/bin/catnats --raw --no-exit --pong --user user1 --pass pass1
数分待つと、表示される出力は次のようになります。
OutputINFO {"server_id":"A8qJc7mdTy8AWBRhPWACzW","version":"0.8.1","go":"go1.6.2","host":"0.0.0.0","port":4222,"auth_required":true,"ssl_required":true,"tls_required":true,"tls_verify":false,"max_payload":1048576}
+OK
+OK
MSG stats.loadaverage 0 27
your_hostname 0.01 1
MSG stats.loadaverage 0 27
your_hostname 0.00 1
CTRL+C
を押して、catnats
を終了します。
モニターのセットアップに成功し、NATSサーバーにメッセージを送信しています。 次に、このデータを使用する通知機能を設定します。
Notifierの作成
NATSサービスに接続し、stats.loadaverage
メッセージをリッスンする通知機能を作成しましょう。 プログラムがメッセージを受信するたびに、プロセッサごとの負荷平均を計算します。 0.6またはプロセッサあたり60%のCPU使用率よりも高い場合、メッセージを発行したホストに警告フラグを設定し、事前定義されたアドレスに電子メールを送信します。 プロセッサあたりの負荷平均が0.4未満の場合、ホストの警告フラグはクリアされます。 受信ボックスのフラッディングを防ぐために、警告フラグが設定されている場合は1つのメールを送信します。
Node.js用の優れたNATSクライアントがあるため、Node.JSを使用してノーティファイアを作成します。 そのため、最初にNode.jsをインストールします。
sudo apt-get install -y npm
次に、通知機能のディレクトリを作成し、切り替えます。
mkdir ~/overload_notifier && cd ~/overload_notifier
Node.js projects use a file called package.json
which contains information about the project and its dependencies. 次のコマンドを実行して、そのファイルを作成します。
npm init -y
次に、Node.js用のNATSクライアントと、このプロジェクトで警告メールを送信するために使用するnodemailer
モジュールをインストールします。
npm install [email protected] [email protected] --save-exact
これで、通知機能を作成できます。 ファイルnotifier.js
を作成します。
nano notifier.js
次に、次のコードをファイルに追加します。
notifier.js
var NATS_URL = 'nats://127.0.0.1:4222';
var NATS_USER = 'user1';
var NATS_PASS = 'pass1';
var EMAIL_TO = '[email protected]';
NATSサービスのユーザー名とパスワード、および電子メールアドレスと一致するようにこれらのオプションを変更してください。
次に、次のコードを追加してNode.js NATSクライアントをインポートし、gnatsd
サービスに接続します。
notifier.js
var tlsOptions = {
rejectUnauthorized: false,
};
var nats = require('nats').connect({url: NATS_URL,
tls: tlsOptions,
user: NATS_USER,
pass: NATS_PASS});
次に、このコードを追加してメーラーをセットアップし、メールを送信するSMTPサーバーに接続します。 このサーバーをすぐにセットアップします。
notifier.js
var nodemailer = require('nodemailer');
var transport = nodemailer.createTransport('smtp://localhost:2525');
次に、残りのコードを追加して負荷平均を計算し、通知メールを送信する必要があるかどうかを判断します。
notifier.js
// keep the state of warnings for each host
var warnings = {};
function sendEmail(subject, text) {
transport.sendMail({
to: EMAIL_TO,
subject: subject,
text: text
});
}
function processMessage(message) {
// message fields: host load processor_count
var fields = message.split(" ");
var host = fields[0];
var loadAverage = parseFloat(fields[1]) / parseInt(fields[2]);
if (loadAverage > 0.6) {
if (!warnings[host]) {
// send warning email if one wasn't already sent
var res = sendEmail('Warning! Server is Overloaded: ' + host,
'Load average: ' + loadAverage);
// set warning for the host
warnings[host] = true;
}
}
else if (loadAverage < 0.4) {
if (warnings[host]) {
// clear the warning
warnings[host] = false;
}
}
}
nats.subscribe('stats.loadaverage', processMessage);
メッセージをサブスクライブし、メッセージを受信するたびに、processMessage
関数を実行します。この関数は、送信したペイロードを解析し、負荷の平均を決定します。 高すぎる場合はメッセージを送信し、ホスト名に基づいてフラグを設定することで以前に送信したかどうかを追跡します。 このようにして、ホストごとに通知を追跡できます。 負荷平均がしきい値を下回っている場合、そのフラグをクリアします。
モニターと通知機能を配置したら、サンプルプロジェクトをテストします。
プロジェクトのテスト
これを試乗してみましょう。 人工的な負荷を生成し、負荷が高くなりすぎたときに通知者が警告メールを送信するかどうかを確認します。
stress
ツールをインストールして、サーバーにCPU負荷を生成しましょう。
sudo apt-get install -y stress
次に、通知機能からメッセージをメールで送信するようにSMTPサーバーを設定する必要があります。 本格的なSMTPサーバーをインストールして構成することは、このテストではやり過ぎになるため、実際に送信する代わりに、渡された電子メールを表示するだけの単純なSMTPサーバーを使用します。 Pythonプログラミング言語にはDebuggingServer
モジュールがあり、受信した電子メールを破棄しますが、画面に表示するので、確実に機能します。 PythonはすでにUbuntuサーバーにインストールされているため、これは完璧なソリューションです。
バックグラウンドでSMTPサーバーのデバッグを開始しましょう。 notifier.js
コードで構成したSMTPアドレスと一致するlocalhost
ポート2525
でリッスンするようにします。 次のコマンドを実行して、SMTPサーバーを起動します。
python -m smtpd -n -c DebuggingServer localhost:2525 &
次に、次のコマンドを使用して、バックグラウンドで通知機能を起動します。
nodejs ~/overload_notifier/notifier.js &
最後に、サーバーのすべてのプロセッサに負荷をかけましょう。 次のオプションを指定してstress
コマンドを実行します。
stress --cpu $(getconf _NPROCESSORS_ONLN)
数分後、SMTPサーバーがノーティファイアによって送信されたメッセージの表示を開始すると、次のような出力が表示されます。
Output---------- MESSAGE FOLLOWS ----------
Content-Type: text/plain
To: [email protected]
Subject: Warning! Server is Overloaded: your_hostname
Message-Id: <1466354822129-04c5d944-0d19670b-780eee12@localhost>
X-Mailer: nodemailer (2.4.2; +http://nodemailer.com/;
SMTP/2.5.0[client:2.5.0])
Content-Transfer-Encoding: 7bit
Date: Sun, 19 Jun 2016 16:47:02 +0000
MIME-Version: 1.0
X-Peer: 127.0.0.1
Load average: 0.88
------------ END MESSAGE ------------
これにより、サーバーの負荷が高くなりすぎたときにメールを正常に送信したことがわかります。
CTRL+C
を押して、負荷の生成を停止します。 サンプルプロジェクトを完了しました。これで、ご使用の環境でこの作業を行う方法を十分に理解できるはずです。
結論
この記事では、NATS PubSubメッセージングシステムについて学び、サービスとして安全な方法でインストールし、サンプルプロジェクトでテストしました。 サンプルプロジェクトではNode.JSクライアントを使用しましたが、NATSには、NATS download pageにリストされているより多くの言語とフレームワークのクライアントがあります。 NATSの詳細については、そのofficial documentationを参照してください。