Laden...

WebAPI-Result komprimieren

Erstellt von scoKi! vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.903 Views
scoKi! Themenstarter:in
90 Beiträge seit 2009
vor 5 Jahren
WebAPI-Result komprimieren

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:

  • Was ist die beste Art und Weise das Ergebnis dieser einen Funktion umzustellen?
    ---> Soll man manuell die Daten komprimieren?
    ---> Soll man die Serialisierung dem Framework überlassen und allgemein auf einen anderen Serializer setzen? Wenn ja, welchen?
  • Die Daten werden von einer Angular-Anwendung angefragt, weshalb diese dann in der Anwendung auch dekomprimiert werden müssten?

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!

T
2.224 Beiträge seit 2008
vor 5 Jahren

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.

16.834 Beiträge seit 2008
vor 5 Jahren

*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.

3.003 Beiträge seit 2006
vor 5 Jahren

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)

scoKi! Themenstarter:in
90 Beiträge seit 2009
vor 5 Jahren

@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!

16.834 Beiträge seit 2008
vor 5 Jahren


>
. 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?

scoKi! Themenstarter:in
90 Beiträge seit 2009
vor 5 Jahren

@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:

  • Gzip kann über
app.UseResponseCompression();

aktiviert werden

  • Muss im Client (Browser) noch irgendetwas durchgeführt werden, sodass die Daten komprimiert werden? (z.B. festlegen von bestimmten HttpHeader?)
  • Benötigt man einen ausgewachsenen Webserver oder ist dies auch rein mittels Kestrel möglich?
  • 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)

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!

T
156 Beiträge seit 2010
vor 5 Jahren

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 !

T
156 Beiträge seit 2010
vor 5 Jahren

Schaue Dir z.B. mal OData an...

scoKi! Themenstarter:in
90 Beiträge seit 2009
vor 5 Jahren

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!

16.834 Beiträge seit 2008
vor 5 Jahren

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.

scoKi! Themenstarter:in
90 Beiträge seit 2009
vor 5 Jahren

Ich erwarte keine Zauberei.

OK, ich danke für alle Antworten.

Kumatin tanaki - Grabt den Klappstuhl aus!

3.003 Beiträge seit 2006
vor 5 Jahren

@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

  • auf reverse proxy verzichtet und Kestrel oder WebLIstener "nackt" laufen lässt (fettet no-no, wie Abt zu Recht geschrieben hat)
  • wenn der benutzte reverse proxy aus irgendwelchen Gründen keine Kompression anstellen kann (absoluter Ausnahmefall)

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)