2012年9月13日木曜日

OpenBlocks AX3でasteriskのパフォーマンス測定


◆はじめに

Asteriskはご存知の方も多いと思いますがオープンソースのPBXです。今回はOpenBlocks AX3にAsteriskを導入しSIPサーバとして利用します。
内線通話やSIPプロバイダへの接続設定を行いiPhoneをSIPクライアントとして動作確認を行います。
さらにOpenBlocks AX3がSIPサーバとしてどの程度のパフォーマンスがでるかを簡単に測定してみます。


◆Hard Float対応のasterisk導入

OpenBlocks AX3の標準OSであるDebian 6.0では、バイナリパッケージとしてasteriskが用意されておりますが、今回は後述の通りソースパッケージからビルドして利用しています。

OpenBlocks AX3に搭載しているCPUは、Marvell社のARMADA XPというものでARMv7に対応しハードウェアFPUを搭載したCPUですが、現状のDebian 6.0では残念ながらARMv7やハードウェアFPUを活かしたAsteriskの利用が出来ません。
これは、ハードウェアFPUがなく、古くからあるARMアーキテクチャのハードウェアでも動作させるためであろうと推測しますが、バイナリがARMv4の命令セットを使用しハードウェアFPUを使用しない状態で構築されています。そのため、本記事では性能をフルに発揮できるようにソースパッケージからの利用方法をご紹介しています。
(なお2013年に公開予定となっているDebianの次期バージョン7.0では、armhfという新たなアーキテクチャが用意され、ARMv7及びハードウェアFPUを利用するバイナリが用意される見込みのようです。)

今回の利用環境としてOpenBlocks AX3のkernelイメージとして以下のものを利用しました。
ftp://ftp.plathome.co.jp/pub/OBSAX3/squeeze/3.0.6-4/uImage.initrd.obsax3
またストレージ併用モードを利用しました。
ストレージ併用モードではパッケージビルドの際に/tmpの容量が足りなくなってしまうためあらかじめSSDを利用するように対応しておきます。(/etc/fstabにあるtmpfsを使ったサンプル設定でも構いません)
 $ su
 # mkdir /.rw/tmp
 # mount -t unionfs -o dirs=/.rw/tmp=rw:/tmp=ro unionfs /tmp

 # df /tmp
 Filesystem           1K-blocks      Used Available Use% Mounted on
 unionfs               30771896  12702648  16506128  44% /tmp
早速asteriskの導入に入ります。
asteriskは2012年8月21日現在では10系や11系(beta)なども利用可能ですが1.8系が安定版のLTS(Long Term Support)となってますので今回は1.8系を利用します。

OpenBlocks AX3のdebian環境(squeeze)のaptでもインストール可能ですが標準でインストールasteriskは1.6系になってしまいます。
今回は1.8系を利用したいのでasterisk.orgで提供しているdebian用のパッケージを利用します。
残念ながらarmel用のバイナリパッケージは提供されていませんのでソースパッケージからビルドします。
この際OpenBlocks AX3で利用可能なHard Floatに対応するためにコンパイルフラグを少々変更してコンパイルを行います。

手順は https://wiki.asterisk.org/wiki/display/AST/Asterisk+Packages を参考に以下のように行いました。
 $ su
 # apt-key adv --keyserver pgp.mit.edu --recv-keys 175E41DF
 # echo "deb-src http://packages.asterisk.org/deb squeeze main" > /etc/apt/sources.list.d/asterisk.list
 # exit

 $ mkdir ~/asterisk-18
 $ cd ~/asterisk-18
 $ apt-get source asterisk
 $ cd asterisk-1.8.11.1
 $ vi debian/rules
 (Hard Float対応のため以下を追加)
  CFLAGS += -march=armv7-a -mhard-float -mfloat-abi=softfp -mfpu=vfpv3-d16
 $ su
 # apt-get build-dep asterisk
 # exit
 $ dpkg-buildpackage -us -uc
以下のようにdebパッケージが生成されます。
 $ ~/asterisk-18
 $ ls -1 *.deb
 asterisk-config_1.8.11.1-1digium1~squeeze_all.deb
 asterisk-dahdi_1.8.11.1-1digium1~squeeze_armel.deb
 asterisk-dbg_1.8.11.1-1digium1~squeeze_armel.deb
 asterisk-dev_1.8.11.1-1digium1~squeeze_all.deb
 asterisk-doc_1.8.11.1-1digium1~squeeze_all.deb
 asterisk-h323_1.8.11.1-1digium1~squeeze_armel.deb
 asterisk-mobile_1.8.11.1-1digium1~squeeze_armel.deb
 asterisk-mp3_1.8.11.1-1digium1~squeeze_armel.deb
 asterisk-mysql_1.8.11.1-1digium1~squeeze_armel.deb
 asterisk-ooh323_1.8.11.1-1digium1~squeeze_armel.deb
 asterisk-voicemail-imapstorage_1.8.11.1-1digium1~squeeze_armel.deb
 asterisk-voicemail-odbcstorage_1.8.11.1-1digium1~squeeze_armel.deb
 asterisk-voicemail_1.8.11.1-1digium1~squeeze_armel.deb
 asterisk_1.8.11.1-1digium1~squeeze_armel.deb
