先週の月曜日、私の同僚からオンラインOOMの問題の調査を手伝ってほしいと頼まれました。調査の手順はここでは説明しません。これは、以前に調整したOOMの手順と実際には同じです。前回の調査については、この記事を参照してください:mybatisのソースコードを通じて、一度分析する不適切な使用によるOutOfMemoryErrorの共同調査
今日は主に結果について話し、結果を要約します。
今回、OOMは主に使用頻度の低いクエリ機能であるフルテーブルクエリが原因で発生しました。これは、データ量が多すぎてヒープメモリオーバーフローが発生したためです。
まず、mybatis xmlのフラグメントであるsql(オンラインsqlではなく、同様のsqlがリストされています)を見てみましょう。
このフラグメントは、ページのクエリ関数が最終的に実行するSQLです。where条件の3つの値は、ページ上のユーザーの入力から取得されます。
select * from t_user usr
<where>
<if test=" email != null" >
and usr.email = #{email ,jdbcType= varchar}
</if>
<if test=" certNo!= null" >
and usr.cert_no = #{ certNo,jdbcType= varchar}
</if>
</where>
ここでのすべてのwhere条件は空の判断です。本番環境では、ユーザーが入力せず、最終的に実行されたsqlがselect * from t_user usrになり、テーブルデータ全体が照会され、このテーブルには1000Wがありました上記のデータ、ユーザーがさらに2つのポイントをクリックすると、システムがハングする
ここでいくつかの問題について話します
1.データはページングされていません
データが多すぎる場合、クエリはページングである必要があり、それはデータページングです。メモリおよびページ側でページングを実行しないことが最善です。他のmysqlデータテーブルが数千万行に達した後に単一のテーブルのパフォーマンスを最適化する方法は、特に良くありません。 、ここでは誰でもサブテーブルサブデータベースの最適化を検討することができます
2.ページが繰り返し送信されない
ビッグデータをチェックしたり、SQLのクエリが非常に遅い場合は、少なくともフロントエンドで制御する必要があります。バックエンドで結果が返されない場合は、システムがハングアップしないように、ユーザーに再度クリックさせないでください。
3.フロントエンドはユーザー入力をチェックしません
フロントエンドは入力確認を行う必要があり、ユーザーは条件を入力できません。実際、ページチェックをバイパスする方法はいくつかあると考えている学生もいます。ここでは、手順4が必要です。
4.バックエンドは入力検証を行いません
ページをバイパスできる人が常にいるため(フロントエンドチェックでは紳士を防ぐことができるだけ)、バックエンド検証が必要になります。
5. SQLレイヤーはクエリ保護を行いませんでした
プログラムがより堅牢であることを確認するために、実際にはSQLレイヤーで、ビジネス条件が動的であることがわかった場合、撤回して適切に保護することができます。上記のSQLは、次のように記述して防止できます(すべてのクエリはパンツまたはフルテーブルスキャンによって引き起こされます)。サービスは死ぬまで激突しました):
select * from t_user usr
<where>
<if test=" email != null" >
and usr.email = #{email ,jdbcType= varchar}
</if>
<if test=" certNo!= null" >
and usr.cert_no = #{ certNo,jdbcType= varchar}
</if>
<if test=" email = null" >
<if test=" certNo= null" >
and 1=2
</if>
</if>
</where>
6.このビジネスの発展はビジネスをうまく整理し、ニーズを理解しませんでした
調査の結果、このテーブルには1000wのデータが含まれていることがわかりました。開発時に驚いていました。この関数を最初に開発したとき、開発者はこの関数が一般的に使用されていないことを感じており、テーブルに入力されるデータの量が明確ではないことを知りました。これは事前にニーズを理解し、データを評価することの失敗であり、ニーズをよく理解し、毎日のデータを確認し、事前に設計する場合、ここに穴をあけるべきではありません。
結論として:
開発の際には、ビジネスについてもっと学び、需要側とコミュニケーションをとり、機能の本質を理解した上で需要開発を行う必要があります。同僚の開発プロセスでは、インターフェイスの異常な状況も考慮する必要があります。ユーザーが意図したとおりに操作することは決してありません。もう1つは、問題を解決するためにより多くのツールを使用することです。