Laden...

[Artikel] Die myCSharp.de Infrastruktur

Letzter Beitrag vor 6 Monaten 30 Posts 4.042 Views
[Artikel] Die myCSharp.de Infrastruktur

Stand: Februar 2021

Dieser Artikel behandelt die Infrastruktur - im heutigen Projekt-Speech oft Solution Architecture genannt - von myCSharp.de. Die Software Architektur ist hier beschrieben: [Artikel] Die myCSharp.de Software Architektur

Anforderungen an die Technik

Mit einer virtuellen Windows Server 2019 Maschine sowie einer 2-Kern MySQL-Instanz lieferte das Forum, bisher zwischen 300.000 und 1 Mio Anfragen pro Tag aus, wobei das potentielle Maximum bei circa 1.200 Requests pro Sekunde lag und eine PHP-Anfrage in durchschnittlich innerhalb 700 Millisekunden beantwortet wurde. Pro Monat wurden zwischen 100 und 200 GB an Inhalten ausgeliefert, wobei "nur" rund 7% aller Inhalte zwischengespeichert werden konnte.

Das von uns gesteckte Ziel ist es daher eine zukunftssichere Plattform zu haben, die wir selbst erweitern können, aber so wenig wie möglich selbst betreiben müssen, sondern stattdessen auf fertige Services und weiteren Automatisierungen setzen, die dabei auch noch eine bessere Performance bietet. Da wir die Kosten derzeit privat selbst übernehmen liegt dieser Punkt ebenfalls im Fokus, diese so gering wie möglich zu halten.

Zu beachten sei auch, dass besonders in den letzten Monaten - vermutlich Pandemie-bedingt, wie viele andere Wissens-Webseiten auch - es einen deutlichen Anstieg an Besuchern zu verzeichnen gab; wobei zu sagen sei, dass wir seit 2017 rund 50% mehr Besucher pro Tag verzeichnen können.

Disclaimer

Die von uns genutzten Services und Schnittstellen sind primär direkt für die Nutzung mit und von myCSharp.de gedacht. Sie basieren auf unseren Entscheidungen; bilden aber nicht zwangsläufig den einzigen Weg nach Rom ab. Sicherlich hätten für die ein oder andere Sache andere Services ebenfalls gepasst.

Cloud vs. Nicht-Cloud

Ein Web-Projekt wie myCSharp lässt sich problemlos in der Cloud wie auch On-Prem betreiben. Letzten Endes liegt zumindest aktuell die Entscheidung, welche Art und Weise für das Hosting verwendet wird, bei mir - und da ich die letzten 15 Jahre eigentlich nur im Cloud und hybriden Umfeld tätig war bzw. immer noch bin, lag die Entscheidung nahe, dass eine Cloud-only Variante verwendet wird.

Die Cloud-Variante sieht - wenn man die blanken €-Zahlen vergleicht - auf den ersten Blick teurer aus:* Eine virtuelle Nicht-Cloud-Maschine bekomme ich schon für eine Handvoll Euros.

  • Das Betreiben in der Cloud befindet sich deutlich im dreistelligen Bereich.

Trotzdem gehen wir den Cloud-Weg, da wir einfach keine / sehr viel weniger Schattenkosten durch Zeit haben, da wir die Systeme weder betreiben noch warten müssen: wir verwenden ausschließlich Managed-Services, die von Microsoft verwaltet werden und uns so Freizeit schenken.
Das ist uns mehr wert und wir können uns auf die wichtigen Themen konzentrieren.

Des weiteren bietet die Cloud ganz andere Skalierungsmöglichkeiten - in beide Richtungen.
Sollten wir "zu groß" gedacht haben, dann lassen sich sehr schnell Kosten sparen.

Die Location

Bisher wurde myCSharp aus dem Azure Rechenzentrum in West-Europa betrieben, was sich örtlich auf die Umgebung von Amsterdam bezieht. Grund war, dass dies das näheste Azure Rechenzetrum aus Deutschland war. Mittlerweile gibt es Azure Rechenzentren auch in Frankreich, Österreich, der Schweiz - und seit 2020 auch in Deutschland.
Ja, es gab bisher eine Private Azure Cloud in Deutschland, betrieben durch die Telekom; mittlerweile ist dies aber Geschichte.

Der Latenzgewinn, den wir nun durch das deutsche Rechenzentrum haben, beträgt zwischen 20 und 30 Millisekunden pro Request.

Der neue Service Stack

Betrieben wird myCSharp.de auf Microsoft Azure im Rechenzentrum Germany West, das sich in Frankfurt befindet.
Hierfür verwenden wir primär folgende Services:* Azure App Service for Linux für den Betrieb der Anwendung

Weitere Microsoft Services, die wir einsetzen:* GitHub für die Quellcode-Verwaltung

  • Azure DevOps für Continuous Integration sowie Continuous Deployment auf Azure

Des weiteren im Einsatz:* CloudFlare für die Verwaltung unserer Domain und den DNS-Settings

Noch im Einsatz:* Google Recaptcha (leider notwendiger Bot-Schutz; wird in naher Zukunft ersetzt)

Security Gateway

Ein Security Gateway ist ein absolutes Muss; nicht unbedingt gerade für eine Webseite, auf der man einen Koch-Blog betreibt - aber durchaus für Foren und jeder Art von Web-Plattform, die Anmeldedaten und Benutzerinhalte ausliefern bzw. annehmen.

Im Fall des Security Gateway hatten wir prinzipiell zwei Optionen, die in die nähere Auswahl kamen:* Azure Frontdoor *CloudFlare

Beide Produkte haben den Zweck einer Web-Application-Firewall, DDoS-Protection und andere Annehmlichkeiten den HTTP-Traffic zu steuern und zu überwachen. Für uns besonders relevant ist eben der DDoS-Schutz sowie der allgemeine Schutz, den eine Firewall bietet. Besonders Azure Frontdoor bietet Services, die genial für "große" Microservice-Plattformen sind; wir aber gar nicht haben.
Das wichtigste hier für uns ist vor allem das Erkennen bösartiger Requests: In der Vergangenheit wurde das Forum häufiger Ziel von "offenbar verärgerten Script-Kiddies", die versucht haben mit DDoS-Anfragen das Forum temporär lahm zu legen. Dank unseres Security Gateways können wir 9 von 10 solcher Attacken blocken, bevor sie die Anwendung erreichen.
*Dies erfolgt meist ganz ohne zutun; einzig eine DDoS-Attacke im Sommer 2020 musste manuell über CloudFlare geblockt werden, in dem wir die Anfragen aus einem bestimmten Land und einer deutschen IP geblockt haben. Durch die deutsche IP, die einem Webhosting-Anbieter zugeordnet werden konnte, konnten wir entsprechend weitere Schritte gegen die Angreifenden einleiten. Man ist halt doch nicht so anonym im Internet, wie viele denken 🙂*

