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での標準プラットフォームへの統合を推す声もあるが、具体的な議論にはなっていない。

いずれにせよリソース管理機能は幅広い分野で必須となるものであり、正式仕様の決定と実装の登場が待ち遠しい限りだ。