小田急予約サイトで競合状態バグによるトラブル 98
ストーリー by yoosee
あーあやっちゃいました 部門より
あーあやっちゃいました 部門より
Anonymous Coward曰く、"13日の朝日新聞の記事によると、小田急電鉄の特急券予約サイト「ロマンスカー@クラブ」で、システム障碍により少なくとも6件の情報漏洩または誤課金が発生したとのことで、小田急の公式アナウンスが出ている。
それによると、予約操作したのに予約が行われない、何も操作していないのに予約された、購入していないのにポイントが減額された、他の会員の画面が表示されたなどの現象が確認されているとのことで、いわゆる競合状態バグ(race condition bug)による事故だと思われる。類似の事故として2004年2月のストーリー「国税庁のWeb確定申告書作成システム、作ってみたら他人の申告書」が思い起こされる。この種のバグをなくすためにはどのような開発手法、検証手法が有効であろうか。"
開発手法、検証手法以前に (スコア:3, 参考になる)
あとはstaticの認識と。
Re:開発手法、検証手法以前に (スコア:2)
デバック環境って言うのであれば、
競合関連は処理速度が速くなればなるほど再現が困難になるので
最低限必要なのは、わざと処理速度を遅く出来るデバッグ環境とかかなぁ
でもデバックで求められるのは結局普通の試験と一緒の検証方法でしょう。
地道な努力しかないのではないかと、無論それに伴ってコストは増大しますが..
逆にこんなアルゴリズムなら回避しやすいとかなら有りそう?
Re:開発手法、検証手法以前に (スコア:2, 参考になる)
# うちではStrutsベースなんだけど、Actionについても同様。
VBとかからクラスチェンジしてきた奴とかは、その辺の概念まできっちり押さえてくれてないことが多い。
人材不足なんだろうけど、その辺きちんと把握しているエンジニアが一人はいるんだよな。
Re:開発手法、検証手法以前に (スコア:1)
Re:開発手法、検証手法以前に (スコア:1)
その問題を回避する為に、Servletの全メソッドでsynchronized していた後輩が居ました。どこでそんなテクを…
Re:開発手法、検証手法以前に (スコア:1)
staticを使ってのパフォーマンス向上は諸刃の剣のはずなのだけど…やたらとpubli staticなsetter/getterを作りたがるPGがたまに居て…_no
Re:開発手法、検証手法以前に (スコア:0)
いまどき、こんな事言うヤツを開発に参加させてはイカンのでは?
オマエだけはCで書けって言ってあげましょうよ。
Re:開発手法、検証手法以前に (スコア:2, 参考になる)
public class Configuration {
private static String s1;
public static void setS1(String s){
s1 = s;
}
public static String getS1(){
return s1;
}
}
こんなの書いてきた人います。しかも複数…。
Re:開発手法、検証手法以前に (スコア:1, 興味深い)
Struts使ったフレームワークのActionFormでこれやられました。
バグを指摘したら各Actionでresetメソッド呼んでくれと回答されて
マジ切れしました。
DB以外に手出すなよこの会社~!!!!
そのDBもバグで酷い目にあった事もあるけど・・・
会社名は言わなくても解るよね。
Re:開発手法、検証手法以前に (スコア:1)
『newしないとクラスが使えないようだが?』
『staticなんて飾りです。偉い人にはそれが分からんのです』
まあ、Math classみたいにそれ自体にデータを持たない場合の
static methodはありだし、システム全体の排他制御のための
オブジェクトなど複数オブジェクトがあると困るような場合は
Singletonが正しいアプローチだけどさ。
なんにしろ、設計に存在しないグローバル変数はバグの元。
Re:開発手法、検証手法以前に (スコア:1)
>別なスレッドの影響を受けちゃうような実装に*なっていない*ことを、
>表明できる仕組みがあればいいのになぁ
コンパイラに対してってのは難しいですねぇ。
コンパイラに宣言する以上はコンパイラは実装をチェックする
必要がありますが、そのメソッドから呼び出される処理は全部
再帰的にチェックしなくてはいけません。
流石にコンパイラの手に負えないですね。クラスファイルの
形式にも変更が必要になります。
変に採用すると
「ちゃんとスレッドセーフだけど、コンパイラが文句を言うので表明できない」
なんてケースが出てきそうです。
>そういうグローバル変数に触れていないメソッドであることを、
>コンパイラにも分かる形で宣言できたらいいのに
グローバル変数云々だけならコンパイラにもできそうですが、
スレッドセーフかどうかはとは別問題なので、役立つ場面は
少なくなります。
ありがちなパターンを見つけ出したいなら、FindBugsなどの
ツールを使って「バグっぽい」コードを警告してもらうのが
限界でしょう。
それ以上のことは、JavaDocの表明を信じる or 自分でソースを追いかける しかないです。
Re:開発手法、検証手法以前に (スコア:1)
Re:開発手法、検証手法以前に (スコア:1)
ただ、アノテーションは「スレッドセーフをコンパイラに対して表明する」ではなく、「ツールや
他の開発者にそう主張している」ですから、JavaDocでの表明と本質的な違いがないです。
・他の開発者に伝えるのなら、JavaDocで表明する
(フォーマットを統一したりしたいなら-tagオプションやTaglet、Doclet)
・コンパイラやツールがスレッドセーフの保障をするのは無理
・作成者の表明(JavaDocやアノテーション)を疑うならソースを追うしかない
が本題です。
Re:開発手法、検証手法以前に (スコア:0)
Re:開発手法、検証手法以前に (スコア:0)
「特定のタイプのバグ」を起きないように設計する事はできる。
そうでなきゃそこいら中のシステムが競合状態ばかりになっちゃうよ。
逐次処理 (スコア:2, おもしろおかしい)
逐次処理しろ!処理中だったら待たせとけ!!
# でもマルチスレッド大好きなのでID。
Re:それてるのでオフトピ (スコア:1)
システム「現在、予約が多数の方と競合しています。出し抜きますか?」
システム「処理待機中に23名の方に追い越されました」
システム「本日の営業時間内で処理が完了しません」
システム「本日のご利用ありがとうございました」
誰も使わなくなりそうだ、と思った。(笑
似たような体験 (スコア:2, 参考になる)
券売機で切符を買って席に行くと、すでに別の人が座ってました。
きっとどちらかが間違えているんだろうって思い、切符を見比べてみると、これがまったく同じ。
私はちょっと酔っ払ってたので、自信なさげに駅員を捕まえて確認してもらったら、駅員曰く、「きっと、同時に押しちゃったんですねえ」。
別の席をもらって無事にかえりました。
#まさか、あいかわらずのシステムだったなんて・・・
Re:似たような体験 (スコア:1, 興味深い)
意味不明のユーザーインターフェースに加え、説明も皆無。
初めてアレを使って、ちゃんと券が買える人がいるのか疑問。
valgrind & 思いで (スコア:1)
一応、multithread での資源の共有違反を検査してくれます。
共有違反チェックで幸せになったことないのですが、他の人はどうなんでしょ?
昔新人が、loop counter の変数をいちいち宣言するのが面倒なんで global で
external int loopcnt ;
みたいにしていました。なかなか斬新な考え方だなと感心しました。
しかしdebug にはかなり苦労していた模様です。
このタイプの共有違反は valgrind では見つけてくれません。
Re:valgrind & 思いで (スコア:1)
> 今の現場は、グローバル変数禁止というコーディングルールがあるのですが
グローバル変数なし、って辛くないですか?
static なグローバル変数もやっぱりグローバル変数なんでしょうか。
関数の中に static で変数宣言しておいて、
getter のようなもので静的変数にアクセスするのでしょうか。
けど、そうするとグローバル変数を置かない意味があまり無いような。
ん・・・まてよ? MFC 使おうものなら、
最初からグローバル変数なコードが。
# ずっと子供のままでいたいw
Re:valgrind & 思いで (スコア:1)
> 完全になしってのは難しいかもしれません。
> でもほとんどの場合は必要ないし、乱用されれば死ねます。
>
> デスマーチマニアならグローバル変数を使えばいいけど、
> それ以外の方にはお奨めしません。
もちろん、不必要にグローバル変数を増やすような真似はしません。
1. グローバル変数をコーディングしてはいけないこと、と
2. グローバル変数が多いことによるバグ&デバッグが難しいこと、
は別問題だと思っているので聞きました。
言い換えると、
悪いからなくせばいいという規則を作るのではなく、
無くすアプローチが大切なんじゃないの?と。
> ...でもこういうことを聞いてくる人に、プログラミングなんて
> させたくないと思う今日この頃。こういう人がつくったグローバル
> 変数の尻拭いに一体どれだけ人生を浪費させられたことか。
こちらの意見は肝に銘じておきます。
1プログラマとして... (スコア:1)
ついこの間カットオーバーしたシステムでもあったし...
# そっちはシステムテストで発覚して、即時対応したけど。
構成がわからない以上、ここが悪い、こうした方がよかったみたいなのは言えませんが、
ツールを使った過負荷テストをやってみるか、10人くらい人を集めて
「せーの、どん」
で操作するテストをしてみるとかでも検出できるはずなんだけどなあ。
そろそろテスト手法の標準化にも着手する必要があるかな、と思ったりはしているのですけどね。
# あ、普通やってる? ...失礼しました~
500円? (スコア:1, 参考になる)
Re:500円? (スコア:1)
ちゃんと物価の変動に連動してくれるんだろうな>デファクトスタンダードのお詫び。
# 心配するところが大間違いなのでID。
全線乗車券2枚のがよさそう (スコア:1)
ロマンスカー@クラブを使う客なら特急乗車をひんぱんにする客だから、新宿~町田 (360円) の客が多いということを考えると、全線乗車券2枚なら500円に見合うのではないかと。
システム障害は避けられない (スコア:1)
銀の弾丸はやっぱりないことを物語っているんじゃないかな。
当然そんな中で開発していればこういったことはいくらでも起こると思う。
自分は大抵、事後処理の火消し役なんで
FileOutputStreamでGrepしたりstaticでgrepしたり、Diffしたり、
request,session,applicationの内部変数監視ツール作ったり、
トランザクション管理をトレースしたり、オープンカーソ…うう悪夢が…
これ以上は勘弁して下さい…。
何にしろGrepとDiffで大抵解決できますっ!ってダメかな?
Re:システム障害は避けられない (スコア:3, おもしろおかしい)
ほしいなら、すぐにあげてもいいけど、
途中から検証ツールに「あの機能は無駄だから削ってくれ、この機能が必要だからつけてくれ」みたいな話になって…
まったく、もう!
えんじにありんぐ (スコア:1, おもしろおかしい)
にこやかに説明するのやめてくれ。
この障害を再現するシステムはどうやってできる? (スコア:1)
効率化のためにオブジェクトをいちいち生成・開放せずにプーリングするようにしておいて
ログイン時に開いているオブジェクトを取得、
ログアウト時にオブジェクトを手放すようにして、
ただし、同一セッションでログインしたら以前のオブジェクトへの参照を取得できるようにすればいいのかな?
マクロの基本は検索置換(by y.mikome)
Re:この障害を再現するシステムはどうやってできる? (スコア:1)
--- de FTNS.
原因(プレスリリースのPDF)より (スコア:0)
Re:原因(プレスリリースのPDF)より (スコア:1)
要は、仕様変更の影響範囲の把握と退行テスト項目が
適当ではなかったということですか。
ありがちと言えばありがち・・・。
--- (´-`)。oO(平和な日常は私を鈍くする) ---
Re:原因(プレスリリースのPDF)より (スコア:1)
b. エラーにならないことだけを確認していて、中身まで見てなかった。
c. 複数同時アクセステストはやってたけど、同じデータを入れてたので発覚しなかった。
どれにしても、ちゃんとした手順なりツールなりを適用していれば避けられたはずだが...
Re:原因(プレスリリースのPDF)より (スコア:1, すばらしい洞察)
「ちゃんとしたツール」
って何よ?
Re:原因(プレスリリースのPDF)より (スコア:1)
# あったら教えて欲しい
Re:ストーリの題名 (スコア:1)
そもそも利用履歴の照会ページが(元から重かったんですが)常軌を逸するほど激しく重くなっていて確認しづらいことこの上ありません。
おまけにどうも、利用履歴自体はどうやら整合性は取れていて、残高だけがさっくりと消えている現象もあるみたいです。私の場合だと、積み立て履歴とカード会社からの請求履歴が一致しているかどうかまでチェックしてようやく気付いたほど。
それでも「とにかく自己申告してくださいね」との一点張りなので、泣き寝入りを狙っているとしか思えませんでした。
双方の言い分をきいてみたい (スコア:0)
開発発注者側と受託側の言い分を聞いてみたいナァ。
「仕様が云々」
「予算が云々」
「テストとデバッグの時間が云々」
「エンジニアのスキルが云々」
「上司が云々」
「チームのあの娘を云々」
………だれが正しいのか判断がつかなくなる悪寒
私が携わってきた数十のプロジェクトでリリース後に障害が発生した中で共通しているのは「テストを含めた開発期間不足」→「予算不足」→「きっと政治的な云々」だったかなー。
もう足を洗ったからどうだっていいことなんだけど。
Re:双方の言い分をきいてみたい (スコア:2, 興味深い)
毎月新しいバグが出て挙動が変わるからサイトを更新してるのがわかります。ただ単にリリース期間が短すぎてテストしてないだけなんじゃないかな。
言っちゃ悪いですが座席の予約なんて本来は大した処理じゃないんです。ドル箱システムですからハードやインフラに問題があるとは考えられません。おそらくは大本のレガシーな予約システムとの連携部分の設計か実装が稚拙で思った以上にパフォーマンスが出ず、HWの増強予算が出るまでの応急的なパフォーマンス対策をしているうちにぼろが出始めたってことなんじゃないでしょうか。
Re:双方の言い分をきいてみたい (スコア:1)
Re:双方の言い分をきいてみたい (スコア:1)
Re:双方の言い分をきいてみたい (スコア:1)
一日27時間が必要になります。
# 机の下で2時間、仮眠をとるのも憚られる状況だと、一日24時間では...
notice : I ignore an anonymous contribution.
Re:いきなりオフトピですみませんが (スコア:1, 興味深い)
このあたりの問題の元凶は
これだな。当時の(今も?)国語審議会が馬鹿をやったってことだ。
「障碍→障害」のほかにも「妨碍→妨害」「註文→注文」「遺蹟→遺跡」とかいろいろある。
まあ、漢字一文字一文字に意味を込めたがることもあるんで、「『害』の字が気に入らん」という人が出てくるのも分からんではないが……。
ちゃちゃで申し訳ないが (スコア:1)
fjの教祖様
Re:ちゃちゃで申し訳ないが (スコア:1)
「あの作品、萌えないけど燃えるよな」とか使いますし。
システムしょうがい (スコア:1)
そうして、にほんごがどんどんひらがなになっていくのであった:-)
外注もやばい? (スコア:1)
日本語には同音異義語がいっぱいあるので、「同じ音でよくない単語がある」と言いだすと使える単語がかなり減ってしまいます。今はこういうマヌケな意見は聞かれなくなったので安心ですが。
Re:単純に (スコア:1)
> そんなに回避が簡単なバグなのかい?これは
同感。 Google辺りのエンジニアでもやらかしますし、我々のような一山幾らの人材がミスるのは仕方ないでしょう。
但し、想定内の事態でなければならないのは言うまでもありませんが。
Re:単純に (スコア:1)
そんなの Web アプリケーションじゃなくても常識です。 シェル・スクリプトでも、オフィス・アプリケーションでもね。
経験上、タコな開発者かどうかの区別は、 競合やセキュリティをちゃんと意識して設計・開発しているかどうかでわかるような気がする。 ほかには、シンプルさとか、パフォーマンスとかかな?
Re:単純に (スコア:1, 参考になる)
うん、それは同意する。こういうのが出したら恥ずかしいバグだってことにもね。
その上で、ベテランでも足をすくわれることがあるのが排他制御絡みのバグだと思う。
足をすくわれるのは大抵、陽に表われていない操作が色々絡んでいることが多くて
簡単な例を示すのが難しいんだけど、例えば「double-check lock patternはthread
safeじゃない」っていう話。今ではあちこちで取り上げられてるから常識に
なってるだろうけど、あれを自分一人で最初から気づいていた人ってどのくらい
いるだろうか。
他には例えばfinalizer絡みのバグ。finalizerは実質非同期に走るんで、
マルチスレッドと同じ配慮が必要なんだけれど、「このオブジェクトはこの
スレッドでしか触ってない」と思い込んでると見落とすことがある。
経験的には、コードレビューが効果的だと思う。たとえベテランであっても
思い込みって自分ではなかなか気づかないものだしね。