この章では、既存のアプリケーション・ページにキャッシング・サポートを追加する方法について説明します。
この章の内容は次のとおりです。
ほとんどのWebベースのアプリケーションでは、リクエストの大部分は同一または類似のコンテンツに対して行われます。動的コンテンツと静的コンテンツの両方に対してこのように繰返しリクエストが行われることにより、アプリケーションのインフラストラクチャには大きな負荷がかかります。
キャッシングにより、Webページの全部または一部がそれ以降のレスポンスで使用するためにメモリーに格納されます。クライアント・リクエストへのレスポンス時間は、それ以降のリクエストに対して、コンテンツを作成するコードを実行せずに、キャッシュされたコンテンツを再利用することで、著しく短縮されます。
Oracle ADF Facesキャッシュでは、リクエストにより生成されたレスポンスの一部をキャッシュする簡便な方法が提供されています。キャッシュするフラグメント・コンテンツを、開始タグ<afc:cache>
および終了タグ</afc:cache>
を使用してラップするだけです。動的コンテンツと静的コンテンツの両方をキャッシュすることにより、スループットを向上させ、レスポンス時間を短縮することができます。
<afc:cache>
タグを追加すると、次のフラグメント・タイプをキャッシュできます。
ページ・フラグメント: <afc:cache>
タグを<f:view>
タグの直接の子とし、ページのコンテンツをそのタグで囲みます。
ページ内のフラグメント: フラグメント部分のみを<afc:cache>
タグで囲みます。リクエストごとにページのセクションを作成する必要がある場合は、フラグメントをキャッシングすると便利です。
それ自身のサブページ内に存在する組込みフラグメント: <afc:cache>
タグを<f:subview>
タグの直接の子とし、フラグメントのコンテンツをそのタグで囲みます。
JavaServer Faces(JSF)を使用して開発したアプリケーションでは、ADF Facesキャッシュ・ライブラリを使用できます。
次のタイプのコンテンツについては、<afc:cache>
タグを使用することを検討してください。
リソース集中型のコンテンツ
特定のJSFまたはADFコンポーネントのレンダリングにリソース集中型の操作(データベースまたはネットワークの問合せの作成など)が必要となる場合は、キャッシングを行うと、コンテンツを再生成せずにキャッシュから取得できるため、レンダリングのコストの低減に役立ちます。
共有可能なコンテンツ
キャッシュは、複数のユーザーまたはセッションに対して同一オブジェクトを提供できます。
共有の程度は、アプリケーション全体にすることも、特定のプロパティ(Beanプロパティ、ユーザーCookie、リクエスト・ヘッダーなど)に限定することもできます。
頻繁に変更されないコンテンツ
キャッシュは長期にわたってコンテンツを提供できるため、頻繁に変更されないコンテンツはキャッシュに入れると効果的です。ADF Facesキャッシュの存続時間および無効化のメカニズムにより、キャッシュ内のコンテンツを無効化できます。コンテンツのソースがいつ変更されるかを正確に予測できる場合は、存続期間を使用します。リクエストに基づいて変更されるコンテンツに対しては、無効化を使用します。
頻繁に変更されるコンテンツの場合は、常にキャッシュを更新する必要があるため、キャッシュの使用に向いていません。
SRDemoアプリケーションでは、いくつかのページでCache
コンポーネントを使用してフラグメントをキャッシュしています。キャッシング・サポートがどのようにSRCreate.jspx
およびSRFaq.jspx
に追加されているかを分析することで、アプリケーション内のフラグメントがキャッシュされる方法をより深く理解できます。
図15-1は、SRCreate.jspx
ページを示しています。このページには、次のキャッシュ可能なフラグメントが含まれています。
最初のフラグメントにはページの先頭のコンテンツが含まれ、「Frequently Asked Questions」のテキストとリンク、問題の基本的な説明の入力を求めるプロンプト、およびobjectSeparator
コンポーネントが表示されています。
このコンテンツはすべてのユーザーに共通です。
2番目のフラグメントには、機器を選択するためのpanelForm
コンポーネントが含まれ、データベース問合せを要求します。
このコンテンツはユーザーによって異なります。このコンテンツは、同じユーザーのすべてのセッションにわたって有効になります。
3番目のフラグメントには、「New Service Request」タブなどの各タブが含まれます。
このコンテンツはユーザーによって異なります。このコンテンツは、同じユーザーのすべてのセッションにわたって有効になります。
4番目のフラグメントには、ページ最上部の「Logout」および「Help」メニュー項目が含まれます。
このコンテンツはすべてのユーザーに共通です。
これらのフラグメントは特定のユーザーがセッション全体にわたって共有したり、すべてのユーザーが共有することができるため、キャッシングに適しています。
例15-1に、最初のフラグメント(ページ・コンテンツの先頭)のコードを示します。
例15-1 ページ先頭コンテンツのフラグメント
<!--Page Content Start--> <afc:cache duration="864000"> <af:objectSpacer width="10" height="10"/> <af:panelHorizontal> <f:facet name="separator"> <af:objectSpacer width="4" height="10"/> </f:facet> <af:outputText value="#{res['srcreate.faqText']}"/> <af:commandLink text=" #{res['srcreate.faqLink']}" action="dialog:FAQ" useWindow="true" immediate="true" partialSubmit="true"/> </af:panelHorizontal> <af:objectSpacer width="10" height="10"/> <af:outputFormatted value="#{res['srcreate.explainText']}"/> <af:objectSeparator/> </afc:cache>
<afc:cache>
タグの属性は、次のものを指定しています。
duration
属性は、フラグメントの有効期限を86,400秒に指定しています。フラグメントの有効期限が満了した場合に、クライアントがそのフラグメントを要求すると、フラグメントはキャッシュから削除されてから、新しいコンテンツでリフレッシュされます。
例15-2に、2番目のフラグメント(機器を選択するためのpanelForm
コンポーネント)のコードを示します。
例15-2 機器選択のフラグメント
<af:panelForm> <afc:cache duration="86400" varyBy="userInfo.userId"> <af:panelLabelAndMessage valign="top" label="#{res['srcreate.info.1']}"> <af:selectOneListbox id="navList1" autoSubmit="false" value="#{bindings.findAllProduct1.inputValue}" size="6" required="true"> <f:selectItems value="#{bindings.findAllProduct1.items}"/> </af:selectOneListbox> </af:panelLabelAndMessage> </afc:cache>
<afc:cache>
タグの属性は、次のものを指定しています。
duration
属性は、フラグメントの有効期限を86,400秒に指定しています。
varyBy
属性は、userInfo
Beanに基づいて表示されるフラグメントのバージョンを指定しています。この属性は、ユーザーごとにフラグメントのバージョンをキャッシュすることを指定します。このコンテンツは、同じユーザーの複数のセッションにわたって有効になります。
例15-3に、3番目のフラグメント(ページ最上部に並んだ各タブ)のコードを示します。
例15-3 メニュー・タブのフラグメント
<f:facet name="menu1"> <afc:cache duration="864000" varyBy="userInfo.userId"> <af:menuTabs var="menuTab" value="#{menuModel.model}"> <f:facet name="nodeStamp"> <af:commandMenuItem text="#{menuTab.label}" action="#{menuTab.getOutcome}" rendered="#{menuTab.shown and menuTab.type=='default'}" disabled="#{menuTab.readOnly}"/> </f:facet> </af:menuTabs> </afc:cache> </f:facet>
<afc:cache>
タグの属性は、次のものを指定しています。
duration
属性は、フラグメントの有効期限を86,400秒に指定しています。
varyBy
属性は、userInfo
Beanに基づいて表示されるフラグメントのバージョンを指定しています。
例15-4に、最後のフラグメント(「Logout」および「Help」メニュー項目)のコードを示します。
例15-4 「Logout」および「Help」メニューのフラグメント
<f:facet name="menuGlobal"> <afc:cache duration="86400"> <af:menuButtons> <af:commandMenuItem text="#{res['srdemo.menu.logout']}" action="GlobalLogout" immediate="true" icon="/images/logout.gif"/> <af:commandMenuItem text="#{res['srdemo.menu.help']}" action="GlobalHelp" immediate="true" icon="/images/help.gif"/> </af:menuButtons> </afc:cache> </f:facet>
図15-2は、SRFaq.jspx
ページを示しています。このページのコンテンツは、すべてのユーザーによって共有可能です。
例15-5に、このページ・フラグメントのコードを示します。
例15-5 FAQのフラグメント
<f:view>
<afc:cache duration="86400"
searchKeys="FAQ"
...FAQ Page Content...
</afc:cache>
</f:view>
<afc:cache>
タグの属性は、次のものを指定しています。
duration
属性は、フラグメントの有効期限を86,400秒に指定しています。
searchKeys
属性は、このページ・フラグメントにFAQ
の検索文字列を割り当てています。このフラグメントは、この検索キーを使用して無効化できます。
Webページおよびフラグメントを異なるグループに編成するには、検索キーを使用します。特定のグループ内のすべてのページは、同じ検索キーを使用して割り当てることができます。たとえば、検索キーnew_request
を、新規のサービス・リクエストの作成に関連するすべてのページに割り当てることができます。オブジェクトのグループを無効化するには、その特定のグループに関連付けられた検索キーを指定する無効化リクエストを送信します。たとえば、無効化リクエストで検索キーnew_request
を指定した場合、new_request
検索キーが割り当てられたすべてのページが無効化されます。SRDemoアプリケーションでは、SRFaq.jspx
ページのみに検索キーが割り当てられています。
オブジェクトに無効のマークが付けられている場合、クライアントがそれらのオブジェクトを要求すると、オブジェクトは削除されてから、新しいコンテンツでリフレッシュされます。
Cache
コンポーネントを使用するには、ADF Facesキャッシュ・ライブラリをアプリケーションのプロジェクトに追加し、ライブラリを特定のJSPページに適用します。
ADF Facesキャッシュ・ライブラリを追加する手順:
アプリケーション・ナビゲータで、Cache
コンポーネントを使用するプロジェクトを選択します。
ポップアップ・メニューから「プロジェクト・プロパティ」を選択します。
「プロジェクト・プロパティ」ダイアログが開きます。
「ライブラリ」ノードを選択します。
「ライブラリ」ページで「ライブラリの追加」をクリックします。
選択ツリー内でADF Facesキャッシュ・ライブラリを見つけ、「OK」をクリックします。
「ライブラリ」ページで「OK」をクリックします。
JSPドキュメントまたはページごとに、<afc:cache>
タグを適用する計画を立て、次のライブラリ構文を<jsp:root>
タグに追加します。
xmlns:afc="http://xmlns.oracle.com/adf/faces/webcache"
これで、コンポーネント・パレットからCache
コンポーネントを挿入したり、「コード・インサイト」を使用して<afc:cache>
タグを使用することができます。
<afc:cache>
タグを含むアプリケーションを実行すると、コンテンツは、ブラウザにより最初にそのコンテンツがリクエストされた時点でキャッシュされます。キャッシュされた後、コンテンツはキャッシュからサービスされます。コンテンツがキャッシュに挿入された日時、およびフラグメント・リクエストから発生したキャッシュ・ヒットとキャッシュ・ミスの数は、次のツールを組み合せて使用すると確認できます。
ADF Facesキャッシュを使用すると、JavaロギングAPI(java.util.logging.Logger)によってイベントおよびエラー・メッセージが記録されます。これらのメッセージには、オブジェクトがキャッシュに挿入されて、キャッシュから使用された方法が順に示されます。
j2ee-logging.xml
ファイル内に指定されているロギング構成に応じて、ロギング情報をJDeveloperのログ・ウィンドウに表示し、log.xml
ファイルに書き込むことができます。j2ee-logging.xml
ファイルでは、log.xml
のディレクトリ・パス情報が指定されます。
例15-6に、フラグメントSRCreate.jspx
が最初にリクエストされ、キャッシュ内に見つからず(cache miss
)、キャッシュに挿入された(insert
)場合のログ部分を示します。SRCreate.jspx
が再びリクエストされ、キャッシュから使用されています(cache hit
)。
例15-6 ログ・サンプル
fragment is SRCreate.jspx:_id13 fragment (SRCreate.jspx:_id13) fetch: cache miss fragment (SRCreate.jspx:_id13) insert: cached for 86400 secs ... fragment is SRCreate.jspx:_id19 fragment (SRCreate.jspx:_id19) fetch: cache hit ...
AFC統計サーブレット(図15-3)では、次のキャッシュ統計が表示されます。これらの統計を使用すると、キャッシュのスループットの全体的な概要がわかります。
キャッシュ内のオブジェクト数: キャッシュ内に格納されているオブジェクトの数。
キャッシュ・ヒットの数: キャッシュ内のオブジェクトが使用されたリクエストの数。
キャッシュ・ミスの数: キャッシュが使用されなかったキャッシュ可能リクエストの数。この数は、最初のリクエストと、リフレッシュされた無効化済または期限切れのオブジェクトに対するリクエストの合計を表します。
無効化リクエスト数: キャッシュによりサービスされた無効化リクエストの数。
無効化されたドキュメント数: キャッシュにより無効化されたオブジェクトの合計数。
無効化リクエスト数と無効化されたドキュメント数は同じでないこともあります。この違いは、1つの検索キーが複数のオブジェクトに適用されることがあるために発生します。
図15-3に示されている「統計をリセットするにはここをクリックしてください。」リンクをクリックすると、キャッシュ内のオブジェクト数を除いて、これらの統計がリセットされます。
サーブレットを有効化する手順:
アプリケーションの/WEB-INF
ディレクトリのweb.xml
ファイル内に次のエントリを作成します。
<servlet> <servlet-name>AFCStatsServlet</servlet-name> <servlet-class>oracle.webcache.adf.servlet.AFCStatsServlet</servlet-class> </servlet>
ブラウザで次のURLを宛先指定します。
http://application_host:application_port/application-context-root/servlet/AFCStatsServlet
関連項目: AFC統計サーブレットの詳細は、JDeveloperのオンライン・ヘルプのキャッシュ・パフォーマンス統計の表示に関するトピックを参照してください。 |
ビジュアル診断機能を使用すると、フラグメントがキャッシュ・ヒットかキャッシュ・ミスかを視覚的に表示できます。この機能により、キャッシュ・ヒットまたはキャッシュ・ミスのステータスに対して適切なクラスを使用して、HTML <SPAN>
タグを持つフラグメント出力に境界が設定されます。固有のクラス・スタイルを設定することにより、フラグメントがキャッシュに格納されているかどうかを視覚的に判断できます。
SRDemoアプリケーションではビジュアル診断機能を使用していませんが、この機能を使用すると、アプリケーションをテストする際に便利です。
関連項目: 詳細は、JDeveloperのオンライン・ヘルプのビジュアル診断の使用に関するトピックを参照してください。 |
AFC統計サーブレットを使用すると、次の問題が発生することがあります。
「HTTP 404 Page Not Found
」エラー・コード
サーブレットへのアクセス時にこのエラーが発生した場合は、構成問題が起因している可能性があります。
この問題を解決するには、web.xml
ファイル内に次の行が存在していることを確認します。
<servlet> <servlet-name>AFCStatsServlet</servlet-name> <servlet-class>oracle.webcache.adf.servlet.AFCStatsServlet</servlet-class> </servlet>
「キャッシュ・インスタンスが実行されていません。」
エラー
このエラーは、キャッシュを監視するためにサーブレットが起動されていないために発生します。サーブレットは、最初のオブジェクトがキャッシュに挿入され、キャッシュ・インスタンスが作成されてた時点で、キャッシュの監視を開始します。