Java EEの話(仮)

65
Java EEの話() 久保智

description

2014/9/17 の #JJUG 並行処理勉強会の発表内容です。

Transcript of Java EEの話(仮)

Page 1: Java EEの話(仮)

Java EEの話(仮)久保智

Page 2: Java EEの話(仮)

本日のレガシー枠です。

Page 3: Java EEの話(仮)

今回の内容

• Java EEの昔の話

• 並行処理でハマった内容

Page 4: Java EEの話(仮)

WebサーバーとしてのJava EE

Page 5: Java EEの話(仮)

WebサーバーとしてのJava EE

• 多数のリクエストを同時にさばくため平行に処理が行われている

Page 6: Java EEの話(仮)

Java EE(Servlet)以前

Page 7: Java EEの話(仮)

Java EE(Servlet)以前

• CGIに代表されるリクエストを受け付けるたびにプロセスを立ち上げる形式のWebサーバー

• プロセスを立ち上げるため、メモリの確保等だけで無駄な負荷がかかっていた

Page 8: Java EEの話(仮)

Java EE(Servlet)後

Page 9: Java EEの話(仮)

Java EE(Servlet)

• プロセスが立ち上がっておいてその中で処理を行う

• 処理自体の負荷だけで、オーバーヘッドはあまりない

Page 10: Java EEの話(仮)

Java EE(Servlet)

• Servletは更に最適化を行ってServlet毎に1インスタンスで全てのリクエストを処理する

• 昔のJVMはクラスのnewに時間がかかっていた

Page 11: Java EEの話(仮)

並行処理は難しいのか

Page 12: Java EEの話(仮)

難しいです

Page 13: Java EEの話(仮)

難しい例:SingleThreadModel

Page 14: Java EEの話(仮)

難しい例:SingleThreadModel

• Servletがimplimentsすると一つしか出来ないインスタンスがリクエストごとに生成されるようになるJ2EEのspecで定められたクラス

• スレッドセーフになるように

Page 15: Java EEの話(仮)

難しい例:SingleThreadModel

• 現在は非推奨

• インスタンスを生成するだけでは意味がなかった(例:static変数へのアクセス)

Page 16: Java EEの話(仮)

Java EEの仕様を決めている人も間違えることがある

Page 17: Java EEの話(仮)

難しいので どんどん失敗しましょう

Page 18: Java EEの話(仮)

ここから失敗した例ベースで

Page 19: Java EEの話(仮)

SimpleDateFormat

Page 20: Java EEの話(仮)

SimpleDateFormat

• スレッドセーフでないクラスの例として有名

• 今はJavaDocにスレッドセーフでないと記載されているが昔はされていなかった

• JavaDocにスレッドセーフだと記載されていない場合はスレッドセーフでないものとして扱おう

Page 21: Java EEの話(仮)

System.out

Page 22: Java EEの話(仮)

System.out

• 複数スレッドから同時に書き込むとブロックする

• 拾ってきたjarで呼ばれてた/(^o^)\

Page 23: Java EEの話(仮)

System.out

• ログ出力ライブラリ使いましょう\(^o^)/

Page 24: Java EEの話(仮)

HttpSession

Page 25: Java EEの話(仮)

Servletのスコープ

Page 26: Java EEの話(仮)

Servletのスコープ

• Pageスコープ

• HttpRequestスコープ

• HttpSessionスコープ

• Applicationスコープ(Singleton)

Page 27: Java EEの話(仮)

Servletのスコープ(その他)

• Flashスコープ

• Viewスコープ

• Conversationスコープ

Page 28: Java EEの話(仮)

Servletのスコープ(その他)

• Flashスコープ

• Viewスコープ

• Conversationスコープ

Sessionスコープの亜種

Page 29: Java EEの話(仮)

Page、HttpRequestスコープ

• スレッドごとに生成されるので特に意識することなし

Page 30: Java EEの話(仮)

Applicationスコープ

• アプリケーション内で共有される

• アクセスには気をつけるよね?

Page 31: Java EEの話(仮)

HttpSessionスコープ

Page 32: Java EEの話(仮)

HttpSessionスコープ

• ブラウザ単位で同時にアクセスされる可能性がある

• アクセス時には安全のためロックしましょう

Page 33: Java EEの話(仮)

HttpSessionスコープ

Page 34: Java EEの話(仮)

ロックできない場所もある

Page 35: Java EEの話(仮)

HttpSession#invalidate()

Page 36: Java EEの話(仮)

