Midnightjapan

Tag: Ajax

AJAX on PHP WEB Aplication Lsync+Rsyncシンクロミラーサーバー稼動!

by jun on 6月.28, 2010, under Linux

AJAXとutf8には、いろいろと悲惨な目にあいましたが、なんとか開発も無事に完了して仮稼動しました。

このサーバーを利用した面白い構成を紹介します。

通常はこの手のシステムはcronなどでバックアップを作成しておいて、トラブルがあった場合はそこから復旧のようなことを行いますがLsync+Rsyncを利用して、2台のサーバーを稼動させてほぼリアルタイムでバックアップを実現する構成を構築しましたので紹介します。

サーバー構成

◇ Apache[WEBサーバー]
設定ファイルはすべて[/etc/httpd/]にあります。シンボリックリンクもありますが、まぁいいでしょう。

◇ PHP[PHPシステム]
なにかと追加ライブラリなどを追加だ削除だと結構な頻度で更新されます。設定ファイルは[/etc/php.ini]のみ。Centosからはほぼ
すべてのライブラリをyumで受けつとることができてしまうため・・・あんまり意味ないかw

◇ MYSQLサーバー[SQLサーバー]
設定ファイルは[/etc/my.ini]。一度設定したら、ほぼ再設定はないでしょう。少なくとも私はほぼそうです。

◇ Sambaサーバー[Windowsファイル共有サーバー]
このサーバーの微妙なところが、ユーザー・グループごとの権限もあり、ユーザーの追加もユニックスユーザーとは別に行う必要があるため、設定が複雑になりやすく、完全にシンクロはむつかしいでしょうねぇ。ディレクトリにでもしてしまってもいいのですが・・・

このサーバーの目的は、かなり以前からの目標であった、クラウドの一環として考えられているため大人数とか少人数とか関係ありません。

それを特定企業の社内用に利用したいということなので、少人数の場合でも利用が容易になるようコストも抑えられ、クライアントライセンスも無制限になっています。

なので、セキュリティーはあまり考慮されていませんでの、決して単純に真似して乗っ取られないようにしてくださいね。

要するに数人しかいないので、ディレクトリまではいらないってことですね。
さて、これをどのようにするかというと・・・

1)各種設定をシンクしてみる。

各サーバーをみてみると、みんな/etcのなかにあるので、ためしにシンクしてみました。簡単にわかることですが、まぁためしに。

メインサーバー[192.1.1.1] → [/etc]シンク → セカンダリーサーバー[192.1.1.2]

当然ながら、ユーザー情報、サーバー情報(IPアドレス等)が違うので、まともにうごくわけもなく。バックアップどころか、セカンダリーサーバーで動いているサーバーはすべて停止して、システムエラーになり、無駄なプロセスがどんどん起動して、お話になりません。

そこで、考えます。

設定はダメだろう。

じゃデータだけやってみる。

ところが、Mysqlはデーターベースサーバー起動しているとコピーはできない。もちろんできたとしても破損の可能性大。シンクロは絶対にできない。

では、mysqlhotcopyを使ってコピーを行う。なるほど、これなら定期実行をcronで行える。

そこで

メインサーバー[192.1.1.1] → [mysqlhotcopy]Cronで定時実行 → [/share/mysql/]

メインサーバー[192.1.1.1][/share/mysql/] → [Lsync]でシンクロ → セカンダリーサーバー[192.1.1.2][/var/lib/mysql]

なるほど、いい考えだった。

実際にセカンダリーを起動してみると、稼動しました。

ん?起動したら?

じゃあ普段はとめておいて、どうやって起動するの?

そこはapacheからsudoすればいいじゃん!・・・?apacheユーザーがsudoできたらやばくね?たしかにやばいんですが、ここは社内用途専用ということで、やってみます。PHPではこのようにパスワードをパイプで渡して-Sモードで実行すればいいので、このように記述すると実行してくれます。

<?php
$cmd = "echo 'password' | sudo -S ls -la /root"; #rootのデフォルトフォルダをリスト表示
exec($cmd, $output);
?>

ところが、apacheユーザーには権限がありません。そこでまずはapacheにパスワードを設定します。