In meinen Kunden-Projekten verwende ich ausschließlich Azure Frontdoor. Aber da für das Forum beide Varianten für uns einfach nutzbar waren lag es am Ende am Preis: CloudFlare bietet uns kostenlos, was wir benötigen. Azure Frontdoor hätte und zusätzliches Geld gekostet.
Im Fall von CloudFlare gibt es eine weitere nette Funktionalität: es gibt einen eingebauten Cache. Diesen nutzen wir für das Ausliefern von statischen Inhalten wie Icons, Bilder, Anhänge etc. Dies spart uns den Azure CDN Service (wobei dies nur wenige Cent sind, weil das echt spott-billig ist).

Der Nachteil der kostenlosen Variante von CloudFlare ist, dass wir - nachvollziehbar - den bezahlten Kunden hinten an stehen, was sich im Routing bemerktbar macht.
Normalerweise wird unsere Seite vom CloudFlare Endpunkt in Frankfurt an deutsche Besucher ausgeliefert. Ist auf Frankfurt aber entsprechend Last, dann erhalten bezahlende Kunden Priortät und es kann sein, dass unser Forum über Paris, Madrid oder London etc ausgeliefert wird und die Latenz entsprechend höher wird.

Portal Web App

Die "Portal Web App" ist einfach der interne Name unserer myCSharp.de Webapplikation und beinhaltet alles, was ihr auf mySSharp.de tun könnt.
Diese basiert auf .NET 5 und verwendet ASP.NET Core mit der MVC-Controller-Middleware. Des weiteren haben wir SignalR integriert, mit der wir in Zukunft Push-Benachrichtigen senden könnten bzw. wollen, zB. wenn eine private Nachricht empfangen wird oder man eine Antwort in einem Forenthema erhält.

Als Identity System nutzen wir die Schnittstellen der ASP.NET Core Identity, wobei wir die gesamte Implementierung selbst geschrieben haben. Das Ziel ist es hierbei, dass wir uns um das Loginsystem nicht kümmern müssen und wollen, sodass wir die maximale Sicherheit durch die native Integration in ASP.NET in unserer Webanwendung gewährleisten können.

Ich bin zwar ein großer Freund von Microservices und mache seit vielen Jahren auch kaum was anderes; die Anforderungen haben wir jedoch im Falle des Forums nicht, sodass das Portal prinzipiell wie klassische monolithische Webapplikation aufgebaut ist. Den Overhead hier können wir uns einfach sparen. Wir haben jedoch alle Inhalte in Module aufgeteilt (wir nennen sie "Features"), sodass eine isolierte Anpassung und Erweiterung jederzeit möglich ist.
Die Basis hierfür ist das strikte Einhalten der C# Namespaces.

Alle Aktionen innerhalb des Portals wurden mit Hilfe des CQRS-Patterns über MediatR umgesetzt. Dies wird näher im Artikel der Software Architektur erklärt, der aktuell noch in der Mache ist.

App Service

Wie bereits erwähnt verwenden wir .NET 5 als Runtime.

Dies ermöglicht es uns die Linux-Variante des Azure App Service zu verwenden, die technisch gesehen nichts anderes als ein Container mit einem Debian-Image darstellt. Als Webserver haben wir dahingehend nginx (durch das Debian-Image) sowie den Kestrel-Server innerhalb der .NET Pipeline.

Im Footer ist auch sichtbar, welche .NET Runtime und welche Hosting-Runtime verwenden.
Zum Zeitpunkt dieses Artikels: Running Version 0.1.247+24d2e41cb9 on Azure App Service (debian.10-x64 with .NET 5.0.1-servicing.20575.16)

Wir haben keinen direkten Einfluss auf die Runtime; jedoch auf die .NET 5 Version: wir veröffentlichen die Webanwendung mit dem Runtime-Zusatz, sodass wir von den vorhandenen .NET Runtimes unabhängig sind und immer unsere eigene Runtime mitbringen. Dies erhöht die Kompatibilität und macht uns vom App Service unabhängig.
Im Endeffekt entspricht dies der Empfehlung von ASP.NET Core Deployments; und hat nebenbei den Vorteil, dass wir eben Container-Ready sind, falls wir das irgendwann mal brauchen sollten.

Warum Linux?

Wir haben keinerlei Abhängigkeiten an Windows bzw. die Umgebung. Unsere Anwendung würde sowohl unter Windows wie auch unter Linux funktionieren und ist prinzipiell vollständig Container-Ready.
Sogar ein Betrieb auf dem Raspberry PI 4 wäre möglich, da selbst das Kompilieren als ARM-Anwendung problemlos möglich wäre.

Der Fakt ist, dass Linux-App Services viel günstiger sind als Windows-App Services.
Als Vergleich: * Der Windows App Service Basic kostet 6,4 Cent pro Stunde = ~46€ / Monat

  • Der Linux App Service Basic kostet 1,6 Cent pro Stunde = ~11€ / Monat

Wir haben also mit Linux eine viel günstigere Umgebung als mit Windows.
Der Hintergund ist, dass App Services mit Linux eben auf Containern basiert, diese sich effizienter Skalieren lassen und Microsoft damit ebenfalls weniger Kosten hat als mit Windows-Lösungen, die mit dem IIS Web Farms betrieben werden.

Des weiteren ist Linux in vielen Fällen (nicht allen!) die
schnellere Umgebung für ASP.NET Core Anwendungen; wir haben ca. 18% mehr Leistung mit dem App Service auf Linux.

Die Datenbank

Außer Frage stand, dass wir weg von MySQL wollen. Die Optionen für die zukunftige Datenhaltung waren: MSSQL, PostgreSQL oder die CosmosDB.

Mit CosmosDB hätten wir unsere Daten nicht-relational Speichern können, was ja die letzten Jahre extrem beliebt wurde - für unsere Daten so aber wenig Sinn gemacht hätte. Sicherlich lässt sich damit in Zukunft jedoch das ein oder andere sinnvoller realisieren, als es mit einer relationalen Datenbank der Fall wäre.
PostgreSQL wäre für uns aus Betriebskostensicht die mit Abstand günstigste Art und Weise für die aktuelle Datenhaltung gewesen. Das Problem hier hier ist aber ein wenig das Ökosystem: es gibt kein einheitliches DevOps Konzept.
Wir hätten für verschiedene Schritte der Entwicklung und des Deployments einfach verschiedene Tools benötigt, die wir in der MSSQL-Welt aus einer Hand bekommen.

