WCSのキャッシュは夜ひらく

 みなさん、こんにちは。毎日寒い日が続きますね。大雪の被害にあわれた方々には、心よりお見舞い申し上げます。
東京も記録的な大雪でした。幸い週末にかかったため、大きな混乱はなかったようですが、未だ山間部では道路や線路が不通のところがあるようです。
※東京に山間部なんてあるのかよ!って方は一度、Googleマップなどで東京の奥多摩あたりをご覧になってください。ちなみに、最高峰は奥多摩の雲取山(標高2017m)です。(筆者も初めて知りました!)

 今回は、キャッシュのお話です。動的配信を行っている場合、キャッシュはクライアントからのアクセスに素早く反応したり、サーバの負荷を軽減するために非常に有効な手段ではありますが、その使い方を間違えると大変なことになります。
以下にキャッシュを使う上での問題点を挙げてみます。

1. ページのファーストアクセスが遅い問題
パブリッシュ時にキャッシュを再生成しない場合は、キャッシュの有効期限が切れたあと、最初のアクセスが発生した段階でキャッシュを生成することになります。つまり、アクセスする誰かがババを引くことになるのです。
もちろん、パフォーマンスとしての要件を満たすようページ出力に要する時間は、厳しくチェックされチューニングされていますが、それでもキャッシュが有効な場合に比べれば、時間がかかることには違いはありません。
一般的なWCSの動的配信の案件では、概ね3秒以内のレスポンスを目指してチューニングが行われていますが、それでもページの作り上、より時間がかかったり、コンマ数秒で表示されるキャッシュ有効時の表示よりは、はるかにレスポンスが遅い結果になります。

2. パブリッシュ終わらない問題
WCSではパブリッシュ時にキャッシュを自動再生成する機能があります。
これを使えば、パブリッシュした資材に関して関連するページのキャッシュを再生成することができます。
これを使えば、たまたまファーストアクセスに当ってしまう人もなく、すべての問題が解決できるのではないか?と一瞬思ってしまいますが、そこに落とし穴があります。

 キャッシュを再生成するには時間がかかるということです。自動で再生成するとはいえ、キャッシュを生成するにはそれなりの時間がかかります。
例えば、製品が数千あるサイトにて、製品を1つ追加したとします。その製品にたどり着くための中間的なカテゴリページに製品数の表示などがあったとしたら、製品を1つだけ追加したとしても、その中間経路のページの製品数の表示をすべて直さなければなりません。その経路自体が数百もあったとしたらどうでしょうか?
製品を1つだけパブリッシュしたのに、キャッシュの自動再生成に時間がかかりパブリッシュがいつまで経っても終わりません。そんな結果になってしまいます。

運用に合わせたキャッシュルールを考える!
 以上の問題を解決するためには、運用に合わせたキャッシュルールを策定する必要があります。
いくらパブリッシュが早くても、キャッシュ率の低いサイトはアクセスが遅くなりますし、いくらキャッシュ率が高くても、運用時間中のパブリッシュに時間がかかりすぎては運用に支障を来します。
例えば、サイトの構成、運用方法や要望、アクセスするクライアントの性質が以下の通りだったとします。

  • 製品情報の詳細は多数の経路を辿り表示され、それぞれの経路に配下の製品数やスペックの一部が表示される。
  • 運用時間は、概ね通常の勤務時間(9:00~18:00)。
  • サイトへのアクセスもB to Bのため、9:00~18:00の間のアクセスが殆どを占める。(夜間のアクセスが少ない)
  • 運用時間中は、製品情報の更新も頻繁に行う上、重要なお知らせが突発で入る場合もあるのでパブリッシュ時間はなるべく短くしたい。
  • キャッシュ率は極力100%に近づけたい。
  • 製品情報は特別な場合を除いて、次の日にすべての導線が繋がり、導線に表示される製品数なども表示されればよい。

以上の条件を踏まえ、以下のようなスケジュールを構築します。

