旅のトラブルシューティングを行うために、一度、非常に困難なバグ

午後、最終的には私の良い日にはバグの問題を解決するため、このバグは調査の非常に困難な旅で、最終的な解決策は驚くほど簡単です。シンプルな分析。

前提

これは、その後、その依存関係がアップグレード中に発生したピットを解決するために一緒に人々の束からアップグレードされた移植から古いプロジェクトから新しいプロジェクト、2.xへフレーム春のブートアップグレード1.1であり、各古いプロジェクトのための痛みのポイントは、改善するための軌道に乗って..です移植ビジネスロジックの後、測定を入れて、物事はこの時点まではかなりうまくいっている、このバグのない、ということを提供!

似たバグを言及したいくつかの試験では、メッセージが二度押しボックスをプレイすると、2回出現しシステムメッセージの再多重化、メインルーチンのエラーなどが挙げられます。

調査ツアー

事の優先順位を分割するには、爆弾ボックスが2回表示、およびシステム・メッセージは、この問題は全体的な状況には影響しません繰り返し、フロントエンドは、問題のように見えるので、これらの最初のバグはさておき、メインフローのエラーを見て

何も、ログは解決できない付加されていない、そして、より多くのポイントがある場合、

それは移植可能なコードなので、私は再処理ならば、特に明確なロジック、コードの行数千人の、ないです、その日のすべての並べ替えがユリ最初にすべての古いロジックよりもコードの一部をしたいと見て、寒いです、外観はポータブルではありません無視するとき、何の問題!どのように行うか?プラスログレコードは、彼らが関連付ける統一場を持っていなければならないときに、重要なステップと、この論理的に関連するコードごとにログを追加し、主要な変数でレコードの変更あなたはログを表示することができたときに、例えば、完全なプロセスを観察します

...
logger.info("userId [{}] xxxxxxxxxxxxx",userId);
...
logger.info("userId [{}] xxxxxxxxxxxxx",userId);
...
logger.info("userId [{}] xxxxxxxxxxxxx",userId);

まず登場

コードキーステップの対数比を観測することにより、状態エラーが2回更新された、それだけで、一度正常に対応するチェックコードDAO層を更新しなければならない、とコピーが時に見ていません混乱し、このような状況のDAO層のメソッドを呼び出して、次に何をする古いプロジェクト、問題なしを比較し、対応する更新プログラムの状態を見て、何の問題を下にチェックしません。

このエントリー方法のロジックが2回呼び出され、状態は次のようになります。この問題は難しいフィルタリングと検索した後に発生したときにここで問題を見つけるので、その後、すべてのログを確認し、最終的にはキーメッセージを見つけました2回更新。

Falseの外観

ここで、私は問題の鍵を見つけたと思う、私はこのバグの原因が発生したと仮定し、この時間はあるし、いくつかのロジックは、このエントリメソッドを呼び出すと、これらの論理コピーが間違っていたとき、それは、この入力方法にされリード、移植されなければなりません二回と呼ばれる。そして、次の焦点は、どのようなローカルコールこのエントリの方法を見つけることです。

検査後、方法は、(タイマタスクモジュールは、2つのインスタンスを実行した)タイミングタスクを開発する内部コールと外部コール、外部コールに分割され、間接的にトップモジュールに送信、トップモジュールは、入口タイミングでこの方法が達成されるコール内部コールは、別の内部は間違いなく呼び出し、その後、内部的に呼び出されるロジックを探し、スローがある。対応するUUID通話時間それによれば、対応する最上位モジュールでの成功を見つけるためにログを呼び出し、直接ログイン見る他のロジックへの呼び出しです多くの相関ロジック、今回のメンタリティに1つのレベル調整、決して、一日の大半のために苦労し、ログ頭皮、こうしたログとプラス側のチェックの多くを参照してくださいもう一度功を記録ディッシング、何も、爆発は、助言のための兄を放棄したかったが、今のデータによると、チェックアウトしていた、自分自身の鍋のために意味のある参照を提供したり、それをバックアップ、探し続けることができません。

