カテゴリー別アーカイブ: LAMP[Linux, Apache, MySQL, PHP]

NGINXをProxy利用 = UpstreamでKeepaliveを使う

 バランシングのテストにお名前.com VPS(KVM)を3台契約して、1台をバランサ、2台をアプリケーションサーバ(Apace)として構築して試験中。

 デフォルト設定でNGINXを通すと、NGINX-Apache間がHTTP 1.0 Closeコネクションになるため、abとかで叩くとApacheのスレッドが大量に立ち上がる。 この状態だと、リクエストのたびに新しい通信が立ち上がってくるし、Apacheのプロセスが切り替わりまくるからパフォーマンス的に美味しくない。
 調べてみると、最近のNGINXではupstream.keepaliveのディレクティブを使うことで、裏の通信をKeepAlive接続にできるようになるので、早速導入して評価。

と、設定前に負荷試験。

abで同時接続100、10000回のGETを実行(400KBのHTML、GZIPで60KBになるファイル)
NGINXでGZIP/SSL処理してAPACHEにつなぐと、200requests/sec程度のスループットだった。

#nginx.conf

upstream appservers {
server 192.168.10.10:80;
server 192.168.10.11:80;
keepalive 1000;
}

server {
listen 443;
server_name _;

location / {
proxy_http_version 1.1;
proxy_set_header Connection “”;
proxy_pass http://appservers;
}
}

 upstream.keepaliveをセットするのと、proxy_http_versionを1.1に(KeepAlive実装)、proxy_set_headerでConnectionを空にする(デフォルトでは、Connection: closeを送信してしまうため)

 Apache側は

KeepAlive On
MaxKeepAliveRequests 1000
KeepAliveTimeout 15

としてみた。

 先と同じようにabを実行してみた結果、210requests/sec程度になった。 もともと、ネットワーク転送量がワイヤースピード近くに達していたため、速度的にはそれほど改善していない。
 しかし、サーバのリソース的には相当改善が見られた。 CPU使用率のSys値(ユーザプログラム以外の部分で消費される無駄)が低下した。
 重いアプリケーションを動作させている場合には、オーバーヘッドが低下する分だけ応答速度の向上が期待できそうだ。

(1960)


カテゴリー: サーバ設定 | コメントをどうぞ

NGINXを使う(Proxy利用)

 Webサーバとしては使い慣れていることもあってApacheをずっと使い続けてきたが、細かい設定がしにくいという点があり、今回NGINXを使用することにした。
 ただし、今回はApacheを代替するわけではなく、Proxyとして利用することにした。
 バランシングのテストにはお名前.com VPS(KVM)を3台契約して実装してみた。

 まずは、基本のProxy構成。
 と言っても、何も難しいことはない。

server {
listen 80 default_server;
server_name _;

location / {
proxy_pass http://localhost:10080;
}
}

 これだと、NGINXがポート80で待ち受けて、すべてのリクエストをlocalhostポート10080に送る(Apache等をポート10080で待たせておく)
このままだと何も効果がないから、ここから色々追加していく。

location /php/ {
proxy_pass http://localhost:10080;
}
location /ruby/ {
proxy_pass http://localhost:20080;
}

 こうなると、/phpに来たリクエストは10080に、/rubyに来たリクエストは20080に行くので、apache + passengerを一つの入口で受けられるようになる。 localhostの部分を変えて、192.168.10.10とかにすれば、別サーバに流れていくから、一つの入口からアプリ単位で内部では別サーバで動かすことができる。

 更に、ロードバランシングも簡単に作れる。

upstream appservers {
server 192.168.10.10:80;
server 192.168.10.11:80;
}

server {
listen 80 default_server;
server_name _;

location / {
proxy_pass http://appservers;
}
}

 これで、来たリクエストは192.168.10.10と11に分配される。

 upstream.serverには簡単に重み付けが出来るので、

server 192.168.10.10:80 weight=5;
server 192.168.10.11:80 weight=10;

みたいにすることで、アプリケーションサーバの重み付けができる。

 さらに、スタンバイ構成も簡単で

server 192.168.10.10:80;
server 192.168.10.11:80;
server 192.168.10.12:80 backup;

とすると、10,11が応答しない時だけ12に振り分けることもできる(backupと書かれたサーバが正常時待機系となる) 10,11のいずれかが復帰すればbackupは待機状態に戻る。
VerisgnのSSL証明書はバランシングすると台数分の取得を要求されるが、ホットスタンバイ・コールドスタンバイであれば、同時に動作する台数分で良いのこんなかんじで設定できるのは便利。

 HTTPのgzip圧縮をNGINX側に任せられるので、アプリケーションサーバを本来の処理に専念させることもできる。

