JSR 284: Resource Consumption Management API
「JSR 284: Resource Consumption Management API(以下、RCM-API)」は、Javaアプリケーションにおいてさまざまなリソース管理のために必要となる機能を提供するAPIだ。たとえばCPU時間やヒープメモリ、ディスクスペース、ネットワークリソース、JDBCコネクション、トランザクションレートなどのリソースに対して、使用状況の監視や制限、通知などといった管理機能を提供する。
通常、このようなリソース管理機能はOS側で提供されるものである。従来のJavaアプリケーションの場合、これらの機能を利用するためにはネイティブコードやシェルスクリプトなどをjavaプログラムとは別に記述するのが一般的だった。しかしこういった方法は、Javaの持つ可搬性/汎用性といった特徴を潰してしまう。
RCM-APIではこれをJavaプログラムのみで利用できるようにすることにより、アプリケーションレベルでのリソース管理を標準的な方法で容易に行えるようにする。
同APIは現時点ではまだ仕様策定中の段階であり、具体的な実装は提供されていないが、JCPのサイトにおいてProposed Final Draftが公開されている。今回はこのドラフトを元にRCM-APIの機能を紹介したい。
RCM-APIの使用例
現在公開されているProposed Final Draftはjavadoc形式のドキュメントになっている。それによれば、RCM-APIにはjava.rcmとjava.rcm.managementという2つのパッケージが含まれる。コア部分は前者であり、後者はRCMの機能をJMXで利用できるようにするためのMBeanインタフェースを提供するものだ。
javax.rcmパッケージでは、主要機能として以下の3つのクラス/インタフェースが定義されている。
- ResourceConsumer: リソース管理を実行するためのエンティティとなるクラス
- ResourceAttributes: リソースの属性やプロパティを表すインタフェース
- ResourceDomain: ResourceConsumerをグループ化して管理する。ドメイン単位でリソース管理ポリシーを適用できる
ドラフトではこれらのクラス/インタフェースを利用するコード例が紹介されている。たとえば現在システムで利用可能なResourceConsumerを取得するには、リスト1のようにする。
リスト1 ResourceConsumerの取得
// 現在利用可能なResourceConsumerを取得する
ResourceConsumer[] currentConsumers = ResourceConsumer.currentConsumers();
また、ResourceAttributesオブジェクトを取得するには、ResourceAttributesFactoryクラスを利用してリスト2のようにすればいいようだ。getInstanceByName()メソッドの引数には取得したいリソース名を指定する。
リスト2 ResourceAttributeの取得
// ResourceAttributesを取得する
ResourceAttributes attributes
= ResourceAttributesFactory.getInstanceByName("[リソース名]");
あるResourceConsumerが所属するResourceDomainはリスト3のようにして取得できる。
リスト3 ResourceDomainの取得
// 属性を指定してResourceDomainを取得
ResourceDomain domain = currentConsumers[0].currentDomain(attributes);
// ResourceDomainを全て取得
ResourceDomain[] domains = currentConsumers[0].currentDomains();
現在のリソースの状況はResourceDomainから取得できるようになっている(リスト4)。
リスト4 リソースの状態を調べる
long usage = domain.getUsage();
long totalUsage = domain.getTotalUsage();
long totalQuantity = attributes.getTotalQuantity();
assert(attributes.isReservable());
long reservation = domain.getReservation();
RCM-APIでは、リソースの消費前や消費後にそれを通知する機能がある。前者はConstraintインタフェースを、後者はNotificationインタフェースを用いて実現する。たとえばリソースの消費要求前に何らかの処理を実行したい場合には、リスト5のようにConstraintをimplementsしたクラスを用意し、ResourceDomainに登録しておく。するとリソースの消費要求前にpreConsumer()メソッドが呼ばれるようになる。
リスト5 Constraintの定義と登録
// Constraintの定義
class CheckProposedConstraint implements Constraint {
public void preConsume(ResourceDomain domain,
long currentUsage, long proposedUsage) {
return Math.min(proposedUsage, 100);
}
}
// Constraintの登録
Constraint constraint = new CheckProposedConstraint();
domain.addConstraint(constraint);
リソースの消費要求後に処理を行いたい場合には、リスト6のようにNotificationをimplementsしたクラスを用意し、ResourceDomainに登録しておく。するとリソースの消費要求後にpostConsumer()メソッドが呼ばれるようになる。
リスト6 Notificationの定義と登録
// Notificationの定義
class CheckGrantedNotification implements Notification {
public void postConsume(ResourceDomain domani,
long previousUsage, long currrentUsage) {
long time = System.currentTimeMillis();
long granted = currentUsage - previousUsage;
System.out.println("Granted " + granted + "@" + time);
}
}
// Notificationの登録
Notification notification = new CheckGrantedNotification();
domain.addNotification(notification);
RCM-APIは現時点ではJava SEをターゲットとして仕様策定が進めるられているが、リソース管理はエンタープライズアプリケーションでも必須な機能であるため、Java EEの分野においても活用される可能性が高い。また、Java SE 7での標準プラットフォームへの統合を推す声もあるが、具体的な議論にはなっていない。
いずれにせよリソース管理機能は幅広い分野で必須となるものであり、正式仕様の決定と実装の登場が待ち遠しい限りだ。