システム群ってユーザーがアクセスしないサーバをどう設計するかが鍵だよね

スケールアウトや対障害性ってユーザがアクセスしない、裏側のシステムをどう作りこむか、どういう配置にするか鍵だよね。
ユーザがアクセスしないサーバなんて一見無駄のように感じられるけど、そこがシステム全体のキーを握っているに等しい。
ここに運用と開発のノウハウが詰まっている。

3つにわけるとしたらこんな感じで、これの人気のない地味だけど重要な裏方のサーバについて書きます。



監視サーバ

各マシンのステータスを監視して問題があればメール等でアラートを上げてくれるサーバ。
初心者はまず配置しないw
配置しないとサーバの実績や現状の数値化ができずに大きなシステムトラブルを発生させることになるw
そんなに負荷がかからないサーバなので、他の裏方サーバと共有してもよいと思われる。
個人的に munin が好きなので munin で監視と状態推移のグラフを作ってます。

ログ回収サーバ、分析サーバ

それぞれのサーバからログを収集してバックアップ、分析を行うサーバ。
超初心者はバックアップ何それ食えるの?って状態でそもそもバックアップしないw。
初心者は、運用マシンの同一ハードディスクにバックアップを作成し、RAIDのトラブルでデータが消えて泣く。
本番サーバにもログを残すけど、定期的にログをこのサーバに収集し保存と分析を行う。

また、取得したデータを analog だったり、独自のログ回収ツールで分析を行うのにも利用できる。
これも初心者は本番サーバで grep してロードアベレージを上昇させて泣くことになるだろう。

監視サーバと分析サーバで得られた値は社内SLAを作るうえでの参考値と実績値なのでこいつらの存在は大変重要。
常時高負荷でなければ、他のサーバと一緒にしてもいいのかも。

データベースバックアップ、レスキューサーバ

ログ回収サーバと似ているんだけど、データベースのバックアップやレスキューに利用するサーバ。
本サービスで利用しないけどデータベースレプリケーションを引いてくる。
データベースバックアップや重い分析バッチなどを本番システム群に負荷をまったくかけずに流すことができるので大変便利。
初心者は本番サーバでデータベースバックアップをして負荷に泣くことになる。
また、mysqlの最強のバックアップ方法はmysqldを落としてtarで固めること、、、みたいなのでそれをするには本番サーバ群ではまず不可能だろう。

あと、pixivのメディクDBの構成が面白いと思った。
http://www.nicovideo.jp/watch/1254230843

それほど負荷が高くないので、他のサーバと一緒にしてもいいと思われる。

管理ページ系

本サービスのデータやユーザを管理したりする、サポート用の管理ページを置くサーバ。
初心者は、本番サーバに /manage/ とか作ってアクセス制限するのを忘れて、誰でも入れちゃったり、最悪googleにクロールされたりするw
そういうことがないように、VPN経由でしかアクセスできない領域でこっそり運営する。

これも負荷が高くないだろうから、他のサーバと一緒でいいと思う。

VPNサーバ

データセンターと自社をつなぐVPN
初心者はVPNって何食べれるの?ってことでそもそも張らない。
その場合sshとかでアクセスすることになる。globalIPを持っていないサーバにアクセスするには別のサーバを踏み台にするしかなく超不便。
VPNを張れば、安全に任意のサーバに直接接続できるので大変便利。

図では専用サーバみたいに書いちゃったけど、たいていのルータはVPNの機能を持っていると思うのでそれを利用した方がいいと思う。
それと個人的に、DCから社内LANへの逆流が怖いので 逆流する syn パケットを落としてほしいんだけど、どうなんだろう。

まとめ

んなわけで、直接サービスを提供しないけど、サービスを陰で支えるサーバについて説明しました。
こいつらは常時負荷が高いわけではないからサーバの台数をケチりたければ、裏方系は全部同一サーバでもいいのかもしれないけどさ。

他にも俺はこんなすごいサーバ配置にしているって人がいたら教えてください!

キッズgooで見れなくなりました。

そういえば、この前キッズgooでアクセスしたら表示できませんになってしまった。
ActiveDirectoryというかLDAPをdisったのが悪かったのか?


