SharePoint 2010 形式ワークフローの動作制御について (チューニング)

こんにちは、SharePoint サポートの森 健吾 (kenmori) です。

今回の投稿では、SharePoint における 2010 形式ワークフロー (SharePoint 2007、2010 のワークフローと SharePoint 2013 および SharePoint Online の 2010 形式ワークフロー) ランタイム側の仕組みについておさらいします。

下記投稿を現時点 (2015 年 5 月) での最新である SharePoint Server 2013 の情報に更新した内容であり、トラブルシューティング時に役立てていただけるよう記載させていただきました。

タイトル : SharePoint ワークフローのチューニング
アドレス : https://blogs.technet.com/b/sharepoint_support/archive/2011/01/12/sharepoint.aspx

なお、 2013 形式のワークフローは Workflow Managerという別製品上にホストされて動作しますため、本投稿の記載は該当しません。

1. ワークフローの動作について

ワークフローは、長い場合には数年、数か月など長期にわたるビジネス ロジックを安定して実行可能なように実装されています。また SharePointは、より即時性が求められる Web サーバーの処理を優先させながら、サーバー負荷を考慮してリソースを調整し、許容量を計算した上でワークフローを動作させる仕組みになっています。

2. ワークフローのホスト プロセスについて

ワークフローは、様々なプロセス上で処理をロードして少しずつ実行する仕組みとなります。

ワークフローを構成するアクティビティは永続化ポイント (*1) を保持します。このポイントで、ワークフローはワークアイテムという単位でバッチ処理が分割され、処理内容がシリアル化されてコンテンツ データベースに格納されます。継続処理はタイマー サービスやイベントをトリガとして、コンテンツ データベースから再度読み取られ、再開される動作となります。

それぞれの分割された処理が、どのようにホスト プロセスに組み込まれ、どう実行されるかについて記載します。

1) w3wp.exe ( ワーカー プロセス )

ワークフローは、ワークフロー処理を開始したプロセス内で起動します。ユーザーによる手動開始、アイテム作成、更新時の自動起動が一般的ですので、多くの場合、w3wp.exe 内で次の永続化ポイントまで動きます。
ただし、既定では 15 個以上 <Throttle> のワークフローを同時に起動しようとした場合、ワークフロー インスタンスの状態を開始処理中とマークしてワークフローをプロセスからアンロードします。アンロードされたワークフローについては、タイマー サービスがピックアップして後続処理を実行します。

また、ユーザーのブラウザー操作 (タスクの承認、アイテムの変更など) によるイベント起動時も、w3wp.exe プロセス上で処理が起動し、次の永続化ポイントまで実行されます。

補足

PowerShell やカスタム アプリケーションでこれらの処理を実行した際には、当然 powershell.exe やカスタム アプリケーション内でワークフローが動作します。
これらのアプリケーションはメイン スレッドが終了されたタイミングで、ワークフローが実行されているサブ スレッドを破棄しますので、メイン スレッドの終了までに Sleep などで十分な時間を設けない限り、ワークフローが正常に処理できない可能性があります。

2) OWSTIMER.EXE (SharePoint Foundation Timer サービス  )

ワークフローがアイドル状態になった場合や、各種チューニング値によって即時実行されない場合、あるいは即時実行が失敗した場合においては、以降の処理はこの OWSTIMER.EXE プロセス内で実行されるワークフロー タイマー ジョブ (SPWorkflowJobDefinition) が実行します。

既定では5 分に 1 回 <Workflow Timer Interval>、最大 100 個 <Batch Size> のジョブがピックアップされて動作します。

その他、OWSTIMER.EXE プロセスで実行される形式ではジョブで管理されているため、一部の条件で失敗したワークフローのリトライも可能であり、進行が停止してしまったワークフローのフェイルオーバー再実行なども備わっています。

ただし、ワークフローがエラー終了する状況を完全に防ぐことができるわけではありません。

