パフォーマンス上の理由から、メッセージのバッチの送信、バッチの送信、一般的なバッチ内のメッセージに対する操作の実行に関して、すべてのアダプターをバッチ認識する必要があります。 アダプターは、アダプターのデザイン時ユーザー インターフェイスから構成可能な、バッチのサイズやバッチ内のバイト数など、構成可能なパフォーマンス関連の属性を公開する必要があります。
前述のように、送信アダプターは常に非ブロッキング送信を実行して、送信ホストのパフォーマンスが低下しないようにする必要があります。 メッセージング エンジン API をさらにブロックすることはお勧めしません。
メッセージ コンテキストへの書き込みとメッセージ コンテキストからの読み取りは、実行時のパフォーマンスに影響します。 一般に、アダプターは、メッセージ コンテキスト プロパティの過剰な数の読み取り、書き込み、昇格を回避する必要があります。 プロパティを昇格すると、実行時に昇格された各プロパティでサブスクリプションの評価が行われるため、パフォーマンスが低下します。 ただし、アダプターは、パフォーマンスに著しく影響を与えるために、膨大な数のプロパティを昇格させる必要があります。 しかし、昇格が必要なプロパティのみを昇格させることを推奨します。
送受信を制限する
BizTalk エンジンの負荷が構成されたしきい値を超えると、エンジンは最適なパフォーマンスを確保するためにアダプターとオーケストレーションを調整します。 受信側では、エンジンのワークロードが特定のしきい値を超えると、負荷が十分に減少するまで、アダプターの IBTTransportBatch.Done の呼び出しがブロックされます。 これにより、アダプターは、エンジンが使用可能な場合にのみ、新しい作業をエンジンに送信します。 送信側では、エンジンが送信メッセージを送信するアダプターを調整している場合、エンジンは、負荷が軽減されるまで、送信される新しいメッセージを配信しません。
このような理由から、アダプターは、バックエンド システムへの接続の数を制限するために必要な場合を除き、調整に関係する必要はありません。 このようなシナリオでは、エンジンもアダプター フレームワークもサポートを提供しません。
カスタム送信アダプターから送信されるメッセージの数の調整は、アダプターのソース コードを制御するかどうかに応じて、いくつかの方法で処理できます。
Send-Side 制御によりパフォーマンスが向上
アダプターのソース コードを制御する場合は、キューに送信するメッセージの最大数をヒューリスティックからいつでも確認できます。 メッセージング エンジンが TransmitMessage
メソッドを呼び出し、送信アダプターに新しいメッセージを渡す場合は、スレッドをブロックするか、キュー内のメッセージの数が前に決定した最大値より大きいかどうかを確認するかを選択できます。 メッセージの最大数を超えた場合は、 Resubmit
メソッドを使用してメッセージをメッセージング エンジンに再送信できます。 アダプターが同期の場合、メッセージは既にブロックされることに注意してください。
アダプターのソース コードを制御しない場合は、BizTalk 管理データベースの Adm_serviceclass テーブルの Highwatermark 値を変更することで、キューに登録されたメッセージの数を変更できます。 Highwatermark プロパティの最大値は 200 です。 Lowwatermark プロパティの値を小さな値に変更することもできます。
非同期アダプターの Highwatermark プロパティの値は、メッセージング エンジンがアダプターに渡したメッセージの数を占める点に注意してください。 メッセージング エンジンは、 TransmitMessage
メソッドを介してアダプターに渡します。たとえば、アダプターが DeleteMessage
、 Resubmit
、 MoveToNextTransport
、 または Microsoft.BizTalk.TransportProxy.Interop.BatchOperationType.MoveToSuspendQ メソッドに対して対応する呼び出しを行っていない場合など、これらのメッセージは送信で未処理のままである可能性があります。 同期アダプターの場合、 Highwatermark プロパティは、メッセージング エンジンが TransmitMessage メソッドを使用してアダプターに渡したメッセージの数のみを考慮します。この呼び出しは同期的に処理され、呼び出し元のメッセージング エンジン スレッドがブロックされるためです。
本質的に低速なプロトコル (HTTP、FTP、双方向 SOAP など) の送信アダプターを作成する場合は、次の点を考慮してください。
このようなアダプターは、BizTalk メッセージング エンジンから送信するメッセージを送信するよりも速く受信する場合があります。 この不一致により、さまざまなレベルで問題が発生します。 送信中のメッセージはメモリ内に残り、仮想メモリを占有し、システム全体の速度が低下します。
アダプターがプロトコル固有のリソースを占有する場合があります。 たとえば、サーバーへの同時接続が多すぎるため、リモート サーバーが中断される可能性があります。
アダプターが他のアダプターに影響する可能性があります。 たとえば、特定のアダプターに対してキューに登録されているメッセージが多すぎる場合、メッセージング エンジンは、そのプロセス内の他の送信アダプターへの要求の発行を停止します。
解決策は、低速で高速なアダプターを別々の BizTalk ホストに配置し、[高基準値] と [低基準値] の設定を使用してメッセージの数を制御することです。
Receive-Side スロットリングによるパフォーマンスの向上
受信アダプターは、システムの残りの部分がメッセージを処理できる速度よりも速くメッセージを受信する多くの状況があります。 このような状況が発生すると、MessageBox データベースがバックログされます。 この場合、システム全体のパフォーマンスが大幅に低下します。
これがアダプターで発生している場合は、次のいずれかの手法を使用して、受信アダプターの速度を下げることができます。
メッセージング エンジンのスレッド プール のサイズを小さくします。 メッセージ ボックスにメッセージを発行するためにメッセージング エンジンが使用するスレッドの数を制御できます。 スレッドの数を減らすことで、受信アダプターがメッセージ ボックスにメッセージを受信する速度を減らすことができます。 この設定は、アダプターの受信ハンドラーに対応するホストに対してのみ行う必要があります。 送信アダプターの速度を低下させる場合を除き、アダプターの送信ハンドラーに対応するホストに対してこれを設定しないでください。
アダプターのバッチ サイズを小さくします。 ほとんどの高速受信アダプターは、メッセージをメッセージ ボックスにバッチで発行します。 通常、これらのバッチのサイズは、受信場所のプロパティ ページで構成できます。 バッチ サイズを小さくすることで、システムに入ってくるメッセージの全体的なスループットを低下させることができます。
その他のアダプター固有の設定を変更します。 前の 2 つの手順を完了したら、他のアダプター パラメーターを調整してスループットをさらに減らすことができます。 一部のアダプターは、スループットの低下に使用できる内部パラメーターを公開します。 たとえば、MQSeries アダプターには "Ordered Delivery" の設定があります。 順序指定された配信では、アダプターがメッセージのバッチを発行し、完了するまで待ってから、次のバッチを発行することを指定します。 この設定を有効にすると、基本的にすべての並列処理を受信アダプターから削除します。 逆に、逆の方法でパラメーターを調整して、受信アダプターの受信速度を上げることができます。
アダプターは、必要な数のバッチをトランスポート プロキシに送信できます。 システムに大きな負荷がかかっている場合、IBTTransportBatch インターフェイスの Done メソッドを呼び出すと、必要なリソースがシステムに解放されるまでメッセージがブロックされます。
非同期受信と送信の計画
BizTalk Server メッセージング API には、非同期プログラミングの豊富なサポートがあります。 スケーラブルなアダプターを記述する場合は、非同期モデルの方がコンカレンシーが向上するため、最初から非同期モデルの使用を計画してください。
受信側では、アダプターが ( IBTTransportBatch::D one を呼び出して) BizTalk メッセージング エンジンにメッセージのバッチを送信すると、メッセージング エンジンは内部スレッド プールを使用して作業をキューに入れ、直ちに返します。 エンジンは別のスレッドでメッセージを処理し、アダプターはソースからメッセージを自由に読み取り、前のメッセージ処理が完了するのを待たずに送信します。
送信側では、アダプターは非同期でも同期でもかまいません。 ただし、プロトコルで非同期操作がサポートされている場合は、このサポートを使用してスケーラブルなアダプターを作成する必要があります。 たとえば、ファイル送信アダプターと HTTP 送信アダプターは完全に非同期であり、ブロック/同期操作の実行が非常に少なくなります。
非同期操作により、メッセージング エンジンとアダプターの両方がそれぞれの作業を並行して実行し続け、通常のメッセージ処理を待機しないようにします。
バッチ処理を使用してパフォーマンスを向上させる
バッチ処理は、スケーラブルなアダプターを記述するための最適な開始点です。 これは、送信側アダプターと受信側アダプターの両方に当てはまります。 アダプターが非トランザクションである場合でも、すべてのバッチは BizTalk Server 内のデータベース トランザクションを通過します。 各トランザクションには固定遅延があるため、複数の操作を 1 つのバッチに結合して、トランザクションの数を最小限に抑える必要があります。
.NET スレッド プールを枯渇しない
BizTalk アダプターの記述は、.NET ランタイム コードを記述する演習です。.NET ランタイム コードの記述は、必ず非同期プログラミングの演習です。
.NET スレッド プールの不足は、.NET のすべての非同期プログラミングのリスクであり、BizTalk アダプター プログラマが回避することが特に重要です。
.NET スレッド プールは、限られているが広く共有されているリソースです。 .NET スレッド プール スレッドの 1 つを使用して長時間保持し、他の作業項目の実行をブロックするコードを簡単に記述できます。
BeginInvoke を使用するか、タイマーを使用するたびに、.NET スレッド プール スレッドを使用します。 複数の作業 (たとえば、MQSeries から BizTalk Server にメッセージをコピーする) がある場合は、1 つの作業項目 (BizTalk Server へのメッセージの 1 つのバッチ) を実行し、さらに作業がある場合はスレッド プールで再キューする必要があります。 スレッドの while
ループに座らないでください。
具体的には、これは while
ループを BeginInvoke への繰り返し呼び出しに置き換えることを意味します。 この単純な変更により、実装全体の応答性とスケールアウト機能が大幅に向上します。
バッチ サイズを制限するときに適切な測定を選択する
メッセージをバッチで BizTalk Server に送信する場合は、メッセージ数のみに基づいてバッチ サイズを制限しないでください。 メッセージ数のみに基づいてバッチ処理するようにアダプターが構成されている場合の動作を検討してください。バッチ サイズが 2 で、アダプターがそれぞれサイズ 4 KB、8 KB、1 MB、5 MB の 4 つのメッセージを取得する場合、最初のバッチはサイズ 12 KB、2 番目のバッチはサイズ 6 MB になります。
BizTalk メッセージング エンジンは 1 つのバッチ内のすべてのメッセージを順番に処理するため、この例の 2 番目のバッチは最初のバッチよりもはるかに遅く処理されます。 これにより、スループットが効果的に低下します。 この問題を処理するより良い方法は、メッセージ数とバッチ内の合計バイト数 (つまり、バッチ サイズ (バイト単位) の両方に基づいてバッチ処理することです。 合計バイト数にマジック番号はありません。 ただし、通常の処理シナリオでは、バッチ サイズが 1 MB を超えると、コンカレンシーとスループットが低下します。
通常、アダプターはメッセージに依存せず、運用環境のメッセージのサイズを認識しません。 受信メッセージのサイズは大きく異なる可能性があります。 このため、常にメッセージ数と合計バイト数を使用してバッチをビルドします。