デフォルトでは、Mule Runtime Engine (Mule) は通常の Java シリアル化を使用します。ただし、Mule アプリケーションで defaultObjectSerializer を設定すると、異なるシリアル化メカニズム (Kryo シリアライザーや他のカスタムシリアライザーなど) を指定できます。
カスタムシリアライザーを使用すると、Mule で次のいずれかのプロセスを実行する場合に機能とパフォーマンスが向上する可能性があります。
-
永続的なオブジェクトストアに対する読み書き
-
永続的な VM キューまたは JMS キューに対する読み書き
-
Mule クラスターを介したオブジェクトの配信
-
ファイルからのオブジェクトに対する読み書き
カスタマイズはバッチモジュールの動作に影響しません。バッチモジュールでは 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 を使用することによるパフォーマンスの向上を実現することはできません。
Java 17 のサポート
バージョン 4.6 以降、Mule Runtime は Java 17 をサポートしています。Java 17 では JPMS が適用されます。この機能を実現するため、Mulesoft ではデフォルトの Kryo フレームワークに替わるいくつかのカスタムシリアライザーが導入されます。これは、デフォルトのフレームワークで使用するメカニズムでは JPMS のカプセル化が壊れるためです。 Mule Runtime 4.6 と Java 17 への移行時に、Kryo シリアライザーが HTTP Connector 証明書をシリアル化しない可能性があります。この問題は、属性内に証明書がある HTTP 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 シリアル化は失敗します。ただし、Serializable インターフェースを実装していない別のオブジェクトがシリアル化に含まれていても、Kryo は成功する可能性があります (ただし保証できません)。典型的な例として、 NetSuite または Microsoft Dynamics CRM Connector で使用されている org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl, を含む POJO があります。