X



トップページ運用情報
1001コメント347KB

bbs.cgi再開発プロジェクト 3

■ このスレッドは過去ログ倉庫に格納されています
00012chtubo愛用者〜ヘ(゚д゚ヘ))))))〜61 ◆yBEncckFOU
垢版 |
04/02/13 19:08ID:o3jHs/Mb
peko鯖の稼動によりボトルネックの一つである事がより明らかになった
bbs.cgi作り直しプロジェクトです。

関連スレ
【Project peko】2ch特化型サーバ構築作戦 Part6
http://qb3.2ch.net/test/read.cgi/operate/1076413123/
◆ 全サーバトリップ統一作戦
http://qb3.2ch.net/test/read.cgi/operate/1067245837/
bby -- スレッド情報一元管理システム構築スレ
http://qb3.2ch.net/test/read.cgi/operate/1073058944/
BBQ システム(公開串リストメンテ)
http://qb3.2ch.net/test/read.cgi/operate/1073061576/
【連投規制】Samba24 情報要望スレ その3
http://qb3.2ch.net/test/read.cgi/operate/1075568934/
【広告】Rock54【自動排除】 3
http://qb3.2ch.net/test/read.cgi/operate/1074735308/
■ 新しいサーバで read.cgi が正しく動かない問題。 (dat落ち)
http://qb.2ch.net/test/read.cgi/operate/1047840578/


前スレ
bbs.cgi 再開発プロジェクト
http://qb3.2ch.net/test/read.cgi/operate/1053067870/
bbs.cgi再開発プロジェクト2
http://qb3.2ch.net/test/read.cgi/operate/1069144193/
0189GlobalService ★
垢版 |
04/02/27 00:30ID:???
>186
ファイルに書き出すのはやめた方がいいと思う

極端な話SQL鯖のような感じにリアルタイムで返って来るようにする

リアルタイムで返って来ないと・・・
書き込んだ内容が反映されてない -> なんらかの規制になってると判断する可能性有
2chブラウザのかちゅ〜しゃに至っては書き込み後自動的にdat読み込む
0190動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/27 00:38ID:/G/Nn469
>>188
まずいっけ?
もし生成が溜まっていても、bbs.cgiがチェックしていればよさそうだけど。

>>189
書き出しはDBIにしておけば、MySQLでもDBI::Fileでも任意のドライバに変えるのは簡単。
今まではfileオープンしてそこに追記していたんだから。
tai64で1つごとにファイル書き込みしたとしても次元が違うぐらい速度が上がると思うけど。
0191GlobalService ★
垢版 |
04/02/27 00:50ID:???
案1
「bby -- スレッド情報一元管理システム」と同じDNS使用
dnsに板とキーを投げる
dnsは板・キー・レスカウントを保持
通常は127.0.0.1を返し
レス数1000になったら127.0.0.2を返す

案2
レス数管理にSQL鯖使用

>190
>書き出しはDBIにしておけば、MySQLでもDBI::Fileでも任意のドライバに変えるのは簡単。
2つのプログラム(2重起動含む)から1つのファイルを使って大丈夫なのか?
0192動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/27 02:59ID:/G/Nn469
DNSはキャッシュされるのでそういう用途には向いていないと思います。

>2つのプログラム(2重起動含む)から1つのファイルを使って大丈夫なのか?
そういう泥臭いことを引き受けてくれるのがDBIです。
パフォーマンスを考えるとSQLデータベースになりますが、それはまぁ後々の話として。
インターフェースさえDBIにしておけば後でいくらでも入れ替えられます。

http://module.jp/works.html
のPerlによるハイパフォーマンスWebアプリケーションの開発を参考に
0195GlobalService ★
垢版 |
04/02/27 10:28ID:???
>192
http://member.nifty.ne.jp/hippo2000/perltips/DBD/file.htm
>このモジュールは内部で flock() を使っています。
2つのプロセスから同時に使えない気がするけど

*dat書き込みプロセスがtxt経由するファイル使用中にbbs.cgiプロセスが書き込めないのはダメだぞ

bbs.cgiプロセスとdat書き込みプロセスはtxt経由ではなくTCP経由ってこと?
0196 ◆garnetGnNk
垢版 |
04/02/27 10:48ID:5SP01m4Q
突貫工事で一番簡単な方法。