asterisk-voicemail*はconflictしてしまいますので上記のうちasterisk-voicemail-imapstorageとasterisk-odbcstorageを除いたdebパッケージをインストールします。
 $ su
 # dpkg -i asterisk-[c-o]*.deb asterisk-voicemail_1.8.11.1-1digium1~squeeze_armel.deb
ここまででasteriskパッケージの導入は完了です。


◆iPhoneとMacで内線通話を行う

まずはasteriskの基本動作の確認ということでSIP内線通話の設定を行います。
動作確認を行うための機材とSIPクライアントは以下のものを利用しました。
 - iPhone 4S / AGEphone 1.41
 - MacbookAir / Telephone 1.0.4
iPhone,MacbookAirともにローカルネットワークにWifiで接続されているものとします。
asteriskパッケージでは設定ファイルが山のようにインストールされますが、これらは使用せずに今回は必要最小限度の設定のみを行います。
設定ファイルは/etc/asteriskディレクトリ以下に置きます。
今回は以下のように設定しました。users.confでクライアントの設定、extensions.confで動作を設定します。
内線番号は6000番台として、それぞれ6000, 6001が各クライアントの内線番号としました。
users.conf:
 [general]
 hassip = yes

 ; iphone 4s(AGEphone)
 [6000]
 type=friend
 secret=test0
 canreinvite=no
 host=dynamic

 ; macbook air(Telephone)
 [6001]
 type=friend
 secret=test1
 canreinvite=no
 host=dynamic

extensions.conf:
 [default]
 exten=_6XXX,1,Dial(SIP/${EXTEN},30,tT)
 exten=_6XXX,n,HangUp

asterisk.conf:
(空)

sip.conf:
(空)

modules.conf:
 [modules]
 preload => codec_alaw.so
 preload => codec_ulaw.so
 preload => codec_gsm.so
 preload => codec_g722.so
 preload => pbx_config.so
 preload => pbx_realtime.so
 preload => chan_sip.so
 preload => app_dial.so
 preload => app_macro.so
 load => res_rtp_asterisk.so
asteriskが動作している場合は一度停止します。
 # /etc/init.d/asterisk stop
デバッグ用メッセージを確認するためasteriskをフォアグラウンドで起動します。
 # asterisk -ddddvvvvc
 *CLI>
各SIPクライアントを起動します。
SIPクライアントの設定の詳細は省略しますが、SIPサーバはasteriskを動作させているマシンのIPv4アドレス、ユーザ名は6000または6001、パスワードは上記users.confに記載したパスワードとします。
各クライアントがサーバに接続するとasteriskのCLIにはSIP REGISTERなどのデバッグ用メッセージ等がでてきます。
ここでasteriskがSIPクライアントを認識していることをCLIで確認します。
 *CLI> sip show peers
 Name/username              Host                                    Dyn Forcerport ACL Port     Status  
 6000/6000                  192.168.111.228                        D   N             15060    Unmonitored
 6001/6001                  192.168.111.29                           D   N             52374    Unmonitored
 2 sip peers [Monitored: 0 online, 0 offline Unmonitored: 2 online, 0 offline]
クライアント2台がonlineになっていることが確認できました。

実際にiPhoneのAGEphoneから6001番で発信し通話ができることを確認します。同様に逆方向も確認します。
上記設定でとくに問題なく通話できることを確認しました。


◆SIPプロバイダへの接続設定

次はasterisk確認その2としてSIPプロバイダへの接続を試します。
今回はFusionのIP-Phone SMARTというサービスを使って確認します。

今回はOpenBlocks AX3のeth1側にグローバルアドレスを付与してインターネットとつながるようにしました。
全体のネットワーク構成は以下のようになります。























IP-Phone SMARTの申込手続き等はすでに済んでいるとものとしてasteriskの設定をします。
6000番台は内線、0からはじまる番号は外線としてSIPプロバイダに接続するような設定を行います。
前項の設定のsip.confとextensions.confを以下のように修正します。
sip.conf:
 [general]
 port = 5060
 bindaddr = 0.0.0.0
 qualify = no
 disallow = all
 allow = alaw
 allow = ulaw
 dtmfmode = rfc2833
 srvlookup = yes

 register => <ユーザID>:<パスワード>@<SIPドメイン>

 [sipprovider]
 type = friend
 insecure = port,invite
 nat = no
 canreinvite = no
 authuser = <ユーザID>
 username = <ユーザID>
 fromuser = <ユーザID>
 fromdomain = <SIPドメイン>
 host = <SIPドメイン>
 secret = <パスワード>
 usereqphone=yes
 context = incoming
 allowsubscribe=no