#passwd apache

次にsudoをApacheに許可します。

#visudo
Defaults requiretty           # コメントアウトされていないのでコメントアウトする
=># Defaults requiretty
=> apache  ALL=(ALL)       ALL # 末尾に追加

この、[Defaults requiretty]はsudoユーザーはtty(端末)を必ず必要とする設定なので、apacheのように端末が起動しない命令の場合実行してくれないわけです。ただし、セキュリティーとしては非常に危険な設定なので、普段は必須項目としてみてよろしいかと思います。
これで、apacheからのsudoが可能になります。
今回の目的となる命令的には[/etc/rc.d/init.d/mysqld start]を実行してあげればブラウザから実行されます。
共有ユーザーの同期はできないにしても、共有ファイルはシンクロしても問題ない!これをすべてサーバーに実装すると。

1.crontabでmysqlhotcopyを定時に実行

メインサーバー[192.1.1.1] → [mysqlhotcopy]Cronで定時実行 → [/share/mysql/]

2.シンクロしてセカンダリーと同期。

メインサーバー[192.1.1.1][/share/mysql/] → [Lsync]でシンクロ → セカンダリーサーバー[192.1.1.2][/var/lib/mysql]
メインサーバー[192.1.1.1][/var/www/html] → [Lsync]でシンクロ → セカンダリーサーバー[192.1.1.2][/var/www/html]
メインサーバー[192.1.1.1][/share/hoge/] → [Lsync]でシンクロ → セカンダリーサーバー[192.1.1.2][/share/hoge/]

3.緊急時にはブラウザからセカンダリーサーバーにアクセスする。PHPでsudoでステータス取得を行い、mysqlが起動していたらシステムを表示。起動していない場合はシステムを起動させるスイッチを表示させる。

4.スイッチをブラウザから実行[index.php]

<?php
//DB接続
$db_host = '192.1.1.1';
$db_user = 'hoge';
$db_pass = 'hoge';
$db = mysql_connect($db_host,$db_user,$db_pass);
$errorstr= mysql_errno();		//起動していない場合はエラーコード(2002)を返す
$apachepassword ='password';   //ユーザーapacheに設定したパスワード

