カスタムシリアライザーの設定

デフォルトでは、Mule Runtime Engine (Mule) は通常の Java シリアル化を使用します。ただし、Mule アプリケーションで ​defaultObjectSerializer​ を設定すると、異なるシリアル化メカニズム (Kryo シリアライザーや他のカスタムシリアライザーなど) を指定できます。

カスタムシリアライザーを使用すると、Mule で次のいずれかのプロセスを実行する場合に機能とパフォーマンスが向上する可能性があります。

  • 永続的なオブジェクトストアに対する読み書き

  • 永続的な VM キューまたは JMS キューに対する読み書き

  • Mule クラスターを介したオブジェクトの配信

  • ファイルからのオブジェクトに対する読み書き

カスタマイズは Batch Module の動作に影響しません。Batch Module では Kryo シリアライザーが常に使用されます。

シリアライザーと Mule の互換性

Mule Runtime Engine (Enterprise Edition) を実行している場合、Kryo シリアライザーを設定してパフォーマンスを向上できます。

Mule Kernel (Community Edition) を使用している場合は、シリアル化 API を使用してカスタムシリアライザーを作成できます。

Kryo シリアライザーの設定

Mule では、Kryo フレームワークに依存する ​ObjectSerializer​ の実装が提供されます。Kryo を使用すると、次の利点が得られます。

  • パフォーマンスの向上
    Kryo は Java シリアル化よりも大幅に高速です。

  • より広範な Java 型のサポート
    Kryo は、Java シリアル化のほとんどの制限に拘束されません。たとえば、​Serializable​ インターフェースを実装する必要はなく、デフォルトのコンストラクターを持つ必要もありません。

  • 圧縮のサポート
    Deflate または GZip 圧縮アルゴリズムを使用できます。

Kryo 名前空間を使用すると、カスタム Spring bean を定義せずに、Mule アプリケーション内でこのシリアライザーを有効にできます。次の設定例では、デフォルトのシリアライザーを Kryo ベースのシリアライザーに設定します。

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:kryo="http://www.mulesoft.org/schema/mule/kryo"
       xsi:schemaLocation="
        http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
        http://www.mulesoft.org/schema/mule/kryo http://www.mulesoft.org/schema/mule/kryo/current/mule-kryo.xsd">

    <kryo:serializer name="kryo" />
    <configuration defaultObjectSerializer-ref="kryo" />

</mule>

圧縮を設定するための ​compressionMode​ XML 属性を含めることもできます。

<kryo:serializer name="noCompression" compressionMode="NONE" /> <!-- NONE is the default value -->
<kryo:serializer name="deflate" compressionMode="DEFLATE" />
<kryo:serializer name="gzip" compressionMode="GZIP" />

シリアル化 API を使用したカスタムシリアライザーの作成

オープンソースのシリアル化 API で提供されている ​ObjectSerializer.java​ インターフェースを使用して、オブジェクトをバイト配列にシリアル化したり、非シリアル化したりできます。 GitHub の ObjectSerializer.java​ を参照してください。

シリアル API には次の機能があります。

  • スレッドセーフである

  • シリアル化およびストリーミング時に OutputStream を渡す

  • 入力ソースとして InputStream を使用可能

Mule でシリアル化および非シリアル化する場合、​getInternalProtocol()​ メソッドを定義する必要があります。 シリアル化されたオブジェクトを外部システムで使用する場合、そのオブジェクトを ​getExternalProtocol()​ メソッドで定義します。
Serialization Protocol (シリアル化プロトコル)​ は、シリアル化および非シリアル化するために使用するオブジェクトです。

カスタムシリアライザーの設定

Mule の ​<configuration>​ タグを使用して、Mule アプリケーションのデフォルトの ​ObjectSerializer​ を設定します。

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:spring="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="
        http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd">

  <spring:config name="Spring_Config" files="serializer.xml" />
  <configuration defaultObjectSerializer-ref="customSerializer" />

</mule>

次に、​serializer.xml​ ファイルで bean を設定します。

<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
	<bean id="customSerializer" name="customSerializer"
		class="com.my.CustomSerializer">
		<!-- ... -->
	</bean>
</beans>

設定済みの ObjectSerializer の取得

Java コード内で ​ObjectSerializer​ を取得するさまざまな方法があります。一般に、連動関係を挿入する方法をお勧めします。次のコード例は、現在設定されている ​ObjectSerializer​ を取得する方法を示しています。

public class MyClass {
   @Inject
   private  ObjectSerializer objectSerializer;
}

特定の名前のシリアライザーが必要な場合 (それがデフォルトかどうかに関係なく)、名前でシリアライザーにアクセスできます。

public class MyClass {
  @Inject
  @Named ("mySerializer")
  private ObjectSerializer objectSerializer;
}

Kryo を使用したパフォーマンスの向上

