verwendeter Webserver: Kestrel
ASP.NET Core Version: 2.1
Angular Version: 7.1.1
Hallo zusammen,
ich würde gerne die Antwort einer WebAPI-Funktion komprimieren. Aktuell wird als Result ein JSON-String verwendet, welcher allerdings in diesem speziellen Fall einen zu großen Overhead besitzt.
Meine Fragen lautet nun:
Ich arbeite mich gerade durch folgenden Artikel, jedoch steht dort geschrieben dass die angegebenen Techniken nicht rein mit Kestrel funktionieren. (...Kestrel server don't currently offer built-in compression support)
https://github.com/aspnet/Docs/blob/master/aspnetcore/performance/response-compression.md
Danke
Kumatin tanaki - Grabt den Klappstuhl aus!
JSON an sich ist schon kompakt genug.
Dein Problem ist also die Datenmenge die der Client enthält.
Diese muss der Client auch verarbeiten, weshalb du nur die Übertragung zum Client durch Kompression bei der Übertragung verkleinern kannst.
Ansonsten wirst du nur durch Änderung an den gelieferten Daten was ändern können.
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
*Was* genau willst Du komprimieren?
Geht es Dir um den Body (Gzip) oder geht es Dir um das Entfernen von Spaces in Json? Wird hier nicht klar im Post.
Für das Komprimieren gäbe es ohnehin Middlewares in ASP.NET (zB Gzip).
Kestrel hat damit nichts am Hut.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
HTTP Compression. Die Komprimierung auf Anwendungsebene zu implementieren, ist keine so richtig dolle Idee.
LaTino
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)
@Abt:
Ich möchte den Body komprimieren. Das Result vom Standard-MS-JsonSerializer hat sowieso keine Spaces. (Weshalb ich's auch nicht thematisiert habe)
Diese Middlewares kann ich meines Wissens aber nicht direkt mit Kestrel verwenden, weshalb ein IIS etc On-Top nötig ist. Oder liege ich hier falsch?
@T-Virus:
Konkretes Beispiel:
Die Anwendung erhält >100000-Datensätze durch diesen einen Funktionsaufruf. Jeder Entry hat hierbei ca. 200 Properties (Jetzt mal Flach dargestellt. Diese Informationen liegen verschachtelt vor)
Wenn ich mir die Übermittlung zwischen Server <-> Client anschaue, dann werden über 1GB an Daten übermittelt.
Die Anwendung benötigt so viele Daten da diese diverse Auswertungen / Statistiken durchführt. In Deserialisierter Form habe ich eine (geschätzte) RAM-Auslastung von 50MB. In Serialisierter Form ist der String jedoch wie gesagt > 1GB groß.
Kumatin tanaki - Grabt den Klappstuhl aus!
> . Die Komprimierung auf Anwendungsebene zu implementieren, ist keine so richtig dolle Idee.
Gzip ist in der ASP.NET Core Welt nur eine Middleware.
Wird mit app.UseResponseCompression();
aktiviert.
Das ist auch gut (und by design) so, um von einem Webserver unabhängig zu bleiben.
Die Anwendung erhält >100000-Datensätze durch diesen einen Funktionsaufruf. Jeder Entry hat hierbei ca. 200 Properties (Jetzt mal Flach dargestellt. Diese Informationen liegen verschachtelt vor)
Ist das wirklich Sinn des API Designs 1GB an Daten zu verschieben....? 🤔
Aber Middlewares sind immer Teil der Pipe in ASP.NET Core. Man kann das natürlich auch im IIS machen - nur halt nicht im Kestrel.
Der Kestrel hat andere Aufgaben.
Aber ohne Webserver (IIS, Nginx..) sollte man Kestrel ohnehin nicht betreiben (wird auch nicht empfohlen, auch wenn es technisch funktioniert).
Im Endeffekt hab ich aber nicht verstanden, was Du genau komprimieren willst.
Wenn Du Gzip bereits aktiviert hast und die Json-Format-Möglichkeiten ausgeschöpft hast.. und auch den Body selbst nicht verkleiner willst... was soll denn noch komprimiert werden können, ohne auf Daten zu verzichten?
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
@Abt
Sinn der API ist nicht 1GB an Daten an den Client zu schieben, sondern eben 100000 Einträge. (Die Anzahl ist hierbei variabel und kann durch Parameter verändert werden)
Da jeder Eintrag sich durch eine Menge Informationen identifiziert, ist in diesem Fall so gegeben.
Wie gesagt, es geht hierbei um Auswertungen / Statistiken, welche von der Client-Anwendung erzeugt werden.
Ich möchte dass nochmals kurz zusammenfassen:
app.UseResponseCompression();
aktiviert werden
Im Endeffekt hab ich aber nicht verstanden, was Du genau komprimieren willst.
Wenn Du Gzip bereits aktiviert hast und die Json-Format-Möglichkeiten ausgeschöpft hast.. und auch den Body selbst nicht verkleiner willst... was soll denn noch komprimiert werden können, ohne auf Daten zu verzichten?
--> Gzip hatte ich bisher nicht aktiviert.
--> Json-Format ist bereits minified
Den Body könnte ich theoretisch so manipulieren dass ich gleiche Objekte zusammenfasse und diese aus den eigentlichen Informationen heraustrenne. Im Client müsste ich dann allerdings den gleichen Weg Rückwärts gehen, was technisch zwar machbar ist m.M.n. den (recht großen) Aufwand allerdings nicht rechtfertigt. Genau hierfür möchte ich eben das Result (bzw. aktuell den JSON-String) komprimieren.
Kumatin tanaki - Grabt den Klappstuhl aus!
Hi,
Die Anwendung erhält >100000-Datensätze durch diesen einen Funktionsaufruf. Jeder Entry hat hierbei ca. 200 Properties
sorry, wenn ich es so schreibe, aber bitte welche Anwendung soll speichertechnisch damit umgehen (können)? Das ist schon eine Menge !
Jetzt mal Flach dargestellt. Diese Informationen liegen verschachtelt vor
Was höchstwahrscheinlich noch viele JOINS auf Serverseite zur Folge hat...
Und Warten des Clients...
Du musst wirklich die Datenmengen begrenzen, die von dem Server abgerufen werden und durch den Client materielisiert werden !
Die Anwendung kann aktuell sehr gut damit umgehen. Das Problem ist aktuell nur die Übertragung.
Ich weiß es ist nur nett gemeint mich darauf hinzuweisen, aber das hat nichts mit meiner eigentlichen Frage zu tun.
Macht es Sinn ODATA einzusetzen? Wie gesagt, mein eigentliches Ziel war es die Datenmenge zu komprimieren.
Kumatin tanaki - Grabt den Klappstuhl aus!
Sinn der API ist nicht 1GB an Daten an den Client zu schieben, sondern eben 100000
Einträge. (Die Anzahl ist hierbei variabel und kann durch Parameter verändert werden)
Es ist hier nicht klar, wie die 1 GB im Verhältnis zu 100000 Einträge stehen.
Wie gesagt, es geht hierbei um Auswertungen / Statistiken, welche von der Client-Anwendung erzeugt werden.
Der Ansatz ist jetzt halt auch nicht gerade der sparsamste...Rohdaten via HTTP ist halt...
- Muss im Client (Browser) noch irgendetwas durchgeführt werden, sodass die Daten komprimiert werden? (z.B. festlegen von bestimmten HttpHeader?)
Schau doch einfach mal in die Doku der genannten Middleware, dann siehst Du, dass das ein Standard ist - seit bald 30 Jahren. Wäre die Frage sofort beantwortet gewesen 😉
Gzip alternativ Brotli; braucht mehr Ressourcen aber komprimiert statisch aggressiver.
Benötigt man einen ausgewachsenen Webserver oder ist dies auch rein mittels Kestrel möglich?
Erneut: Kestrel ist dafür nicht verantwortlich.
Weshalb wird nicht empfohlen rein auf Kestrel zu setzen? Bisher habe ich während meiner Forschungsarbeit nichts dergleichen lesen können (Gut, es kann auch sein dass ich etwas übersehen habe)
Weil Kestrel nicht dafür gedacht ist, dass er gegen das Internet exposed wird.
Les Dir bitte die Basic Doc für Kestrel in der MSDN durch.
Logische Kompression musst Du selbst programmieren.
Das kann Dir keine Middleware abnehmen. Nie.
Schaue Dir z.B. mal OData an...
Da würde ich eher auf GraphQL verweisen.
Wie gesagt, mein eigentliches Ziel war es die Datenmenge zu komprimieren.
Es ist immer noch nicht klar, wie Du komprimieren willst: durch Encoding oder inhaltlich.
Zaubern kann halt auch ASP.NET nicht.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Ich erwarte keine Zauberei.
OK, ich danke für alle Antworten.
Kumatin tanaki - Grabt den Klappstuhl aus!
@Abt, die Middleware ist in 99% der Fälle keine Option. Das ist der Job des reverse proxy, und dabei sollte man es auch belassen.
When to use Response Compression Middleware
Use server-based response compression technologies in IIS, Apache, or Nginx. The performance of the middleware probably won't match that of the server modules. HTTP.sys server server and Kestrel server don't currently offer built-in compression support.
Die einzigen Anwendungsfälle sind, wenn man
Also: schalte die Kompression in deinem Nginx/Apache/IIS an, und dein Problem ist erledigt.
LaTino
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)