運用スケジュール
製品ページツリー
 製品詳細に至る複数の経路のページ(製品中間A~E)のキャッシュを、アクセスの少ない夜間に再生成することによって、クライアントのアクセスの負担を軽減し、通常運用時のパブリッシュ時間を短縮し、キャッシュ率を極力高くすることを実現します。
 キャッシュはサイトへのアクセスを高速化する素晴らしい手段ですが、キャッシュは作らないと存在しない、作るためにはそれなりの時間がかかるということを忘れずに、サイト運用に則したキャッシュルールやスケジュールを策定することがWCSでの開発では非常に重要になります。

 今回のタイトルは…わかる方だけわかっていただければ幸いです。


入力欄をカスタマイズする!属性エディタ

ゆるゆるアニマルコラム担当のエンジニアKです。今回は「属性エディタ」についてです。新米PGのリス田くんはあれから成長したのでしょうか。それとも…?

◆登場人物紹介◆
mega02
メガネ先輩
ベテランSE。数々のWCS案件を経験してきたツワモノ。

risu02
リス田
新米プログラマー。WCSについて学び始めたばかり。
risu08 げへへー
mega02
risu08 うふふー
mega06 ???
mega06 …おい、リス田。何よだれ垂らしながらニヤニヤしてんだ。気持ち悪いぞ…。
てか、課題はちゃんと進んでいるのか?
risu02 ハッ!先輩っ!?課題ですか?
い、今まさに進めていたところですよー!
見て下さい、僕の…、WebCenter Sites牛丼屋メニューサイトを!!

2117_02_img01

mega02 …ほう。メニュー一品一品をアセット化したのか。
管理画面側はどんな感じ?
risu06 こんな感じです!

2117_02_img02

mega06 こ、これは…。
リス田、お前…、この入力画面、何か感じないのか??
risu07 何か…?
あっ!!サイドメニューも必要ですね!僕、健康志向なんでサラダとか付けちゃいますよー!
mega07 ばかもん!!貴様自身の健康活動なんぞどうでもいい!!
入力画面の入力欄を見てみろ!全部一行テキストボックスだろうが!
これじゃ使い勝手良くないわ!
risu04 ヒ、ヒィッ!!す、すいません!
って、入力欄をテキストボックス以外にする方法ってあるんですか?
mega04 お前、開発者ガイドちゃんと読んでないだろう…。
risu04 ウッ!
mega02 開発者ガイド「属性エディタの設計」に、入力欄の形を変える方法がちゃーんと載っているんだ。
属性エディタを使えば、ラジオボタンやチェックボックス、テキストエリア等々、入力欄を別の形に変える事が出来るぞ。
例えば「肉の種類」は牛肉・豚肉・鶏肉しか入力させたくない場合は、選択肢がその3つのラジオボタン項目を作ってしまえばいい。
属性エディタは以下の様なXMLを使って定義するんだ。

<?XML VERSION="1.0"?>
<!DOCTYPE PRESENTATIONOBJECT SYSTEM "presentationobject.dtd">
<PRESENTATIONOBJECT NAME="Radio_MeatType">
<RADIOBUTTONS LAYOUT="VERTICAL">
<QUERYASSETNAME>Query_MeatType</QUERYASSETNAME>
</RADIOBUTTONS>
</PRESENTATIONOBJECT>

mega01 XMLの内容を簡単に説明すると、Query_MeatTypeという問い合わせアセットの結果を用いて、ラジオボタン項目を縦方向(VERTICAL)に並べる、という事だな。
もちろん、問い合わせアセットは、「牛肉」「豚肉」「鶏肉」の3件が結果として返ってくるようにする。
risu02 おぉー。
mega02 「トッピング」なんかも、トッピングできる食材でチェックボックスとかにしてしまえばいい。
何でもかんでもトッピングできる訳じゃないだろう?
チェックボックスの場合の属性エディタはこんな感じかな。ラジオボタンの場合とよく似ているね。