Aber auch hier haben wir viel mehr Erfahrung mit MSSQL als mit anderen relationalen Datenbanken; daher hat Azure SQL trotz im Verhältnis 30% mehr Kosten klar die Nase vorn gehabt, da uns auch hier die Zeitersparnis und die Einfachheit wichtiger war.

Innerhalb der Runtime verwenden zwar primär Entity Framework Core 5; doch verzichten wir auf EF Migrations: EF Migrations fehlt es einfach an vielen Features, sodass wir für die Verwaltung des Schemas DACPACs verwenden. DACPACs haben ein vollständiges DevOps Konzept, ein wunderbares Tooling, eine exzellente Unterstützung in Azure DevOps sowie allgemein in Azure SQL - was EF Migrations leider nicht hat.
Meiner Meinung hat EF Migrations höchstens in der In-Process-Migration einen Vorteil; aber nicht bei einem Deployment, wie wir es benötigen.

Zusätzlich zum Entity Framework verwenden wir klassisch Stored Procedures. Ich bin kein mega Fan davon, aber in einigen Fällen sind sie einfach viel effizienter und wir sparen uns unnötige Round-Trips zwischen Applikation und Datenbank, sodass die Webseite - in einigen Fällen bei uns - insgesamt viel schneller ist.

Wie bereits angedeutet haben wir jedoch durchaus Ideen, die wir nicht zwangsläufig in relationaler Art und Weise speichern werden, sondern zum Beispiel im Azure Table Storage oder in der Azure CosmosDB.

Azure Active Directory

Azure Active Directory ist das primäre System für die Identitätsverwaltung in Azure. Mit einer Identität ist aber nicht unbedingt ein Benutzer gemeint, sondern auch jeder Service in Azure hat eine Identität. Dies ist bereits ein eingebautes Feature in jeder Azure Umgebung.

Wir verwenden die Identitäten (genauer gesagt System Identities) dazu, dass wir keine Credentials zwischen den Applikationen benötigen und uns so vielleicht ein Leck einholen. Diese Identität ist nicht abgreifbar und bildet den maximalen Schutz bei der Kommunikation zwischen Azure-Services.

Beispielsweise ist die Web-Anwendung als Identität in der Datenbank hinterlegt.
Dadurch kann auch wirklich nur die Web-Applikation auf die Datenbank zugreifen - und nichts anderes. Es können keine Credentials verloren gehen oder ausgenutzt werden.

Application Insights

Azure Application Insights ist ein Teil des Azure Monitor Services und dient der Live In-Process-Überwachung unserer Applikation. Managed Services wie unsere Datenbank oder unser Storage sind ebenfalls an den Azure Monitor angebunden, sodass ein einheitliches Monitoring aller Komponenten gewährleistet wird.

Application Insights haben wir über das Full Structured Logging Framework Serilog angebunden, das sich in die verschiedenen Pipelines der ASP.NET Middleware bzw. der .NET Hosting Service Middleware registriert.
Wir haben damit ein prinzipiell vollständiges Applikationslogging geschenkt bekommen.

In unserem Fall loggen wir jedoch auch weitere Telemetrieinformationen in Application Insights; zum Beispiel wie oft ein CQRS-Command ausgeführt wird, wie performant er ist und ob er vielleicht Exceptions wirft.
Mit diesem Operation-based Logging haben wir eine vollständige Einsicht wie gut unsere Applikation funktioniert und wie performant sie ist - und wissen genau, welche Dinge wir vielleicht nochmal überarbeiten sollten.

Application Insights ist durch ein JavaScript-Paket ebenfalls im Browser aktiv. Hier werden jedoch keinerlei personenbezogene Daten geloggt, sondern nur geschaut, wie lange braucht der Browser zum Rendern unseres HTMLs und werfen unsere externe eingebundenen JavaScript-Referenzen (zB. Bootstrap) vielleicht irgendwelche Fehler.

Azure Monitor

Der Azure Monitor überwacht alle Services, die wir in der Azure Plattform nutzen. Wir haben verschiedene Dashboards, mit denen wir verschiedene Metriken berechnen, anzeigen und Ungereimtheiten entdecken können.
Des weiteren haben wir in Azure Monitor Alerts angelegt: erreicht unsere Anwendung gewisses Limits oder wird dieses gar überschrieben, dann erhalten die Admins eine automatische Benachrichtigung, dass mal bitte nachgeschaut werden soll.

Auf Basis der Telemetrieinformationen haben wir uns ein Dashboard gebaut, mit denen wir alle Informationen in Echtzeit sowie historisch veranschaulichen können.
Das betrifft nicht nur die Performance, sondern auch Exceptions, Laufzeitverhalten, Anzahl von Ausführungen etc etc.

Des weiteren erkennen wir, ob und wo wir Exceptions haben, und durch welche Aktionen diese ausgelöst werden. Wir haben hier in den letzten 24 Stunden beim Schreiben des Artikels vor allem RateLimit Exceptions: hier hat also jemand versucht die Webseite öfter aufzurufen, als wir das pro Minute bzw. pro Stunde gestatten.
Die SQL bzw. Win32 Exceptions sind Datenbank-Timeouts, die durch einen derzeitigen Issue bei Azure SQL ausgelöst werden.

Die vielen 404-Fehler kommen überwiegend von Bots bzw. Threats: diese versuchen immer noch in einer relativ hohen Frequenz WBB / PHP Bugs auszunutzen

DevOps

Wir verwenden einen klassischen DevOps Prozess. Klassisch deshalb, da wir mit einem Dev-Test-Stage-Setup entwickeln, was in moderneren Cloud-Plattformen so eigentlich nicht mehr gemacht wird; hier wird vor allem mit Ring-based DevOps Setups gearbeitet.
Aber auch an dieser Stelle haben wir uns einfach den Overhead gespart. Ja, es ist zwar moderner: aber für uns hat das keinen Nutzen.

Wir arbeiten mit einem vereinfachten Pull Request Workflow.
Das bedeutet, dass jegliche Änderungen in Form eines Pull Requests gegen unseren Main-Branch erfolgt. Alle PR-Builds werden automatisch auf die Dev-Stage deployed.
Das ist bei Projekten mit wenig parallelen Pull Requests sehr simpel, hat wenig Overhead und man kann trotzdem alles während der Feature Entwicklung auf der echten Umgebung testen. Bei größeren projekten in Teams, die mehrere PRs parallel haben, ist das ein sehr unpraktisches Vorgehen, weil man sich die ganze Zeit gegenseitig den Stand auf dem Dev-System ersetzt, sodass damit nie jemand so wirklich damit testen kann.
In so einem Szenario ist es viel besser wenn man sich mit Hilfe von Infrastructure as Code isolierte Pull Request Umgebungen automatisch erstellen lässt. Auch hier haben wir uns den Overhead einfach erspart.