次のコンポーネントを使用している場合、Kryo を使用すると、通常の Java シリアル化よりもパフォーマンスが特に向上します。

  • 永続的なオブジェクトストアまたはクラスタリングされたオブジェクトストア

  • 永続的な VM キューまたは分散 VM キュー

  • JMS Connector

どのような場合も、圧縮を使用しない Kryo シリアライザーは通常の Java シリアライザーよりも大幅に高速です。ただし、高可用性 (HA) の場合に限り、圧縮モードでパフォーマンスが向上します。

圧縮を価値のあるものにするには、圧縮と圧縮解除にかかる CPU 時間が、ペイロードサイズの縮小によって節約された I/O 時間を大幅に下回る必要があります。通常、ネットワーク操作はディスク操作よりも低速です。また、HA クラスタリングにはノードの複製が必要です (つまり、より多くのトラフィックが発生します)。このため、圧縮は HA 環境でのみ役立ちます。

これは普遍定数ではありません。低速のディスクや高い I/O 要求のあるマシンで Mule を実行する場合があります。どのような場合も、この状況では圧縮に価値がある可能性があります。また、テストは 1 MB のペイロードを使用して実行されました。データストリームがこれより大きい場合、圧縮の価値がさらに高まります。

シリアル化を使用する場合の考慮事項

シリアル化を使用する場合は、以下の制限と考慮事項に注意してください。

シリアライザーの変更には白紙の状態が必要

シリアライザーは相互運用可能ではなく、代替可能でもありません。つまり、アプリケーションで使用するシリアライザーを変更する場合は、VM および JMS キュー内のすべてのメッセージがコンシュームされていること、および新しいシリアライザーに引き継がれるまでにそれらのキューが空になっていることを確認します。

Kryo シリアライザーは、Java シリアライザーが書き込んだデータグラムを読み取ることはできません (その逆も同様)。永続的なオブジェクトストアでも同様です。1 つのシリアライザーで生成されたエントリを別のシリアライザーで読み取ることはできません。

共有された VM Connector ではドメインのデフォルトのシリアライザーを使用

ドメインを使用すると、アプリケーション間でリソースを共有できます。たとえば、ドメインで VM Connector を定義すると、VM メッセージキューを介してアプリケーション間の通信ができます。

ただし、シリアライザーはアプリケーションレベルでのみ設定できます。シリアライザーをドメインレベルで設定することはできません。

アプリケーション A と B が、その両方が属しているドメインで定義された VM Connector を介して、相互に通信するとします。ただし、A はシリアル化に Java を使用し、B は Kryo を使用します。この場合、その特定のメッセージはアプリケーションのシリアライザーではシリアル化されず、VM Connector で使用されているシリアライザー (ドメインレベルのデフォルトのシリアライザー) でシリアル化されるため、シリアル化は機能します。これは「プラグアンドプレー環境」には適していますが、共有された VM Connector で Kryo を使用すると、パフォーマンスの向上を実現することはできません。

ローカルの永続的なオブジェクトストアでのわずかなパフォーマンスの向上

ローカルの永続的なオブジェクトストアでは、オブジェクトストアの実装に対する競合が多いためにパフォーマンス上の利点はありません。

JMS キューでのわずかなパフォーマンスの向上

JMS API では、キューが ​javax.jms.Message​ クラスのインスタンスを提供する必要があることが指定されており、キューは未加工のペイロードオブジェクトを操作しません。メッセージをシリアル化するのは Mule ではなくブローカークライアントです。そのため、このシナリオでは、Kryo の設定による影響は最小限に抑えられます。

JMS で Kryo を使用する場合のパフォーマンス上の利点は、Mule が MuleSession をシリアル化して Base64 形式でヘッダーとして使用することのみです。Kryo を使用して MuleSession をシリアル化すると、パフォーマンスが最大 10% 向上する可能性がありますが、これは Mule ではなく主に JMS ブローカーによるものです。

問題のある型

Kryo は、​Serializable​ インターフェースを実装していないオブジェクトをシリアル化できますが、Kryo をデフォルトのシリアライザーとして設定しても、それは、VM Connector、ObjectSerializer、クラスターなどのコンポーネントがこのインターフェースを実装していないオブジェクトを処理できることを意味しません。Kryo はこのようなオブジェクトを操作できますが、これらのコンポーネントの Java API では、メソッドの署名内の ​Serializable​ のインスタンスが引き続き予期されます。

Serializable​ インターフェースを実装していないオブジェクトでは、通常の Java シリアル化は失敗します。ただし、シリアル化可能なインターフェースを実装していない別のオブジェクトがシリアル化に含まれていても、Kryo は成功する可能性があります (ただし保証できません)。典型的な例として、 NetSuite​ または Microsoft Dynamics CRM​ Connector で使用されている ​org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl,​ を含む POJO があります。

関連情報