Övning – Omstrukturera en tjänst inom monoliten som en mikrotjänst
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.
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
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)"
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 .
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.
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"
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
I kodredigeraren ersätter du värdena
PackageServiceUri
ochPackageServiceFunctionCode
. IPackageServiceUri
ersätter du<FunctionName>
med namnet på funktionsappen.I
PackageServiceFunctionCode
ersä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==" }
Tryck på Ctrl + S för att spara filen och sedan Ctrl + Q för att stänga kodredigeraren.
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
När webbplatsen har återlanserats uppdaterar du sidan. Den bör nu uppdateras.
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.
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.
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.
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.