Wurde ein Pull Request akzeptiert, wird er entsprechend in Main gemerged. Daraufhin erfolgt automatisch das Deployment auf unsere Test-Umgebung, auf der wir final testen. Abschließend wird dann manuell auf die Produktivumgebung deployed bzw. mit dem Approval-Feature von Azure DevOps.

Aktuell arbeiten wir noch ohne Always-On Deployment, sodass wir aktuell eine kleine Downtime haben, wenn wir die Webseite neu deployen.
Das ziehen wir die nächste Zeit noch gerade. Daher kann es derzeit bei einem Deployment dazu kommen, dass nur "Offline" angezeigt wird, statt unser netter neuer Update-Screen.

Kosten

Bisher wurde das Forum auf einer virtuellen Windows-Maschine sowie mit einer Managed MySQL Instanz auf Azure betrieben. Dieses Setup war ohnehin teurer als das "Linux-Single-Virtual-Machine" Setup, wie es früher mal war - das war aber durchaus bewusst so; hatte dafür andere Vorteile, die insbesondere mir wichtiger waren.
Virtuelle Maschinen gehören zu den IaaS-Produkten; das Preismodell richtet sich also nach reservierten Ressourcen und nicht nach benötigter Leistung. Verhältnismäßig teuer ist eine virtuelle Maschine: unsere 4-Kern CPU lag bei 250€. Hinzu kam der Wartungsaufwand der Maschine in Form von Updates und Co.
Das MySQL Angebot bei Cloud-Plattform ist auch verhältnismäßig teuer: unsere Datenbankinstanz lag bei 220€ + 15€ für die Backups, wobei hier wenigstens keinerlei Wartungsaufwand angefallen ist. Hinzu kam der Traffic mit 10-200 GB und kleinere Kostenposten. Aber wie gesagt: ein Cloud-Angebot vergleicht man auch nicht nur auf Preis-Basis.

Für die neue Plattform haben wir den Cloud-nativen Ansatz umgesetzt, dadurch teure Cloud-Resourcen wie virtuelle Maschinen vermieden und damit so gut es geht (und soweit auch sinnvoll ist) entsprechend die Kosten optimiert; so teilen wir zum Beispiel Ressourcen über verschiedene Stages hinweg, was man in einer Business-Umgebung nicht tun würde.
Ansonsten sind alle Ressourcen so gut es geht isoliert.* Wir haben einen App Service Plan Premium mit Linux für alle 3 Stages

  • Wir haben einen App Service pro Stage (im Preis des Plans enthalten)
  • Wir haben pro Stage einen Datenbankserver mit einer Datenbank, wobei wir Dev und Test mit je 10-50 DTU und Prod mit 100-200 DTU betrieben
  • Wir haben drei Storage Accounts für statischen Dateien
  • Wir haben mehrere Regeln im Azure Monitor
  • Der Traffic schwankt zwischen 100 und 200 GB
  • Wir haben eine virtuelle Maschine (Ubuntu) für unsere automatischen Builds in Azure DevOps, also einen Self-Hosted Agent (drei Agents auf einer virtuellen Maschine, da uns zumindest aktuell die kostenlosen Minuten/Monat nicht ausreichen)
  • Wir haben verschiedene Domains für das Entwicklungs-, Test- und Produktivsystem

Mit diesem Setup können wir aktuell bis zu 18.000 Requests pro Sekunde beantworten, bevor wir weiter hoch skalieren müssten.
Als Vergleich: das alte Forum konnte mit vergleicherbarer Leistung circa 1.200 Requests pro Sekunde beantworten.

Zu beachten hierbei ist jedoch, dass die DB für Dev und Test nur 10 DTU haben, wenn sie nicht gebraucht werden und damit nur noch 15€ statt 77€ kostet.
Ebenfalls skaliert der App Service Plan auf S2, wenn wir die Leistung von S3 nicht benötigen.

Die reinen Betriebskosten (ohne Entwicklung, Zeit etc..) betragen daher zwischen 350€ und 500€ Brutto für den Entwicklungs- und Produktivbetrieb von myCSharp.de pro Monat.
*Dazu sei gesagt, dass wir das Forum noch günstiger betreiben könnten, wenn wir auf ein paar Annehmlichkeiten (keine Deployment Slots, kein automatisches Skalieren..) verzichten würden, sodass wir zum Beispiel statt einem Premium Plan für den App Service nur einen B2 bzw B4 Plan benötigen würden. Der Preis würde sich (für uns minimalster Skalierungsoption aller Services) auf 180€ drücken lassen.*

Performance

Wie bereits genannt können wir nun statt 1.200 bis zu 18.000 Requests pro Sekunde beantworten.

Das PHP-Forum hat 95% der Anfragen innerhalb 400ms beantwortet und 99% der Anfragen binnen 700ms.
Laut aktueller Metrik beantworten wir - also von Browser Request bis zur Server Antwort - mit der neuen Plattform 50% der Antworten binnen 2.5ms, 95% der Anfragen binnen 57ms und 99% der Anfragen binnen 270ms. Wir haben nur ein paar Ausreiser; viel weniger als gedacht.
Hinweis: im Footer geben wir die Zeit aus, die unser Code braucht, um eine Ansicht zu generieren.

Verantwortlich für die extrem gute Performance ist, dass unsere Datenbank sehr gut indiziert ist und damit die kürzesten Antwortzeiten ermöglichen sowie dem sehr großen Fokus auf Performance in der .NET Runtime während der Entwicklung. Hier hat vor allem gfoidl wahnsinnige Fortschritte ermöglicht.
Das Grundprinzip war hier, dass immer so wenig wie möglich allokiert werden muss während so viele Dinge wie möglich wiederverwendet und nicht bei jedem Request neu instanziiert werden muss. Des weiteren haben wir sehr darauf geachtet, dass der sogenannte Hot Path - also Quellcode, der mit jedem Request ausgeführt wird - extrem effizient ist und niemals blockiert.

Wir haben also unterm Strich eine wirklich sehr gute Performance erreicht.
Hier nochmal vielen Dank an gfoidl, der das maßgeblich möglich gemacht hat!

Wie wir Performance messen

Wir messen Performance vor allem auf zwei Arten:* Theoretische Performance mit Hilfe von .NET Benchmarks, die vor allem dazu dienen, die Runtime-Performance zu maximieren

  • End-zu-End Performance, die wir mit Hilfe von Lasttests durch K6 messen

Alle anderen Performance-Metriken ermitteln wir einzig und alleine durch Application Insights. Wir werden dann aktiv, wenn wir ein Problem identifizieren.
Denn premature optimization is the root of all evil 😉