http://kids.goo.ne.jp/tool/kgframe.php?BL=0&FM=0&SY=2&MD=2&TP=http%3A%2F%2Fd.hatena.ne.jp%2Frti7743%2F

まーそんなわけで、ブログの説明にも書いているとおり、お子様でも安心して閲覧できる世界一健全なサイトを目指して挫折したわけだけどw、お子様は見れなくなったので大人だけの紳士の社交場としていろいろやっていきたいと思います。

今後ともよろしくー

ブログの説明文

当サイトはお子様でも安心して閲覧できる世界一健全なサイトを目指して挫折しています。お子様はきっずgooでも見てな。

validate は if文より劣る

cakephp や zend freamwork なんかだと、値をチェックする validate っていう機能がある。
これって一見便利な気がするけど、if文に比べると優れているどころか劣っていると思う。

ソースの中にリソースを書くんぢゃねーよ

いきなり脱線するんだけど、ソースの中にエラーメッセージを入れるのはどうかと思う。
エラーメッセージを内容はプログラムではない見たくれのデータだから、ビューに任せるべきだ。
メモリが足りないとか、絶対必要なコントローラーがないとかの緊急なエラーは埋め込みでもいいんだけど、「〜が入力されていません」などのような緊急以外でエンドユーザーが見る可能性があるエラーメッセージはすべてビューが持つべきだろう。
世の中の人は、エラーメッセージの文体を変更しなくてはいけなくなったら、プログラマがソースを調べて修正してんの?だるくない?

まぁ、それについては本題ではないのでとりあえずおいとく。

で、validate が if文より劣っている点は次の2つ。

ディフォルト入力

たとえば、名前が入力されていなかったときに、ななしさんにしたい場合どうするか。

if (!isset($_POST['name']))
{
	$name = 'ななしさん';
}
else
{
	$name = $_POST['name'];
}

validate でやるとしたら、一度 validate チェックにかけて、name のみ入力エラーだったら握りつぶして「ななしさん」と書き換えるような2度手間の書き方だと思う。

分岐対応がメンドイ

入力項目によってチェックする項目の切り替えに対応しづらい。

たとえばこんなフォームがあったとして、
選択内容によってチェックしなければいけない内容が変更される場合。

if (@$_POST['contact'] == 'tel')
{
	if (!IsTel(@$_POST['tel']))
	{
		$error['bad_tel'] = true;
	}
}
else
{
	if (!IsMail(@$_POST['mail']))
	{
		$error['bad_mail'] = true;
	}
}

入力チェックルーチンのあるべき姿

では、入力チェックルーチンを提供する場合どうすればよいのか。
難しいことは何も考えずに、こんな感じの入力チェック関数集って形で提供するのが一番効率的な気がする。

//簡易チェック
class L_Check
{
	//数字か?
	public static function IsNumber($p)
	{
		return preg_match('/^[0-9]+$/' ,$p);
	}
	//ASCIIか?
	public static function IsAscii($p)
	{
		return preg_match('/^[a-z0-9]+$/i' ,$p) ;
	}
	//長さ
	public static function IsLength($p,$min,$max)
	{
		$len = strlen($p);
		return ($len >= $min && $mlen <= $max);
	}
...
};

利用するほうは普通に、こんな感じで呼び出す。

if (! L_Check::IsLength( @$_POST['name'] , 1, 2) )
{
	$error['bad_name'] = true;
}

L_Check::IsLength っていうのが長すぎる場合は、 L_Check 取っ払って メソッドから関数 にしてもいいかもしれない。

ソースが長すぎる?
コレでどうだ!

$error['bad_name'] = ! (IsLength( @$_POST['name'] , 1, 2));

validateを使おうが、使いまいがエラーチェックを記述する行数や内容はたいした変化はないはずだ。
何より、if文だと多少無理が利くし、デバッグしやすいという最大のメリットがあるww
だったら、最初からif文でかけばいいぢゃないかと。

もし、間違いや、
俺様の作った validateは最高だという人は非常に興味があるから教えてください。
先生どうすれば幸せになれますか?