Ajaxで低負荷な掲示板を作ってみるテスト

スタンダードなCGI掲示板をそのへんのフリースペースに設置して、そこそこ利用者が増えて人が多い時間帯に403とか吐きはじめたらもうそろそろ終わりが見えている。


perlプロセスが立ち上がってデータをファイルなりSQLなりから読み込んで出力。
これがリクエストがある度に繰り返されるのだからサーバの負荷はどんなもんなのか容易に想像できる。
mod_perlなりFastCGIなりで立ち上げのコストがある程度吸収できてもPerlでデータをごにょごにょするコストはどうにもならない。


シンプルに考えれば、掲示板は書けて読めればいい。
書くときはサーバサイドでなにがしか処理する必要がある。
しかし読むときにPerlを経由する必要はない。
サーバ上のperlは書き込み処理のみをする。
そして読み込み処理は、javascriptを使って動的にサーバ上のデータファイルを読み込んで、それを元にHTMLを作ればいい。


http://sorr.biz/sepr/lcf/

とりあえず思いついたままに適当につくってみたseprなんでも掲示

  • サーバ側
my $sth = $dbh->prepare("insert into comments values(null, ?, ?, ?);");
$sth->bind_param(1,"$ipAdress");
$sth->bind_param(2,$date);
$sth->bind_param(3,$time);
$sth->execute();

IPと日時だけをSQLに記録して

open  FH , ">:utf8", "$targetDir/$outputDir/$commentId\.txt";
print FH "$commentTitle\n".
         "$commentName\n".
	 "$commentMD5\n".
	 "$commentDateTime\n".
	 "$commentBody";
close FH;

コメントをファイルに出力

open( FH, "+>:utf8", "$targetDir/index\.txt");
flock(FH, 2);
seek( FH, 0, 0);
print FH "$commentId";
truncate(FH, tell(FH));
close(FH);

indexを更新



  • クライアント側
	$.ajax({
			'type'	  : "GET",
			'url' 	  : dirName + "/index.txt",
			'cache'   : false,
			'success' : function(res){
							var n = parseInt(res);
							if(isNaN(n)){
								//エラー処理
								block('indexファイルが破損しています<br />管理者までご連絡ください');
								return;
							}
							postsCount = n;
							viewRefresh();
							release();
						},
			'error'   : function(xml, status, e){
							//404
							block('サーバとの接続に問題があるためindexを読み込めませんでした');
							//postsCount = 0; //元の値のままの方がいいか
							//viewRefresh();
							setTimeout("release();",5000);
						}
		});	

indexを取得して

		$.ajax({
				'type'	  : "GET",
				'url' 	  : dirName + "/" + postDirName + "/" + n + ".txt",
				'cache'   : true,
				'success' : function(res){
								if(-1 != res.lastIndexOf("\r")){
									res = res.replace(/\r/g,"");//IE用									
								}
								var resArr = res.split("\n");
								var titleStr = "[" + n + "]" + resArr[0];
								var nameStr  = resArr[1];
								var idStr    = "id:" + resArr[2];
								var dateStr  = resArr[3];
								
								var fstr = new FString();
								for(var i = 4, i_n = resArr.length; i < i_n; i++){
									fstr.append(escapeSC(resArr[i]));
									if(i < i_n - 1){
										fstr.append("<br />");
									}
								}
								var index = getPosOfView(n);
								if(0 <= index || index <= postsPerPage){
									//表示処理
									$("#lcfTitle" + index).text(titleStr);
									$("#lcfId"    + index).text(idStr);
									$("#lcfName"  + index).text(nameStr);
									$("#lcfDate"  + index).text(dateStr);

									$("#lcfBody"  + index).css("text-align", "left");
									$("#lcfBody"  + index).html(bodyStr);
								}

データを読み込んで表示する

	$.ajax({
			'type'	  : "POST",
			'url' 	  : "lcf.fcgi",
			'cache'   : false,
			'data'    : {'title' : titleStr,
						 'name'  : nameStr,
						 'body'  : bodyStr
						},
			'success' : function(res){
							if("SUCCESS" == res){
								$("#postFormTitle").val("").blur();
								$("#postFormName").val("").blur();
								$("#postFormBody").val("");	
								release();
								loadIndex();
							}else{
								//エラー処理
								block('書き込みに失敗しました<br />(' + res + ')');
								setTimeout("release()",5000);
							}
							
						},
			'error'   : function(xml, status, e){
							//エラー処理
							block('サーバとの接続に問題があります');
							setTimeout("release();",5000);
						}
		});	

投稿する



みたいな感じでどうだろう。
これで少なくともperlを経由してた分のロスはなくなった。
フリースペースで掲示板やるにしても多少は寿命が延びるはず!


sorrはこんな感じの負荷削減を前提にしたもう少し高機能な文章系サイトにする予定。
乞うご期待。