Solltet ihr noch Fragen haben oder wenn wir auf einzelne Dinge weiter eingehen sollen, dann schreibt einfach in dieses Thema.
Das Thema bleibt dauerhaft bestehen; ein Changelog im ersten Beitrag wird entsprechende Anpassungen aufzeigen.

Sehr interessante Beiträge Abt!

Spannend finde ich, dass Ihr die ASP.NET Core App auf einem Linux-Server hostet.

Wo seht Ihr die Nachteile eines Linux-Servers gegenüber einem Windows-Server im Bezug auf eine ASP.NET Core Anwendung?

  • Der IIS ist ja schon sehr ausgereift. Wie sicher schätzt Ihr den Kestrel-Server ein?
  • Wie handelt Ihr das SSL/TLS Zertifikat?
  • Gibt es Features die Ihr vermisst?
  • Performance: IIS in-process, etc.

Cloud-Hosting scheint mir immer noch sehr teuer zu sein.
Bei Hetzner krieg ich einen "Dedicated Root Server" ab ca. 70 Euro mit Top Hardware (inkl. Windows Server 2019 Standard Edition).

Wo seht Ihr die Nachteile eines Linux-Servers gegenüber einem Windows-Server im Bezug auf eine ASP.NET Core Anwendung?

Gibt es Features die Ihr vermisst?

Es gibt keine Feature Unterschiede von ASP.NET zu Windows oder Linux.
Und die Performance unter Linux ist in den meisten Fällen viel besser als unter Windows (siehe oben), was maßgeblich am Thread Handling liegt, das unter Linux einfach performanter ist..
Oder auch TechEmpower Web Framework Benchmarks.
Davon abgesehen hat der IIS eine geringere Performance als nginx.
nginx schlägt den IIS in den meisten Benchmarks sowohl in Sachen Memory Usage wie auch in Sachen RPS.

Den meisten Performance-Impact wird aber immer schlechte Programmierung darstellen, weniger das OS.

Die Nachteile von Windows für eine einfache ASP.NET Anwendung ist natürlich, dass Du Windows-Standard Ressourcen hast, die Du gar nicht brauchst und Dir natürlich von den zur Verfügung stehenden Ressourcen abgezogen wird.
Und natürlich hast Du bei einem ganzen Server viel mehr potentielle Risiken, als bei einem Web-Only Angebot.

Deinen Server kann jemand knacken; unsere Umgebung nicht (btw. nur wenn Du die Azure Infrastruktur knackst).

Wie sicher schätzt Ihr den Kestrel-Server ein?

Der Kestrel ist nur ein Reverse Proxy. Egal ob auf Linux hinter nginx, auf Windows mit IIS: Der Kestrel ist immer im Spiel (ausser Du willst den WebListener verwenden, der nur noch aus Legacygründen da ist und nur unter Windows funktioniert).
Technisch gesehen kannst Du auch völlig ohne nginx / IIS direkt mit dem Kestrel arbeiten; hast dann aber nicht die Features eines vorgeschaltenen Webservers.
Daher gibt es aus Sicherheitssicht mit dem Kestrel null Unterschied zwischen nginx und IIS.

Edit kleine Korrektur:
Ja, im IIS kannst Du auch ohne Kestrel mit In Process arbeiten.
Das hat aber nur Auswirkung auf die Performance, nicht auf die Sicherheit.

Wie handelt Ihr das SSL/TLS Zertifikat?

Versteh die Frage nicht.

Bei Hetzner krieg ich einen "Dedicated Root Server" ab ca. 70 Euro mit Top Hardware (inkl. Windows Server 2019 Standard Edition).

Das ist das, was ich oben geschrieben hab: Wenn Du nur den Euro vergleichst, dann vergleichst Du Äpfel mit Birnen; Du vergleichst unmanaged IaaS Hosting vs. managed PaaS Hosting.

Wenn Du rein IaaS vergleichen willst, dann musst Du Managed vs. Managed vergleichen.
Gleiches Spiel für PaaS. Aber IaaS vs. PaaS ist halt Käse.

Bei Deinem Hetzner IaaS Angebot fehlen Dir ja dutzende von Features, was Dir Managed Hosting von Azure (odder AWS / GCP) hier bietet.
Ob Du das brauchst; das steht auf einem anderen Blatt.

Ich (als rechtlicher Vertreter) will so wenig Wartungsaufwand (kostet Freizeit) und rechtliches Risiko (Leaks, Hacks... kostet Zeit in der Planung, Ausführung und sollte es mal eintreten) wie möglich.
Daher kommt ein IaaS Angebot für mich absolut nicht infrage. Ein Managed Angebot nimmt mir hier alles / das meiste ab.
Managed ist daher auch eine Versicherung, dass eben nichts passiert. Und nichts hab ich weniger wie Zeit 😉

Und die Performance unter Linux ist in den meisten Fällen viel besser als unter Windows

Interessant. Wusste ich nicht.

Wie handelt Ihr das SSL/TLS Zertifikat?

Mit "LettuceEncrypt" soll das ja automatisch gehen. Aber eben nur wenn keine WebServer vorgeschaltet ist. Mit dem IIS voran geht das ja leider nicht.

Bei Deinem Hetzner IaaS Angebot fehlen Dir ja dutzende von Features, was Dir Managed Hosting von Azure (odder AWS / GCP) hier bietet.

Würde mich interessieren, welche Features lohnenswert sind.

Bei den meisten meiner Web-Apps brauche ich in der Regel nur den SQL-Server Express und ein Mail-Server (MailEnabled) drauf.
Remote-Desktop Zugriff sehr praktisch. Kann mir gar nicht vorstellen wie das ohne gehen soll 😉.
Nehme an, bei Azure connecte ich direkt mit meinem lokalen SQL Server Management Studio zur DB?

Mit "
>
" soll das ja automatisch gehen.

Das kannst Du nicht pauschal anwenden - und kannst Du nicht in Azure anwenden.

In Azure musst Du das Zertifikat beim Domain Setup als SSL Binding hinterlegen.
Dafür gibt es auch (wenn man will) einen direkten Automatismus für LetsEncrypt Zertifikate.

In unserem Fall haben wir ein eigenes Zertifikat, das in CloudFlare hinterlegt ist.
So ist deren Full / Strict SSL aufgebaut. Ohne CloudFlare hätten wir einfach den in Azure eingebauten Lets Encrypt Automatismus.

Würde mich interessieren, welche Features lohnenswert sind.

  • Azure Monitor
  • Azure Security Center
  • Azure Application Insights
  • Alles rund um die Konfiguration, Credential, Security, DevOps und Co

