Övning – Omstrukturera en tjänst inom monoliten som en mikrotjänst

Slutförd

Nu när Fabrikam har analyserat sitt program är de redo att starta omstruktureringsprocessen för att flytta tjänster från sin monolitiska arkitektur till mikrotjänster. Nu ska vi ändra programmet för att flytta paketbearbetningstjänsten till en mikrotjänst.

Visualisering av resurserna för drone delivery-programmet.

Omstrukturera programmet

Innan vi distribuerar det uppdaterade programmet ska vi ta en titt på hur det uppdaterades. Den monolitiska appen har en tjänst för att bearbeta paket, PackageProcessor.cs. När programmets prestanda har analyserats identifierades den här tjänsten som en flaskhals för prestanda. I takt med att kunderna ökar efterfrågan på drönarleveranser blir den här tjänsten hårt belastad medan den hanterar schemaläggning och logistik för drönarleveranser. Ett dedikerat team hanterar den här tjänsten fullt ut, så att flytta den till en mikrotjänst hjälper till med prestanda och ger förbättrad utvecklingsflexiitet.

Nu ska vi titta närmare på de ändringar som har gjorts.

Drönarleverans före

Klassen PackageProcessor hanterar huvudfunktionerna i paketbearbetningen i PackageProcessor.cs-filen. I det här exemplet utför den en del arbete som är resursintensivt. Ett verkligt scenario kan omfatta beräkning av leveranstider och leveransvägar och uppdatering av datakällor med den här informationen.

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 });
        }
    }

I takt med att begäranden om den här tjänsten ökar ökar resursanvändningen och begränsas till de fysiska resurser som allokeras till det monolitiska programmet. Om den här tjänsten distribueras i Azure App Service kan vi skala upp och ut den. Vi rekommenderar att du vill att den här resursen ska skalas separat för att optimera prestanda och kostnader. I det här scenariot använder vi Azure Functions för att göra just det.

Drönarleverans efter

Låt oss ta en titt på DroneDelivery-after programkod innan vi implementerar den. Du kan se att klassen PackageProcessor har ändrats till en PackageServiceCaller-klass. Det implementerar fortfarande IPackageProcessor-gränssnittet, men i stället gör det ett HTTP-anrop till mikrotjänsten.

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 };
        }
    }

Mikrotjänsten distribueras på en Azure-funktion. Koden finns i PackageServiceFunction.cs och innehåller följande kod.

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));
        }
    }

När du placerar den här koden på Azure Functions kan den här tjänsten skalas separat när användarbelastningen ökar. Du kan behålla tjänsterna för den återstående programkoden optimerade för resten av programmet. Pakettjänsten skalas ut när fler förfrågningar om drönarleveranser kommer in i systemet.

Nu ska vi distribuera om programmet. Först distribuerar vi vår omstrukturerade tjänst på Azure Functions. Sedan implementerar vi det omstrukturerade programmet på App Service och pekar det mot funktionen.

Distribuera funktionsappen

  1. Kör följande kommando för att konfigurera miljövariabler som pekar på våra tjänster.

    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. Nu ska vi skapa och zippa upp programkoden för funktionsappen.

    cd ~/mslearn-microservices-architecture/src/after
    dotnet build ./PackageService/PackageService.csproj -c Release
    cd PackageService/bin/Release/netcoreapp2.2
    zip -r PackageService.zip .
    
  3. Kör följande kommando för att skicka koden till funktionsappen.

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

Distribuera det uppdaterade drone delivery-programmet

Nu när vår tjänst körs på Azure Functions måste vi peka vårt drönarprogram till funktionsappen.

  1. Vi måste först hämta åtkomstkoden för funktionsappen så att vi kan anropa den från programmet. Kör följande kommandon för att hämta den här koden. Du visar funktionsappens namn och kod för användning i nästa steg.

    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. I Azure Cloud Shell kör du följande kommandon för att öppna appsettings.json i kodredigeraren.

    cd ~/mslearn-microservices-architecture/src/after
    code ./DroneDelivery-after/appsettings.json
    
  3. I kodredigeraren ersätter du värdena PackageServiceUri och PackageServiceFunctionCode. I PackageServiceUriersätter du <FunctionName> med namnet på funktionsappen.

    I PackageServiceFunctionCodeersätter du <FunctionCode> med den funktionskod som du hämtade. Filen appsettings.json bör se ut ungefär som i det här exemplet:

    {
        "Logging": {
        "LogLevel": {
            "Default": "Warning"
        }
        },
        "AllowedHosts": "*",
        "PackageServiceUri": "https://packageservicefunction-abc.azurewebsites.net/api/packages/",
        "PackageServiceFunctionCode": "SvrbiyhjXJUdTPXrkcUtY6bQaUf7OXQjWvnM0Gq63hFUhbH2vn6qYA=="
    }
    
  4. Tryck på Ctrl + S för att spara filen och sedan Ctrl + Q för att stänga kodredigeraren.

  5. Kör följande kommando för att distribuera det uppdaterade programmet till Din App Service.

    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. När webbplatsen har återlanserats uppdaterar du sidan. Den bör nu uppdateras.

    Skärmbild av den omdistribuerade webbplatsen för drönarleverans.

Testa prestanda för den nya arkitekturen

Nu när den resursbegränsade tjänsten har flyttats till en mikrotjänst som körs på Azure Functions ska vi se hur den här ändringen påverkade programmets prestanda.

  1. På webbplatsens startsida väljer du Skicka begäranden. Den här åtgärden skickar begäranden från din monolitiska app till mikrotjänsten som körs på en Azure-funktion.

  2. Det första försöket kan resultera i liknande resultat som det monolitiska programmet. Uppdatera sidan och skicka begäran igen om du uppmanas att göra det. Gör det här steget flera gånger och du bör se 100 meddelanden skickade på 1 sekund.

    Skärmbild av prestanda för webbplatsen för drönarleverans när du har flyttat till en arkitektur för mikrotjänster.

Det första försöket var långsammare när funktionsappen startades. När den var igång var svarstiden bättre än när den här koden kördes i den monolitiska arkitekturen.

Den här delen av arkitekturen kan nu skalas ut nästan oändligt medan den fortfarande ger samma prestanda. Genom att flytta den här programkoden till en mikrotjänst förbättrade vi prestanda med 5 till 10 gånger. Eftersom Fabrikam har ett dedikerat utvecklingsteam för den här tjänsten kan de även iterera på den här mikrotjänsten och dra nytta av fördelarna med ökad flexibilitet och funktionsutgåvor.