LoginSignup
3
4

More than 5 years have passed since last update.

node.jsで待機サーバーBを自動 ifconfig up する

Last updated at Posted at 2012-08-02

これの途中経過。https://www.facebook.com/javascripting/posts/398389730217171
もっと良い手は無いかなぁ。。。とりあえず、身近で気楽そうなping監視版。
ソケット使う版はまたあとで。あと、ARPどうするかとか、メインサーバー生き返った時どうするかとかもあとで。ただ、heartbeatでいんじゃないの?という強い誘惑に勝てるかどうかは不明な今日この頃。。。

node.jsで待機サーバーBを自動 ifconfig up する

node.jsで待機サーバーBを自動 ifconfig up する

サーバーA eth0 192.168.1.11 (メイン)
サーバーB eth0 192.168.1.12 (待機)

ルーターからのNATの宛先LAN側サーバーアドレス 192.168.1.10で

サーバーA に仮想IP eth0:1 192.168.1.10 を立てている時、

サーバーB から ping打って192.168.1.10を監視し、
死んでいたら、サーバーBの eth0:1へ仮想IP 192.168.1.10 を起動してサーバーを切り替える。

サーバー構成
                       Internet
                           | 
                  +--------+---------+
                  |     GateWay      |
                  +--------+---------+
                           | 192.168.1.1
                           |
                           | 192.168.1.0/24
  +-----------+------------+------------+-----------+
              |                         | //on err, 
              | 192.168.1.10(eth0:1)    | //ifconfig eth0:1 192.168.1.10 up
              | 192.168.1.11(eth0)      | 192.168.1.12(eth0)
     +--------+-------+        +--------+-------+
     | Main Server A  |        |  Sub Server B  |
     +--------+-------+        +--------+-------+

それぞれの機器のネットワークはたとえば下記な感じで設定しておく

ネットワーク構成

【GateWay】example.comとか
WAN側 ***.***.***.***
LAN側 192.168.1.1

NATエントリ
LAN側ホスト プロトコル ポート番号 優先度
192.168.1.10    TCP 22-22   1
192.168.1.10    TCP 80-80   2
192.168.1.10    TCP 443-443 3
192.168.1.10    TCP 21-21   4

【Main Server A : OS Ubuntu 12.04 LTS】192.168.1.11

$sudo vi /etc/network/interfaces

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.1.11
netmask 255.255.255.0
network 192.168.1.0
gateway 192.168.1.1
dns-nameservers 8.8.8.8

【Sub Server B : OS Ubuntu 12.04 LTS】192.168.1.12

$sudo vi /etc/network/interfaces

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.1.12
netmask 255.255.255.0
network 192.168.1.0
gateway 192.168.1.1
dns-nameservers 8.8.8.8

ファイルの構成は次の通り
待機サーバーBへ設置してますが、両方に置いても可。

ファイル構成 
Sub Server B
 home                          
  └hoge                       
     └kagemusya
        ├ping-ifup.js           ... 0705 サーバーAの監視・障害時に仮想IPを起動する
        ├kage-start.sh          ... 0705 サーバーB起動時用スクリプト rc.localへ設定
        └log                    ... 0606
           └kage-start-log.txt  ... (自動生成)サーバーB起動時のログ

pingで監視して、障害時にはifconfig upで仮想IPを起動する

*node.jsは、nvmでインストール済みです。

ping-ifup.js

#!/home/hoge/nvm/v0.8.3/bin/node

//Vars
var targetAddr = '192.168.1.10';
var cmdPing = '/bin/ping';
  var count = '3';      //pingパケット試行回数
  var interval = 10000; //監視間隔
  var aliveStr = '100% packet loss';
  var tid;
var cmdIfconfig = '/sbin/ifconfig';
  var nic = 'eth0:1';
  var ifcmd = 'up';

//Modules
var sys = require('util');
var spawn = require('child_process').spawn;

//Go!
main(targetAddr);

//ping process
function ping(targetAddr, callback) {
  clearInterval(tid);
  tid = setInterval(function(){
    var pingProcess = spawn(cmdPing, ['-c ' + count , targetAddr]);
    pingProcess.stdout.on('data', function (data) {
      var data = data.toString().split('\n').join();
      var isOk = 
        data.indexOf(aliveStr) === -1 ;
      var is = isOk ? ' is ok.' : ' is ng.';
      console.log('============================================');
      console.log('targetAddr ' + targetAddr + is);
      console.log('stdout: ' + data);
      if(isOk) {
        //targetAddr is alive. 正常 
      }
      else {
        clearInterval(tid);
        pingProcess.kill();
        callback(isOk);
      }

    });
    pingProcess.on('exit', function (code) {});
  },interval);
}

//ifconfig process
function ifconfigUpDown(targetAddr) {
  var ifup = spawn(cmdIfconfig, [nic, targetAddr, ifcmd]);
  ifup.stdout.on('data', function (data) {
    console.log('stdout: ' + data);
  });
  ifup.stderr.on('data', function (data) {
    console.log('stderr: ' + data);
  });
}

