私はService Fabricでホストされているステートフルなサービスを作成しています。このサービスの役割は、外部キューからメッセージを消費して変換し、それを当社独自のメッセージングシステムに配置することです。スループットは、サプライヤのドキュメントに従って6kメッセージ/秒まで上がることができます。System.Fabric.FabricNotPrimaryExceptionタイマーから状態を保存するとき
サービスを複数のパーティションに構成してメッセージの負荷を分散し、各パーティションに最小2 /最大3のレプリカがあります。障害から回復するために、私はサプライヤの待ち行列に加入し、メッセージを受信したい時点からタイムスタンプを渡すことができます。これを行うには、サービス状態で処理された最後のメッセージのタイムスタンプを保存します。
private async void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
var saveRetryPolicy = Policy
.Handle<Exception>()
.WaitAndRetryAsync(5, retryAttempt =>
TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
);
await saveRetryPolicy.ExecuteAsync(async() =>
{
using (var tx = _stateManager.CreateTransaction())
{
var state = await _stateManager.TryGetAsync<IReliableDictionary<string, long>>(TimestampStateName);
if (state.HasValue)
{
await state.Value.AddOrUpdateAsync(tx, TimestampStateName, _lastTXTimestamp,
(s, l) => _lastTXTimestamp);
await tx.CommitAsync();
}
else
{
var s =
await _stateManager.GetOrAddAsync<IReliableDictionary<string, long>>(tx, TimestampStateName);
await tx.CommitAsync();
_timer_Elapsed(this, null);
}
}
});
}
たびに:ため、私は、これはタイマーに「保存」(及び下流メッセージの潜在的なDUPを許可する)行うことを決めたメッセージの量
にこれは時間によって呼び出されるコードでありますこれを永続化しようとすると、各パーティションに「System.Fabric.FabricNotPrimaryException」エラーが発生します。
私はリトライポリシー(Polly Retryの礼儀)を含んでいますが、これを行うことを推奨した同様の問題に関するコメントがありました。これは何の効果もありませんでした。エラーが報告されるまでの時間が長くなりました。
SFをどのように使用するべきかについて私は誤解していますか?これは私にとって単純なユースケースのようです。コメントから
すべてのレプリカでタイマーを開始しますか?またはプライマリレプリカでのみですか? – LoekD
大きなスポット(私は今は馬鹿に見えません)。ありがとう –