ASP.NET erfreut sich bei der Entwicklung von Webanwendungen immer größerer Beliebtheit. Viele dieser Anwendungen weisen einen hohen Datenverkehr auf und bedienen Millionen von Benutzern. Daher haben diese Anwendungen einen großen Einfluss auf das Geschäft und sind daher sehr wichtig.
Interessanterweise ist die ASP.NET-Anwendungsarchitektur auf der Anwendungsebene sehr skalierbar. Und auch das HTTP-Protokoll ist zustandslos. Beides bedeutet, dass Sie Ihre ASP.NET-Anwendung in einer Webfarm mit Lastenausgleich ausführen können, in der jede HTTP-Anfrage an den am besten geeigneten Webserver weitergeleitet wird. Dadurch können Sie ganz einfach weitere Webserver zu Ihrer Webfarm hinzufügen, wenn Ihr Benutzerverkehr zunimmt. Und dadurch ist Ihre ASP.NET-Anwendungsebene sehr skalierbar. Aber was meine ich hier mit Skalierbarkeit?
Unter Skalierbarkeit versteht man im Wesentlichen die Fähigkeit, auch bei Spitzenlasten eine hohe Leistung zu liefern. Wenn also die Reaktionszeit Ihrer ASP.NET-Anwendungsseite bei 10 Benutzern sehr schnell ist und bei 100,000 Benutzern genauso schnell bleibt, dann ist Ihre ASP.NET-Anwendung skalierbar. Wenn sich Ihre ASP.NET-Antwortzeit jedoch verlangsamt, wenn die Anzahl der Benutzer steigt, ist Ihre Anwendung nicht skalierbar.
Trotz einer sehr skalierbaren Architektur auf der Anwendungsebene sind ASP.NET-Anwendungen heute mit großen Skalierbarkeitsengpässen konfrontiert. Diese Engpässe treten in vier verschiedenen Bereichen auf:
Lassen Sie mich die einzelnen Punkte im Folgenden näher erläutern.
Anwendungsdatenbanken wie SQL Server oder Oracle werden schnell zu einem Skalierbarkeitsengpass, wenn Sie die Transaktionslast erhöhen. Dies liegt daran, dass Sie die Datenbankebene zwar durch den Kauf eines leistungsstärkeren Datenbankservers vergrößern können, eine Skalierung durch das Hinzufügen weiterer Server zur Datenbankebene jedoch nicht möglich ist. Es kommt beispielsweise sehr häufig vor, dass auf der Anwendungsebene 10 bis 20 Server vorhanden sind, auf der Datenbankebene ist dies jedoch nicht möglich.
Darüber hinaus muss der ASP.NET-Sitzungsstatus irgendwo gespeichert werden. Und die von Microsoft bereitgestellten Standardoptionen sind InProc, StateServer und SqlServer. Leider weisen alle drei Optionen erhebliche Leistungs- und Skalierbarkeitsprobleme auf. InProc und StateServer zwingen Sie dazu, Sticky-Sitzungen zu verwenden und alle HTTP-Anfragen auf demselben Server zu senden, auf dem die Sitzung erstellt wurde. Wenn Sie StateServer als eigenständigen Server konfigurieren, um Sticky Sessions zu vermeiden, wird StateServer zu einem Single Point of Failure und seine Leistung wird ebenfalls zu einem großen Problem. Und SqlServer speichert ASP.NET-Sitzungen in der SQL Server-Datenbank als BLOBs. Außerdem gibt es bei diesem Ansatz ernsthafte Leistungs- und Skalierbarkeitsprobleme.
ASP.NET View State ist eine codierte, versteckte Zeichenfolge (oft Hunderte von KB groß), die als Teil der HTTP-Antwort an den Browser des Benutzers gesendet wird. Der Browser macht damit nichts und sendet es im Falle eines HTTP-Post-Backs an den Webserver zurück. Dies verlangsamt die Reaktion der ASP.NET-Seite, belastet die Netzwerkkarten des Webservers stärker und verbraucht außerdem viel zusätzliche Bandbreite. Und wie Sie wissen, ist Bandbreite nicht billig.
Schließlich ASP.NET framework Führt eine ASP.NET-Seite anhand einer Benutzeranforderung aus, auch wenn sich die Seitenausgabe gegenüber der vorherigen Anforderung nicht ändert. Dies kann in Umgebungen mit wenigen Transaktionen in Ordnung sein. Aber in einer Umgebung mit hohem Transaktionsaufkommen, in der alle Ressourcen bereits an ihre Grenzen stoßen, kann diese zusätzliche Ausführung recht kostspielig werden und einen Engpass bei der Skalierbarkeit darstellen.
Wie das Sprichwort sagt: „Die Stärke jeder Kette ist nur so stark wie ihr schwächstes Glied.“ Solange es also irgendwo in der ASP.NET-Anwendungsumgebung Skalierbarkeitsengpässe gibt, wird die gesamte Anwendung langsamer und kommt sogar zum Stillstand.
Und ironischerweise geschieht dies unter Spitzenlast, wenn Sie ein Höchstmaß an Geschäftsaktivität ausüben. Daher sind die Auswirkungen einer Verlangsamung oder Ausfallzeit für Ihr Unternehmen viel kostspieliger.
NoSQL database Die Bewegung begann als Folge der Skalierbarkeitsprobleme in relationalen Datenbanken. NoSQL database Partitioniert die Daten auf mehrere Server und ermöglicht eine horizontale Skalierung wie bei der Anwendungsschicht.
Aber NoSQL database erfordert, dass Sie Ihre relationale Datenbank aufgeben und Ihre Daten in eine NoSQL database. Und das ist aus einer Vielzahl von Gründen leichter gesagt als getan und in vielen Fällen tatsächlich nicht möglich.
NoSQL databases verfügen nicht über die gleichen Datenverwaltungs- und Suchfunktionen wie relationale Datenbanken und möchten, dass Sie Daten auf eine völlig andere Art und Weise als in relationalen Datenbanken speichern. Darüber hinaus ist das Ökosystem rund um relationale Datenbanken für die meisten Unternehmen zu stark, um es aufzugeben.
Dadurch NoSQL databases sind nur dann nützlich, wenn Sie mit unstrukturierten Daten arbeiten. Und die meisten ASP.NET-Anwendungen befassen sich mit Geschäftsdaten, die überwiegend strukturiert und für relationale Datenbanken geeignet sind. Daher können diese Daten nicht in eine verschoben werden NoSQL database einfach.
Und selbst diejenigen, die am Ende ein verwenden NoSQL database Tun Sie dies für eine kleine Teilmenge ihrer Gesamtdaten, die als unstrukturiert betrachtet werden können. Und sie nutzen NoSQL database zusammen mit ihrer vorhandenen relationalen Datenbank.
Daher müssen Sie in den meisten Fällen mit Ihrer relationalen Datenbank leben und eine andere Lösung für Ihre Skalierbarkeitsprobleme finden. Glücklicherweise gibt es eine sehr praktikable Lösung, auf die ich weiter unten eingehen werde.
Die Lösung für alle oben genannten Probleme besteht darin, In-Memory Distributed Cache in Ihrer Anwendungsbereitstellung zu verwenden NCache. NCache ist ein Verteilter Open-Source-Cache für .NET, das extrem schnell und linear skalierbar ist. Stellen Sie sich das als einen In-Memory-Objektspeicher vor, der ebenfalls verteilt ist. Durch die In-Memory-Speicherung ist es extrem schnell und durch die Verteilung linear skalierbar.
Das Schöne an einem In-Memory Distributed Cache wie NCache besteht darin, dass Sie nicht aufgefordert werden, die Nutzung Ihrer vorhandenen relationalen Datenbank einzustellen. Sie können den Cache zusätzlich zu Ihrer relationalen Datenbank verwenden, da der Cache alle Engpässe bei der Skalierbarkeit relationaler Datenbanken beseitigt.
Wie sieht also ein verteilter In-Memory-Cache aus? NCache skalierbarer als eine relationale Datenbank? Also, NCache bildet einen Cluster von Cache-Servern und bündelt die CPU, den Speicher und andere Ressourcen aller dieser Server.
Und, NCache ermöglicht das Hinzufügen von Cache-Servern zur Laufzeit, ohne den Cache oder die Anwendung anzuhalten. Dadurch können Sie Ihre Anwendung linear skalieren und extreme Transaktionslasten bewältigen. Dies ist etwas, was Sie mit Ihrer relationalen Datenbank nicht tun können.
In-Memory Distributed Cache wie NCache skaliert linear, indem Sie zur Laufzeit Cache-Server zum Cache-Cluster (der Caching-Ebene) hinzufügen können. Aber welche Leistungszahlen sollten Sie von einer Lösung wie dieser erwarten? NCache.
Hier sind NCache Leistungszahlen. Sie können voll sehen NCache Leistungsbenchmark .
Wie Sie sehen, ähnelt ein In-Memory Distributed Cache NCache Bietet eine Leistung von weniger als einer Millisekunde für Lese- und Schreibvorgänge und ermöglicht Ihnen die lineare Skalierung Ihrer Transaktionskapazität durch einfaches Hinzufügen weiterer Cache-Server.
Sehen wir uns nun an, wie ein In-Memory Distributed Cache aussieht NCache Behebt verschiedene oben erwähnte Skalierbarkeitsengpässe.
Mit Application Data Caching können Sie Ihre Datenbankengpässe beseitigen. In-Memory Distributed Cache wie NCache ermöglicht es Ihnen, Anwendungsdaten zwischenzuspeichern und teure Datenbankfahrten zu reduzieren. Sie können davon ausgehen, dass 70–90 % des Datenbankdatenverkehrs zum verteilten In-Memory-Cache umgeleitet werden. Dies verringert den Druck auf Ihre Datenbank und ermöglicht eine schnellere Leistung sowie die Bewältigung größerer Transaktionslasten ohne Verlangsamung.
Customer Load(string customerId)
{
// Key format: Customer:PK:1000
string key = "Customers:CustomerID:" + customerId;
Customer cust = (Customer) _cache[key];
if (cust == null)
{ // Item not in cache so load from db
LoadCustomerFromDb(cust);
// Add item to cache for future reference
_cache.Insert(key, cust);
}
return cust;
}
Abbildung 4: Verwendung des verteilten In-Memory-Cache für das App-Daten-Caching
Anwendungsdaten-Caching bedeutet, dass Sie alle Anwendungsdaten zwischenspeichern, die Sie aus Ihrer relationalen Datenbank erhalten. Dies geschieht normalerweise in Form von Domänenobjekten (auch Entitäten genannt). Hier ist ein Beispiel für die Verwendung eines verteilten Caches NCache für das Zwischenspeichern von Anwendungsdaten.
In-Memory Distributed Cache wie NCache ist auch ein großartiger Ort zum Speichern Ihres ASP.NET-Sitzungsstatus. Es ist viel schneller und skalierbarer als alle drei oben genannten Optionen (InProc, StateServer und SqlServer). NCache ist schneller, da es sich im Arbeitsspeicher befindet und eine Schlüsselwertschnittstelle bereitstellt, wobei der Wert ein „Objekt“ ist, das ein ASP.NET-Sitzungsstatus ist. Und es ist skalierbar, da es sich um einen verteilten Cache handelt.
Und, NCache Darüber hinaus repliziert es Sitzungen intelligent über seine umfangreichen Caching-Topologien, sodass selbst bei einem Ausfall eines Cache-Servers keine Sitzungsdaten verloren gehen. Diese Replikation ist erforderlich, weil NCache Stellt einen In-Memory-Speicher bereit und der Speicher verletzt den Speicher.
NCache Beschleunigt außerdem die Serialisierung des ASP.NET-Sitzungsstatusobjekts, die erforderlich ist, bevor es außerhalb des Prozesses gespeichert werden kann. NCache Dies geschieht mithilfe der Funktion „Dynamic Compact Serialization“, die zehnmal schneller ist als die reguläre .NET-Serialisierung. Sie können diese Funktion verwenden, ohne Codeänderungen vorzunehmen.
Sie können einstecken NCache Sitzungsstatusanbieter (SSP)-Modul zu Ihrer ASP.NET-Anwendung hinzufügen, indem Sie einige Änderungen in Ihrer web.config-Datei vornehmen, wie unten gezeigt.
<system.web>
...
<assemblies>
<add assembly="Alachisoft.NCache.SessionStoreProvider, Version=4.3.0.0,
Culture=neutral, PublicKeyToken=CFF5926ED6A53769" />
</assemblies>
<sessionState cookieless="false" regenerateExpiredSessionId="true"
mode="Custom" customProvider="NCacheSessionProvider"
timeout="20">
<providers>
<add name="NCacheSessionProvider"
type="Alachisoft.NCache.Web.SessionState.NSessionStoreProvider"
useInProc="false" cacheName="myDistributedCache"
enableLogs="false“ writeExceptionsToEventLog="false” />
</providers>
</sessionState>
...
</system.web>
Abbildung 5: Plug-in NCache als ASP.NET Session State Provider (SSP) in Web.Config
Wie das geht, habe ich bereits beschrieben ASP.NET View State ist eine verschlüsselte Zeichenfolge, die vom Webserver an den Browser des Benutzers gesendet wird, der sie dann im Falle eines HTTP-Postbacks an den Webserver zurücksendet. Aber mit Hilfe eines InMemory Distributed Cache wie NCache, können Sie dies zwischenspeichern ASP.NET View State auf dem Server und sendet stattdessen nur eine kleine eindeutige ID.
NCache hat eine implementiert ASP.NET View State Caching-Modul über einen benutzerdefinierten ASP.NET-Seitenadapter und ASP.NET PageStatePersister. Hier entlang, NCache fängt sowohl HTTP-Anfragen als auch -Antworten ab. Zum Reaktionszeitpunkt NCache Entfernt den „Wert“-Teil der codierten Zeichenfolge, speichert ihn zwischen und fügt stattdessen eine eindeutige Kennung (einen Cache-Schlüssel) in diesen „Wert“ ein.
Wenn dann die nächste HTTP-Anfrage eintrifft, fängt es diese erneut ab und ersetzt die eindeutige Kennung durch die tatsächliche codierte Zeichenfolge, die es zuvor im Cache abgelegt hat. Auf diese Weise bemerkt die ASP.NET-Seite keinen Unterschied und verwendet die codierte Zeichenfolge, die den Ansichtsstatus enthält, wie zuvor.
Das folgende Beispiel zeigt eine ASP.NET View State codierte Zeichenfolge ohne Caching und auch, was passiert, wenn Caching integriert ist.
//ASP.NET View State without Caching
<input id="__VIEWSTATE"
type="hidden"
name="__VIEWSTATE"
value="/wEPDwUJNzg0MDMxMDA1D2QWAmYPZBYCZg9kFgQCAQ9kFgICBQ9kFgJmD2QWAgIBD
xYCHhNQcm2aW91c0NvbnRyb2xNb2RlCymIAU1pY3Jvc29mdC5TaGFyZVBvaW50Lld
lYkNvbnRyb2xzLlNQQ29udHJbE1vZDA1XzRlMjJfODM3Y19kOWQ1ZTc2YmY1M2IPD
xYCHhNQcm2aW91c0NvbnRyb2xNb2RlCymIAU1pY3Jvc29mdC5TaGFyZVBvaW50Lld
lYkNvbnRyb2xzLlNQQ29udHJbE1vZDA1XzRlMjJfODM3Y19kOWQ1ZTc2YmY1M2IPD
... ==" />
//ASP.NET View State with Caching
<input id="__VIEWSTATE"
type="hidden"
name="__VIEWSTATE"
value="vs:cf8c8d3927ad4c1a84da7f891bb89185" />
Abbildung 6: ASP.NET View State Codierter String mit oder ohne Caching
ASP.NET bietet ein ASP.NET-Ausgabecache-Framework, um das Problem übermäßiger Seitenausführung zu beheben, selbst wenn sich die Seitenausgabe nicht ändert. Mit diesem Framework können Sie die Ausgabe entweder der gesamten Seite oder einiger Teile der Seite zwischenspeichern, sodass diese Seite beim nächsten Aufruf nicht ausgeführt wird und stattdessen die zwischengespeicherte Ausgabe angezeigt wird. Das Anzeigen einer bereits zwischengespeicherten Ausgabe ist viel schneller als das erneute Ausführen der gesamten Seite.
<caching>
<outputCache defaultProvider ="NOutputCacheProvider">
<providers>
<add name="NOutputCacheProvider"
type="Alachisoft.NCache.OutputCacheProvider.NOutputCacheProvider,
Alachisoft.NCache.OutputCacheProvider, Version=x.x.x.x,
Culture=neutral, PublicKeyToken=1448e8d1123e9096"
cacheName="myDistributedCache" exceptionsEnabled="false"
writeExceptionsToEventLog="false" enableLogs="true” />"
</providers>
</outputCache>
</caching>
Abbildung 7: Einrichten des ASP.NET-Ausgabecache-Anbieters für NCache in Web.Config
NCache hat einen ASP.NET Output Cache Provider für .NET 4.0 oder spätere Versionen implementiert. Dies ermöglicht Ihnen das Einstecken NCache nahtlos und ohne Programmieraufwand. Im Falle von NCacheDieser Anbieter ist für einen verteilten In-Memory-Cache gedacht, der sich über mehrere Server erstreckt. Wenn Ihre ASP.NET-Anwendung also in einer Webfarm mit Lastenausgleich ausgeführt wird, ist die von Server 1 zwischengespeicherte Seitenausgabe sofort für alle anderen Server in der Webfarm verfügbar. Unten erfahren Sie, wie Sie es anschließen können NCache als ASP.NET-Ausgabecache-Anbieter.
ASP.NET-Anwendungen mit hohem Datenverkehr können es sich nicht leisten, auszufallen, insbesondere während der Spitzenzeiten. Für diese Art von Anwendungen gibt es drei wichtige Architekturziele, die einem guten In-Memory Distributed Cache entsprechen NCache bietet. Sie sind:
Lassen Sie mich die einzelnen Bereiche im Folgenden erläutern.
Eines der wichtigsten architektonischen Ziele von NCache besteht darin, eine hohe Verfügbarkeit und Cache-Elastizität zu erreichen. Und das geschieht durch die folgenden architektonischen Fähigkeiten:
Da In-Memory Distributed Cache gefällt NCache Da es Speicher als Speicher verwendet, muss es eine Datenreplikation ermöglichen, um die Zuverlässigkeit sicherzustellen. Gleichzeitig darf die lineare Skalierbarkeit jedoch nicht beeinträchtigt werden, da dies der wichtigste Grund für die Verwendung eines verteilten Caches ist NCache.
Hier sind einige NCache Caching-Topologien die dazu beitragen, diese beiden Ziele zu erreichen.
Wie Sie sehen, legt Partitioned-Replica Cache eine Partition und ein Replikat auf jedem Cache-Server ab. Außerdem wird sichergestellt, dass sich das Replikat aus Gründen der Zuverlässigkeit immer auf einem anderen Cache-Server befindet.
Ich habe versucht, die häufigsten Leistungs- und Skalierbarkeitsengpässe hervorzuheben, mit denen ASP.NET-Anwendungen heute konfrontiert sind, und Ihnen zu zeigen, wie Sie diese mithilfe eines verteilten In-Memory-Cache überwinden können NCache. NCache ist ein verteilter Open-Source-Cache für .NET- und Java-Anwendungen. Sie können es also ohne Einschränkungen nutzen. Erfahren Sie mehr über NCache unter folgendem Link