#DATを書き込む前に
open(FILE, '>> ../$FORM{'bbs'}/dat/$FORM{'key'}.idx');
print FILE '1';
close(FILE);

# レス数取得
$res = -s '../$FORM{'bbs'}/dat/$FORM{'key'}.idx';

# DAT書き込み
open(FILE, '>> ../$FORM{'bbs'}/dat/$FORM{'key'}.dat');
print FILE ""; #適当に
if ($res >= 1000) { #レスが1000超えてるときは1000ストップ
print(FILE "1000 over ...");
close(FILE);
chmod(0444, '../$FORM{'bbs'}/dat/$FORM{'key'}.dat');
} else { #通常は何もせずクローズ
close(FILE);
}



突貫だけあってその後いろいろめんどくさいです。
0197動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/27 12:13ID:bFrSuaS6
素人が書き逃げするですよ

8) 512KB越え or datが書き込めない or ロックディレクトリが存在するならエラー

17) subject.txt更新 and 1000越え判定
 1000越えててカキコ可能なら
 ・ロックディレクトリ作成
 ・1001カキコ
 ・chmod --- 成功したらロックディレクトリ消去
0198GlobalService ★
垢版 |
04/02/27 18:54ID:???
1)の前に "keyfile.txt"(増加カウントファイル)のサイズをチェックして
1000いってなかったら"1>>keyfile.txt"を実行
1000超えてたら書き込み失敗
*書き込めなくてもカウントする

書き込めなかったら
マイナスカウントファイルを作って・・・
0202GlobalService ★
垢版 |
04/02/28 01:38ID:???
>201
排他処理やると

ABCDEFG・・・と50ms順番に投稿したとする(cgiの処理は75msかかるとする)

書き込み成功 ACEG・・・ (奇数回)
書き込み失敗 BDFH・・・ (偶数回)

こんな感じになる
0203動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/28 01:55ID:2OurBtXJ
>>202
ロックが取れなかったら書き込み失敗とみなすならそうですが、
ロックは取れなかったら取れるまで待つものなので、
全部がちゃんと書き込めるです。
0204GlobalService ★
垢版 |
04/02/28 02:16ID:???
>203
>ロックは取れなかったら取れるまで待つものなので
NHK実況板だけで動作確認して次は
NTV実況板・・・と1つの板毎に実装していかないとlive8鯖がいきなり死ぬ可能性あるね
0205 ◆garnetGnNk
垢版 |
04/02/28 02:38ID:a22kVdoK
よし。レス数はctimeにやらせよう。
1970/1/1 9:0:1 が1レス目ってことで。
するとアレアレ。
subject.txtなんて/bbs/datみるだけであっという間にできちゃったりアレアレ。

