構築中。

名古屋のITインフラお守り係です。ITイベントへの参加記録などを残していきます。

Tech Deep Dive #1 Revenge Edition「Javaアプリケーションのチューニングとトラブルシューティング」(3/13)

先週末のJAWS DAYS 2018に続き、東京遠征。
なお、今回は本編のTech Deep Diveの前に、駒場にある日本民藝館に寄ってきました。

www.mingeikan.or.jp

f:id:hmatsu47:20180314092351j:plain

見終わってから時間が余ったので、今回もBOOK LAB TOKYOへ。

booklabtokyo.com

6,000円もしましたが、これ↓を買ってミルクティーを飲んできました(ドリンク1杯サービスになるのは2,000円以上購入の場合でした。前回訪問時の記事を訂正)。

www.kyoritsu-pub.co.jp

※後で調べたら、名古屋の大型書店にも在庫があったみたいですが。

 

それでも時間が余ってしまったので、しばらく神宮外苑の前で休息(不審者?)。

 

さて、本編です。
JFR(Java Flight Recorder)は使ったことがないので、↓の本などで予習しつつ参加しました。

www.oreilly.co.jp

 

講師は、Oracle松林さん。元々予定していた日にインフルで高熱が出て断念、ということでリベンジマッチです。

個人的には、そのおかげで参加できてよかったです(本人は大変だったと思うけれど)。

システムトラブルには、

  • 停止
  • 遅い
  • エラー(主にテスト時)

などがあり、それらをJFRを使って効果的に解析するよ、というお話でした(以降、ほぼ勝手な意訳をしつつ、箇条書き)。

 

トラブルが発生するポイント

 ①アクセス流量多すぎ問題
 ②イケてないアプリケーションコード問題
 ③SQLダメダメ問題
 ④スレッドやコネクション枯渇問題
 ⑤ヒープ・GCアルゴリズム問題
 ⑥CPU・メモリ・I/O等のリソース問題

 

ケース1:10年前くらいのWeb

  • Struts1系、Spring Framework等のFramework上に独自Framework乗っけてその上にアプリケーション
  • DBアクセスはHibernateiBatis
  • WebアプリケーションサーバWebLogicとかTomcatとかJBoss APとか
  • ユニットテストで異常がないのに、結合テストで特定の情報だけなぜかDBから取れてこない
  • エラー/Exception発生してない(ように見える)
  • テストデータかSQLの問題?
  • JFRで見てみると、java.lang.NoSuchMethodExceptionがいっぱい
  • CatchでExceptionを食ってた(握りつぶしてた)のでログにExceptionが記録されず
  • Reflectionで呼び出すときの記述をTypoしていた
  • Mockテストで独自Framework完成前にテストしてCommit
  • 独自Framework:バグが入った状態で後からCommit
  • FindBugs等を使ってなかった→使うようにした

所感

  • Exception握りつぶすな!

 

ケース2:IoTシステム

  • 位置情報リアルタイムモニタリング(高齢者向け施設の見守りシステム)
  • GW端末の近くをIoTタグが通ったら通知・記録・モニタリング画面に表示
  • リリース直後はよかった
  • 途中から、人によって通知が遅い、全体的に遅い、画面に表示されないなどのトラブル発生
  • Spring FrameworkJDBC使用
  • OSレベルで異常見つからず
  • JFRで見ても、Tomcatを使っていたので詳細情報が取れず、異常が見つからなかった
  • JFRでカスタムイベントを追加(注:Java8までのJFRはカスタムイベントはサポート外・使うなら自己責任で)
  • やたら遅いSQLを即座に発見
  • 不要なJOIN→サブクエリ化
  • INDEXがない→張る
  • スロークエリログ取ってなかった

所感

  • データ量の設計はどうした?最初にしてなかったの?
  • テーブル設計が見えないと質問に答えられない…
  • JFRカスタムイベントより、tcpdump取ってpt-query-digest→EXPLAINのほうが早くない?
  • MySQLのバージョンは5.6以降?5.5までだと、JOINだろうがサブクエリだろうが基本内部でNLJ扱いだし、相関サブクエリとして実行されるケースが多いからかえって遅くなりそうだけど
  • ORDER BY狙いのキーを使えないときは、なるべく絞り込んでからソートすべし

 

ケース3:遅いバッチ

  • Qiitaの記事のやつ

qiita.com

  • Java.util.LinkedList#getで順番にリストの要素を拾っていたので、先頭(と終端)は良いが中間の要素のフェッチがやたら遅い
  • ArrayListに変えるか、for文で1から順にフェッチするのではなく拡張for文でフェッチする(記事の解決法は後者)

所感

  • Linked○○など、内部的にどうソート情報をもって処理しているかに思いをはせるべし。処理系に丸投げするべからず
  • JFR関係なさそうに見えるのは「原因箇所が特定できたところから話は始まっているから」であって、原因箇所の特定にはJFR有効そう

 

ケース4:グリッド処理システム(注:Oracle Coherenceではない)

  • 計算クラスタで計算を実行すると一部のJVMがなぜかDOWN、最終的にクラスタが停止
  • インメモリデータグリッド
  • JVMのスレッドが多い:4コアなのに500スレッド
  • 但し、停止しなかったJVMも同じ
  • 計算処理のスレッドが詰まる→クラスタ維持のためのスレッドも詰まる→停止
  • workerスレッドの数を減らしてみる→JVMあたり16スレッドが適切だった
  • 計算処理だけでなくクラスタ維持も考慮してスレッド数等を決める
  • 止まる/止まらないの差→各JVMに割り当てるデータ量が平準化されていなかった→平準化する
  • クラスタメンバにも優しい社会を作ろう
  • Oracle Coherenceについてもろもろ宣伝?

所感

  • グリッド処理でなくてもクラスタ/HA系はクラスタ/HAの維持管理にCPUリソースを使っているので、同様に気を付けよう
  • クラスタ台数増えるとその分クラスタ維持に必要なリソース量(CPU・メモリ・I/O・時間など)も増えるから、そこも気にしてね!

 

その他告知・情報など

  • JDK11あたりでOpenJDKにもJFRが入りそう(約束はできないけど)
  • JFR:6.0でUIが大幅変更、メニューがタブから左側ツリーへ移行(必要な範囲を絞って見れるように)

 

全体の感想など

  • 普段参加するイベント等とは文化が違う感じがして、新鮮だった
  • スーツ族は自分だけかと思ったら意外といた。Javaだから?
  • というか、松林さんもスーツだった(意外)
  • インフラ族にとってアウェイ感Maxの状態で始まったが、全体を通してみると意外とそうでもなかった
  • 予定より30分早く終わってビックリ。延長を見込んで宿を取っておいたが、名古屋に帰れる時間だった。キャンセル料100%だったのでそのまま1泊

 

次回は17日土曜日、大阪開催です(すでに申し込み済み)。