server {
listen 80 default_server;
server_name _;

gzip on;

location / {
proxy_pass http://appservers;
}
}

 また、SSL処理もNGINX側で行う事になる。

server {
listen 443;
server_name _;

ssl on;
ssl_certificate /etc/pki/tls/certs/ssl.crt;
ssl_certificate_key /etc/pki/tls/private/server.key;

location / {
proxy_pass http://appservers;
}
}

 NGINXでは帯域制限が容易にできるので、

location / {
proxy_pass http://appservers;
}

location /file/ {
limit_rate 2m;
proxy_pass http://appservers;
}

こんなふうにすると、file配下のダウンロードを2Mに制限できるので、ファイルダウンロードのせいでアプリが遅くなるみたいなことの解消が期待できる。

 また、制御構造を使って、

location / {
proxy_pass http://appservers;
if ($http_user_agent ~* “msnbot”){
limit_rate 1m;
}
}

みたいなこともできるので、BOT様の速度を制限して通常接続の帯域を確保できる。

 色々、更に便利な機能があるから、しばらく検証しよう。

(615)


カテゴリー: サーバ設定 | コメントをどうぞ

安物のRAID装置は禍の元

 サーバの記憶装置では通常RAID構成がされていますよね。

 以前の職場で、なぜかRocketRAIDアダプタが乗っているサーバがあって、RAID5構成になっていました。 予算をケチって安く売っているカードを買って自前で組んだのでしょう。

 そのサーバであるときファイルが読めなくなりました。 アレイマネージャを確認すると何もエラー無し。
論理エラーかとも思ったのですが、システムが異常停止したわけでもない状態のサーバ機で論理エラーが発生することはあまりありません(主記憶やバスはECCで保護されているので)
OSのシステムログを確認するとデバイスドライバの応答停止エラーが発生していました。
しかし、他のファイルのアクセスは全く問題なく、システムの再起動を実行してもそのファイルだけアクセス不能。
システムを落として、別マシンで個別ドライブをフルリードスキャンしてみた結果、1台のドライブで読み込み不能セクタが発生していました(アクセスすると数十秒応答停止して、SMARTを確認すると再配置待ちセクタなどの値が変化する状態)
どうやら、このRAIDアダプタはドライブがデバイスタイムアウトした場合の扱いがしっかり実装されておらず、ドライブが応答しないときにアダプタもタイムアウトしてしまうお粗末な物だったようです。
結局、該当のドライブを外した状態で電源投入すると、Critical状態でシステムが起動して、該当ファイルは読み込めました。

 確かに、RAID5の仕様である、ストライピング&パリティ書き込みを実行して、高速化と1デバイスが喪失された状態でデータ復元は出来ましたが、冗長構成はエラーが発生しても処理を継続し、かつ正常にエラーが検出できなければ実用に耐えません。 このアダプタの存在によって、障害の切り分けが困難になったという点は特に問題ですね。

 やはり、価格差はあってもメジャーブランドの製品を選択するべきだと認識させられました。 予算的にハードウェアRAID構成が難しい場合は、無理にRAIDアダプタを搭載せずソフトウェアRAIDで構成しておく方がベターでしょう。

(117)


カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | コメントをどうぞ

Office365をはじめました

 先日、Office2013がリリースされて、1台導入したのだけど、PCを多数保有しているとちょっと不便。
 楽天などで怪しいOEMライセンスの激安品を売っているけど、途中でProductキーがロックされたりして安心して使えないようだ(キー自体は正式なものだが、キーの用途が不正なので、購入していても正式ライセンスではない)

 そこで、この度、個人的にOffice365の契約を検討することになった。
 現在、30日の無料試用が利用できるので、早速申し込んで試用開始。

 今回のプランはOffice365 SmallBusinessPremiumで、月額1250円or年額12360円のクラウド型ビジネス向けサービスで、ビジネス向けではあるが1アカウントから契約できる。

 25GBのメールボックス、7GBのストレージ、Webベースのオフィスアプリなどが利用できるところまではGoogleAppsと大差ないけど、これに加えてSBPではOffice365 ProPlus(最新のOfficeスイートが利用できるサービスで、現状はOffice2013 ProPlusのデスクトップアプリ)が利用できる。
 Office365 ProPlusで利用したデータは標準でクラウドストレージに保存されていて、Officeのライセンスとストレージのアカウントが統合されているから、自宅でも外出先でも会社でも、同じようにアカウントでログインしてOfficeを使えば同じファイルを共有して作業ができる。

 SBPは1アカウントあたり5台のデバイスにOffice365 ProPlusを導入できるそうだ。
 私は自宅のメインデスクトップとメインノート、外出用のモバイルノート、MacのBootCamp環境で利用したいので多くのデバイスに入れられるこの契約は非常に有利だ。

 このサービスを会社で導入してくれると、自宅のPCで持ち帰った仕事をするためだけにオフィスを購入すると言う必要もなくなるのは大きな利点だろう(会社のアカウントでログインすればそのまま使える)
 クラウド型はもたつく印象もあるが、デスクトップ版を一度導入しておけば、普段は意識することなく利用できる感じで、問題は無さそうだ。

 Officeを複数導入する必要がある、イニシャルコストを抑えたいというニーズでは、Office365月額プランはかなり有利そうだ。