flockなんて過去の遺物です。
1000のプロセスが全て並行で動いていることを想定して考えないと。
0206▲ 某ソレ511
垢版 |
04/02/28 02:46ID:CMWFcqez
>>205
お、それ結構(・∀・)ゐゐ!! かも。
ちょっと移転作業がめんどくなりそうだけど。
0207 ◆garnetGnNk
垢版 |
04/02/28 02:52ID:a22kVdoK
今1000ストップが遅れてるのってあれでしょ?
dat書き込んだあとに/bbs/html/*.htmlからレス数とって、
1000ストップ判定するっていう処理だったかな。
うるおぼえ。

まず、DATに書く前に1000ストップ判定すべきですよ。
これだけでかなり違うかと。
処理順で言えば、DATを書き込む処理からエラーを吐いちゃいけないので、
DATを開くときにエラーにすればいいんじゃないすか?
0208 ◆garnetGnNk
垢版 |
04/02/28 02:59ID:a22kVdoK
んで、実際書けない時のエラーはずーっと上の方でやっちゃっているわけで、
間の処理が長くていっぱいかけるわけですよ。
「開く前に調べる」
これだけではないかと・・・。

それと、bbs.cgiを作り直すなら、設計からやるように(す
0209動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/28 03:52ID:iCijLgHG
use IO::File;
use Fcntl qw(:flock :mode);
use constant LIMIT_SIZE => 512*1024;

$file = new IO::File($DATAFILE, '+<')
  or DispError("ERROR!", "スレッドが見つからない");
flock($file, LOCK_EX);
DispError("ERROR!", "このスレッドには書けない")
  unless -w $DATAFILE and -s $file < LIMIT_SIZE;
@logdat = $file->getlines();
$lognum = scalar @logdat;
$file->print("$outdat\n");
$logdat[$lognum++] = "$outdat\n";
if ($lognum >= 1000) {
  $file->print("1001<><>Over 1000 Thread<>このスレッドは〜\n");
  $lognum++;
  chmod(S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, $DATAFILE);
}
$file->close();

flockを使っていいなら楽なんだけど。
0210動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/28 05:55ID:BfJ3Pp5X
>>205

http://nais.to/~yto/tools/kuttuki-counter/
くっつきカウンター
と同じアイデアだね。
秒数を進めるところで競合が起こるけど。
今のレス数からepoch + secondすればいいから厳密に1000秒を検知しなくていいのなら面白いね。
0211動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/28 05:57ID:BfJ3Pp5X
>>208
>それと、bbs.cgiを作り直すなら、設計からやるように(す

じゃあサブルーチンごとにパラメータとか列記していきましょうよ。
1)から分かる範囲でやりましょう。
0212動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/28 09:01ID:oRqqiPOI
泥縄的にアプローチ。

chmodが効かない(全部closeされるまで反映されない?)のが問題なわけで、
(1) chmodと同時に適当なファイル(たとえば「スレッドキー.stop」)も作る
(2) サイズオーバーや書込み禁止のチェックと同時に (1) のファイルの存在チェックも行う
とすれば、とりあえずは解決するかな、と。

スレッドが1000に達するたびにファイルができるのが難点だけど。
0213GlobalService ★
垢版 |
04/02/28 13:02ID:???
>chmodが効かない(全部closeされるまで反映されない?)のが問題なわけで
そうなのか

書き込む直前に1000行ったことを知らせるファイルチェック -> ファイルがあったらエラー
現在の投稿が1000なら1000行ったことを知らせるファイルを作る
実際の書き込み
chmodをやる
でどうだ
0215仕事人 ★
垢版 |
04/02/28 13:27ID:???
今度は いつ実験できそうですか?
0216root ★
垢版 |
04/02/28 13:41ID:???
>>215
重い番組はいつか、という質問かしら。
0217仕事人 ★
垢版 |
04/02/28 13:43ID:???
そです
1,000 超えて 3,000 とか行くのは いつかなと?
その前にチャレンジ版を投入するといいかな?

改善を目指したけど、結果は改悪になるかもしれないけどさ。
0219動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/28 13:46ID:pSul7e9k
318 :名無しさん :04/02/28 03:08 ID:atMg9E5Y
2/28(土)ヨモギタ少年愚連隊・記憶編 ←ここ
3/ 2(火)16:00〜16:59・チャンネルα「ヨモギダ・ダイジェスト」
「今週土曜から撮影9年超大型企画ついに解禁ヨモギダ少年と感動の再会最新作」
3/ 3(水)16:00〜16:59・チャンネルα「めちゃ2イケてるッ!(再放送)」
 「180日超大作!!岡村大学受験涙と感動ヨモギダ少年3年後の姿」
3/ 4(木)16:00〜16:59・チャンネルα「めちゃ2イケてるッ!(再放送)」
 「岡村受験(秘)結果速報・ヨモギダ原宿で盗撮された涙の衝撃映像は」
3/ 5(金)16:00〜16:59・チャンネルα「めちゃ2イケてるッ!(再放送)」
 「岡村(秘)大学受験本番・美人教師は19歳東大生・恋と勉強の記録公開」
3/ 6(土)15:25〜17:25・めちゃ2イケてるッ!ヨモギダ完結編
3/ 6(土)ヨモギタ少年愚連隊02編
3/13(土)ヨモギタ少年愚連隊03編
3/20(土)ヨモギタ少年愚連隊04編
0220root ★
垢版 |
04/02/28 13:47ID:???
今日のブレーメンはたぶんなかなかだと思うけど、単にスレが速いだけでは
なかなか再現しないんすよね。

ROMも含めたユーザ数が多くないと、再現しないみたい。
ゴールデンタイムで各局の主力番組が目白押しの時の、
一番の人気番組で発生することが多いみたいだから、、、。

とすると、どれが該当するだろう。
live総合スレで聞いてみるかな。
0221動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/28 13:48ID:xMa1zrwb
>>217
peko系実況だけ3000にして人柱にして見るのはどうよと振ってみるテスト。

で、来週金曜1855-2148、TBSでオウム特番あり。

あとテロ朝は1、3、5の深夜、五輪サッカーの予選中継が。
0222仕事人 ★
垢版 |
04/02/28 14:08ID:???
>>122 を基本にちょっと改造してみる。
0223仕事人 ★
垢版 |
04/02/28 14:24ID:???

open(OUT, $DATAFILE, "a+");

これが Configration Error になるんですが
どうすればいいのかなぁ。。。
0226GlobalService ★
垢版 |
04/02/28 15:57ID:???
>214
>ファイル生成のコストがそれなりにかかりますよ。

「1つのファイル作成」と「数百のプロセス待機」のコストを考えるとどうだろ?
実況板とそれ以外の板でbbs.cgiの使い分けが必要になるかも
0228動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/28 23:03ID:PwAhsg/U
試してみたが、他プロセスでファイルをopenしているときでも、chmodは効く。
パーミッションはopen時に判定で、print時は関係無いみたい。
となると、以下の部分で1000越えのメッセージいくつも書かれるのが納得いかないが、
もしかして別のところでchmodで書き込み可能にしてない?

if(-w $dattemp && $lognum > 999){
open(OVER, ">>$dattemp");
print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n";
close(OVER);
chmod(0555, $dattemp);
0230サザン ★
垢版 |
04/02/28 23:34ID:???
>>229
サブルーチンなので、変数名が変わってるだけかと。
0231root ★
垢版 |
04/02/28 23:48ID:???
>>228
あるbbs.cgiが「1000を超えました」を書いて、
そのbbs.cgiがdatをクローズして、chmodするまでのわずかな時間に、
別のbbs.cgiが書いていると。

典型的な競合状態ってやつではないかなと。
つまり、プログラミング的には「腕の見せ所」のはず。
0232動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/28 23:59ID:qYEToTcP
228じゃないけど

あるプロセスがchmodを行って、完了する前に別のプロセスが書き込みモードでopenしてしまう。
すると、最初のプロセスのchmodが完了せず、別のプロセスの書き込み完了まで待たされる。
その間に、さらに別のプロセスがオープンして、、

という感じで、全プロセスがファイルをcloseしない限り、chmodが完了しないのかな。
0233動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/29 00:11ID:VMV/4FdL
でも、なんかおかしいな。

ファイルに対する実際の処理は、要求された順番に行われて欲しいのに
chmod完了待ちの間に、次のopenが成功してしまうというのはどうも・・
カーネル内部でこの辺の優先度がいじられてるのかな。

http://www.dd.iij4u.or.jp/~okuyamak/Documents/NetworkFileSystem.Tune.4.html
の真ん中ちょい下で「chmodを優先するのもアリ」と書いてあるけど
その逆に「chmodをあとまわし」にしているのかもしれない。
0234root ★
垢版 |
04/02/29 00:30ID:???
>>233 のリンク先にこんなのがありますね。

http://www.dd.iij4u.or.jp/~okuyamak/Documents/NetworkFileSystem.Tune.4.html より引用:

File System は、実は、順序による結果の一意決定性の保証をしなくても File System と
して動作するものを作ることができる。 たとえば、2つの process がほぼ同時に write() と
chmod() を リクエストしてきたとしよう。 一応、順序的には『write→chmod』だとする。

この場合、File System は、
「んー。なんかこの write、時間がかかりそうだな。 先に chmod やるか」
と言って、内部で順序を入れ替えてしまっても、 実は バレナイ 。 ばれないということは
(公平性には欠けるかも知れないが)、 File System の実装としては「あり」だと言うことになる。

しかし、write() と chmod() の間の時間が十分に離れていれば、 そしてこの間にこれ以外の
リクエストがいっさい来なければ、 write() と chmod() はこの順序通りに実行される。

仮に、同一のファイルに対する write() 並びに chmod() で、 しかも chmod() されると
write() が実行できなくなるような場合、 外部から観察した場合のリクエスト順序 と
内部でのリクエスト順序 が一致しなくなる。 しかも、常に一定の結果になれば良いのだが、
その保証が無い場合、journal を利用しても結果が再現できなくなる。 上の例だと、
wirte と chmod が十分時間間隔を開けて到着したので write->chmod の順で
ファイルシステムに反映した結果を client に返したのだが、 この直後に system down
を起こしたとしよう。 journal を実行する際には write と chmod は十分短い間隔で
要求されるので、 chmod->write の順で実行してしまったら、 同じ結果を得ることはできない。

0235root ★
垢版 |
04/02/29 00:34ID:???
つまり、>>234の例とは逆に、chmod()が(コストが高いから等の理由で)
なかなかスケジュール(実行)されないということも、当然ありうるということになりますね。
0237動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/29 00:57ID:YkP68lMj
chmodの後の
>$lognum++;
って、subject.txtに書き込むレス数で使われるはずで、実際subject.txtには
1000以上の数値が書き込まれているから、chmodで待つということは無いと
思うんだけど。
0238197
垢版 |
04/02/29 01:00ID:7x47pFWz
えと、>>197 あるいは >>212(←これは俺と別の人)の方法はどうでしょう。
これなら over 1000 判定されたら、 すでに 8) 以降にある別プロセスは蹴れないけれど
8) 以前のプロセスは蹴ることができるので、まあ 1050 位で止まると思う。

>>212 の人が言うように泥縄的アプローチではあるけれど。
0240GlobalService ★
垢版 |
04/02/29 01:10ID:???
>>238-239
>213-214にあるが
ファイルを作らないでやる方法を考える方が先らしい
0241197
垢版 |
04/02/29 01:16ID:7x47pFWz
>>239
じゃ、>>212 の方法で、ロックファイル(ディレクトリ)はそのまま残して
後で適当に消すってことで。

>>240
それは I/O 負荷的問題?それともポリシーの問題?
0242root ★
垢版 |
04/02/29 01:22ID:???
気になったんで、さらっとカーネルソースを読んでみた。

ひさしぶりなんで感覚がよみがえらないけど(ctagsの作り方をすっかり忘れていた私)、
chmod()やfchmod()すると結局、
setfmode()っていうカーネル内の関数が呼ばれて、
その中でvn_start_write(vp, &mp, V_WAIT | PCATCH)して、
それが正常終了しないとVOP_SETATTR(chmodの本体部分)に
いきつかないようになってるみたい。

vn_start_write()のコメントを読んでみると、

/*
* Preparing to start a filesystem write operation. If the operation is
* permitted, then we bump the count of operations in progress and
* proceed. If a suspend request is in progress, we wait until the
* suspension is over, and then proceed.
*/
int
vn_start_write(vp, mpp, flags)