extensions.conf:
 [globals]
 MYDIAL=<自番号>

 [default]
 exten => _6XXX,1,Dial(SIP/${EXTEN},30,tT)
 exten => _6XXX,n,HangUp
 exten => _0.,1,Dial(SIP/sipprovider/${EXTEN},180,tT)
 exten => _0.,n,Hangup

 [incoming]
 exten => ${MYDIAL},1,Dial(SIP/6000&SIP/6001,30,tT)
 exten => ${MYDIAL},n,HangUp
<ユーザID>、<パスワード>、<SIPドメイン>、<自番号>はそれぞれSIPプロバイダから提供されるものを利用します。
IP-Phone SMARTのサービスの場合、<ユーザID>,<自番号>はどちらも050に続く8桁の電話番号、<SIPドメイン>はsmart.0038.netとなります。
設定ができたらasteriskを起動します。
 # asterisk -ddddvvvvc
 *CLI>
SIPプロバイダに登録されたかを確認します。
 *CLI> sip show registry
 Host                                    dnsmgr Username       Refresh State                Reg.Time              
 smart.0038.net:5060                     N      5???????           105 Registered           Thu, 23 Aug 2012 00:00:00
 1 SIP registrations.
次にPEERの情報を確認します。
 *CLI> sip show peers
 Name/username              Host                                    Dyn Forcerport ACL Port     Status  
 6000/6000                  192.168.111.228                        D   N             15060    Unmonitored
 6001/6001                  192.168.111.29                           D   N             62240    Unmonitored
 sipprovider/5???????       ??.???.???.???                                          5060     Unmonitored
 3 sip peers [Monitored: 0 online, 0 offline Unmonitored: 3 online, 0 offline]
実際にiPhone/AGEphoneから外部の固定電話に対し発信し無事に通話できることを確認しました。
また外部の固定電話からSIPプロバイダから付与された番号に対し発信したところ、内線6000,6001の両方で着信音が鳴り、どちらかのSIPクライアントで通話できることを確認しました。

今回は単純化のためにセキュリティ対策についての記載は省略しましたが、実運用時にはセキュリティ対策について十分な考慮が必要となりますのでご注意ください。


◆sippを使用したasteriskのパフォーマンス測定

asteriskのパフォーマンスを測定してみます。
今回はsippというツールを用いて同時接続数がどの程度まで耐えられるかを測定します。
OpenBlockSのasterisk一台に対してsippをインストールしたLinux PCからテストを行います。
ネットワーク構成は以下のようにします。



sippを使用するマシンはCore2Duo 2.13GHzにUbuntu Linuxをインストールしています。
http://sourceforge.net/projects/sipp/
からsipp.svn.tar.gzをダウンロードしbuildします。
 pc$ tar zxvf sipp.svn.tar.gz
 pc$ cd sipp.svn
 pc$ make pcapplay
これでsippが生成されます。

次にsippでの測定のためにasteriskの設定を行います。
200番は直ちに応答し音声をそのままエコーする設定にしました。
users.conf:
 ; 以下を追加
 [sipp]
 type=friend
 canreinvite=no
 host=dynamic

extensions.conf:
 [default]
 exten => 200,1,Answer()
 exten => 200,n,Echo()
 exten => 200,n,Hangup()

modules.conf:
 ; 以下を追加
 preload => app_echo.so
asteriskを起動します。性能測定なのでできるだけ余分なメッセージがでないようにします。
 # asterisk -c
 *CLI>
今回の測定にはsippに標準で用意されている二つのシナリオで行います。

シナリオ1は1通話は10秒無音待機後に接続を切るという動作とします。MAX接続数を増やしながら、再送数(Retrans)が0より大きくなる地点を探します。
実際のコマンドは以下になります。<MAX接続数>は100から100ずつ増やして確認を行います。
 pc# ./sipp -sn uac -d 10000 -s 200 -r 100 -l <MAX接続数> -m 5000  192.168.111.217
測定の結果、500までは再送数が0でしたが600以上では再送が出現しました。
よってOpenBlocks AX3上でのシナリオ1の同時最大接続数は500程度のようです。

シナリオ2は1通話8+1=9秒で音声を流し接続を切るという動作とします。シナリオ1と同様にMAX接続数を増やしながら、再送数(Retrans)が0より大きくなる地点を探します。
 pc# ./sipp -sn uac_pcap -s 200 -r 100 -l <MAX接続数> -m 5000  192.168.111.217
測定の結果、400までは再送数が0でしたが500以上では再送が出現しました。
よってOpenBlocks AX3上でのシナリオ2の同時最大接続数は400程度のようです。

上記のシナリオ実行中に、内線通話でiPhone/AGEphoneとMac/Telephone間(音声もasteriskを経由)で通話を行いましたが、音飛びや遅延などは感じられませんでした。


◆まとめ

今回はOpenBlocks AX3にasteriskを用いてSIPサーバの設定を行いました。
内線通話およびSIPプロバイダへの接続設定を行い問題なく使用できることを確認しました
SIPサーバのパフォーマンス測定を行い、同時接続数400〜500程度まで行けそうなことを確認しました。

0 件のコメント:

コメントを投稿