Alles Produkte, die nur Cloudanbieter in dieser Form von Haus aus bieten - und das eben eingepreist im Service. Nutzt Du das geniale Zeug nicht, dann zahlst es halt trotzdem. Aber eigentlich nutzt es halt auch in Azure und den anderen Clouds jeder, weil das einfach mitterlweile selbstverständlich in der Cloud ist.
Auf eigenen Servern ist die einzige echte Alternative in meinen Augen Retrace - und das lassen sie sich gut bezahlen. Und ja, On Prem hat man ein ganz anderes Verständnis davon, was "selbstverständlich" ist - sehe ich jeden Tag bei meinen Kunden.
On-Prem IT fühlt sich für mich oft an wie 80er Jahre.

Wir wissen exakt, welcher User (also unsere administrative Tätigkeit, nicht bezogen auf myCSharp User) in welcher Umgebung aktiv ist. Wir haben Automatismen und Alerts, wenn Unregelmäßigkeiten entdeckt werden (zB unüblicher Login).
Viele denken: wozu? Und ja, ist wie eine Versicherung: Du lernst es zu schätzen, wenn Du es brauchst. Aber Du hast immer die Sicherheit und Gewissheit.
Die Sicherheitsfeatures und Automatismen sorgen dafür, dass nichts passieren kann. Wir erhalten Hinweise, wenn wir irgendwo tätig werden muss, erzahlen automatische Empfehlungen für Security, Performance und Co.
Sollte doch etwas passieren, dann haben wir Alerts, sodass wir Zeug so schnell wie möglich fixen.
Ohne das Zeug hast Du keine Ahnung, was bei Dir in der Umgebung abgeht. Und dann muss man sich nicht wundern, wenn Firmen entdecken: "ups, wir haben seit Monaten einen ungewollten Besucher in unserer Umgebung", wie derzeit CD Projekt: »Cyberpunk 2077«: CD Projekt wird erpresst - DER SPIEGEL

Wir wissen exakt was in unserer Anwendung Performance kostet, wo Fehler sind, wir gut sind (erfreut gfoidl derzeit sehr), um weitere Optimierungen zu machen.
Ohne solch eine Software (welche auch immer) arbeitest Du bei Performance-Optimierungen oder der Fehlersuche im Blindflug.
Wer einmal mit so einer Software gearbeitet hat, der will das immer haben.

Bei den meisten meiner Web-Apps brauche ich in der Regel nur den SQL-Server Express

Ja, das ist es: Du siehst nur die primären Dinge, nicht die sekundären.

Du musst bei Deinem Setup manuell die Anwendung konfigurieren (oder Drittanbieter-Software verwenden), wir haben App Configurations und Azure Key Vault für Credentials.
Wir wissen genau, welche Credentials wann und von wem geändert oder gesehen wurden, wir können exakt steuern welche Anwendung unsere Credentials kennt.
Für den Zugriff auf unsere Datenbank gibts gar keine Credentials, die man verlieren kann:

  • Die Anwendung greift über die System Identity zu, die unfälschbar ist
  • Wir greifen auf die DB über den Active Directory Account zu, der bei jeder Aktion eine Zwei-Faktor Auth will und zusätzlich von der Firewall gesichert ist.

Bei Dir kann jeder alle Inhalte und alle Credentials sehen, der auf die VM kommt: und die VM ist vermutlich nicht mit einem AAD verbunden und hat daher auch keine 2 Faktor Authentifizierung 😉
> Du hast keinerlei Möglichkeit zu schauen, wer aktuell (unbemerkt) auf Deiner VM ist.
> Du kannst Credentials verlieren und generell sind sie ungeschützt
> Du musst überall manuell zugreifen

Bei einem Hosting Anbieter musst Du eine VM über nen Zeitraum buchen, damit auch fixe Ressourcen für einen Zeitraum planen.
Wir erkaufen uns natürlich auch Flexibilität: wir können im Sekundentakt die Skalierung ändern, wo Du Dich vermutlich 12 Monate gebunden hast.

und ein Mail-Server (MailEnabled) drauf.

Mögen die meisten Spam-Filter überhaupt nicht (und ist bei den meisten VM Anbietern auch deaktiviert).
Mails verschicken kann man entweder via SMTP über nen eigenes Postfach (so machen wir es) oder auch extrem günstig über Amazon Simple Mail Service.

Remote-Desktop Zugriff sehr praktisch. Kann mir gar nicht vorstellen wie das ohne gehen soll

Braucht man nicht, wenn man keinen Server administrieren muss. Und das ist es ja: in der Cloud willst Du eigentlich so wenig IaaS wie möglich.
IaaS kostet Geld und IaaS kostet Zeit und Wartung.

Auf IaaS Ebene hast nur IaaS DDos Schutz; wir habens auf App-Ebene.
Ich will mich doch nicht um OS Lücken kümmern, sorgen dafür, dass irgendwelche Firewalls korrekt eingestellt sind, dass Patches in Windows kommen: ich will mich um die Anwendung kümmern und nicht um den Overhead.
Und natürlich zahle ich dafür, dass Microsoft tausende von Mitarbeitern haben, die dafür sorgen, dass die Plattform sicher und dauerhaft läuft.
Das zahlst Du bei Dedicated Hosting nicht; da zahlst Du nur Strom und die Hardware, sonst nix.
Security, Patches, Zeit und Co: alles Dein Problem.

Wenn man aber doch eine virtuelle VM hat, dann hat man entweder Azure Bastion (RDP über den Browser) oder eben RDP/SSH.

Nehme an, bei Azure connecte ich direkt mit meinem lokalen SQL Server Management Studio zur DB?

Azure ändert hier nicht die direkte Arbeitsweise, sondern primär den Betrieb und die Sicherheit.

Gibt sowohl im Azure Portal ein DBM Lösung (basiert auf Azure Data Studio) oder eben Management Studio.
Ansonsten erfolgt die gesamte Verwaltung über das Azure Portal.

Wenn Du von Außen auf Deine SQL Datenbank zugreifen willst dann heisst das automatisch, dass Deine DB direkt im Internet hängt: und es gibt aus Sicherheitssicht nichts schlimmeres, als eine Datenbank, die mit eigenem Benutzersystem direkt vom Internet aus zugreifbar ist (was übrigens bei allen Cloud-Providern aus Sicherheitsgründen nicht geht).

Bei den meisten meiner Web-Apps brauche ich in der Regel nur den SQL-Server Express und ein Mail-Server (MailEnabled) drauf.
Remote-Desktop Zugriff sehr praktisch. Kann mir gar nicht vorstellen wie das ohne gehen soll 😉.
Nehme an, bei Azure connecte ich direkt mit meinem lokalen SQL Server Management Studio zur DB?

