Übung: Umgestalten eines Diensts in der monolithischen Architektur in einen Microservice

Abgeschlossen

Nachdem Fabrikam die Anwendung analysiert hat, kann der Refactoringprozess gestartet werden, um Dienste aus der monolithischen Architektur in Microservices zu verschieben. Ändern Sie die Anwendung, um den Paketverarbeitungsdienst in einen Microservice zu verschieben.

Visualization of the resources for the Drone Delivery application.

Refactoring der Anwendung

Bevor wir die aktualisierte Anwendung bereitstellen, werfen wir einen Blick darauf, wie sie aktualisiert wurde. Die monolithische App verfügt mit PackageProcessor.cs über einen Dienst zum Verarbeiten von Paketen. Nachdem die Leistung der Anwendung analysiert wurde, wurde dieser Dienst als Leistungsengpass identifiziert. Wenn der Bedarf an Drohnenlieferungen aufgrund der hohen Kundennachfrage steigt, wird dieser Dienst während der Verarbeitung der Planung und Logistik für Drohnenlieferungen stark ausgelastet. Dieser Dienst wird vollständig von einem dedizierten Team verwaltet. Die Verlagerung zu einem Microservice verbessert daher die Leistung und die Flexibilität bei der Entwicklung.

Wir betrachten die Änderungen, die wir vorgenommen haben, nun etwas genauer.

Drohnenlieferungsanwendung vorher

Die Kernfunktionen der Paketverarbeitung werden von der PackageProcessor-Klasse in der PackageProcessor.cs-Datei gehandhabt. In diesem Beispiel werden einige ressourcenintensive Aufgaben ausgeführt. Ein praxisorientiertes Szenario könnte die Berechnung von Lieferzeiten und Lieferrouten sowie das Aktualisieren von Datenquellen mit diesen Informationen umfassen.

public class PackageProcessor : IPackageProcessor
    {
        public Task<PackageGen> CreatePackageAsync(PackageInfo packageInfo)
        {
            //Uses common data store e.g. SQL Azure tables
            Utility.DoWork(100);
            return Task.FromResult(new PackageGen { Id = packageInfo.PackageId });
        }
    }

Wenn die Anforderungen für diesen Dienst zunehmen, erhöht sich die Ressourcennutzung. Diese wird daher auf die physischen Ressourcen begrenzt, die der monolithischen Anwendung zugeordnet sind. Wenn dieser Dienst in Azure App Service bereitgestellt wird, können wir ihn zentral und horizontal hochskalieren. Im Idealfall sollte diese stark genutzte Ressource unabhängig skaliert werden, um Leistung und Kosten zu optimieren. In diesem Szenario verwenden wir hierfür Azure Functions.

Drohnenlieferungsanwendung nachher

Sehen wir uns den DroneDelivery-after-Anwendungscode an, bevor wir ihn bereitstellen. Sie können sehen, dass die PackageProcessor-Klasse in eine PackageServiceCaller-Klasse geändert wurde. Zwar wird noch immer die IPackageProcessor-Schnittstelle implementiert, aber stattdessen wird ein HTTP-Aufruf an den Microservice durchgeführt.

public class PackageServiceCaller : IPackageProcessor
    {
        private readonly HttpClient httpClient;

        public static string FunctionCode { get; set; }

        public PackageServiceCaller(HttpClient httpClient)
        {
            this.httpClient = httpClient;
        }

        public async Task<PackageGen> CreatePackageAsync(PackageInfo packageInfo)
        {
            var result = await httpClient.PutAsJsonAsync($"{packageInfo.PackageId}?code={FunctionCode}", packageInfo);
            result.EnsureSuccessStatusCode();

            return new PackageGen { Id = packageInfo.PackageId };
        }
    }

Der Microservice wird in einer Azure-Funktion bereitgestellt. Der Code befindet sich in PackageServiceFunction.cs und enthält den folgenden Code.

public static class PackageServiceFunction
    {
        [FunctionName("PackageServiceFunction")]
        public static Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "put", Route = "packages/{id}")] HttpRequest req,
            string id, ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            //Uses common data store e.g. SQL Azure tables
            Utility.DoWork(100);
            return Task.FromResult((IActionResult)new CreatedResult("http://example.com", null));
        }
    }

Wenn Sie diesen Code in Azure Functions einfügen, kann der Dienst bei steigender Benutzerauslastung unabhängig skaliert werden. Sie können die Dienste für den verbleibenden Anwendungscode für den Rest der Anwendung optimiert beibehalten. Der Paketdienst wird horizontal hochskaliert, wenn mehr Anforderungen von Drohnenlieferungen an das System gesendet werden.

Nun können Sie die Anwendung erneut bereitstellen. Zuerst stellen wir den umgestalteten Dienst in Azure Functions bereit. Anschließend stellen wir die umgestaltete Anwendung in App Service bereit und verweisen sie auf die Funktion.