//do it!
function main(targetAddr) {
  ping(targetAddr, function (isOk) {
    ifconfigUpDown(targetAddr, isOk);
  });
}

【修正履歴】
2012/08/02
     '100% packet loss'じゃなければOK。に変更^^;微調整中。
2012/08/02
     clearTimeoutとclearInterval書き間違えてた(^^;
     '0% packet loss'は'1.0% packet loss'の場合もあるので' 0% packet loss'へ変更
2012/07/31
     少しでも早く障害把握したいと思って、'Unreachable'と'100% packet loss'で
     死亡確認してたけれど、pingの返事には'Request timed out'とか他にもいろいろ
     あるので、結局最初の'0% packet loss'がひとつも無いという確認に変更。
     早く確認したければ、pingパケット試行回数を減らす(精度とトレードオフ)とか他の手で。
     注:この生存確認文字列aliveStrは、マシンによっても異なると思います。
2012/07/30
     pingによるUnreachable検出に数十秒かかってしまっていたので、
     ping -c 3 192.168.1.10 でループした方が検出速いんじゃないかな?ってことで
     少し書き換えたら少し速くなった。
2012/07/30
     昨日は192.168.1.11をpingで監視したんだけれど、192.168.1.10を監視に変更。
     目的は192.168.1.10の監視なのに、192.168.1.10が死んで、192.168.1.11が
     生きてるというケースもあるので。

マシン起動時用スクリプト

上記のping-ifup.js を下記のような起動時用スクリプトの中に書いて、待機サーバーB 192.168.1.12の /etc/rc.local に置くと起動時にrootとして実行してくれるのでifconfig upも実行できる。

kage-start.shのパーミッションは0705とか実行権限を与えておく。rc.localだけで動かすなら0700でも良いかもしれない。

log用ディレクトリは /var/log 以下でも良いけど、ここではプロジェクト内の /home/hoge/kagemusya/log へ書き込み可で用意しました。

kage-start.sh
#!/bin/sh

#This is a Sub Server 192.168.1.12
#NAT IP eth0:1 192.168.1.10

#一応起動ログもとっとく
logFile=/home/hoge/kagemusya/log/kage-start-log.txt

echo "================================================" >> $logFile
date '+%Y/%m/%d %H:%M:%S.%N' >> $logFile
echo "${0}" >> $logFile
echo "i am $(whoami)" >> $logFile

#サーバーAの仮想IP 192.168.1.10を監視して、
#落ちてたら自分でeth0:1へ仮想IP 192.168.1.10を立ち上げるスクリプト
/home/hoge/nvm/v0.8.3/bin/node /home/hoge/nvm/v0.8.3/bin/forever start /home/hoge/kagemusya/ping-ifup.js
echo "start /home/hoge/kagemusya/ping-ifup.js" >> $logFile

#サーバーで動かしたいWebSocketアプリとか
/home/hoge/nvm/v0.8.3/bin/node /home/hoge/nvm/v0.8.3/bin/forever start /home/hoge/node/ws-app.js
echo "start /home/hoge/node/ws-app.js" >> $logFile

rc.localへ設定する

これで、マシン起動時に上記のping監視が自動で立ち上がります。

rc.local
#!/bin/sh -e

/home/hoge/kagemusya/kage-start.sh

exit 0

今回作ったマシンのお会計です。

マシン購入費
【サーバーA】
ベアボーンキット    Shuttle XH61V ¥16,800
メモリ   TRJ JM1333KSN-8GK(SODIMM DDR3 PC3-10600 4GBx2) ¥3,170
CPU Intel Core i3-2120 BOX (1155/3.30/3M/C2/T4) ¥9,760
SSD OCZSSD2-1VTXPL60G ¥5,980
----------------------------------------------
合計 35,710円

【サーバーB】
ベアボーンキット    Shuttle XH61V ¥16,800
メモリ   TRJ JM1333KSN-8GK(SODIMM DDR3 PC3-10600 4GBx2) ¥3,170
CPU Intel Celeron G540 BOX(1155/2.50/2M/C2/T2) ¥3,480
SSD SP060GBSSDV30S ¥4,870
----------------------------------------------
合計 28,320円

ちなみに、サーバーAとサーバーBをWebSocketのシンプルなレスポンスで比較すると同一
ネットワーク内でどちらも2~5ms、インターネット側の別のマシンからは、どちらも
10~15msということで、全然差はありませんでした。

まぁ、数千件の同時アクセスとかなら差が出るのかもしれませんが、そういう用途以外
ならサーバーBの構成でも十分という感じ。もし、お金をかけるなら回線側の方が効果あ
るかも?

ちなみに、私が現在業務で使ってるWebSocketマシンはAtomなので、サーバーBより安物
ですが、これも快適です^^。node.js & WebSocket 万歳!(^0^)/。
3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4