Ich kann da auch jeden nur empfehlen Azure mal auszuprobieren.
Habe das vorher auch immer nur mit Docker auf eignen Servern aufgesetzt
und war von Azure und dem Funktionsumfang abgeschreckt.
Aber wenn man es mal mit einem kleinen Projekt (Web App + Datenbank) testet, merkt man schnell wie viel Aufwand und Overhead man sich da sparen kann 😁 Auch einrichten von GitHub Actions und automatisches deployen...

Mit einem Studentennachweis kann man sogut wie alles 1 Jahr ++kostenlos ++testen (im entsprechenden Umfang)

Sehr schöner Artikel.
Leider fehlt mir zu viel Backgroundwissen um das ganze irgendwie in eine brauchbare Relation zu packen.
Ich muss mich mal in die einzelnen Tools einlesen.
Insgesamt arbeite ich aber auch nicht im Cloud Bereich, privat schon gar nicht.
Aber denoch Hut ab für die ganze Leistung.

@Abt
Soweit ich mleadb verstanden habe, meint er eine reine Root Server Umgebung.
Also direkt Webserver und DB auf Hardware ohne zusätzliche VM.
In deiner Antwort scheinst du davon auszugehen, dass er eine VM mietet.

Aber selbst diese würde bei Hetzner keine 12 Monate Bindung bedeuten.
Das war vor 10+ Jahren so, dass man hier teilweise 12 Monate einen Vertrag bei den Hostern abschließen musste.
I.d.R. hat man hier einen Monat mindestens als Laufzeit für VM und Root Server.

Hab selbst meinen zweiten Root Server bei Hetzner, deshalb kann ich da bei Root Servern eher aus dem Nähkästchen quarken.
Aber wenn man wirklich den ganzen Admin Teil nicht machen will, dann macht halt Cloud auch mehr Sinn.
Egal ob VM/Root Server, am Ende muss man sich dabei um alles selbst kümern.
Bei der Cloud liegt dieser Administrative Part eben bei dem Anbieter.

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.

Also direkt Webserver und DB auf Hardware ohne zusätzliche VM.
In deiner Antwort scheinst du davon auszugehen, dass er eine VM mietet.

Spielt für den Anwendungsfall hier keine Rolle bzw. ist es kein Unterschied.
Eine dedizierte Hardware hat rechnerisch sogar noch eine höhere Ausfallwahrscheinlichkeit wie eine virtuelle Maschine.

Aber selbst diese würde bei Hetzner keine 12 Monate Bindung bedeuten.
Das war vor 10+ Jahren so, dass man hier teilweise 12 Monate einen Vertrag bei den Hostern abschließen musste.
I.d.R. hat man hier einen Monat mindestens als Laufzeit für VM und Root Server.

Egal ob 1, 3, 12 oder 200 Monate. Du hast eine Bindung an die Ressource und kannst nicht frei skalieren.
Frei skalieren heisst "sofort".

Der genauer Bezeichner hier ist Hyper-Scaling: genau der Faktor, der eine Cloud von einem "Standard" Hosting unterscheidet.
Hyperscale computing

Aber nochmal als Betonung: natürlich gibt es Anwendungsfälle, bei denen dedizierte Maschinen Sinn machen und die Cloud zu teuer ist / andere Nachteile hat.
Der Artikel beschreibt ja eben, warum das für uns keinen Sinn macht, weshalb wir Vorteile für uns sehen und begründet dieses.

Mails verschicken kann man entweder via SMTP über nen eigenes Postfach (so machen wir es) oder auch extrem günstig über Amazon Simple Mail Service.

Wo habt Ihr das Postfach den "gehostet"?
Bei vielen Mails (> 200 Mails/Tag) scheint mir das keine Lösung zu sein.

Mögen die meisten Spam-Filter überhaupt nicht (und ist bei den meisten VM Anbietern auch deaktiviert).

Das mit dem Spam-Filter ist tatsächlich immer so eine Sache 🤔
Direkt verschicke ich die Mails natürlich auch nicht. Das wäre der sichere tot für meine Website 😉
Ein zuverlässiger Mailversand ist ein absolutes Muss.

SMTP relay service - MailChannels - 80$ für 40'000 Mails/Monat
Funktioniert tadellos. Kann den Service auch gleich für mehrere Domains nutzen.

Wo habt Ihr das Postfach den "gehostet"?

Noch als Standard 1und1 Postfach.
Aber das leistet locker mehrere tausend Mails am Tag.

SMTP relay service - MailChannels - 80$ für 40'000 Mails/Monat

Würde mit Amazon SES 3€ kosten, siehe Amazon SES Preiskalkulator
Ist der mit Abstand günstigste Service für das Verschicken von Mails.

Würde mit Amazon SES 3€ kosten, siehe Amazon SES Preiskalkulator

Das wäre in der Tat sehr günstig. Muss ich mal genauer anschauen. Meine Devise derzeit "never toch a running system" 😉

Ich bin zwar ein großer Freund von Microservices und mache seit vielen Jahren auch kaum was anderes; die Anforderungen haben wir jedoch im Falle des Forums nicht, sodass das Portal prinzipiell wie klassische monolithische Webapplikation aufgebaut ist.

Würde mich genauer interessieren wie Ihre euer Projekt strukturiert habt.

Ich selber fahre mit der "Features Folder"-Struktur sehr gut. (Ist ja eigentlich auch ne Art Microservices)
Finde das Standart-Template ("Tech Folders") (Controllers/Models/Views,etc.) einfach schrecklich.
Irgendwann kommst du an einen Punkt, wo die Übersichtlichkeit einfach stark leidet.

Alle Aktionen innerhalb des Portals wurden mit Hilfe des CQRS-Patterns über MediatR umgesetzt. Dies wird näher im Artikel der Software Architektur erklärt, der aktuell noch in der Mache ist.

Ein Artikel dazu fände ich spannend.
Nutze zwar nicht das MediatR. Jedoch ist es IMO schon Pflicht, die Submit-/ViewModels ModelBuilding und CRUD-Operationen in separate Klassen auszulagern.

Ich selber fahre mit der "
>
"-Struktur sehr gut. (Ist ja eigentlich auch ne Art Microservices)

Wir bzw. ich verwende dieses Grundkonstrukt in jeder meiner Applikationen; auch für myCSharp.
Nur eben in einer individualisierteren bzw. weiterentwickelten Variante.

Aber dazu kommt ein extra Artikel.

Finde das Standart-Template ("Tech Folders") (Controllers/Models/Views,etc.) einfach schrecklich.