(655)


カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | コメントをどうぞ

jQueryで非同期処理の完了を待つ(jQuery.Deferred())

 jQueryのAJAX実装をすると、通常、通信が戻ってくるのを待たずに次の処理に進んで、通信の結果はコールバックで処理するよね。

function getResponse(url, parameters, target){
  jQuery.post(url, parameters, function(response){
    for(i in response){
      $(target).html(response[i]);
    }
  });
}

みたいな感じね。

 でも、この処理をまたどこからか呼び出していて、呼び出し元で、この通信が終了している必要がある場合(たとえばappendした結果に対して何か処理したいとか)、普通に

getResponse(‘http://hoge.tld/piyo.php’, {‘request’:’getMessage’}, ‘#targetArea’);
alert($(‘#targetArea’).html());

とかすると、getResponseは要求を作っただけで戻ってきてしまうので、alertの中身は空っぽ、みたいな事になる。
で、これに対応するためにどうするかというと、jQueryのDeferredを使うと良いようだ。

ファンクションの方は

function getResponse(url, parameters, target){
  var def = jQuery.Deferred();
  jQuery.post(url, parameters, function(response){
    for(i in response){
      jQuery(target).html(response[i]);
    }
    def.resolve();
  });
  return def.promise();
}

みたいな感じで、Deferred.promise()を戻すようにする。
AJAXの戻り値を待つ必要がない既存のコードは、特に何も変えなければそのまま動く。 そして、先のように待機する必要がある場合のコードでは、

jQuery.when(
  getResponse(‘http://hoge.tld/piyo.php’, {‘request’:’getMessage’}, ‘#targetArea’)
).done(
  function(){
    alert($(‘#targetArea’).html());
  }
);

みたいな感じにすると、getResponseが返したDeferredがresolveを実行次第doneの中身が呼び出される。
done()は、Deferredにバインドしている形なので、

jQuery.when(
  getResponse(‘http://hoge.tld/piyo.php’, {‘request’:’getMessage’}, ‘#targetArea’)
).done(
  function(){
    alert($(‘#targetArea’).html());
  }
);
window.close();

みたいにすると、表示してから閉じると言う動きにはならず、すぐ閉じてしまう。

なお、失敗時のために、resolve doneの組み合わせに対して、reject failがある。。

jQuery.when( asyncFunc() ).done( trueFunc() ).fail( failFunc() );

みたいにすれば、asyncFunc()の返したDeferredでresolve()が実行されればtrueFunc()を、reject()が実行されればfailFunc()が実行されるようになる。

 ファンクションが何かの値を戻していた場合、普通に書き換えるとDeferredを戻さなくてはならなくなると言う問題があるが、resolve/rejectに引数として与えると、done/failの引数として引き継がれる。

function getResponse(url, parameters, target){
  var def = jQuery.Deferred();
  jQuery.post(url, parameters, function(response){
    for(i in response){
      jQuery(target).html(response[i]);
    }
    def.resolve(response.length);
  });
  return def.promise();
}

jQuery.when(
  getResponse(‘http://hoge.tld/piyo.php’, {‘request’:’getMessage’}, ‘#targetArea’)
).done(
  function(len){
    alert(len + ‘:’ + $(‘#targetArea’).html());
  }
);

みたいな感じ。

whenはDeferredを複数くっつけるための物なので、1個の実行を待つだけならDeferredを戻すファンクションに対して、 asyncFunc().done(trueFunc()) 的な呼び出しでも良いっぽい。

(10608)


カテゴリー: jQuery | コメントをどうぞ

RTX1000で複数の経路を切り替える

 RTX1000を1台使用したネットワークで2本のプロバイダ接続を行って、使用する経路を切り替える。
 宛先毎にルートを指定する場合は、スタティックルーティングで

ip route 8.8.8.8 gateway pp 1
ip route default gateway pp 2

みたいにするわけだけど、今回の要望は同じサブネット上に存在する特定の端末について、回線を切り替える必要が生じた。

この場合は、フィルタ型ルーティングと言う方法を利用して、

ip filter 101 pass 192.168.0.0/24 * * * *
ip filter 201 pass 192.168.0.100 * * * *
ip route default gateway pp 2 filter 201 gateway pp 1 filter 101

のようにすると、各ゲートウェイに対してフィルタを適用して、先頭から順次チェックして通れるゲートウェイを通過するようになる。
この場合は、192.168.0.100から送出されたパケットはpp2を通り、それ以外の192.168.0.0/24ネットワークから送出されたパケットはpp1を通る。
pp2を通るPCを追加する場合は、

ip filter 202 pass 192.168.0.101 * * * *
ip route default gateway pp 2 filter 201 202 gateway pp 1 filter 101

みたいな感じで並べる。
連続IPなら、

ip filter 201 pass 192.168.0.100-192.168.0.101 * * * *

でもOK。

(1689)


カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | コメントをどうぞ

自宅のテープドライブを更新した

 昔から自宅のデータ保管装置としてテープドライブを使ってます。
 DDSからDLT、SDLTと変遷し、今まではLTO(LTO2)を使っていたんだけど、このたび、LTO4に更新しました。
 LTOは最新の6が出始めた感じで、その流れからLTO4の安い中古品が結構で回り始めていて、今回のLTO4購入となりました。

 最近は、テープは過去の遺物的に言われることも多いのですが、諸々考えると十分選択肢となり得るデバイスだと思います。

 手軽なバックアップメディアとしてはBD-Rがあるかと思いますが、LTO4は1本で800GBの保管が可能なので、BD-R1層25GBの32枚分が1本のテープに収まります(BD-Rは2層やXLメディア等もありますが、容量単価、書き込み速度、信頼性などの点では、BD-R1層メディアがベストでしょう)
 また、BD-Rは書き込みエラー率も結構高く、保管中に記録面に傷が付いて読み込み不能という確率も結構あります。 LTOは書き込みエラーはほぼ無く、カートリッジ式で記録面むき出しではないので保管が容易です。
 転送速度的に、BD-Rは最新16倍速で毎秒72MBの転送が可能であるものの対応メディアは価格が高く、信頼出来て容量単価に優れたメディアでは6倍速の毎秒27MBの転送速度です。 LTO4は毎秒100MB以が可能であるのに比べると低速と言わざるを得ません。
 容量単価としては信頼出来る6倍速メディアは30枚で2100円程度です。 LTO4カートリッジは海外から仕入れれば1本20ドル以下なので、容量単価は同等~やや高価な感じです(BD-Rのディスクは怪しいメーカーの製造した物が多々ありますが、LTO4のテープなんてメジャーメーカーしか作っていないため、ブランド不明の物を購入しても、たいていTDKや富士フイルム等が製造した物です)
 BD-Rはランダムアクセスが可能なので、保管したメディアをドライブに入れればすぐ読めるのは利点ですが、バックアップ作業時のメディア交換の手間や、速度・信頼性を考えるとLTO4が有利だと思います。

 大容量・高速と言う意味では、HDDをそのまま保管という方法もありますね。
 速度はLTO4よりも高速、大容量、ランダムアクセス可能であり便利ではありますが、保管の難しさは高く、衝撃や静電気への高い配慮が必要ですね。
 容量単価は1本あたり3TBの物で1万円程度、LTO4カートリッジ4本3.2TBの80ドルと比較するとやや高価です。

 テープはバックアップソフトが必要等という意見もありますが、単純にファイルバックアップであれば、Linux環境でAmanda等のフリーソフトを使用すれば無料で構築可能です。

 今回はドライブを348ドル、PCI-Express接続のSCSIアダプタとケーブルセットを38ドルで購入しました。 同時に、クリーニングカートリッジ5本を17ドル、データカートリッジ50本を950ドルで購入しました。
 約11万5千円で40TBの保管が出来る計算になります。
 そんなに容量なにするねんと言う人もいるかもしれませんが、テレビ録画しまくってて、それを保存したいんです。
 これから年末・年始にかけて10TBくらい開けておかないと番組が保存しきれません。

 今後、熱アシスト記録方式によりHDDは一気に大容量化が進む(最終的に3.5インチ装置で60TB程度まで)と言われていますが、2013年中に一般向け製品が出るかどうかと言うところのようです。 それまでは、現行の垂直磁気記録方式の密度上限で現行の4TB、移行の状況によっては経過的に5TBが出る程度のようです。
 1ドライブ10TBとかのHDDが低価格化してくると、ミラーして同じデータを複数保管等の方法をとって容量単価と信頼性をある程度得られるようになるかなと思いますが、2~3年はLTO4かなと思います。

(1026)


カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | 1件のコメント