なんてことが書いてあって、V_WAITといういやーなフラグ立ててるみたいだから、
すべてのペンディングになっているwrite()がいったん(カーネル的に)一区切りつかない限り、
VOP_SETATTR()が行われないような予感。

つまり、fchmod()にしても(>>139)だめっていうことになるすね。
というか、カーネル的にこうなっているということは、chmod()するアプローチでは絶対だめってことじゃん。

うーむ。
0243GlobalService ★
垢版 |
04/02/29 01:27ID:???
>>242
それって今までの処理(書込み禁止のチェック)は破綻ってこと?

だとしたら
(>212に処理順番を入れて書いた) >213を実行?
0244動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/29 01:33ID:fKbOd8s3
>>241-242
>>91もそうなんだけど、だからこそストップ(ロック)ファイルを作成してはと書いてみた。
あらかじめ作っておいてストップするときにリネームするという方法もあるが
ディレクトリ内のファイル数が増えるのが難点だなあ。
あと、I/Oを減らしたいなら1001以降のレス数を
subject.txtに反映するのを止めるという手もある。
0245239
垢版 |
04/02/29 01:33ID:fntZHoXb
chmodが完了して帰ってくるまでに時間がかかるとすると
> ・chmod --- 成功したらロックディレクトリ消去
がイイような。
0246root ★
垢版 |
04/02/29 01:37ID:???
>>243
超多数のwriteが超同時多発的に出たりすると、vn_start_write()でブロックされて、
VOP_SETATTR()に行かなくなるような気がします。