Keiner zwingt Dich das zu übernehmen; aber es macht halt auch wenig Sinn Feature Folders für ein Scaffolding anzubieten.
Templates sollen simpel sein, unabhängig und nur die Technik zeigen.

Aber dazu kommt ein extra Artikel.

👍

Es sieht ja so aus als würdet Ihr keine Client-Side Framework wie Angular/React/Blazor-Wasm verwenden.
Was waren die Gründe dagegen?

Finde Blazor-Wasm schon sehr interessant. Das Prerendering ist schon sehr nice gelöst.
Leider die Download-Grösse (Trimmed ~2-3MB)... naja.
Bin gespannt wies um die Zukunft von Blazor (Wasm) steht.

Blazor-Server ist mir leider wieder zu sehr "WebForms". Da geschehen zuviele Dinge im Hintergrund... (z.B auch die dauerhafte SignalR-Connection).

Weil Webseiten mit statischem Content extrem abhängig vom SEO sind und Suchmaschinen SEO (besser) indizieren, wenn dies server-seitig passiert.

Das heisst, dass wir so oder so immer eine Server-seitige Auslieferung von Inhalten benötigen.
Viele SPA Webseiten rendern daher inititale Requests auch Server-seitig. Für Angular gibts hier SSR über Angular Universal.
Eine SPA wäre also ein zusätzlicher Aufwand; der Nutzen jedoch eher gering.

Weil Webseiten mit statischem Content extrem abhängig vom SEO sind und Suchmaschinen SEO (besser) indizieren, wenn dies server-seitig passiert.

Das meinte ich eben mit dem PreRendering. (Bei Blazor-Wasm ist das mit Dependency-Injection sehr gut gelöst)
Damit hätte man das SEO Problem eigentlich behoben.

Tue mich da noch etwas schwer von den normalen MVC-Views wegzukommen (ebenfalls wegen SEO).

Nur Google unterstützt derzeit WASM für den Google Bot.
Ändert also am generellen SEO Problem derzeit nichts (wenn Du mehr beachtest als Google).

Ankündigung für die Infrastruktur:

Wie oben zu lesen verwenden wir derzeit aus Kostengründen CloudFlare CDN.
Microsoft hat mit dem Azure Frontdoor nun jedoch auch eine Standard-Variante im Angebot (aktuell im Preview), die 14€ im Monat kosten wird, was in unserem Fall die deutlich bessere Wahl des bisherigen Serverless-Angebots der Frontdoor ist (in unserem Fall einfach viel zu teuer).

Sobald Azure Frontdoor Standard GA ist werden wir darauf migrieren und die CloudFlare Middleware deaktivieren.
Damit sollten die aktuellen Request-Time-Issues (TTFB ist relativ hoch, weil CloudFlare uns über Paris bzw. Kopenhagen leitet statt über Frankfurt) auch behoben sein.

Mit der Preview-Variante haben wir bereits ein Frontdoor-Testsetup gebaut, und das funktioniert sehr gut und hat sehr gute Performance-Ergebnisse.

Mal locker 100ms eingespart, ist schon ein großer Unterschied.

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.

wenns nur 100 ms wären...

Wir haben teilweise Request, die 5 Sek kosten, weil das SSL Handshake und TTFB zu CloudFlare so lange dauert.
Vor allem beim ersten Request des Besuchers >12h. Ebenso der Fall von stalled connections.

Bei einem durchschnittlichen Request (siehe Screenshot) lassen sich von 279ms einfach 240ms wegoptimieren - nur durch anderes Routing.

Seit gestern wird die Applikation (mycsharp.de) nicht mehr von CloudFlare geschützt, sondern von Azure Frontdoor.
Dies war eine geplante Maßnahme, da wir ohnehin langfristig von CloudFlare weg wollten.

Vorteile:* Die Anwendung ist insgesamt schneller, weil Azure Frontdoor ein sogenannter Edge Service ist: das Microsoft Global Network hat fast 200 Netzwerk-Einstiegspunkte (Point of Presence Sites), um möglichst schnell vom öffentlichen in das private Microsoft Netzwerk einzutauchen. Mit entsprechend höherer Bandbreite und Azure Optimierung. Wer also zB in München wohnt, der kommt ab sofort zB über München in das Azure Netz und wird nicht zuerst über CloudFlare Frankfurt oder Paris geroutet.

  • Da wir nun den eingebauten Azure Mechanismus nutzen, können wir die Azure Web App so einstellen, dass ein Zugriff nur noch über die Frontdoor möglich ist; es gibt kein bypass mehr (also basierend auf den CF IPs und Access Restrictions wäre das auch vorher gegangen, aber is halt erhöhter Aufwand - jetzt ist es eine Zeile Konfiguration).
  • Wir haben drei Meldungen bekommen, dass es im CloudFlare ab und zu HTTP 525 Errors gibt. Es gibt dazu auch einen Artikel und betroffen war nur der Zugriff zwischen CF und dem App Service (nicht statische Dateien) - aber der Grund ist mir trotzdem unbekannt. Der Fehler sollte nun aber nicht mehr auftauchen.
  • Wir haben mehr Möglichkeiten, was das Thema Protection, Caching und Compression betrifft

Nachteile* Wir haben bisher das Free Modell von CloudFlare verwenden. Azure Frontdoor (wir verwenden Standard) ist ein SaaS Service und kostet nun halt etwas.

  • Die Frontdoor Konfiguration ist im Vergleich etwas (zu) kompliziert
  • Im Gegensatz zu CF hat Azure Frontdoor keine Metric, wie viele User in einem Zeitraum (Stunde, Tag, Woche, Monat...) oder aktuell auf der Webseite sind. Müssen wir nun selbst machen.

Der CDN (cdn.mycsharp.de) liegt (vorerst) weiterhin bei CloudFlare.

Kleines Update zur Architektur: wir verwenden nun den Azure Communication Service, der seit Kurzem auch einen Datenstandort in Deutschland hat, für das Versenden von E-Mails. Der bisher eigene (gesicherte) SMTP-Endpunkt wurde damit ersetzt. Kam uns gelegen, da es ab und zu auch zu nicht zugestellten E-Mails kam, was nun der Vergangenheit angehören sollte.

Zudem werden unsere E-Mails nicht mehr von einer Custom ASP.NET Core Razor Engine gerendert, sondern mit der Hilfe von Handlebars.net, was uns sowohl das Rendern selbst wie auch das Testen deutlich vereinfacht.

Update zur Architektur:
Seit einiger Zeit haben wir aus einer handvoll Ländern automatisierte Bot und Spam-"Angriffe", weswegen wir diese Länder - aus denen wir quasi keine regulären Zugriffe erwarten - blockiert.

Genaue Details zu Länder und Regel-Implementierung lass ich mal aus Gründen weg.