java eeの話(仮)
DESCRIPTION
2014/9/17 の #JJUG 並行処理勉強会の発表内容です。TRANSCRIPT
Java EEの話(仮)久保智
本日のレガシー枠です。
今回の内容
• Java EEの昔の話
• 並行処理でハマった内容
WebサーバーとしてのJava EE
WebサーバーとしてのJava EE
• 多数のリクエストを同時にさばくため平行に処理が行われている
Java EE(Servlet)以前
Java EE(Servlet)以前
• CGIに代表されるリクエストを受け付けるたびにプロセスを立ち上げる形式のWebサーバー
• プロセスを立ち上げるため、メモリの確保等だけで無駄な負荷がかかっていた
Java EE(Servlet)後
Java EE(Servlet)
• プロセスが立ち上がっておいてその中で処理を行う
• 処理自体の負荷だけで、オーバーヘッドはあまりない
Java EE(Servlet)
• Servletは更に最適化を行ってServlet毎に1インスタンスで全てのリクエストを処理する
• 昔のJVMはクラスのnewに時間がかかっていた
並行処理は難しいのか
難しいです
難しい例:SingleThreadModel
難しい例:SingleThreadModel
• Servletがimplimentsすると一つしか出来ないインスタンスがリクエストごとに生成されるようになるJ2EEのspecで定められたクラス
• スレッドセーフになるように
難しい例:SingleThreadModel
• 現在は非推奨
• インスタンスを生成するだけでは意味がなかった(例:static変数へのアクセス)
Java EEの仕様を決めている人も間違えることがある
難しいので どんどん失敗しましょう
ここから失敗した例ベースで
SimpleDateFormat
SimpleDateFormat
• スレッドセーフでないクラスの例として有名
• 今はJavaDocにスレッドセーフでないと記載されているが昔はされていなかった
• JavaDocにスレッドセーフだと記載されていない場合はスレッドセーフでないものとして扱おう
System.out
System.out
• 複数スレッドから同時に書き込むとブロックする
• 拾ってきたjarで呼ばれてた/(^o^)\
System.out
• ログ出力ライブラリ使いましょう\(^o^)/
HttpSession
Servletのスコープ
Servletのスコープ
• Pageスコープ
• HttpRequestスコープ
• HttpSessionスコープ
• Applicationスコープ(Singleton)
Servletのスコープ(その他)
• Flashスコープ
• Viewスコープ
• Conversationスコープ
Servletのスコープ(その他)
• Flashスコープ
• Viewスコープ
• Conversationスコープ
Sessionスコープの亜種
Page、HttpRequestスコープ
• スレッドごとに生成されるので特に意識することなし
Applicationスコープ
• アプリケーション内で共有される
• アクセスには気をつけるよね?
HttpSessionスコープ
HttpSessionスコープ
• ブラウザ単位で同時にアクセスされる可能性がある
• アクセス時には安全のためロックしましょう
HttpSessionスコープ
ロックできない場所もある
HttpSession#invalidate()
HttpSession#invalidate()• セッションを破棄する
• すでに破棄されている場合に呼び出すとExceptionが発生する
• HttpSessionにすでに破棄されているかどうかを判定するメソッドspecにはない
HttpSession#invalidate()
例外処理中に呼び出されることが多いのでここでExceptionを発生させない
HttpSession#invalidate()
• Tomcatだと実装を直接扱えば破棄されているかを判定するメソッドがある\(^o^)/
JSF(mojarra)/CDI(weld)の場合
JSF(mojarra)/CDI(weld)の場合
• 複数スレッドからの同一オブジェクトへの同時アクセスはブロックされる
• getterだけでも\(^o^)/
JSF(mojarra)/CDI(weld)の場合
• CDIのspecには記載なし。weldの仕様?
• なんでもかんでもSingletonにすると逆に性能
劣化が(ヽ´ω`)
JSF(mojarra)/CDI(weld)の場合
• スコープは適切に扱いましょう
EJB
Stateless SessionBean
Stateless SessionBean
• 状態をもたないSessionBean
• コンテナがインスタンスをプールして複数スレッドで使いまわされる
• 同じインスタンスに複数スレッドから同時にアクセスされることはない
Stateless SessionBean
• コンテナのプールはデフォルトでは無効化されている場合が多い
• 作っている最中は毎回インスタンスが生成される
• 結合試験環境に乗せたら/(^o^)\
Stateless SessionBean
• Stateless SessionBeanに状態を持たせるのは止めましょう\(^o^)/
• コードレビューもしましょう\(^o^)/
JPA
JPAのキャッシュ
JPAのキャッシュ
• 毎回データベースに値を取りに行くのは非効率なのでキャッシュを行う
JPAのキャッシュ
• 同じスレッド内でキャッシュを行うL1キャッシュ
• 複数のスレッドにまたがるキャッシュを行うL2キャッシュ
JPAのキャッシュ
• JPAのキャッシュはPKを比較することでキャッシュされているかを判断する
• PKの比較が重い場合はキャッシュしたほうが重くなることも/(^o^)\
JPAのキャッシュ
• 複合主キーはやめましょう\(^o^)/
JPAのキャッシュ
• L2キャッシュはspecではデフォルトでは無効になっていますが、EclipseLinkではデフォルトで有効になってます
JPAの楽観ロック
JPAの楽観ロック
• @versionアノテーションを付けるだけで楽観ロックが出来る
• 複数スレッドからの同時更新を防ぐ
JPAの楽観ロック
• JPQLからのupdateでは楽観ロックが有効にならない
• 自分たちで管理しましょう
JPQL
• ついでにキャッシュも無視するよ\(^o^)/
• L2キャッシュは性能が問題にならない限り切っておきましょう\(^o^)/
最後
CDIの非同期処理
CDIの非同期処理
• @Asynchronousを付けるだけで非同期処理に
\(^o^)/
簡単だけど 障害時を考えるとそれでいいのか
簡単だけど 障害時を考えるとそれでいいのか• 非同期でやるぐらいだから時間のかかる処理のはず
• リトライは?
• APサーバー落としたら一緒に動かなくなっていいの?
CDIの非同期処理
• 非機能要件についても一度考えてから採用を
\(^o^)/
以上 ご清聴ありがとうございました