(*1) 主な永続化ポイントについて

1.       DelayActivity アクティビティなどを使用し、ワークフローがアイドル状態になった場合
2.       SharePoint ワークフローのバッチ実行タイムアウト <Timeout> を迎えた場合
3.       PersistOnCloseAttribute 属性を使用するカスタム アクティビティが完了したとき。

 

 

3. ワークフローの実行数制御

Web サーバー上で使用される実行スレッド数やリソース消費量を考慮して、ワークフローはサーバー上で同時実行できる数や一度の処理時間等が制限されております。

SharePoint オンプレミス環境では、この値を調整できますが、この既定値は様々なパフォーマンス テストの結果指定された推奨値となりますため変更することはお勧めしませんが、運用を進めるにあたり、これらの値がどのような役割をもつかを理解しておく必要があります。

 

1. Throttle

この設定により、ワークフローの同時実行数が、既定ではコンテンツ データベースごとに 15 として設定されております。たとえ、一瞬でもこの値を超えてワークフローが同時実行される際は、ワークフローが “開始処理中” という状態となって待機する動作に移ります。

この値は ScheduledWorkItems テーブル上で、実行中のワークアイテム インスタンスを計上して実行しています。ストアド プロシージャ (proc_GetRunnableWorkItems) を解析することで、この処理内容を確認できます。

ただ待機しているだけの進行中のワークフローは、実行可能なワークアイテムとしてはカウントされません。このため、ワークフローの状態列で確認できるワークフロー数と同じではありません。

 

上記の通り、この値は SharePoint 上での実装値であるため Windows Workflow Foundation パフォーマンス カウンターではこの値を取得することはできません。

 

タイトル : SPWebService.WorkflowEventDeliveryThrottle Property
アドレス : https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spwebservice.workfloweventdeliverythrottle(v=office.15).aspx

例)

$webservice = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$webservice.WorkflowEventDeliveryThrottle
#変更する場合
$webservice.WorkflowEventDeliveryThrottle = 30
$webservice.Update()

タイトル : ワークフロー : Stsadm プロパティ (Windows SharePoint Services)

アドレス : https://technet.microsoft.com/ja-jp/library/cc288139.aspx

 

2.    Batch Size

既定では 5 分に 1 回起動するワークフロー ジョブが、コンテンツ データベースごとに本制限値 (既定では 100) までのワークアイテムをロードして処理を実行します。

 

この値も SharePoint 上での実装値であるため Windows Workflow Foundation パフォーマンス カウンターではこの値を取得することはできません。

タイトル : SPWebService.WorkItemEventDeliveryBatchSize Property

アドレス : https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spwebservice.workitemeventdeliverybatchsize(v=office.15).aspx

例)

$webservice = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$webservice.WorkItemEventDeliveryBatchSize
#変更する場合
$webservice.WorkItemEventDeliveryBatchSize = 200
$webservice.Update()

タイトル : Workitem-eventdelivery-batchsize : Stsadm プロパティ (Windows SharePoint Services)

アドレス : https://technet.microsoft.com/ja-jp/library/cc288293.aspx

3. Timeout

ワークフローのジョブ実行が、この Timeout 値 (既定では 5 分) を超えた場合は、アクティビティの継ぎ目で処理を中断し、後続の処理は再度 ScheduledWorkItems テーブルに戻されます。

後にワークフロー タイマージョブが実行するサイクルとなります。

なお、アクティビティの継ぎ目がチェックポイントですので、カスタムのコード アクティビティなどで無限ループが発生している場合、この制限値が該当する限りではありません。

 

タイトル : SPWebService.WorkflowTimeoutMinutes Property

アドレス : https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spwebservice.workflowtimeoutminutes(v=office.15).aspx

例)

$webservice = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$webservice.WorkflowTimeoutMinutes
#変更する場合
$webservice.WorkflowTimeoutMinutes = "0:10"
$webservice.Update()

 