<?XML VERSION="1.0"?>
<!DOCTYPE PRESENTATIONOBJECT SYSTEM "presentationobject.dtd">
<PRESENTATIONOBJECT NAME="CheckBox_Topping">
  <CHECKBOXES LAYOUT="VERTICAL">
    <QUERYASSETNAME>Query_Topping</QUERYASSETNAME>
  </CHECKBOXES>
</PRESENTATIONOBJECT>

risu01 なるほど…。
mega02 実際の案件だと、お客様の要望を聞いて、その要望に合った形・選択肢の入力項目を作成するんだ。
とりあえず、今の入力画面にいろんな属性エディタを適用させて、使い勝手の良い入力画面にしてみろ。
…あ、そうそう、出来るまでは昼飯に行っちゃだめだぞー。
risu04 な、なんですと!!そりゃ全力でやらねば!!

◇◇数時間後◇◇

risu09 先輩、出来ました…。
は、早く飯…昼飯を…。
mega01 ん?ああ遅かったなぁ。ちょっとまって。今チェックするから。
risu09 空腹時に食べ物関係の作業するのって辛いですね…。

2117_02_img03

mega01 ふむ。いい感じだね。
ラジオボタン、チェックボックスや、プルダウンも盛り込まれているな。よしよし。
アセットの設計をするときは、使う時の利便性までちゃんと考えた上で設計するのがポイントね。
risu06 はい!先輩わかりました!はい!先輩昼飯を食いに行きましょう!!
僕の頭の中はもう牛丼でいっぱいです!!牛丼食べに行きましょう!牛丼!!
mega05 えー。俺魚が食べたい気分なんだにゃ。
risu04 ガーン!!

以上、「入力欄をカスタマイズする!属性エディタ」でした!
次回をお楽しみに!


Content-Typeを動的に指定することは可能なのか

今回は、前回のマネージャーKのコラム(ページは見つかったのか。見つかっていないのか。)でちょっとだけ話に挙がった「Content-Type」についてお話します。

Webcenter Sites(以下WCS)では、Content-Typeをテンプレート作成時に指定することができます。

Content-Typeはテンプレートの設定項目の1つである、ページレットパラメータで”cs.contenttype”をキーに指定します。

ページレット

しかし、このページレットパラメータで指定したcs.contenttypeの値は、そのテンプレートで常に固定となるため、動的にContent-Typeの変更ができません。
サーブレットプログラムでは、下記コードのようにContent-Typeを動的に変更できます。

response.setContentType("text/html");

WCSのテンプレートでこのコードを書いてもエラーは発生しませんが、有効にもならないのです。

それでは、動的にContent-Typeを変更したい要件が出たときにはどうするべきでしょうか。

実際に携わった案件では、使われる可能性のあるContent-Typeのテンプレートを全て用意し、アクセスに応じて適切なContent-Typeのテンプレートを呼び出す方法を取りました。

例えば、gifへのアクセスであれば、cs.contenttypeが”image/gif”のテンプレートを呼出し、pdfへのアクセスであれば、”application/pdf”のテンプレートを呼び出すといった感じです。

呼出し方は色々な方法がありますが、Apacheのrewriteを使うのも一つの方法です。

Rewriteを使ったテンプレート呼出しイメージ

rewrite_image

もう一つ、こちらはまだ検証前ではありますが、テンプレートを”XML”タイプで開発することでContent-Typeを動的に変更できる可能性があります。

XMLにはHTTPのヘッダーを設定するタグ(ICS.STREAMHEADER)が用意されていて、このタグを使うことによってContent-Typeの指定が可能だということです。

実際にこのタグが有効かどうかは次の機会に検証したいと思います。

今のところ、JSPでの開発ではContent-Typeを完全な動的化にする方法が見つかっていませんが、上記に挙げた方法が参考になれば幸いです。