でも、今10分ぐらい読んでみただけなんで、
このへんは、もっと中身をよく知ってる人に確認すべきな気がしますが。

個人的には、書き込みできないことの判定=ファイルモードが555、というのは
いまのままでいいから、1000超えのところだけでも、NNNNNNNNNN.dame とかいう
ファイル「も」作ることにして、
書き込めない または そのファイルがあったら 書き込み禁止とかにすべきかなとも思ったり。

今日はそろそろ、おやすみの時間。
0247root ★
垢版 |
04/02/29 01:40ID:???
読んでみたのはFreeBSD 5.2.1-RELEASEのカーネルなんで、
Linuxでは同じところをどうやってるか、誰かおしえていただけるとうれしいかも。

おやすみなさり。
0248動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/29 02:02ID:VMV/4FdL
厳密に必ず1001で止めなきゃ行けないシステムならatomicなアプローチが絶対必要だけど
2chでは10や20オーバーする程度は全然平気なんだから
素直に「書き込む前にレス数を数えて、1000を超えてたら書き込まない」がよろしいかと。

つまり>>122系統のアプローチで、1001OVER書き込みではなく
レス内容の書き込みの前にレス数を判定すると。

問題は、追記モードでopenした場合に読み込みがうまく出来るかだけど、どうだったかな?
読み込みが可能なら問題なしだけど、不可能な場合、書き換えモードでopenしなくちゃいけない。
この場合、排他モードに(又はlock)しないと
レスを書き込む前に.datの末尾にseekしてから実際に書き込むまでの間に
別プロセスでの書き込みがはさまってしまうかもしれない。
すると末尾にゴミがついたり書き込みが消えると言うことが頻発してしまう。
0249動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/29 02:16ID:VMV/4FdL
で、perl全然知らないんだけど>>122を元に

