gdnsd+rtmpdumpでRTMPを冗長構成にする

# RTMPの冗長構成って面倒ですよね
ストリーミングプロトコルのRTMP(Real Time Messaging Protocol)を冗長するためには
・サーバ側でActionScriptをガリガリ書く
・Flashプレイヤー側でActionScriptをガリガリ書く
の二通りあると思っているのですが、ActionScriptなんてもう書きたくない(※個人の感想です)じゃないですか。
さっくり今あるもので出来ないかなー。

# 概要
![gslbrtmp.png](https://qiita-image-store.s3.amazonaws.com/0/28655/0c56f83e-11f6-3041-8594-6272db626416.png)
GSLBの機能を使うとDNSサーバ側でサービスを監視して異常が合った場合にDNSの問い合わせに対して、該当のIPを除外してくれます。
そのため、DNSレベルでの障害機器を切り離す事ができます。
（もう既につながっている人は救えませんが、次再接続に来れば違うサーバにつながる。）
この機能にRTMPの監視を実装して、オープンソースのFlashプレイヤーを使って手軽に冗長配信を考えてみました。

# 使うもの
**OS：CentOS 7**
**DNSサーバ：gdnsd**
**RTMPチェック：rtmpdump**

rtmpサーバは事前に複数台立てておいてください。
(それぞれ、アプリケーション名とストリームキーは同じものを利用する。)

# gdnsdのインストール
こちらを参考にインストールしました。
http://qiita.com/jh1vxw/items/7ce5d14e9f964f001257

# rtmpdumpのインストール
gitでソースを取ってきます。
>$ mkdir ~/git
>$ cd ~git
>$ git clone git://git.ffmpeg.org/rtmpdump
>$ cd rtmpdump/
>$ make SYS=posix
>$ sudo meke install
>$ sudo cp -p /etc/ld.so.conf /etc/ld.so.conf.org
>$ sudo vi /etc/ld.so.conf
>$ diff /etc/ld.so.conf /etc/ld.so.conf.org
>2d1
>< /usr/local/lib/
>$ sudo ldconfig

#rtmpdumpの動作確認
>$ rtmpdump -V
>RTMPDump v2.4
>(c) 2010 Andrej Stepanchuk, Howard Chu, The Flvstreamer Team; license: GPL
>ERROR: You must specify a hostname (--host) or url (-r "rtmp://host[:port]/playpath") containing a hostname

成功！
以下のようなエラーが出た場合はライブラリの設定が上手くいっていない可能性があります。
>rtmpdump: error while loading shared libraries: librtmp.so.1: cannot open shared object file: No such file or directory

#gdnsdの設定
```lang:/etc/gdnsd/config
plugins = {
  multifo = {
      rtmp = {
        up_thresh = 0.00000001
        service_types = rtmpdump
        fms1 = XXX.XXX.XXX.1
        fms2 = XXX.XXX.XXX.2
        fms3 = XXX.XXX.XXX.8
     }
  }
}

service_types = {
    rtmpdump = {
        plugin = extmon
        cmd = ["/usr/local/bin/rtmpdump", "-vr", "rtmp://%%ITEM%%/{アプリケーション名}/{ストリームキー}", "--stop", "2", "-o", "/tmp/test%%ITEM%%"]
        interval = 30
        timeout = 5
        up_thresh = 5
        ok_thresh = 3
        down_thresh = 2
  }
}
```

```lang:/etc/gdnsd/zones/{ドメイン名}
$TTL 86400

@     SOA ns1 hostmaster (
       2016092600   ; serial
             7200   ; refresh
             30M    ; retry
             3D     ; expire
             10     ; ncache
)

@     NS      {gdnsdプライマリサーバ}.
      NS      {gdnsdセカンダリサーバ}.

fms     10      DYNA    multifo!rtmp
```

# 動作確認
### gdnsdの起動
> $ sudo /usr/sbin/gdnsd start

### gdnsdで現在の状態確認
http://{gdnsdのアドレス}:3506/
![gslbrtmp2.png](https://qiita-image-store.s3.amazonaws.com/0/28655/afc3a088-b732-9f71-3a24-407da065f445.png)
すべて正常です。

### digで確認
> $ dig fms.example.com
> （略）
> ;; ANSWER SECTION:
> fms.example.com. 10      IN      A       XXX.XXX.XXX.8
> fms.example.com. 10      IN      A       XXX.XXX.XXX.1
> fms.example.com. 10      IN      A       XXX.XXX.XXX.2
> （略）

### XXX.XXX.XXX.8のサーバを止める
http://{gdnsdのアドレス}:3506/で確認
![gslbrtmp3.png](https://qiita-image-store.s3.amazonaws.com/0/28655/50297018-1472-c397-9e8c-30c01ac1f95d.png)
XXX.XXX.XXX.8がDOWN表示になりました

### digで再度確認
> $ dig fms.example.com
> （略）
> ;; ANSWER SECTION:
> fms.example.com. 10      IN      A       124.241.66.1
> fms.example.com. 10      IN      A       124.241.66.2
> （略）

XXX.XXX.XXX.8が切り離されましたね。
この後、サーバを再度復帰させるとまた元の状態に戻ります。

#現状の問題点
- サーバのRTMPの生死のみが判断のキーになっているので、エンコーダ側のエラーに対応が出来ない。
    - エンコーダが止まっていても、サーバのアプリケーション名が生きているかぎり EXIT_STATUSが"0"が返ってくるため。
- nginx-rtmp-moduleを使ったRTMPサーバの監視が出来ない。
    - 正常時にもrtmpdumpでRTMP_ReadPacket, failed to read RTMP packet headerのエラーが発生してしまう。

# その他の用途
冗長も大事なんですが、これを使えば、日本のユーザには日本のサーバから、アメリカのユーザにはアメリカのサーバから・・・
みたいな事もかんたんにできるはずです。たぶん。(この辺 https://github.com/gdnsd/gdnsd/wiki/GdnsdPluginGeoip)
むしろこっちのほうが大事なんじゃねえかみたいなツッコミもありますが・・・・