if($input_mysqlexec == "start"){     //これは実行命令がきた場合の処理
	// シェルスクリプト実行
	$shell_start_cmd = "echo {$apachepassword} | sudo -S /root/mysqlswitch start";
	exec($shell_start_cmd,$output);
	 header("Location: index.php");
	 exit();

}elseif($errorstr==2002){		//Mysqlが起動していないので起動スイッチを表示
	 //内部文字コードを変更
	 mb_language("uni");
	 mb_internal_encoding("utf-8");
	 mb_http_input("auto");
	 mb_http_output("utf-8");
	 $page_content .= "<h4>MySQLサーバーは現在停止しています。</h4>\n";
	 $page_content .= "<hr />\n";
	 $page_content .= "<p align=\"center\">このサーバーのデータベースサーバーを起動しますか?</p>\n";
	 $page_content .= "<p align=\"center\"><input type=\"button\" value=\" データベースサーバー起動 \" onClick=\"location.href='index.php?mysqlexec=start'\"></p>\n";
	 print $page_content;
	exit();
?>

このときに[/root/mysqlswitch]で実行される、シェルスクリプトで下記のコマンドが実行される。

# sudo /etc/rc.d/init.d/mysqld start //DBサーバー起動
# sudo /etc/rc.d/init.d/smb start  //ファイル共有サーバー起動
# sudo /root/sharepermitautoexec.sh //権限再設定実行処理

最後の[/root/sharepermitautoexec.sh]なにかというと、すべてのファイルの権限を自動で設定してくれるシェルスクリプトです。ま、こんなのはサンプルに書く必要もないでしょうから、ご自身でGoogle活用してください。

これでファイル共有とWEBDBシステムのシンクロナイズ差分1時間遅れの完全シンクロシステムの設計と設定が完成しました。

ここからは実際ののLsync+Rsyncの設定です。

■rsyncサーバー設定(ミラー先)

[root@sub ~]# vi /etc/rsyncd.conf ← rsyncサーバー設定ファイル作成
[mysql]
        path = /var/lib/mysql
        hosts allow = 192.1.1.1/24
        read only = false
        list = true
        uid = mysql
        gid = mysql
[sharespot]
        path = /share/sharespot
        hosts allow = 192.1.1.1/24
        read only = false
        uid = root
        gid = root
[www]
        path = /var/www/html
        hosts allow = 192.1.1.1/24
        read only = false
        uid = root
        gid = root
~

設定ファイルを作成したら、xintedを再起動。自動起動に設定します。

[root@sub~]# yum -y install xinetd ← xinetdインストール
[root@sub~]# /etc/rc.d/init.d/xinetd restart ← xinetd再起動
xinetd を停止中:                                           [  OK  ]
xinetd を起動中:                                           [  OK  ]
[root@sub ~]# chkconfig rsync on

これでsubサーバーの設定は完了。

Lsyncdインストール(ミラー元)

[root@main ~]# yum -y install libxml2-devel ← lsyncdインストールに必要なパッケージをインストール
[root@main ~]# wget http://lsyncd.googlecode.com/files/lsyncd-1.26.tar.gz
[root@main ~]# tar zxvf lsyncd-1.26.tar.gz
[root@main ~]# cd lsyncd-1.26
[root@main lsyncd-1.26]# ./configure && make && make install
[root@main lsyncd-1.26] # cp -p lsyncd.conf.xml /etc/lsyncd.conf.xml ← lsyncdconfigを流用

次にlsyncのコンフィグを編集(下記を追加)

[root@main ~]# vi /etc/lsyncd.conf.xml
<directory>
        <source path="/share/mysql/"/>
        <target path="192.1.1.2::mysql/"/>
        <!--
        or it can also be an absolute path for localhost
        <target path="/absolute/path/to/target">
        -->
</directory>
<directory>
        <source path="/share/sharespot/"/>
        <target path="192.1.1.2::sharespot/"/>
        <!--
        or it can also be an absolute path for localhost
        <target path="/absolute/path/to/target">
        -->
</directory>
<directory>
        <source path="/var/www/html/"/>
        <target path="192.1.1.2::www/"/>
        <!--
        or it can also be an absolute path for localhost
        <target path="/absolute/path/to/target">
        -->
</directory>

次に起動スクリプトを作成

[root@main ~] #  cp -p /etc/init.d/xinetd /etc/init.d/lsyncd
[root@main ~] # vi /etc/rc.d/init.d/lsyncd
#!/bin/bash
## lsyncd: Starts the lsync Daemon
## chkconfig: 345 99 90
# description: Lsyncd uses rsync to synchronize local directories with a remote
#machine running rsyncd. Lsyncd watches multiple directories
#trees through inotify. The first step after adding the watches
#is to, rsync all directories with the remote host, and then sync
#single file buy collecting the inotify events.
# processname: lsyncd

. /etc/rc.d/init.d/functions

config="/etc/lsyncd.conf.xml"
lsyncd="/usr/local/bin/lsyncd"
lockfile="/var/lock/subsys/lsyncd"
prog="lsyncd"
RETVAL=0

start() {
if [ -f $lockfile ]; then
echo -n $"$prog is already running: "
echo
else
echo -n $"Starting $prog: "
daemon $lsyncd --conf=$config
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch $lockfile
return $RETVAL
fi
}

stop() {
echo -n $"Stopping $prog: "
killproc $lsyncd
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f $lockfile
return $RETVAL
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status $lsyncd
;;
*)

また監視フォルダーが増加するとプロセス足りなくなると思うので32,768に設定。

# vi /etc/sysctl.conf
  -> fs.inotify.max_user_watches = 32768 # 新しい行を末尾に追加
# /sbin/sysctl -p

これで、完成。あとはシステムの設定をDBにいれるんですが、セカンダリー用とメインサーバー用の2つの設定をきちんともたせて、PHPで切り替えるようにしてあげればOKです。

こんな雑なメモは参考にならないと思いますが、私的なメモなので・・・

コメントなし :, , , more...

AJAX on PHP WEB Aplicationのぬかるみ

by jun on 6月.22, 2010, under WEB

こんにちわ!

すっかり家に帰れなくなってきたJUNです。

現在結構でかいPHPクラウドシステムを開発しております。

フレームワークを使って開発効率をあげつつ、サーバーもカスタマイズしてガンガン作ってみました。

CentOS 5.5 +Apache + PHP 5.1.6 (5.2は見送り) +MySQL 5.0.77+GD2です。

これにIFと開発効率をあげるため、AJAXを実装すべく、PrototypeとPHPによる制御が簡単な

PEARライブラリ HTML_AJAX XAJAX CakePHPなどを導入。

さぁ、ガリガリ書くぞ。

おお、こんなことも、あんなこと、おお・・・あん。いやんw

って、ぉぃ。

テストページ作ってる最中は問題なくAJAXの機能を堪能できるんですが

開発中のサーバーに実装してみたら・・・なぜか動きません。

1日かけて文字コードの設定をさまよい歩きました。

Apache(httpd.conf),MySQL(my.ini) ,PHP(php.ini),HTMLのUTF-8化。

いろいろ不備も見つけながら、設定をすすめていくと、ん?

IEだけの問題じゃん。

ということで、グーグル先生をさまよってみると

IEはAjaxの非同期通信でキャッシュを使ってしまうらしい => 対策(具体的には今度書くね)

IEはフォームから送信するときに一部のバージョンでASCIIで送ることがあるのでHeaderをきちんと宣言しないといけない。

IEはバージョンによって・・・もうそれはいろいろでてくるわけですわ。

1日かかって、何も進んでない&何もわからずじまい。

2日目

すべての文字コードをUTF-8へ十分確認したけど、あきらめきれずもう一度確認!

くぅ・・・痛恨のミス!なんでJavascriptのファイルに@charset “utf-8″とか入ってるんだよ!

これかぁ・・・と思いきや、改善せず。

このとき微妙な問題を発見。

ブラウザチェック => 表示される => ソースコード表示 => 問題ない =>ソースをコピーしてエディターへ

すると・・・

???<html>

/省略/

</html>?STM

へ?

もうさっぱりわかんねっすよ。

Ajax?サーバー?ブラウザ?文字コード?エディタ?

いやぁ久しぶりに誰でもいいから女を抱きたくなりました。

(ちなみに私は極度のプレッシャーをかけられると、女を抱きたくなります)

途方もなく、時間もなく、精神状態も限界にきていました。

そんなわけで、ちょっと寝ます。こういうときに何してもいいことありませんから。

翌朝、もうIEの対応は納期延長をきめこんで、もうやらない宣言しようかと思ったのですが

なんだか、ピンときたんです。

これって、PHPでincludeしてるからシステムからでてるんじゃね?

ビンゴでした。

急に発生した問題がまず「エラー c00ce56e のため操作を完了できませんでした

とIEのエラーコンソールに怒られます。

まずこれで見つかったのはphp.iniの中の

「default_charset = “utf8″」

これ間違えらしいです。

正解は

「default_charset = “UTF-8″」

こうしないとIEは勘違い起こすらしいよ。でも、これでもPHP の include問題は解決はしない。

まぁここからも、サーバーの設定やらなにやら、膨大な時間がかかったんですが、月面にたどりついたような感動を与えてくれたサイトがこちら。

phpで.incファイルをincludeするとieですきまがはいる(解決編)

http://pugiemonn.blog6.fc2.com/blog-entry-801.html

結果「utf-8 bom php レイアウト」でグーグル先生に聞いてみなってんで、聞いてみるとビンゴ!

utf-8とutf8-nの違いでした。

utf-8ってBOMなんかつけてたんですね。忘れてました。

このせいで、includeしたときにBOMをみちゃうわけです。

とうぜんこんなもの拾うのはオバカなIEだけでやんす。

そんなわけで、ソースを全部文字コード変換!

問題解決しました。

どうか、一人でも多くのAjax文字コード泥沼戦争から救いの女神がおりますことをお祈りしております。

コメントなし :, , , , , , more...



何かお探しですか?

以下にキーワードを入力してサイト内検索が可能です:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!