トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

BBS-サポート掲示板/537

ページの作成や編集にはユーザ登録が必要です。

 カウンタがリセットされてしまう - akiguti (2006年05月31日 20時43分36秒)

FrontPageにcounter *****で設置したカウンタが何かの拍子にリセットされて再度0からのカウントになってしまう事があるのですが、何か考えられる原因はありますでしょうか?3.6.0でlolipopのレンタルサーバーに設置しています。

  • ファイルロックを処理をかけていないので、複数の箇所から同時アクセスされたりすると壊れることがあります。私が試した環境では、ブラウザの更新キー(WindowsIEならF5キー)押しっぱなしでも壊れました。 - あき (2006年05月31日 22時31分51秒)
  • 対策版をサクッと作成してみました。plugin/info/Counter.pmを添付のものと差し替えてみて下さい。今までは、log/count-*.txtというファイルに、数字でカウントが保存されていましたが、対策版はファイルサイズがカウントと等価になります。アクセスされる度にファイルサイズが1byteずつ増えて行く仕組みです。追記書き込みですので、ファイルが壊れるということはまずありません。(理論上です。私は以前こういうやり方でカウンタCGIを作成して実績もありますが、同様のやり方をしている例を見たことがありませんので、何とも…です。ただ、ロックをきちんときちんとかけても壊れることがあるそうですので、それに比べれば信頼性は高いんじゃないかと思っています) - あき (2006年05月31日 23時47分19秒)
  • 迅速な対応有り難う御座います。自分の設置設定ミスでリセットされていたわけではなく一安心です。早速、対策版を導入させて頂きましたので、これで運用し様子を見たいと思います。 - akiguti (2006年06月01日 14時00分49秒)
  • 補足というべきか分かりませんが、"ロックをきちんときちんとかけても壊れることがある"のではありません。きちんとセマフォが取れる方法でロックをかけないと駄目なだけです。ロックをかける手段は、そのアクション中に他のプロセスなどの横槍が入らない方法でなくてはならず、OSによってはロック用のシステムコールを用意してあったりします。CGIから一般的に使える方法としては、mkdirを用いた方法が良いと思います。ロックをかける際によくやりがちな間違いは、ロックが取れそうか確認して、ロックを実行するようなロジックを用いてしまうことです。正しいやり方は、とにかくロックをかけようとしてみる、そしてそれに失敗したら、ロックが取れなかったのだと判断する、というロジックを用いることです。 - Kinsan (2006年06月01日 21時44分50秒)
  • んん? http://www.tohoho-web.com/wwwcgi8.htmに記載の『■ 結論』の部分をみる限りでは、「上手な手段を使っても壊れる」という意味にとれるのですが…。記載のURLに紹介されているflock()を使ったやり方は、「ロックを取ろうとして失敗したらロックが取れなかったと判断」しているように見えます。間違いではないと思いますよ。おそらくここで言う「ロックをきちんときちんとかけても壊れることがある」と言うのは「flock()を使用していないプロセスの書き込み」があった場合に壊れてしまう(ロックをかけていてもお構いなく上書きされてしまう)、という事ではないかと…。また、同ページには、『mkdir()を使う際の限界(「■ ロックディレクトリが残ってしまうのを防ぐ」の部分)』についても少し触れられています。個人的にはflock()が使えるシステムなら、flock()を選択した方が良いのではないかと…。 - あき (2006年06月03日 15時09分49秒)
  • flock()が使える時にはflock()を使うべきなのですが、プロバイダーのサーバーを用いている場合には、使って良いか判断しづらいのが困りものです。というのは、http://www.linux.or.jp/JM/html/LDP_man-pages/man2/flock.2.html にも記述があるように、古いバージョンのNFSサーバーからマウントされたファイルシステムであれば、flockシステムを用いるべきではありませんので。NFSは元々ステートレスな仕組みですし、Linuxで採用されているNFSはちょっと前までは古いバージョンのものでしたので。また、perlのflock()関数が、どのシステムコールを用いて実現されるかは、perlのソースの./configure実行時にそのシステムで適当と思われる実装に決められますので、ある程度は信用できますが、NFSマウントのこともあり、100%確実とは思いづらい気がします。そういった事情を考慮すると、複数のプラットフォームで実行されるCGI においては、mkdirを用いておくのが安易ではありますが、確実な選択です。Unix系の考え方として、"約束事"は守られると仮定するのが一般的です(/var/tmpにおかれるテンポラリーファイルの扱いなどがそんな感じです)。そのため、"flock()を仕様していないプロセスの書き込み"は、起きない前提でプログラムを書き、起きないような運用ができるようにするというのが一般的なアプローチだと思います。ロックディレクトリーが残ってしまう問題は、プロセスが途中で異常終了した場合などに発生しますので、出来れば対策した方が良いですが、私ならばロックに失敗した時に、ロックディレクトリーがある程度以上(例えば数時間以上)古かったら削除してしまうというロジックを採用します。 - Kinsan (2006年06月03日 17時41分15秒)
  • ちょっと横道に入りましたが、使うべき方法の選択とロジックには注意が必要ですが、きちんとした方法でロックすれば壊れることはないはずということです。そうでなければ、データベースシステムなんて成り立ちませんし、オンラインショップの様な問題が発生したら影響の大きいシステムなんて怖くて動かせません。 - Kinsan (2006年06月03日 20時20分28秒)
  • FSWiki 3.6.2 にて一時的な対策が実装されています。後続バージョンにて再度発生するようでしたら別途起票ください。 - KG (2017年12月06日 16時11分31秒)
お名前: コメント:
Counter.pm

最終更新時間:2017年12月06日 16時11分31秒