2016-11-22 3 views
0

Ich schreibe einen Stateful Service, der in Service Fabric gehostet wird. Die Aufgabe des Dienstes besteht darin, Nachrichten von einer externen Warteschlange zu verarbeiten, sie zu transformieren und auf unser eigenes Nachrichtensystem zu setzen. Der Durchsatz kann gemäß den Unterlagen des Lieferanten bis zu 6.000 Nachrichten pro Sekunde betragen.System.Fabric.FabricNotPrimaryException Beim Speichern des Status vom Timer

Ich habe den Dienst in mehrere Partitionen konfiguriert, um die Nachricht zu verteilen, und jede Partition hat min 2/max 3 Replikate. Um sich von einem Fehler zu erholen, kann ich die Lieferantenwarteschlange abonnieren und einen Zeitstempel übergeben, von dem aus ich Nachrichten empfangen möchte. Um dies zu tun, speichere ich den Zeitstempel der letzten im Servicezustand verarbeiteten Nachricht. Aufgrund des Volumens der Nachrichten habe ich beschlossen, auf einen Timer dieses ‚retten‘ zu tun (und damit potenzielle dups von Nachrichten downstream)

Dies ist der Code, der durch die Zeit genannt wird:

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); 
       } 
      } 
     }); 
    } 

Jedes Mal, Es wird versucht, dies zu verhindern. Ich erhalte den Fehler 'System.Fabric.FabricNotPrimaryException' auf jeder Partition.

Ich habe eine Wiederholungsrichtlinie (mit freundlicher Genehmigung von Polly Retry) eingefügt, da es einen Kommentar zu einem ähnlichen Problem gab, das dies empfohlen hat. Dies hatte keine Auswirkung und verlängerte die Zeit bis zur Meldung des Fehlers.

Versteh ich etwas fundamental mit wie SF sollte verwendet werden? Dies scheint mir ein einfacher Anwendungsfall zu sein.

+1

Starten Sie den Timer für alle Replikate? Oder nur auf dem primären Replikat? – LoekD

+0

Großartiger Ort (Schaue ich jetzt nicht blöd aus). Vielen Dank –

Antwort

1

Antwort von Kommentaren:

Achten Sie darauf, nicht den Timer auf alle Repliken starten, aber nur auf dem primären Replikat.

Verwandte Themen