if (open(OUT, "+>>$DATAFILE")) {
@logdat = <OUT>;
if (scalar @logdat > 999) {
print OUT "$outdat\n";
print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n";
close(OUT);
chmod(0555, $DATAFILE);
} else {
print OUT "$outdat\n";
close(OUT);
}
}


print $outdatやclose(OUT)が複数箇所で出て非常によろしくないけど
とりあえずwindows上では動作した。
0250▲ 某ソレ511
垢版 |
04/02/29 02:20ID:3Ckm5k37
で、そのchmodがうまく効いてくれないのが問題じゃなかったっけ?
1000レスを大幅にオーバーしちゃうのは。
0251動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/29 02:23ID:VMV/4FdL
だから、chmod完了待ちの間に大量のwriteリクエストが来ちゃうことが問題なの。
writeがあまり来なくなる(一段落する)と、chmodが完了するから大丈夫。

↑で動作したと書いたけど、
競合状態(複数プロセス)でどうなるかはテストしてない。
FreeBSD上でどうなるかも。
0252動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/29 02:28ID:VMV/4FdL
あ、違う。
すみません。私がアホでした。


さらに
if (1000over) {
そのままclose();
}
を入れないと意味無いんだった。
0254動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/29 02:32ID:N/LelD+a
まとめ。
・chmodによるロックは高負荷時に効かなくなる。

対策案
まともな対処
・トランザクション処理をするDBDなどで1000ロック処理をする
分かりやすい対処
・ファイルシステムでロックファイルを使う

提案
・泥臭い処理を書くとバグるから、出来るだけCPANの.pm(Perl Module)を流用しよう
0255仕事人 ★
垢版 |
04/02/29 02:36ID:???
>>249