タイトル : Workflow-eventdelivery-timeout : Stsadm プロパティ (Windows SharePoint Services)

アドレス : https://technet.microsoft.com/ja-jp/library/cc288917.aspx

 

 

4. Workflow Timer Interval

ワークフロージョブの実行サイクル (既定では 5 分に 1 回) をこの設定によって変更できます。

既定だと DelayActivity や指定した期間待機するアクションなどで “1 分“ 待機する設定を実装したとしても、この設定の既定値が 5 分であるため、実際にワークフローで処理されるまでに 5分以上待機することになります。本設定値を変更することで、この実行間隔を狭めることは可能です。

 

例)

Get-SPTimerJob job-workflow | Set-SPTimerJob –Schedule “every 1 minutes between 0 and 59”

 

Stsadm コマンドで job-workflow 値を変更する方法は、SharePoint Server2010 以降ではワークフロー タイマー ジョブの実行間隔に反映されなくなりました。

 

4. リトライ動作について

ワークフローの遅延などの多くの要因は、ワークフローが一時的なエラー等に対処するためにリトライされていることに起因します。

特に数時間単位で処理が遅延する場合は、継続的にエラーが発生している可能性が懸念されます。

そのため、以下にエラー発生時のリトライ処理の動作についても合わせて追記します。

 

エラー発生時のリトライ処理について

これまでに記載した通り、SharePoint 2010 形式ワークフローはワークフローの永続化ポイントまでの処理単位をスケジュールされたワークアイテム (ScheduledWorkItems) として分割し処理を進行させます。

この処理単位ごとにエラーが発生した場合は、リトライを行う処理が実装されております。一般的には SharePoint Foundation Timer サービス (OWSTIMER.EXE) においてジョブが実行される状況においてのみ有効となりますが、w3wp.exe 上においても、例えばワークフローが "開始時に失敗 (再試行中) " というフェーズとなっている場合はリトライ実行が可能な状況となります。

 

この際に、ワークフローの状態ページ下部に表示されている履歴リストには、<ワークフロー名> failed to run. や <ワークフロー名> failed to start という内容が記述されます。

 

リトライする際には、以下のようなインターバルを追加して次回実行日時を決定します。最初は 10 分が追加されますが、エラー発生が続けば、1 つずつ大きな値を追加して (増分バックオフ) 新しいイベント日時が設定される動作になります。1280 分のインターバルを追加した後の処理に失敗した場合は、最終的にエラーとして処理されます。

 

10, 20, 40, 80, 160, 320, 640, 1280 (単位 : 分)

 

上記の実装はタイマー ジョブでピックアップされるワークアイテムを分散させる目的となります。

仮に毎回同じワークフローが繰り返しピックアップされると、BatchSize  (既定で 100 件) を超えた時点で、毎回ピックアップされるアイテムがすべてエラー発生する状況になり、今後一切ワーク アイテムが処理されなくなります。

 

ワークフローのフェイルオーバーについて

ワークフローのフェイルオーバーという機能もあります。ワークフローのフェイルオーバー ジョブ (job-workflow-failover) は、15 分に 1 回起動し、進行中のまま 20 分以上経過してしまったワークフローの実行ロックを解除して、再度実行可能な状態に戻します。

実行可能状態に戻された後は、再度ワークフロー タイマー ジョブが 5 分に 1 回ピックアップして起動します。

上記のフェイルオーバー 15 分とワークフローの実行ジョブ 5 分という制約があるため、再実行には 20 分以上かかります。

また、ハングと認識する条件が 20 分以上の停滞であることから、仮に毎回フェイルオーバーが発生する状況に陥ったとしても最速で 30 分に 1 回しか処理されません。

なお、上記のようなリトライ機能は備わっているものの、もしエラーが発生し続ける場合は、手動でワークフローを最初からやり直すことをお勧めします。

今回の投稿は以上となります。