Was Ihre App tun sollte, wenn der Lizenzserver ausgefallen ist
Eine Lizenzprüfung, die hart scheitert, sobald der Server nicht erreichbar ist, macht Ihren Ausfall — oder das wackelige WLAN des Kunden — zu seinem Ausfall. Hier steht, wie man Kulanzfenster entwirft, fail-open vs. fail-closed pro Stufe wählt und verhindert, dass eine vorübergehende Netzwerkstörung zahlende Kunden aussperrt.
Jede Online-Lizenzprüfung hat einen Fehlermodus, für den die meisten Teams nicht entwerfen: Der Server ist schlicht nicht erreichbar. Vielleicht hat Ihr Lizenzdienst einen schlechten Tag; vielleicht hat der Unternehmensproxy des Kunden die Anfrage verschluckt; vielleicht ist sein Laptop in einem Zug. Wenn Ihre Prüfung „ich konnte den Server nicht erreichen” genauso behandelt wie „der Server sagte, diese Lizenz ist ungültig”, dann wird Ihr Ausfall zum Ausfall Ihres Kunden — und ein dreißig Sekunden langer Netzwerk-Blip sperrt einen zahlenden Nutzer aus Software aus, die er besitzt. Die Lösung ist, explizit für Unerreichbarkeit zu entwerfen, mit Kulanzfenstern und einer bewussten Fail-open/Fail-closed-Politik.
„Nein” und „ich weiß nicht” sind verschiedene Antworten
Die wichtigste Unterscheidung in resilienter Lizenzierung ist die zwischen zwei sehr verschiedenen Ergebnissen eines Check-ins:
- Ein autoritatives Nein — Sie haben den Server erreicht und er sagte, diese Lizenz sei abgelaufen, widerrufen oder über ihrer Sitzanzahl. Das ist ein echtes „Nein” und soll greifen.
- Ein nicht schlüssiges Ergebnis — Sie konnten den Server gar nicht erreichen: DNS-Fehler, Timeout, 503, TLS-Fehler. Das ist kein „Nein”. Es ist „ich weiß es gerade nicht”.
Eine naive Prüfung verschmilzt beide zu „nicht gültig → stoppen”. Das ist der Bug. Die überwältigend wahrscheinliche Ursache eines nicht schlüssigen Ergebnisses ist ein vorübergehendes Netzwerkproblem, kein Kunde, der Ihre Software mitten in der Sitzung raubkopiert hat. Stille als Ablehnung zu behandeln bestraft die ehrliche Mehrheit, um einen Angreifer zu behindern, der ohnehin weit leichtere Optionen hat (er kann einfach offline laufen). Resiliente Lizenzierung hält die beiden Fälle auseinander und reagiert auf jeden angemessen.
Die gecachte Lease ist Ihr Rückfall
Resilienz ruht auf einer signierten Lease, die die App bereits von ihrem letzten erfolgreichen Check-in hält — dieselbe Offline-Validierungs-Primitive, die in Offline-Lizenzvalidierung beschrieben ist. Die Lease ist eine server-signierte Aussage, „diese Lizenz ist bis zum Zeitpunkt T gültig”, die die App lokal mit einem eingebetteten öffentlichen Schlüssel verifizieren kann, ohne Netzwerk. Ihr Gültigkeitsfenster ist das Rückgrat der Kulanz: Zwischen Check-ins vertraut die App der Lease, und wenn ein Check-in nicht abschließen kann, vertraut sie der Lease weiter, bis dieses Fenster — plus eine explizite Kulanzperiode — aufgebraucht ist.
Der entscheidende Entwurfsparameter ist, das Lease-Fenster bequem länger als das Check-in-Intervall zu machen. Wenn Sie täglich einchecken, aber eine 7-Tage-Lease ausstellen, kann ein Kunde die meiste Zeit einer Woche offline sein (oder Ihr Server ausgefallen), bevor etwas herabstuft. Ein Check-in ist dann keine Barriere, die bei jedem Start bestehen muss; er ist eine opportunistische Auffrischung, die die Landebahn verlängert:
async Task<LicenseState> EvaluateAsync(CachedLease lease, DateTime now)
{
try
{
var fresh = await _server.CheckInAsync(lease.Key); // reach the server
if (fresh.Status == Status.Revoked || fresh.Status == Status.Expired)
return LicenseState.Denied(fresh.Status); // authoritative NO — act on it
_store.Save(fresh.Lease); // refresh: extend the runway
return LicenseState.Active(fresh.Lease);
}
catch (Exception) // timeout, DNS, 5xx, TLS — INCONCLUSIVE, not a denial
{
return EvaluateOffline(lease, now); // fall back to the cached lease
}
}
LicenseState EvaluateOffline(CachedLease lease, DateTime now)
{
if (now <= lease.ValidThroughUtc)
return LicenseState.Active(lease); // still inside the lease window
if (now <= lease.ValidThroughUtc + GracePeriod)
return LicenseState.Grace(lease, until: lease.ValidThroughUtc + GracePeriod);
return LicenseState.NeedsReconnect(); // runway exhausted — degrade, don't crash
}
Beachten Sie die Asymmetrie: Eine Revoked/Expired-Antwort beendet die Sitzung, aber jede Ausnahme fällt auf die Lease zurück. Der Netzwerkfehler verweigert nie; nur der Server verweigert.
Scheitern Sie offen, dann herabstufen — selten hart sperren
Mit getrennten Fällen schreibt sich die Politik für die meisten Produkte von selbst:
- Innerhalb des Lease-Fensters: normal laufen. Nichts zu entscheiden.
- Nach der Lease, innerhalb der Kulanz: normal laufen, aber anfangen zu stupsen — ein leises Banner „wir konnten Ihre Lizenz nicht verifizieren; wir versuchen es weiter”. Im Hintergrund mit exponentiellem Backoff wiederholen (hämmern Sie keinen Server, der vielleicht schon kämpft).
- Nach der Kulanz: herabstufen, nicht abstürzen. Gehen Sie auf Nur-Lese, deaktivieren Sie nur-bezahlte Funktionen oder blockieren Sie neue Arbeit, während der Nutzer das Vorhandene speichern und exportieren kann. Eine klare „zum Fortfahren neu verbinden”-Meldung macht aus einer Sackgasse ein lösbares Problem.
Der Leitsatz ist, dass Ihre Lizenzierung für den Kunden sicher scheitern soll, nicht aggressiv scheitern. Die Kosten, einen zahlenden Kunden während Ihres eigenen Ausfalls fälschlich auszusperren — Support-Tickets, Rückerstattungen, Abwanderung, Ruf — stellen die Kosten in den Schatten, dass ein entschlossener Pirat ein paar zusätzliche Kulanztage bekommt, die er ohnehin durch Offline-Bleiben hätte bekommen können. Berechtigungsgesteuerte Produkte stufen besonders anmutig herab: Sie können die Premium-Flags deaktivieren und die Kern-App nutzbar lassen.
Wann Fail-closed die richtige Wahl ist
Fail-open-innerhalb-der-Kulanz ist der richtige Standard, kein universelles Gesetz. Zwei Situationen rechtfertigen strengeres Verhalten:
- Ein autoritativer Widerruf. Wenn der Server erreichbar ist und „widerrufen” zurückgibt — eine Rückerstattung, eine Rückbuchung, ein kompromittierter Schlüssel — ist das ein echtes Nein und soll prompt greifen, weshalb der Widerruf den Check-in-Pfad nimmt und nicht dem Kulanzfenster unterliegt. Kulanz deckt Stille ab, nie eine explizite Ablehnung.
- Hochwertige oder compliance-gebundene Stufen. Für ein schwebendes/gleichzeitiges Modell, bei dem ein Sitz freigegeben werden muss, oder ein reguliertes Deployment, bei dem unverifizierte Nutzung selbst ein Problem ist, sind eine kürzere Lease und eine kürzere Kulanz angemessen — das Geschäftsmodell, nicht das Netzwerk, setzt die Toleranz. Machen Sie das zu einer Politik pro Stufe: Eine Verbraucher-App kann sich eine großzügige Woche Kulanz leisten; ein Server-Tool mit gleichzeitigen Sitzen erlaubt vielleicht nur Stunden.
Der Punkt ist, dass Fail-closed eine bewusste Wahl für bestimmte Stufen sein soll, getrieben vom Wert, der auf dem Spiel steht — nicht der versehentliche Standard, den Sie bekommen, wenn Sie einen Timeout wie eine Ablehnung behandeln.
Die Stellschrauben einstellen
Drei Parameter formen das ganze Erlebnis, und sie sollten explizit sein, nicht emergent:
- Lease-Gültigkeitsfenster — wie viel ein einzelner erfolgreicher Check-in kauft. Länger = resilienter gegen Ausfälle, langsamer darin, einen Widerruf abzubilden. Tage für die meiste Desktop-/B2B-Software.
- Kulanzperiode — zusätzliche Zeit nach der Lease vor dem Herabstufen. Ein Sicherheitspuffer speziell für Ihre Ausfälle; selbst ein Tag reduziert Fehlsperren erheblich.
- Check-in-Takt + Backoff — wie oft Sie auffrischen, wenn gesund, und wie Sie bei Fehlern wiederholen. Frischen Sie weit vor Ablauf der Lease auf (damit ein paar verpasste Check-ins harmlos sind), und machen Sie bei Fehlern Backoff, damit ein kämpfender Server nicht überrannt wird.
Stellen Sie diese pro Stufe ein, und Sie bekommen Resilienz durch Konstruktion: Kurze Ausfälle sind unsichtbar, längere stufen sanft mit klaren Meldungen herab, und nur ein echtes, autoritatives „Nein” stoppt je einen Kunden auf der Stelle.
Das Fazit
Eine Lizenzprüfung ist nicht nur ein Ja/Nein-Tor — sie hat einen dritten Zustand, „konnte nicht fragen”, und wie Sie diesen Zustand behandeln, trennt Lizenzierung, die Ihren Umsatz schützt, von Lizenzierung, die gelegentlich Ihr Wohlwollen zerstört. Cachen Sie eine signierte Lease, geben Sie ihr ein Fenster länger als Ihr Check-in-Intervall, fügen Sie eine Kulanzperiode hinzu, und machen Sie den Endzustand zu einer anmutigen Herabstufung mit einem Weg zurück. Behandeln Sie das „Nein” des Servers als autoritativ und die Stille des Netzwerks als „noch nicht”. Tun Sie das, und das nächste Mal, wenn Ihr Lizenzdienst eine schlechte Stunde hat, werden Ihre Kunden es nicht einmal bemerken.
Nebula.NET testen
Härten Sie Ihren .NET-Code in wenigen Minuten — starten Sie mit der kostenlosen Edition.