Bereitstellen der Funktions-App

  1. Führen Sie den folgenden Befehl aus, um Umgebungsvariablen einzurichten, die auf unsere Dienste verweisen.

    APPSERVICENAME="$(az webapp list \
                        --resource-group "<rgn>[sandbox resource group]</rgn>" \
                        --query '[].name' \
                        --output tsv)"
    FUNCTIONAPPNAME="$(az functionapp list \
                        --resource-group "<rgn>[sandbox resource group]</rgn>" \
                        --query '[].name' \
                        --output tsv)"
    
  2. Erstellen und zippen Sie den Anwendungscode für die Funktions-App.

    cd ~/mslearn-microservices-architecture/src/after
    dotnet build ./PackageService/PackageService.csproj -c Release
    cd PackageService/bin/Release/netcoreapp2.2
    zip -r PackageService.zip .
    
  3. Führen Sie den folgenden Befehl aus, um den Code an die Funktions-App zu übertragen.

    az functionapp deployment source config-zip \
        --resource-group "<rgn>[sandbox resource group]</rgn>" \
        --name $FUNCTIONAPPNAME \
        --src PackageService.zip
    

Bereitstellen der aktualisierten Drohnenlieferungsanwendung

Da der Dienst nun in Azure Functions ausgeführt wird, muss die Drohnenanwendung auf diese Funktions-App verweisen.

  1. Wir müssen zuerst den Zugriffscode für die Funktions-App abrufen, damit wir ihn erfolgreich aus der Anwendung aufrufen können. Führen Sie die folgenden Befehle aus, um diesen Code abzurufen. Sie zeigen den Namen und den Code der Funktions-App an, die Sie in den nächsten Schritten verwenden.

    RESOURCEGROUPID=$(az group show \
                        --resource-group "<rgn>[sandbox resource group]</rgn>" \
                        --query id \
                        --output tsv)
    FUNCTIONCODE=$(az rest \
                        --method post \
                        --query default \
                        --output tsv \
                        --uri "https://management.azure.com$RESOURCEGROUPID/providers/Microsoft.Web/sites/$FUNCTIONAPPNAME/functions/PackageServiceFunction/listKeys?api-version=2018-02-01")
    echo "FunctionName - $FUNCTIONAPPNAME"
    echo "FunctionCode - $FUNCTIONCODE"
    
  2. Führen Sie die folgenden Befehle in Azure Cloud Shell aus, um appsettings.json im Code-Editor zu öffnen.

    cd ~/mslearn-microservices-architecture/src/after
    code ./DroneDelivery-after/appsettings.json
    
  3. Ersetzen Sie im Code-Editor die Werte PackageServiceUri und PackageServiceFunctionCode. Ersetzen Sie in PackageServiceUri<FunctionName> durch den Namen der Funktions-App.

    Ersetzen Sie in PackageServiceFunctionCode<FunctionCode> durch den von Ihnen abgerufenen Funktionscode. Ihre appsettings.json-Datei sollte in etwa diesem Beispiel entsprechen:

    {
        "Logging": {
        "LogLevel": {
            "Default": "Warning"
        }
        },
        "AllowedHosts": "*",
        "PackageServiceUri": "https://packageservicefunction-abc.azurewebsites.net/api/packages/",
        "PackageServiceFunctionCode": "SvrbiyhjXJUdTPXrkcUtY6bQaUf7OXQjWvnM0Gq63hFUhbH2vn6qYA=="
    }
    
  4. Drücken Sie erst STRG+S, um die Datei zu speichern und anschließend STRG+Q, um den Code-Editor zu schließen.

  5. Führen Sie den folgenden Befehl aus, um die aktualisierte Anwendung in Ihrem App Service bereitzustellen.

    zip -r DroneDelivery-after.zip . -x \*/obj/\* \*/bin/\*
    az webapp deploy \
        --resource-group "<rgn>[sandbox resource group]</rgn>" \
        --name $APPSERVICENAME \
        --src-path DroneDelivery-after.zip
    
  6. Aktualisieren Sie Ihre Seite, nachdem die Website erneut bereitgestellt wurde. Sie sollte jetzt aktualisiert werden.

    Screenshot of the redeployed Drone Delivery website.

Testen der Leistung der neuen Architektur

Nachdem der ressourcenbeschränkte Dienst jetzt in einen Microservice verschoben wurde, der in Azure Functions ausgeführt wird, sehen wir uns an, wie sich diese Änderung auf die Leistung der Anwendung auswirkt.

  1. Klicken Sie auf der Homepage Ihrer Website auf Anforderungen senden. Hiermit werden Anforderungen aus Ihrer monolithischen App an den in einer Azure-Funktion ausgeführten Microservice übermittelt.

  2. Beim ersten Versuch erhalten Sie für die monolithische Anwendung möglicherweise ähnliche Ergebnisse. Aktualisieren Sie die Seite, und übermitteln Sie die Anforderung erneut, wenn Sie dazu aufgefordert werden. Wiederholen Sie diesen Schritt mehrmals. Die Meldung 100 messages sent in 1 second (100 Nachrichten pro Sekunde gesendet) sollte angezeigt werden.

    Screenshot of performance of the Drone Delivery site after moving to a microservices architecture.

Der anfängliche Versuch war langsamer, als die Funktions-App gestartet wurde. Nach der Bereitstellung war die Antwortzeit besser als bei der Ausführung des Codes in der monolithischen Architektur.

Dieser Teil der Architektur kann jetzt fast unendlich horizontal hochskaliert werden und gleichzeitig die gleiche Leistung bereitstellen. Durch das Verschieben dieses Anwendungscodes in einen Microservice ist die Leistung fünf- bis zehnmal so hoch. Da Fabrikam über ein dediziertes Entwicklungsteam für diesen Dienst verfügt, können auch dieser Microservice durchlaufen und die Vorteile der verbesserten Agilität und Featurereleases genutzt werden.