(57)【要約】【課題】複数のモジュールが連携してジョブを実行するシステムにおいて、ジョブの投入状況は時間により、変化するが、スタンバイさせるモジュールをジョブの投入状況に応じて動的に決定することができなかった。【解決手段】ジョブの投入状況に応じて、スタンバイさせる各モジュールの数を動的に変更する。ジョブの投入時に使用するモジュールがスタンバイされていない場合、使用するモジュールのスタンバイさせるモジュールの数を増やし、スタンバイしてから一定期間使用されていないモジュールが存在する場合、一定期間使用されていないモジュールのスタンバイさせるモジュールの数を減らす。【選択図】  図１０
2015146064.tif 000002
【特許請求の範囲】
【請求項１】
複数のモジュールが連携してジョブを実行するシステムであり、複数のモジュールが連携してジョブを実行するシステムは、ジョブを入力する手段（Ｓ１００１）と、ジョブで使用するモジュールを決定する手段（Ｓ１００２）と、ジョブを実行する手段（Ｓ１００６）と、モジュールをジョブの投入前にスタンバイさせる手段（Ｓ８０５）と、スタンバイさせるモジュールを管理する手段（２５１０）を有し、
スタンバイさせるモジュールを管理する手段（２５１０）は、ジョブの投入時に使用するモジュールがスタンバイされていない場合（Ｓ１００３）、前記使用するモジュールのスタンバイさせるモジュールの数を増やし（Ｓ１００４）、スタンバイしてから一定期間使用されていないモジュールが存在する場合（Ｓ１１０２）、前記一定期間使用されていないモジュールのスタンバイさせるモジュールの数を減らす（Ｓ１１０３）ことを特徴とするシステム。
【請求項２】
前記システムはジョブを実行する際、複数のモジュールが順に処理を行うシステムであり、スタンバイさせるモジュールを管理する手段は、各モジュールが過去のジョブにおいて、何番目のモジュールとして使用されたかの順番履歴を保持し、順番履歴の値が小さいほど値が大きくなる重みを算出し（Ｓ１３０１）、スタンバイさせるモジュールの数に対して重みづけをした値を、実際にスタンバイさせるモジュールの数とする（Ｓ１３０２）ことを特徴とする請求項１に記載のシステム。
【請求項３】
スタンバイさせるモジュールの数に上限値（Ｓ１５０４）と下限値（Ｓ１５０３）を設けることを特徴とする請求項１又は請求項２に記載のシステム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、情報処理システム、情報処理装置、制御方法およびコンピュータプログラム
に関する。
【背景技術】
【０００２】
ユーザ端末からのリクエストによりWebサービスが印刷データを生成し、その印刷データを印刷装置で受信して処理し、印刷を実行するシステムが存在する。そのようなWebサービスの代表例は特許文献１に開示されている“cloud print service”が知られている（以下略して“CPS“と称する）。CPSは各プリンターベンダーに仕様を公開し、仕様に沿ったプリンターを開発してもらうことでサービスの急速な拡大と利用者への利便性を実現しようとするものである。特許文献１にはCPSにおけるプリンターの登録と選択、印刷データの生成に関する技術が開示されている。
【０００３】
特徴としてCPSはプリンターベンダー毎に特有のページ記述言語やプリントデータフォーマットに従った印刷データを生成するのではなく、ベンダー非依存の統一的なフォーマットで印刷データを生成し、各プリンターにその印刷データを直接入力データとして受け取ってもらい印刷を実現する点にある。ベンダー非依存の統一的なフォーマットとしてはPortable Document Format(PDF)が挙げられている。この仕様に従えば、CPSはプリンターベンダー非依存の画一的な印刷データ生成を行うことができる。サービスの利用者にとってはどのようなベンダーのプリンターであろうがCPSに準拠したプリンターであれば自分の要求する印刷がどこからでも依頼できてかつ印刷物を受け取れる利便性が得られる。
【０００４】
これまでプリンタードライバーはアプリケーションプログラムが出力するドキュメントをプリンターが理解できるPDLで記述した印刷データに変換する処理を行ってきた。加えてプリンターの特性、トナー、インク、記録紙などに応じて色味の調査や、印刷モードの選定などの処理も行っていた。ところが、プリンタードライバーはユーザ端末上で動作しなければならない為、少なからず端末のリソースを消費する。昨今、ユーザ端末はその形状をデスクトップ型PC、ノート型のPCからスレート（タブレット）型やスマートフォンまで広げている。端末形状は小型化しバッテリーの消費が大きな課題となっている。また多様化するこれらの端末のOSに追従してプリンタードライバーを提供していくことはプリンターベンダーにとっては大きな負担となっている。
【０００５】
このように、プリンタードライバーを不要とするCPSはユーザとプリンターベンダーの両者にとって一見、救世主となるように見える。しかし、実際には、プリンタードライバーが必要とされていた本質的な意義であるプリンターの機能と特性を生かしたデータ変換はやはり必要あることには変わりはない。小型化するユーザ端末とプリンタードライバーを端末上で動作させることなく今までと同じ画質、機能を提供する方策としてプリンタードライバーをクラウド上で動作させる方法が実用となっている。プリンターベンダーは自社のプリンターのプリンタードライバーをWebサービスとして動作させるサービスを提供することで、文献１に示すCPSと同等の利便性とこれまでのプリンタードライバーが提供していたプリンターの特性を生かした印刷データの生成を両立させようとしている。
【０００６】
Webサービス上で動作するサービスやプロセスはユーザ端末から入力された入力ファイルに対して処理を行う。入力ファイルと、その入力ファイルに対する処理内容の組をジョブと呼び、ジョブに対して処理を実行することを、ジョブを実行すると呼ぶ。Webサービス上では、ジョブによって異なる複数のサービスやプロセスが連携してジョブを実行することがある。サービスやプロセスの数が多い場合、すべてスタンバイさせておくと、メモリやCPUを消費し、全体のパフォーマンスが低下する。特許文献２では、ロードさせておくプログラムを、プログラムを使用する頻度による優先度と、メモリの上限から決定する技術が開示されている。
【先行技術文献】
【特許文献】
【０００７】
【特許文献１】米国特許出願公開第2011/0299110号明細書
【特許文献２】特開2004-318860号公報
【発明の概要】
【発明が解決しようとする課題】
【０００８】
ユーザから投入されるジョブは、特定のユーザが短時間に同じフォーマットの入力や同じ出力設定のジョブを連続して投入する傾向があることが知られている。ジョブはユーザに依存するため、時間帯や日時により投入されるジョブを予測することはできない。これにより、使用するサービスやプロセスも時間帯や日時から予測することはできない。特許文献２では、初期化時にスタンバイさせるサービスやプロセスを決定するが、システムを動作させながら、動的にスタンバイさせるサービスやプロセスを変更することができない。これにより、初期化時に想定した頻度よりジョブが投入される頻度が大きい場合、スタンバイされていないサービスやプロセスを使用することになり、ジョブを実行する際に、サービスやプロセスの初期化時間がかかる。
【課題を解決するための手段】
【０００９】
本発明の構成は、
複数のモジュールが連携してジョブを実行するシステムであり、複数のモジュールが連携してジョブを実行するシステムは、ジョブを入力する手段（Ｓ１００１）と、ジョブで使用するモジュールを決定する手段（Ｓ１００２）と、ジョブを実行する手段（Ｓ１００６）と、モジュールをジョブの投入前にスタンバイさせる手段（Ｓ８０５）と、スタンバイさせるモジュールを管理する手段（２５１０）を有し、
スタンバイさせるモジュールを管理する手段（２５１０）は、ジョブの投入時に使用するモジュールがスタンバイされていない場合（Ｓ１００３）、前記使用するモジュールのスタンバイさせるモジュールの数を増やし（Ｓ１００４）、スタンバイしてから一定期間使用されていないモジュールが存在する場合（Ｓ１１０２）、前記一定期間使用されていないモジュールのスタンバイさせるモジュールの数を減らす（Ｓ１１０３）ことを特徴とする。
【発明の効果】
【００１０】
本発明によれば、システムを動作させながら、ジョブの入力状況に応じて動的にスタンバイさせるサービスやプロセスを変更することができる。
【図面の簡単な説明】
【００１１】
【図１】プリントシステムおよびその利用者（印刷ユーザ）の関係を示す図である。
【図２】印刷データ変換サービスが動作するサーバーPCのハードウエア構成図である。
【図３】サーバーPC上で動作するソフトウエアを説明するブロック図である。
【図４】印刷データ変換サービスとそれが依存するコンポーネント群を示す図である。
【図５】コンポーネントの生成シーケンスを示す図である。
【図６】サービスカタログの内容を示す図である。
【図７】サービスイベントリの内容を示す図である。
【図８】フィルターをスタンバイさせる処理のフローチャートである。
【図９】フィルターを複数スタンバイさせた場合のシステムを示す図である。
【図１０】フィルターをスタンバイさせる数を増加させる処理のフローチャートである。
【図１１】フィルターをスタンバイさせる数を減少させる処理のフローチャートである。
【図１２】実施例２におけるサービスカタログの内容を示す図である。
【図１３】実施例２におけるスタンバイ数を算出する処理のフローチャートである。
【図１４】実施例２におけるサービスカタログの内容を示す図である。
【図１５】実施例２におけるスタンバイ数を算出する処理のフローチャートである。
【発明を実施するための形態】
【００１２】
以下、本発明を実施するための最良の形態について図面を用いて説明する。
【００１３】
［実施例１］
図１は本発明の第一の実施例である印刷データ変換サービスとそのユーザから成る構成図である。本実施例では印刷データ変換サービスに本発明を適応させるが、本発明は印刷データ変換サービスに限定されるものではなく、各種フォーマット変換や、データ変換、データ処理に適用可能である。
【００１４】
印刷データの変換を依頼するユーザ（５０）は印刷データの変換要求を送出する機器として、パーソナルコンピュータ（２０）、タブレットPC（３０）や携帯端末（４０）などの機器を利用する。ユーザ（５０）はこれらの機器の内部で動作しているアプリケーション（不図示）を操作して、ネットワーク（１０）上に存在する印刷データ変換サービス（２１００）に対して印刷データの変換を依頼する。印刷データ変換サービス（２１００）はサーバーPC（８０）上でWell-knownのURLを公開している、いわゆるWebサービスとして動作しているプログラムである。サーバーPC（８０）上では前記URLに対して到着した依頼を印刷データ変換サービス（２１００）に転送するWebサーバー（４１００）も動作している。URLへ到着する依頼は通常多数になるため、単一のサーバーPC（８０）では処理させず、複数のサーバーPC（８０）に処理させる構成とする。従って、複数のサーバーPC（８０）の前段にロードバランサー（７０）を設置し各サーバーPC（８０）に転送される依頼が均一に配分されるように構成する。
【００１５】
印刷データ変換サービス（２１００）が提供するサービスは、ユーザ（５０）が指定するデータをプリンター（６０）で印刷できる形式に変換することである。ユーザが指定するデータにはドキュメント、画像ファイルなど各種のアプリケーションプログラムで作成されたフォーマットが存在する。一方、プリンター（６０）が印刷データとして受け付けるデータは前述のフォーマットとは異なり、PDL( Page Description Language )で記述されたデータや、印刷部数等の印刷を制御するための命令とパラメータを備えたPJL( Print Job Language )で記述されたデータとなっている。このように、ユーザ（５０）とプリンター（６０）の間には扱うデータ形式の差異が存在する為に、その差異を埋めるプログラムが必要とされる。
【００１６】
通常この変換処理を行うのがプリンタードライバーと呼ばれるプログラムである。プリンタードライバーはユーザ（５０）が操作する前述のアプリケーションプログラムが動作しているPC上で動作させることが通常である。しかし、プリンタードライバーの処理は比較的CPU、メモリなどのリソースを必要とする重い処理であるため、ユーザ（５０）の操作するPCの保持するリソースが少ない場合には印刷処理が実用的でなくなる程時間のかかる処理になってしまう。ユーザ（５０）が操作する端末（パーソナルコンピュータ（２０）、タブレットPC（３０）や携帯端末（４０））などリソースの比較的少ない端末からの印刷の需要が高まるにつれプリンタードライバーの処理をインターネット上のサービスで行わせることの重要性が増している。
【００１７】
ユーザ（５０）は前述の各種端末から前述のURLに対して印刷データをプリンター（６０）で印刷できる形式に変換するように依頼を行う。依頼に応じてサーバーPC（８０）上で動作している印刷データ変換サービス（２１００）が生成した変換後のデータは前述の端末に対して返送される。ユーザ（５０）の指示によっては変換後のデータは印刷データ変換サービス（２１００）がアクセス可能なファイルサーバPC（９０）で保管される場合もある。
【００１８】
図２は印刷データ変換サービス（２１００）をはじめとするソフトウエア群が動作するコンピュータのハードウエア構成図である。プリントサービスサーバはＯＳ（オペレーティングシステム）上で動作するアプリケーションプログラムであり、ＨＤＤ（１００２）あるいはＲＯＭ（１００３）に格納されている。ＣＰＵ（１００５）がＯＳとアプリケーションプログラムをＨＤＤ（１００２）あるいはＲＯＭ（１００３）から読み出してＲＡＭ（１００４）にロードし、実行することで様々な処理が進行しプリントサービスサーバとしての機能を実現する。処理結果はファイルとしてＨＤＤ（１００２）に格納され、あるいはデータとしてＲＡＭ（１００４）に記憶される。アプリケーションプログラムはコンピュータに接続されている入力装置（１００７）から使用者の入力、各種センサの読み取り値を取得する。さらに出力装置（１００６）に対して情報を出力し、処理結果を表示する。さらに、通信装置（１００８）を介してネットワークに接続された他のコンピュータや装置と通信を行う。これらのハードウエアはバス（１００１）で互いに接続されていてアプリケーションプログラムから操作できるように構成されている。
【００１９】
図３は印刷データ変換サービス（２１００）を含むソフトウエア群がサーバーPC（８０）上でどのように構成されているかを示すブロック図である。Webサーバー（４１００）はユーザ（５０）が操作したパーソナルコンピュータ（２０）上のアプリケーションからHTTPプロトコルで送信されたリクエストを受け取る。ロードバランサー（７０）はWebサーバー（４１００）の前段に位置し、複数のサーバーPC（８０）上で動作しているWebサーバー（４１００）に振り分ける。この振り分ける方式は種々知られているがその詳細は本発明には関係がないため説明を省略する。
【００２０】
ここで、サーバーPC（８０）は必ずしも物理的な一台のサーバーPCを意味する必要はない。現時点で単一のPC上に複数の仮想的なPCを出現させる仮想化技術が一般的となっており、ソフトウエアからみれば自身が動作しているオペレーティングシステムが仮想的に作り出されたものか否かは判別がつかないか、あるいは判別する必要がない。従って本発明におけるサーバーPC（８０）は「場合によっては仮想化されたPC」を意味する場合もある。これ以降、「PC」という表現は物理的なPCと仮想化されたPCのいずれかを意味するものとして扱う。
【００２１】
アプリケーションサーバー（４２００）は要求の送付先として指定されたURLを解析し、関連つけられている印刷データ変換サービス（２１００）を決定する。通常Webサーバー（４１００）とアプリケーションサーバー（４２００）は複数種のサービスを扱うことが可能であり、URLから対応するサービスを特定して要求を振り分けることができる。本実施例ではその複数種のサービスの一つが印刷データ変換サービス（２１００）であることを想定している。このサービスの他にもサービスが稼働しているが発明の説明においては印刷データ変換サービス（２１００）以外のサービスは省略する。
【００２２】
印刷データ変換サービス（２１００）はプロセスとして動作する。アプリケーションサーバー（４２００）は複数の要求を並列実行させるために、印刷データ変換サービス（２１００）を複数起動し、各々に要求を振り分ける。
【００２３】
（印刷データ変換サービス）
図４は印刷データ変換サービス（２１００）が依頼された印刷データを変換する際に利用するソフトウエアコンポーネント群の関連を説明する図である。印刷データ変換サービス（２１００）は先に説明したようにプロセスとして動作しており、変換処理をジョブコントローラー（２３００）に委譲している。構成的には印刷データ変換サービス（２１００）がジョブコントローラー（２３００）の代理としてのプロキシー（２２００）をロードしている。さらにそのプロキシー（２２００）がApplication Programming Interface(API)で提供している関数群を呼び出すことで変換処理の実行を依頼し、さらに結果を受領する。
【００２４】
ここで、ジョブコントローラー（２３００）もまたプロセスとして動作しており、変換処理の受付の為の通信インターフェイスを保持している。この通信インターフェイスへのジョブの依頼はHTTPプロトコルではなく、専用のプロトコルが用いられている。プロキシー（２２００）のAPIを呼び出す行為はジョブコントローラー（２３００）が用意している変換処理受付用通信インターフェイスへのプロセス間通信として変換される。すなわち、印刷データ変換サービス（２１００）にとって変換処理はプロキシー（２２００）によって実行されているように見える。しかし実際にはジョブコントローラー（２３００）および後述する複数のフィルター群、およびフィルター群が利用するいくつかのコンポーネントの相互作用によって実現されている。
【００２５】
（ロケーター）
印刷データ変換サービス（２１００）を構成するコンポーネントの中でロケーター（２５００）は特別な役割を担っている。ロケーター（２５００）はアプリケーションサーバー（４２００）が起動した時点で唯一起動している特殊なプロセスである。ロケーター（２５００）の起動の方法はアプリケーションサーバー（４２００）上で動作しているオペレーティングシステム（OS）によって種々の方法が存在する。例えば、Windows（登録商標）であれば”Windows Service”というシステム起動時に自動的に起動される特殊なプロセスとして実装することが可能であり、Linux（登録商標） やUnix（登録商標）ではデーモンプロセスとして動作させることが可能である。
【００２６】
ロケーター（２５００）はコンポーネントの生成の責務を担っている。さらに他のコンポーネントからの求めに応じて別のコンポーネントのアクセスポイントを返すという機能を提供する。アクセスポイントとはTCP/IPのリスンポートを指す。あるコンポーネントは別のコンポーネントが公開しているアクセスポイントを取得し、そのアクセスポイントにアクセスすることでそのコンポーネントが提供する機能を利用する。あるコンポーネントが他のコンポーネントのアクセスポイントをロケーター（２５００）に対して問い合わせる動作を”ロケーションクエリー”あるいは単に“クエリー”と呼ぶ。
【００２７】
印刷データ変換サービス（２１００）を構成するコンポーネントのうち、プロキシー（２２００）、ジョブコントローラー（２３００）、フィルターホスト（２４００）はロガー（２６００）が提供しているロギングデータをログファイルとして記録するサービスを利用している。そのためロケーター（２５００）に対してロガー（２６００）のアクセスポイントを得る目的でクエリーを行っている。同様にプロキシー（２２００）はジョブコントローラー（２３００）をクエリーし、ジョブコントローラー（２３００）はフィルターA（２７００）、フィルターB(２８００)、フィルターC（２９００）をクエリーする。クエリーの詳細フローは後述する。
【００２８】
（ジョブコントローラー）
プロキシー（２２００）を介してジョブ実行を依頼されたジョブコントローラー（２３００）はジョブおよび、ジョブに含まれている印刷データを解析して変換に必要なフィルターを選定する。解析は印刷データの先頭から既定のサイズを読出しその中に含まれている特徴的な内容から印刷データの種類を判定する。例えば、JPEG形式や、PDF（Portable Document Format）形式のデータなどが入力データとして与えられる。
【００２９】
次に、ジョブに含まれている変換先の印刷データ形式を取得し、変換元の印刷データ形式と変換先の印刷データ形式の両者が確定した時点で、この変換に必要なフィルター群を選定する。必要なフィルターの組み合わせとその変換順番は固定的な情報としてジョブコントローラー（２３００）に実装されている。
【００３０】
必要な複数のフィルターを選定したあとはこれらフィルターのクエリーを行う。この例では変換に必要なフィルターとして、フィルターA（２７００）、フィルターB(２８００)、フィルターC（２９００）が必要である。
【００３１】
ジョブコントローラー（２３００）はフィルターA（２７００）、フィルターB(２８００)、フィルターC（２９００）との間で、パイプライン（３０００）と呼ばれるデータ転送チャネルを作成する。本実施例では、パイプライン構成に本発明を適用するが、本発明はプロセスが連携して動作する処理一般に適用可能である。パイプライン（３０００）は基本的に片方向にのみデータを転送する。ジョブコントローラー（２３００）→フィルターA（２７００）→フィルターB(２８００) →フィルターC（２９００）→ジョブコントローラー（２３００）と一周するようにパイプライン（３０００）が構成される。
【００３２】
また、ジョブコントローラー（２３００）はプロキシー（２２００）との間にもパイプライン（３０００）を作成する。このようにパイプライン（３０００）を作成することで、プロキシー（２２００）から印刷データが複数のコンポーネントを還流し、最後に変換が終了した形で再びプロキシー（２２００）に戻ってくる。
（フィルター）
フィルターはデータ変換処理を実装したプロセスとして存在する。フィルターはデータ変換処理以外に、コントロールバス（５００２）への接続とメッセージ送受信、ジョブコントローラー（２３００）との通信、フィルターのログ出力のロガー（２６００）への転送などの処理を行う。
【００３３】
ここで、パイプライン（３０００）を還流するデータについて説明する。このデータは「変換ジョブ」と呼ばれる。
【００３４】
（変換ジョブ）
変換処理はプロキシー（２２００）のAPIを通じて依頼される際に、変換ジョブ（以降単にジョブと称す）の形で引き渡される。ジョブは概念的には変換されるべき対象データと変換処理用の設定値などをまとまりのある形式に束ねた「チケット」と呼ばれるデータ構造から構成される。ジョブには識別できるようにユニークな識別情報が与えられる（ジョブID）。生成されたジョブはファイルとして記憶装置に格納される。また記憶装置から取り出す際にはジョブIDを指定してそのファイルを取得して内容を参照することが可能である。またジョブを破棄する行為はファイルの削除として実現される。ジョブはこの印刷データの内容を直接ファイル内に含むかあるいはファイル化した印刷データのファイルパスなどの参照情報を含んでいる。さらにジョブは、印刷を行わせるプリンター（６０）が処理できる印刷ファイル形式についての情報も含んでいる。さらに印刷部数や印刷の面付指示などの印刷の処理方法を指定する印刷設定を含んでいる。以降ではジョブを処理する行為を「ジョブを実行する」と呼ぶ。
【００３５】
（印刷データ）
プリンターが理解可能な形式で作成され、その内容をプリンターのメモリを介してハードウエアロジックに与えることが可能なバイナリ形式のデータであるか、あるいはファームウエアとして実装されている変換ロジックに与えて印刷エンジンが処理可能な形式に変換できる何らかの記述言語（PDL）で記述されたデータを印刷データと称している。
【００３６】
印刷データは図２のパーソナルコンピュータ（２０）、タブレットPC（３０）や携帯端末（４０）などの機器内に保持されているファイルから、あるいはメモリ内から変換要求に埋め込まれた形で取得される。あるいは図２のファイルサーバPC（９０）に予め格納されているファイルへの参照（URLあるいはファイルパス）を変換要求から取り出してそのファイル内容を取得する。
【００３７】
ここで図４に立ち戻り、印刷データ変換サービス（２１００）を構成しているコンポーネント群が他のコンポーネントをクエリーする意義と手順を説明する。
【００３８】
（クエリーの意義）
コンポーネントが提供しているサービスはネットワークからアクセスできるエンドポイントとして他のコンポーネントに公開される。具体的にはTCP/IPのアドレスとポート番号の組が公開される。コンポーネントは他のコンポーネントの提供するサービスI/Fを取得して利用する。複数種類のコンポーネントがプロセスとして複数存在し、かつ同一コンポーネントも同一PC上に複数存在する。同一コンポーネントが同一PC上に複数存在することがあるため、各コンポーネントが公開するサービスI/Fのポート番号は固定にすることができず、自ずと動的に生成せざるを得なくなる。動的に生成されたエンドポイントは何らかの管理機構が無くては他から参照することはできない。この管理を担当するのはロケーター（２５００）である。
【００３９】
さらに、コンポーネントが他のコンポーネントの動的に生成されたエンドポイントを取得する手段が必要である。この手段がクエリーである。クエリーに回答するのはやはりロケーター（２５００）の役割である。
【００４０】
（コンポーネントの生成）
コンポーネントはロケーター（２５００）によって、基本的に動的に生成される。図５はコンポーネントの生成シーケンスを説明した図である。図５（１）ではロケーター（２５００）のみが存在する状況である。この状況は図３においてサーバー（８０）が起動した直後に相当する。この時点ではまだ印刷データ変換サービス（２１００）は起動していない想定である。ロケーター（２５００）は単独でコントロールバス（５００２）に参加している状態である。
【００４１】
ロケーター（２５００）は図６に示すサービスカタログ（５００１）を保持している。サービスカタログ（５００１）はこのサーバー（８０）上にインストールされているコンポーネントのリストから構成されている。コンポーネントごとに名前、バージョン、実行ファイルパス、起動時のコンフィギュレーションファイルパス、コンポーネントの寿命、オンデマンドで起動するかスタンバイさせておくかを示す起動モード、スタンバイさせる数を表すスタンバイポイントが格納されている。名前はコンポーネントの機能を表す一般的な名称が階層構造で表現される。例えば”AFilter”という機能名が”system”という階層の下に定義されているため、
“/system/AFilter”という階層形式の表記となっている。この名前の表記方法は特に本発明の特徴とはなっていないがコンポーネントを組織的にかつユニークに命名する為に用いられている。同一の名前を持つコンポーネントであっても、そのバージョンが異なれば異なる機能を提供するためサービスカタログ（５００１）上では異なるエントリーとして扱われる。
【００４２】
図５（２）ではあるコンポーネントA（５００３）の起動モードがスタンバイ（startup）に指定されているとした場合の例を示している。ロケーター（２５００）のスタンバイ数管理部（２５１０）は自身が起動したら、このサービスカタログ（５００１）を参照し、起動モードがスタンバイに指定されているコンポーネントA（５００３）を発見する。スタンバイ数管理部（２５１０）はスタンバイポイントからスタンバイさせる数を決定する。本実施例ではスタンバイポイントの値をそのままスタンバイ数とする。その後、サービスカタログ（５００１）からコンフィギュレーションファイル（５００５）のパスと寿命を取得し、引数に与えてコンポーネントA（５００３）の実行ファイルパスのプログラムを、スタンバイさせる数、起動させる。
【００４３】
コンポーネントは起動し、コントロールバス（５００２）に接続する時点でユニークなIDを与えられる。このIDは本実施例ではGUIDであるが他の形式でも構わない。起動モードにはそのほかにオンデマンド（on-demand）が定義されている。オンデマンドの起動モードを持つコンポーネントはそのシステム起動時には自動的には起動されず、文字通りそのコンポーネントを指定したクエリーがなされて初めて起動される。
【００４４】
図５（３）では起動したコンポーネントA（５００３）は、起動時に与えられたコンフィギュレーションファイル（５００５）の内容を参照して必要な初期値等を取り出し、さらにその初期値を使って自身を初期化する。初期化が完了するとサービスを提供する為に、TCP/IPのポートを取得しサービスI/F（５００４）の待ち受けを開始する。コンポーネントA（５００３）はこれで他のコンポーネントへのサービスの提供の準備ができたため、コントロールバス（５００２）に自身のアドバタイズメッセージ（５００６）を作成して送信する。アドバタイズメッセージ（５００６）にはコンポーネントA（５００３）の名前、ID,バージョン、サービスI/F（５００４）のURL、ポート番号、寿命が記載されている。このメッセージがロケーター（２５００）宛てに送信される。アドバタイズメッセージ（５００６）はコンポーネントが自身の起動完了とサービス提供開始を宣言する行為である。このメッセージの受信によってロケーター（２５００）はコンポーネントA（５００３）の起動を確認し、かつサービスI/Fを取得することができる。
【００４５】
図５（４）ではロケーター（２５００）がコンポーネントA（５００３）からのアドバタイズメッセージ（５００６）を受信した直後にコンポーネントA（５００３）の起動を確認し、以降の管理の為に管理テーブルであるサービスインベントリー（５００７）に登録を行ったことを表している。
【００４６】
図７はサービスインベントリー（５００７）の内容を模式的に表した図である。サービスインベントリー（５００７）にはロケーター（２５００）がアドバタイズメッセージ（５００６）を受け取った時点でそのメッセージの送信元であるコンポーネント毎のエントリーが作成されてそこにメッセージの内容を転記して作成される。なお、エントリーの内容としての「生存時間」欄にはコンポーネントが作成されてからの生存時間（秒数）が記録される。この生存時間は後述するハートビートメッセージ（５００８）の内容から作成される。
【００４７】
また「状態」欄にはコンポーネントの状態を示す値が後述するステートチェンジメッセージから転記される。「最終連絡時刻」欄はロケーター（２５００）がコンポーネントから最後に受け取ったメッセージの受け取り時刻を記録してある。この実施例ではオペレーティングシステムから取得されたシステム時刻が格納されている。通常、名前とバージョンが同一であるコンポーネントのプロセスは複数生成される。これらのサービスインベントリー（５００７）上のエントリーは少なくとも互いに、IDとPort番号が異なった値になるため識別が可能である。
【００４８】
図５（５）ではコンポーネントA（５００３）からハートビートメッセージ（５００８）を受け取る状況を説明している。各コンポーネントは定期的にハートビートメッセージ（５００８）をロケーター（２５００）宛てに送信しなければならない決まりとなっている。ロケーター（２５００）はこのメッセージを受け取ることにより送信元コンポーネントの生存を確認し、サービスインベントリー（５００７）の「生存時間」欄と「最終連絡時刻」欄を更新する。もし、コンポーネントからのハートビートメッセージ（５００８）が既定時間滞ると、ロケーター（２５００）はこのコンポーネントの「状態」欄を「行方不明」に変更する。
【００４９】
この状態でさらに既定時間ハートビートメッセージが滞ると、そのコンポーネントは自動的にサービスインベントリー（５００７）上からエントリーごと削除される。サービスインベントリー（５００７）上から削除されたコンポーネントはもはや他のコンポーネントからのクエリーに対して検索されなくなり、以てサービスを提供できなくなる。エントリーの削除は対象コンポーネントのIDを基に行われるため同一名称の他のコンポーネントのエントリーには影響は与えない。
【００５０】
図５（６）はコンポーネントA（５００３）がコンポーネントB（５０１４）を利用しようとしてロケーター（２５００）に対してクエリーメッセージ（５００９）を送信した様子である。このクエリーメッセージ（５００９）にはコンポーネントB（５０１４）の名前と利用したいバージョンが記されている。あるコンポーネントは複数のバージョンが作成され得る。同一の名前のコンポーネントが機能の違いにより複数作成されて異なるバージョンとして市場にリリースされる。
【００５１】
従ってコンポーネントA（５００３）はバージョン“2.0.0.1”の様に自分が利用したいコンポーネントB（５０１４）のバージョンを指定してクエリーを行うことができる。もし、特定バージョンを利用する必要が無いならばバージョン欄は空で指定することになっている。この図の時点ではコンポーネントB（５０１４）はまだ生成されていない為、ロケーター（２５００）はコンポーネントB（５０１４）を新たに生成する。図５（２）〜（４）で示したコンポーネントA（５００３）の生成手順と同じようにコンポーネントB（５０１４）が生成される。
【００５２】
図５（７）はロケーター（２５００）がクエリーに対するレスポンスをコンポーネントA（５００３）にクエリーレスポンスメッセージ（５０１０）として返却する様子である。クエリーレスポンスメッセージ（５０１０）にはコンポーネントB（５０１４）の名前、バージョン、サービスI/Fを示すURLとポート番号が格納されている。
【００５３】
図５（８）はクエリーレスポンスメッセージ（５０１０）を受け取ったコンポーネントA（５００３）が取得したコンポーネントB（５０１４）のサービスI/Fを利用する様子である。コンポーネントによってはサービスI/Fにアクセスして来る他のサービスからのサービス要求を同時に扱えるものとそうでないものが存在する。例えば、ロガー（２６００）は複数のサービスからのロギングデータを同時並行的に受け取りログファイルに記録していく能力を有する。
【００５４】
一方、パイプラインを構成してジョブを変換するフィルターは同時並行処理の能力をもたない。従って、コンポーネントB（５０１４）が同時並行処理能力を持たないコンポーネントであるとすると、コンポーネントA（５００３）がアクセスしてきた時点で他のコンポーネントからの要求を受け付けられない状態すなわちビジー状態に遷移する。この状態はコンポーネントA（５００３）が明示的なアクセス終了をサービスI/Fを通じてコンポーネントB（５０１４）に宣言するまで継続する。コンポーネントB（５０１４）はビジー状態に遷移したら、自身を利用したいコンポーネントA以外の他のコンポーネントのクエリーで検出してほしくないと考える。
【００５５】
そこで、図５（９）に示すようにステートチェンジメッセージ（５０１２）をロケーター（２５００）に対して送信する。ステートチェンジメッセージ（５０１２）にはコンポーネントB（５０１４）がビジー状態に遷移したことが記されている。このメッセージを受け取ったロケーター（２５００）はサービスインベントリー（５００７）のコンポーネントB（５０１４）のエントリーを検索し、その「状態」欄に受け取った状態を転記する。さらに「最終連絡時刻」欄も更新する。コンポーネントB（５０１４）の「状態」欄がビジー状態に変更になった為、ロケーター（２５００）は以降、名前を指定したクエリーを受け取ってもそのコンポーネントB（５０１４）インスタンスを選定することはなくなる。ただし、サービスインベントリー（５００７）には他のコンポーネントBのプロセスが複数存在している可能性がある。それらのいずれかがビジー状態でなければ「利用可能なコンポーネントB」としてクエリーの発行元のコンポーネントに返却される。また、「利用可能なコンポーネントB」が存在指定なければ、新たにコンポーネントBを起動し、新たに起動したコンポーネントBを「利用可能なコンポーネントB」としてクエリーの発行元のコンポーネントに返却される。
【００５６】
図５（１０）は寿命に達したコンポーネントB（５０１４）が自ら終了する直前にGoodbyeメッセージを送信する様子を示したものである。フィルターの寿命には、サービスカタログ（５００１）に記載されている寿命の時間に達した場合と、ジョブを処理したことにより終了する場合がある。フィルターは１つのジョブを処理すると、プロセスを終了させる。フィルターを１つのジョブで終了させることにより、メモリリークや異常終了のリスクを低減させることができる。本実施例では、フィルターを1つのジョブで終了させるとして説明するが、フィルターが複数ジョブを処理できるとしても、本発明は適用可能である。このメッセージを受け取ったロケーター（２５００）はサービスインベントリー（５００７）のコンポーネントB（５０１４）のエントリーを削除する。
【００５７】
次に、システム稼働中のスタンバイに指定されているコンポーネントの起動処理について説明する。図５（２）において、ロケーター（２５００）起動時の起動モードがスタンバイに指定されているコンポーネントの起動処理について説明したが、システム稼働中も、スタンバイに指定されているコンポーネントが終了した場合は、新たに該当コンポーネントを起動させる。この処理のフローチャートを図８において説明する。以後、コンポーネントはフィルターとして説明する。ロケーター（２５００）はフィルターの終了を検知する（Ｓ８０１）。図５（１０）において説明したように、フィルターは寿命に達した場合、Goodbyeメッセージを送信するので、ロケーター（２５００）はGoodbyeメッセージを取得した際に終了を検知できる。また、図５（５）において説明したように、フィルターからのハートビートメッセージが既定時間滞った場合も、終了と検知する。
【００５８】
次に、スタンバイ数管理部（２５１０）は該当フィルターが現在起動している数を取得する（Ｓ８０２）。本実施例では、スタンバイ数管理部（２５１０）は終了したフィルターと名前とバージョンが一致するサービスインベントリー（５００７）を検索することで、該当フィルターが現在起動している数を取得する。次に、スタンバイ数管理部（２５１０）は該当フィルターのスタンバイポイントからスタンバイ数を算出する。（Ｓ８０３）。本実施例では、スタンバイ数管理部（２５１０）は終了したフィルターのサービスカタログ（５００１）に記載されているスタンバイポイントを取得し、スタンバイポイントをそのままスタンバイ数とする。スタンバイポイントからのスタンバイ数の算出の方法は、あらかじめ定義された定数をかける等の方法でもよい。スタンバイ数管理部（２５１０）は該当フィルターの起動数より、スタンバイ数が少ないかどうか判断し（Ｓ８０４）、少ない場合はスタンバイ数フィルターが起動している状態になるよう、該当フィルターを起動する（Ｓ８０５）。この処理により、システム稼働中も起動しているフィルターがスタンバイ数になるようフィルターを起動させておくことが可能となる。
【００５９】
図９は本発明の概要を示した図である。図９（１）はジョブを処理中でない場合のシステムの状況を表す図である。フィルターＡ（２７００）とフィルターＢ（２８００）とフィルターＣ（２９００）を１つスタンバイさせる設定であり、ロケーター（２５００）によって起動されている。図９（２）はジョブが投入された場合のシステムの状況を表す図である。まず、フィルターＡ（２７００）とフィルターＢ（２８００）とフィルターＣ（２９００）を使用するジョブが投入され、ジョブコントローラー（２３００）によりパイプライン（３０００）が作成され、ジョブを実行する。
【００６０】
この場合、フィルターＡ（２７００）とフィルターＢ（２８００）とフィルターＣ（２９００）があらかじめスタンバイされているので、フィルターの起動時間を待たず、フィルターを使用することができる。前記ジョブを実行している間に、フィルターＡとフィルターＢを別の使用するジョブが投入されたとする。ジョブを処理中のフィルターＡ（２７００）とフィルターＢ（２８００）はビジー状態なので、使用できない。この場合、ジョブコントローラー（２３００）がロケーター（２５００）にフィルターＡとフィルターＢのクエリーを行った際、ロケーターは新たなフィルターＡ（２７０１）と新たなフィルターＢ（２７０２）を起動して、クエリーに回答する。その際、新たなフィルターＡ（２７０１）と新たなフィルターＢ（２７０２）が起動する間、待ち時間が発生し、ジョブの処理が遅くなる。
【００６１】
ユーザから投入されるジョブは、特定のユーザが短時間に同じフォーマットの入力や同じ出力設定のジョブを連続して投入する傾向があることが知られている。ジョブはユーザに依存するため、時間帯や日時により投入されるジョブを予測することはできない。これにより、使用するフィルターも時間帯や日時から予測することはできない。スタンバイ数があらかじめ定められた値であると、想定した頻度よりジョブが投入される頻度が大きい場合、スタンバイされていないフィルターを使用することとなる。これにより、ジョブが投入されてからフィルターを立ち上げることになるので、ジョブの処理が遅くなる。本発明では、ジョブが投入された後にフィルターを立ち上げるのを防ぐため、フィルターのスタンバイ数を動的に変更する。図９（３）では、図９（２）においてフィルターＡとフィルターＢを使用するジョブが２つ同時に投入されたので、その後のフィルターＡとフィルターＢのスタンバイ数を２つに変更している。
【００６２】
図１０はフィルターのスタンバイ数を増やす処理のフローチャートである。プロキシー（２２００）は入力データを受け付け、入力データをジョブコントローラー（２３００）に送信する（Ｓ１００１）。ジョブコントローラー（２３００）は使用するフィルターを特定する（Ｓ１００２）。ジョブコントローラー（２３００）から使用するフィルターのクエリーを受けたロケーター（２５００）は、使用するフィルターがスタンバイ済みかを判断する。本実施例では、サービスイベントリ（５００７）の中から、状態がスタンバイ状態の使用するフィルターを検索する。使用するフィルターがスタンバイ済みの場合は、ロケーター（２５００）はスタンバイ済みのフィルターをクエリーで回答し、ジョブコントローラー（２３００）はジョブを実行する。スタンバイ済みでない場合、スタンバイ数管理部（２５１０）は該当フィルターのスタンバイ数を増やす。
【００６３】
本実施例では、該当フィルターのサービスカタログ（５００１）のスタンバイポイントを増加させる。その後、ロケーター（２５００）はフィルターを起動し、ジョブコントローラー（２３００）に新たに起動したフィルターをクエリーで回答し、ジョブコントローラー（２３００）はジョブを実行する。フィルターがスタンバイ済みでない場合、スタンバイ数を増やしたので、次回の図８において説明したスタンバイするフィルターの立ち上げ処理の際、該当フィルターのスタンバイ数が増える。次回同じように同一フィルターを同時に使用する複数のジョブが投入された場合、既にフィルターがスタンバイされている状態となり、ジョブを実行する際、フィルターの起動時間が短縮される。
【００６４】
前述したように、ユーザから投入されるジョブは、特定のユーザが短時間に同じフォーマットの入力や同じ出力設定のジョブを連続して投入する傾向があることが知られている。ジョブはユーザに依存するため、時間帯や日時により投入されるジョブを予測することはできない。あるフィルターを同時に使用する複数のジョブが連続して投入された後、該当フィルターを使用するジョブが投入されなくなることもある。あるフィルターを同時に使用する複数のジョブが連続して投入された場合、図１０において説明したスタンバイ数を増やす処理により、該当フィルターは複数スタンバイされる。その後、該当フィルターを使用するジョブが投入されなくなった場合、使用されなくなったフィルターをスタンバイさせておくと、スタンバイしているフィルターがメモリを使用する。これにより、メモリ不足によりジョブが失敗する可能性や、メモリ不足時にＯＳがメモリの内容をＨＤＤに記憶する処理を行うことでパフォーマンスが大きく低下する可能性がある。既定時間使用されないフィルターはスタンバイ数を減らすことで、ジョブの失敗やパフォーマンスの低下を防ぐことができる。
【００６５】
図１１はフィルターのスタンバイ数を減らす処理のフローチャートである。ロケーター（２５００）はフィルターの使用状況を取得する（Ｓ１１０１）。本実施例では、サービスイベントリー（５００７）の「生存時間」を取得することにより、使用されていない時間を取得する。本実施例では、１つのジョブを処理するとフィルターが終了するため、「生存時間」がフィルターのジョブを処理していない時間を表す。次に、スタンバイ数管理部（２５１０）はフィルターが既定時間使われていないかを判断する（Ｓ１１０２）。既定時間は、あらかじめ定められた値である。既定時間使われていない場合は、スタンバイ数管理部（２５１０）は該当フィルターのスタンバイ数を減らす。本実施例では、該当フィルターのサービスカタログ（５００１）のスタンバイポイントを減少させる。その後、フィルターは寿命時間になり、プロセスを終了する（Ｓ１１０３）。本実施例では、既定時間と寿命時間を同一としたため、スタンバイ数を減らした直後に、フィルターが終了し、図８のスタンバイするフィルターの起動処理が開始される。既定時間が寿命時間より短い場合は、フィルターの寿命時間に達した後に、実際にスタンバイしている数が変更される。既定時間が寿命時間より長い場合は、フィルターの生存時間に、使用されずに寿命により終了した同一フィルターの寿命時間を足すことで、既定時間使われていないことを判断することができる。
【００６６】
本実施例により、ジョブの投入状況に応じて動的にスタンバイするフィルターを変更することができ、全体のパフォーマンスが向上する。
【００６７】
［実施例２］
実施例２は、フィルターの順番を考慮して、スタンバイ数にフィルターの順番による重みづけをした場合の実施例である。先頭フィルターはジョブの投入後、すぐにジョブを処理し始めるので、スタンバイさせておいたほうがよい。後段のフィルターは前段のフィルターが処理している間に起動が完了する場合があるので、初段フィルターに比べ、フィルターをスタンバイさせていなくてもパフォーマンスへの影響は少ない。本実施例は、先頭に近いフィルターに重い重みをつけて、スタンバイさせる数を変化させることで、スタンバイするフィルターの順番に応じた最適化をさせる。実施例１との差分を説明する。
【００６８】
図１２は本実施例におけるサービスカタログ（５００１）を表した図である。実施例１におけるサービスカタログ（５００１）に対して、パイプラインの先頭からの何番目のフィルターとして使われたかの順番履歴を追加している。あるフィルターは入力データや出力の設定に応じて、１番目のフィルターとなることもあれば、３番目のフィルターになることもある。ジョブコントローラー（２３００）は、ロケーター（２５００）にフィルターのクエリーを要求する際に、そのフィルターを何番目のフィルターとしてパイプラインを構築するかの順番情報を通知する。ロケーターは（２５００）、順番情報を保持し、いままでに該当フィルターが使われた順番の平均を順番履歴として保持する。順番履歴の値を用いて、先頭に近いフィルターに重みづけを行う。
【００６９】
図１３は本実施例におけるスタンバイポイントからスタンバイ数を算出する処理（Ｓ８０３）のフローチャートである。まず、スタンバイ数管理部（２５１０）は順番履歴から重みを決定する。本実施例では、順番履歴の逆数を重みとして使用する。これにより、順番履歴の値の小さいフィルターが大きい値の重みをもつこととなる。次に、スタンバイ数管理部（２５１０）は重みとスタンバイポイントからスタンバイ数を算出する。本実施例では、重みとスタンバイポイントを掛け合わせたものをスタンバイ数とする。スタンバイ数の算出の方法は、重みとスタンバイポイントにさらに定数を掛け合わせたものなど、他の方法で算出してもよい。図１２で示したサービスカタログ（５００１）の例では、順番履歴が２．５のため、その逆数の０．４が重みとなる。スタンバイ数は、スタンバイポイントの２に、重みの０．４を掛け合わせたものであり、０．８となる。本実施例ではスタンバイ数の計算結果の小数点以下を四捨五入したものスタンバイ数とするので、スタンバイ数は１となる。
【００７０】
本実施例では、スタンバイ数に、フィルターの順番を考慮した重みづけをすることで、ジョブ実行時のパフォーマンスに影響の大きい先頭に近いフィルターを優先的にスタンバイさせることができる。これにより、全体のパフォーマンスが最適化される。
【００７１】
［実施例３］
実施例３は、スタンバイ数に上限と下限を設けた場合の実施例である。スタンバイ数が増えすぎると、スタンバイしているフィルターがメモリを使用し、メモリ不足によりジョブが失敗する可能性や、メモリ不足時にＯＳがメモリの内容をＨＤＤに記憶する処理を行うことでパフォーマンスが大きく低下する可能性がある。この場合、スタンバイさせておくより、ジョブが投入された後起動したほうが、メモリを使用しないので、ジョブが失敗する可能性やパフォーマンスが低下する可能性は低い。
【００７２】
一方、スタンバイしているフィルターの数が少ない場合は、スタンバイされるフィルターが使用するメモリはジョブの実行に影響しないほど小さいものである場合がある。本実施例では、スタンバイ数に上限と下限を設けることで、スタンバイ数の増加によるジョブの失敗やパフォーマンスの低下を防ぎ、かつ、スタンバイしているフィルターが少ない場合は、スタンバイさせることで、パフォーマンスを最適化させる。実施例２との差分を説明する。本実施例は、実施例１にも適用可能である。
【００７３】
図１４は本実施例におけるサービスカタログ（５００１）を表した図である。実施例２におけるサービスカタログ（５００１）に対して、スタンバイ数上限とスタンバイ数下限を追加したものである。スタンバイ数上限とスタンバイ数下限はモジュールごとにあらかじめ定義され、サービスカタログ（５００１）に記載される。この値を参照することで、スタンバイするフィルターがスタンバイ数上限より大きくならないように、また、スタンバイ数下限より小さくならないように制御する。
【００７４】
図１５は本実施例におけるスタンバイポイントからスタンバイ数を算出する処理（Ｓ８０３）のフローチャートである。図１３との差分を説明する。スタンバイ数管理部（２５１０）はスタンバイ数を算出した後（Ｓ１３０２）、スタンバイ数がスタンバイ数下限より小さい場合（Ｓ１５０１）、スタンバイ数をスタンバイ数下限の値とする（Ｓ１５０４）。スタンバイ数がスタンバイ数下限より大きく、スタンバイ数がスタンバイ数上限より大きい場合（Ｓ１５０２）、スタンバイ数をスタンバイ数上限の値とする（Ｓ１５０３）。
【００７５】
図１４で示したサービスカタログ（５００１）の例では、順番履歴が２．５のため、その逆数の０．４が重みとなる。スタンバイ数は、スタンバイポイントの２に、重みの０．４を掛け合わせたものであり、０．８となる。本実施例ではスタンバイ数の計算結果の小数点以下を四捨五入したものスタンバイ数とするので、スタンバイ数は１となるが、スタンバイ数下限は３のため、スタンバイ数は３となる。
【００７６】
本実施例では、フィルターのスタンバイ数に上限を設けることで、スタンバイ数が増えすぎて、スタンバイしているフィルターがメモリを大きく使用することによるジョブの失敗やパフォーマンスの低下を防ぐ。また、フィルターのスタンバイ数に下限を設けることで、スタンバイしているフィルターが少なく、スタンバイしているフィルターが使用するメモリとＣＰＵがパフォーマンスに影響しないほど小さい場合はスタンバイさせておくことで、パフォーマンスを向上させる。
【符号の説明】
【００７７】
５０  ユーザ
２０  パーソナルコンピュータ
３０  タブレットPC
４０  携帯端末
１０  ネットワーク
【図１】
2015146064.tif 000003
【図２】
2015146064.tif 000004
【図３】
2015146064.tif 000005
【図４】
2015146064.tif 000006
【図５】
2015146064.tif 000007
【図６】
2015146064.tif 000008
【図７】
2015146064.tif 000009
【図８】
2015146064.tif 000010
【図９】
2015146064.tif 000011
【図１０】
2015146064.tif 000012
【図１１】
2015146064.tif 000013
【図１２】
2015146064.tif 000014
【図１３】
2015146064.tif 000015
【図１４】
2015146064.tif 000016
【図１５】
2015146064.tif 000017