if (open(OUT, "+>>$DATAFILE")) {


ってのがあるんだ。
入れてみよう。
0256仕事人 ★
垢版 |
04/02/29 02:43ID:???
#open(OUT, ">>$DATAFILE");
#print OUT "$outdat\n";
#close(OUT);

if (open(OUT, "+>>$DATAFILE"))
{
print OUT "$outdat\n";
my @logdat = <OUT>;
if(scalar @logdat > 999)
{
print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n";
close(OUT);
chmod(0555, $DATAFILE);
}
else
{
close(OUT);
}
}
0257仕事人 ★
垢版 |
04/02/29 02:44ID:???
>>256 版を全サーバに入れました

live5 を除く
live8/9 は root★さんのもじもじが必要
0258▲ 某ソレ511
垢版 |
04/02/29 02:45ID:3Ckm5k37
if(scalar @logdat > 1000)
{
close(OUT);
}

この文も入れたほうがいいかと、、
0262仕事人 ★
垢版 |
04/02/29 03:06ID:???
こうか?

#open(OUT, ">>$DATAFILE");
#print OUT "$outdat\n";
#close(OUT);

if (open(OUT, "+>>$DATAFILE"))
{
print OUT "$outdat\n";
my @logdat = <OUT>;
$lognum = @logdat;
if($lognum > 1000)
{
DispError("ERROR!", "ERROR:このスレッドには書き込めません。");
close(OUT);
}
if($lognum > 999)
{
print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n";
close(OUT);
chmod(0555, $DATAFILE);
}
else
{
close(OUT);
}
}
0263▲ 某ソレ511
垢版 |
04/02/29 03:10ID:3Ckm5k37
こうかな?

#open(OUT, ">>$DATAFILE");
#print OUT "$outdat\n";
#close(OUT);

if (open(OUT, "+>>$DATAFILE"))
{
print OUT "$outdat\n";
my @logdat = <OUT>;
$lognum = @logdat;
if($lognum > 1000)
{
close(OUT);
DispError("ERROR!", "ERROR:このスレッドには書き込めません。");
}
elsif($lognum > 999)
{
print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n";
close(OUT);
chmod(0555, $DATAFILE);
}
else
{
close(OUT);
}
}

$lognum が宣言してない変数なら、
 $lognum = @logdat;
  ↓
 my $lognum = @logdat;
でたぶんいいかと。
0264仕事人 ★
垢版 |
04/02/29 03:10ID:???
こうだった

#open(OUT, ">>$DATAFILE");
#print OUT "$outdat\n";
#close(OUT);

if (open(OUT, "+>>$DATAFILE"))
{
print OUT "$outdat\n";
my @logdat = <OUT>;
my $lognum = @logdat;
if($lognum > 1000)
{
DispError("ERROR!", "ERROR:このスレッドには書き込めません。");
close(OUT);
}
if($lognum > 999)
{
print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n";
close(OUT);
chmod(0555, $DATAFILE);
}
else
{
close(OUT);
}
}
0265動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/29 03:13ID:fntZHoXb
たまに「このスレッドは1000を超えました〜」が書き込まれないような気はしますが、
1000を超えて書き込まれることはなくなるはずです。

……いいんだろうか。
0266仕事人 ★
垢版 |
04/02/29 03:15ID:???
わくわく
どきどきってことで、
0267▲ 某ソレ511
垢版 |
04/02/29 03:15ID:3Ckm5k37
if($lognum > 999)
 ↓
elsif($lognum > 999)

はなおしてもらわんと結局意味がないような、、
0269仕事人 ★
垢版 |
04/02/29 03:17ID:???
さらに修正

#open(OUT, ">>$DATAFILE");
#print OUT "$outdat\n";
#close(OUT);

if (open(OUT, "+>>$DATAFILE"))
{
print OUT "$outdat\n";
my @logdat = <OUT>;
my $lognum = @logdat;
if($lognum > 1000)
{
close(OUT);
DispError("ERROR!", "ERROR:このスレッドには書き込めません。");
}
if($lognum > 999)
{
print OVER "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n";
close(OUT);
chmod(0555, $DATAFILE);
}
else
{
close(OUT);
}
}
0270仕事人 ★
垢版 |
04/02/29 03:19ID:???
またまた修正

#open(OUT, ">>$DATAFILE");
#print OUT "$outdat\n";
#close(OUT);

if (open(OUT, "+>>$DATAFILE"))
{
print OUT "$outdat\n";
my @logdat = <OUT>;
my $lognum = @logdat;
if($lognum > 1000)
{
close(OUT);
DispError("ERROR!", "ERROR:このスレッドには書き込めません。");
}
if($lognum > 999)
{
print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n";
close(OUT);
chmod(0555, $DATAFILE);
}
else
{
close(OUT);
}
}
0271▲ 某ソレ511
垢版 |
04/02/29 03:22ID:3Ckm5k37
>>268
あ、DispErrorでexitするから結局elsifにしなくてもいい、ってことね、、
何か気味悪いなw
0272動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/29 03:26ID:VMV/4FdL
print OUT "$outdat\n";
を1000over判定の後にして$lognumを++する方が。

もし書き込めなかったら狂っちゃうけど
chmod問題の原因はそっちっぽいから。
0274名無し募集中。。。
垢版 |
04/02/29 03:27ID:Khv3Ivk3
狼で1000いったスレに
1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。
が書きこまれないです。
1000で止まってますけど
0277仕事人 ★
垢版 |
04/02/29 03:28ID:???
chmod(0555, $DATAFILE);
したファイルには書けないんだから
次のbbs.cgiは早めに判定した方がいいなぁ

512 超え判定と同時にやるのがいいのだろうか?

どやってやるの?

これはbbs.cgiのかなり前半
my $datsizeis =(stat("$DATAFILE"))[7];
unless( $datsizeis <= 512000){
DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!");
}
0278▲ 某ソレ511
垢版 |
04/02/29 03:30ID:3Ckm5k37
>>272
あ、それ思った。

if (open(OUT, "+>>$DATAFILE"))
{
my @logdat = <OUT>;
my $lognum = @logdat;
++$lognum;
if($lognum > 1000)
{
close(OUT);
DispError("ERROR!", "ERROR:このスレッドには書き込めません。");
}
print OUT "$outdat\n";
if($lognum > 999)
{
print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n";
close(OUT);
chmod(0555, $DATAFILE);
}
else
{
close(OUT);
}
}

あと、各所で1001が消えてるみたいだけど、気にしない方向で。
0279仕事人 ★
垢版 |
04/02/29 03:35ID:???
変更

if (open(OUT, "+>>$DATAFILE"))
{
my @logdat = <OUT>;
my $lognum = @logdat;
++$lognum;
if($lognum > 1000)
{
close(OUT);
DispError("ERROR!", "ERROR:このスレッドには書き込めません。");
}
print OUT "$outdat\n";
if($lognum > 999)
{
print OUT "1001<><>Over 1000 Thread<>このスレッドは1000を超えました。 <br> もう書けないので、新しいスレッドを立ててくださいです。。。 <>\n";
close(OUT);
chmod(0555, $DATAFILE);
}
else
{
close(OUT);
}
0280▲ 某ソレ511
垢版 |
04/02/29 03:41ID:3Ckm5k37
>>277
それって
unless( -s $DATAFILE <= 512000){
DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!");
}
でよいような気がする。。あとで$datsizeisを別に使うならまだしも。
で、ファイルのパーミッションを取得するのは
 (stat("$DATAFILE"))[2]
だそうです。
0282▲ 某ソレ511
垢版 |
04/02/29 03:45ID:3Ckm5k37
>>281
あっ、そっちのほうがスマートだね、、じゃあ、
unless( -w $DATAFILE){
DispError("ERROR!","ERROR:このスレッドには書き込めません。");
}
unless( -s $DATAFILE <= 512000){
DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!");
}
こうだとよいのかな?(下はどうでもいいけど、、)
0283仕事人 ★
垢版 |
04/02/29 03:47ID:???
入れてこますか

unless( -w $DATAFILE){
DispError("ERROR!","ERROR:このスレッドには書き込めません。");
}
unless( -s $DATAFILE <= 512000){
DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!");
}

でも 二回実行するより stat とったほうがいいのかな?
0284仕事人 ★
垢版 |
04/02/29 03:49ID:???
× 入れてこますか
○ 入れてみますか

0286動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/29 03:58ID:fntZHoXb
unless (-w $DATAFILE) {
DispError("ERROR!","ERROR:このスレッドには書き込めません。");
}
unless (-s _ <= 512000) {
DispError("ERROR!","ERROR:このスレッドは512kを超えているので書けません!");
}
でどうでしょ。
0287動け動けウゴウゴ2ちゃんねる
垢版 |
04/02/29 03:58ID:VMV/4FdL
書き込み可能かの判定はaccess()でも出来るけど
サイズの判定はstat()じゃないと駄目なので、結局stat()は呼ばれる。

と思うのでstat()1回に一票。
0289仕事人 ★
垢版 |
04/02/29 04:02ID:???
つまり

if($lognum > 1000)
{
close(OUT);
DispError("ERROR!", "ERROR:このスレッドには書き込めません。");
}

これは保険で

unless( -w $DATAFILE){
DispError("ERROR!","ERROR:このスレッドには書き込めません。");
}

が通常のルートですなぁ
メッセージ変えておこうかな、
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況