逆転

道に沿って次の日の朝、ライブ馬の薬として死んだ馬を保持しているのアイデア、再びログを表示すると2つの外部コールしていることがわかった、ナニ!、次の参照、定期的なタスクを開発する場所を見つけるためには、ここではありませんロジックの問題は、タフなログ&検索した後、唯一の定期的なタスクが策定再び失速。時間が受け入れ、および頭痛の時からとても近く...長時間経過して確​​認してください。

別の角度

ログをバックチェックして、タイミングの問題に加えて、トップレベルのモジュールは、最初の開発タスクのロジックを説明されているメソッドの入り口に二度非常に近い呼び出すための時間が見つかりました:基本となるモジュールスケジュールされたタスクはトップレベルのモジュールをポーリングして、キーのRedisに格納されて開発するにRedisのは、その後、キーの呼び出しを解析します。これは基本的に、モジュール全体にわたり直接コピー、変更なしで、これは本当に何もしない。唯一の地域の首長を

ビスタ

私は、首長が後少しのログを見て追加し、そこにトップレベルのポーリングを見て、兄が指針を与え、定期タスクの多くは繰り返し呼び出さ非常に類似した時間です見つけ見て、首長を知らせるためにすべての手がかりを調査します。このチェックは、実際に複数存在するので(2ことに注意してください!!!)。問題を特定し、トップレベルのモジュールのインスタンスが存在することを、定期的なタスクを確実にするためのRedis総務の使用は、そのような取引が正常に実行されているかどうかを判断するために、一度だけのコードがある前に実行されますの

List result=redisOperations.exec();
if(result!=null){
// 事务执行成功操作
}else{
//事务执行失败操作
}

ここでの問題は、春ブーツは2.xのをアップグレードしているため、対応するスプリングデータRedisのもアップグレードされた。そして、アップグレード、トランザクションが失敗したときに、EXEC()はもはやnullでない返されますが、空のリストの後。修正し、あります次のコードは、後に正常に解決します

List result=redisOperations.exec();
if(!CollectionUtils.isEmpty(result)){
// 事务执行成功操作
}else{
//事务执行失败操作
}

反射

残りのコードは、トランザクションの前に使用されているため、変更前Execは、関連記事に見られているが、これらの部品も試験した、それはやったことはありません。ここで間違っている私は、この協会に行くとは思いませんでした

どのような兆候が実現するために失敗しますか?

システムメッセージは、2つのインスタンスを有し、これらの機能は無意識が無意味の方向に無駄につながる無視される符号の数は、最上位モジュールと、を参照することができ、そこから二回弾性ブロック、2つのプッシュメッセージを、繰り返されます多くのエネルギー。

違いを考えます

彼はトップレベルのモジュールをギャング理由を尋ねたところ、問題の首長が言う第一印象です?:

問題がある場合、ビジネスロジックは、過去に移植され、長い間されている地獄が緩んで破りました

そして、私の第一印象は、問題を移植したときに、それを考えるビジネスロジックということで、この印象支持できない、移植ビジネスロジック、ほとんどの支店コードを残したり、誤っていくつかのコードを削除で登場。インポッシブル人違いをこの問題。

概要

ギャングスターは最終的にそれは私が無駄な努力の数日間を行っている意味は、バグへの鍵を見つけた?いや、いや、私の意見では、これらの手がかりは、以前に収集した便利な、最初のルールアウト可能多くのその後、判断し、最終的にその問題を迅速に解決するために、それを表示するために証拠を収集し、その後、パフォーマンスの問題の私の視点を与える。(ポットは、他の人に十分な証拠を収集する前に、それがスローされていない場合は、非倫理的です、それだけで)2人の痛みに苦しむ人になるだろう

コードは、標準化されていない同僚、涙の2行、このバグに反映することである:空の文の集まりだけではなく、リスト== nullの操作を行い、ツールを使用する必要があります

ます。https://www.jianshu.com/p/7bcf1b1a0706で再現

おすすめ

転載: blog.csdn.net/weixin_33688840/article/details/91198927