HttpSession#invalidate()• セッションを破棄する

• すでに破棄されている場合に呼び出すとExceptionが発生する

• HttpSessionにすでに破棄されているかどうかを判定するメソッドspecにはない

Page 37: Java EEの話(仮)

HttpSession#invalidate()

例外処理中に呼び出されることが多いのでここでExceptionを発生させない

Page 38: Java EEの話(仮)

HttpSession#invalidate()

• Tomcatだと実装を直接扱えば破棄されているかを判定するメソッドがある\(^o^)/

Page 39: Java EEの話(仮)

JSF(mojarra)/CDI(weld)の場合

Page 40: Java EEの話(仮)

JSF(mojarra)/CDI(weld)の場合

• 複数スレッドからの同一オブジェクトへの同時アクセスはブロックされる

• getterだけでも\(^o^)/

Page 41: Java EEの話(仮)

JSF(mojarra)/CDI(weld)の場合

• CDIのspecには記載なし。weldの仕様?

• なんでもかんでもSingletonにすると逆に性能

劣化が(ヽ´ω`)

Page 42: Java EEの話(仮)

JSF(mojarra)/CDI(weld)の場合

• スコープは適切に扱いましょう

Page 43: Java EEの話(仮)

EJB

Page 44: Java EEの話(仮)

Stateless SessionBean

Page 45: Java EEの話(仮)

Stateless SessionBean

• 状態をもたないSessionBean

• コンテナがインスタンスをプールして複数スレッドで使いまわされる

• 同じインスタンスに複数スレッドから同時にアクセスされることはない

Page 46: Java EEの話(仮)

Stateless SessionBean

• コンテナのプールはデフォルトでは無効化されている場合が多い

• 作っている最中は毎回インスタンスが生成される

• 結合試験環境に乗せたら/(^o^)\

Page 47: Java EEの話(仮)

Stateless SessionBean

• Stateless SessionBeanに状態を持たせるのは止めましょう\(^o^)/

• コードレビューもしましょう\(^o^)/

Page 48: Java EEの話(仮)

JPA

Page 49: Java EEの話(仮)

JPAのキャッシュ

Page 50: Java EEの話(仮)

JPAのキャッシュ

• 毎回データベースに値を取りに行くのは非効率なのでキャッシュを行う

Page 51: Java EEの話(仮)

JPAのキャッシュ

• 同じスレッド内でキャッシュを行うL1キャッシュ

• 複数のスレッドにまたがるキャッシュを行うL2キャッシュ

Page 52: Java EEの話(仮)

JPAのキャッシュ

• JPAのキャッシュはPKを比較することでキャッシュされているかを判断する

• PKの比較が重い場合はキャッシュしたほうが重くなることも/(^o^)\

Page 53: Java EEの話(仮)

JPAのキャッシュ

• 複合主キーはやめましょう\(^o^)/

Page 54: Java EEの話(仮)

JPAのキャッシュ

• L2キャッシュはspecではデフォルトでは無効になっていますが、EclipseLinkではデフォルトで有効になってます

Page 55: Java EEの話(仮)

JPAの楽観ロック

Page 56: Java EEの話(仮)

JPAの楽観ロック

• @versionアノテーションを付けるだけで楽観ロックが出来る

• 複数スレッドからの同時更新を防ぐ

Page 57: Java EEの話(仮)

JPAの楽観ロック

• JPQLからのupdateでは楽観ロックが有効にならない

• 自分たちで管理しましょう

Page 58: Java EEの話(仮)

JPQL

• ついでにキャッシュも無視するよ\(^o^)/

• L2キャッシュは性能が問題にならない限り切っておきましょう\(^o^)/

Page 59: Java EEの話(仮)

最後

Page 60: Java EEの話(仮)

CDIの非同期処理

Page 61: Java EEの話(仮)

CDIの非同期処理

• @Asynchronousを付けるだけで非同期処理に

\(^o^)/

Page 62: Java EEの話(仮)

簡単だけど 障害時を考えるとそれでいいのか

Page 63: Java EEの話(仮)

簡単だけど 障害時を考えるとそれでいいのか• 非同期でやるぐらいだから時間のかかる処理のはず

• リトライは?

• APサーバー落としたら一緒に動かなくなっていいの?

Page 64: Java EEの話(仮)

CDIの非同期処理

• 非機能要件についても一度考えてから採用を

\(^o^)/

Page 65: Java EEの話(仮)

以上 ご清聴ありがとうございました