Projekt ist MVC WebAPI basiert.Was ist der beste Weg, Ergebnisse einer json.net-Serialisierung im Speicher zwischenzuspeichern?
Wir übergeben den Berechtigungskontext eines Clients an unsere API-Server als serialisiertes JSON-Objekt in den Forderungsheadern der Anforderung. Dies ist kein riesiges Objekt: 6 Eigenschaften und eine Sammlung enum-basierter Schlüssel/Wert-Paare (bis zu 6 Elemente hier)
Die überwiegende Mehrheit der Anfragen an API tritt jede Minute (einige häufiger) aus dem gleichen Satz von Kunden. Wahrscheinlich 700-900 Clients (und wachsend), jede einzelne sendet die gleichen Ansprüche jede Minute.
Für jede Anfrage deserialisieren verschiedene Komponenten des Codes dieses Objekt wahrscheinlich 5-6 mal. Diese Deserialisierung verursacht einen erheblichen CPU-Verbrauch auf den Servern.
Was wäre der beste Weg, um diese Deserialisierungen im Speicher zwischenzuspeichern? Würde ein statisches Dictionary-Objekt mit Schlüsseln, die serialisierte JSON-Strings sind, gut funktionieren oder wäre es zu langsam, wenn diese Strings ziemlich groß wären?
EDIT: Jede Aktion eines jeden Controller wird durch dieses Attribut gefiltert, um sicherzustellen, dass Anrufe
public class AccountResolveAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext context)
{
var controller = (ControllerBase) context.ControllerContext.Controller;
var identity = (ClaimsIdentity) controller.User.Identity;
var users = identity.Claims
.Where(c => c.Type == ClaimTypes.UserData.ToString())
.Select(c => JsonConvert.DeserializeObject<UserInformation>(c.Value))
.ToList();
var accountId = controller.ReadAccountIdFromHeader();
if (users.All(u => u.AccountId != accountId))
{
throw new ApplicationException(string.Format("You have no rights for viewing of information on an account Id={0}", accountId));
}
}
}
Es richtigen Berechtigungen haben, werden Anrufe auch in der Basiscontroller, der die Ansprüche befragen, aber AccountResolve könnte wahrscheinlich cachen die Ergebnis der ersten Deserialisierung in den Controller, so dass diese Aufrufe nicht versuchen, erneut zu deserialisieren. Die Ansprüche sind jedoch immer wieder dieselben, und ich versuche nur einen Weg zu finden, nicht immer wieder die gleiche Zeichenfolge zu deserialisieren. Ich habe versucht, die Serialisierung Zeichenfolge als Schlüssel und Ergebnisobjekt in Speicher in einem globalen statischen ConcurrentDictionary, aber es scheint nicht geholfen haben
Sie sagen, dass verschiedene Komponenten des Codes das Objekt deserialisieren. Wie gelangen die Komponenten aus Neugier in erster Linie zu den serialisierten Daten? Zum Beispiel: Ist es das Abrufen vom Hauptthread des aktuellen Threads, wird das Prinzipal als Parameter übergeben? –
Eine andere Frage neben der, die ich gerade gefragt habe: Verwenden Sie einen IoC-Container, und wenn ja, welcher? –
Yah, wir verwenden Autofac – Igorek