Esercizio - Effettuare il refactoring di un servizio all'interno di un'applicazione monolitica come microservizio
Ora che Fabrikam ha completato l'analisi dell'applicazione, è il momento di avviare il processo di refactoring per spostare i servizi al di fuori dell'architettura monolitica creando microservizi. Si modificherà l'applicazione per spostare il servizio di gestione dei pacchetti in un microservizio.
Effettuare il refactoring dell'applicazione
Prima di distribuire l'applicazione aggiornata, è opportuno esaminare in che modo è stata aggiornata. L'app monolitica ha un servizio per la gestione dei pacchetti, PackageProcessor.cs. Dopo aver analizzato le prestazioni dell'applicazione, si è notato che questo servizio fa da collo di bottiglia per le prestazioni. Man mano che le richieste dei clienti per il servizio di consegna con drone aumentano, questo servizio deve sopportare un carico sempre maggiore mentre gestisce la pianificazione e la logistica per le consegne con drone. Un team dedicato gestisce completamente questo servizio, quindi il passaggio a un microservizio contribuisce a migliorare le prestazioni e offre una migliore flessibilità di sviluppo.
Si osserveranno ora le modifiche apportate.
Consegna con drone prima delle modifiche
La classe PackageProcessor
gestisce le funzionalità di base per l'elaborazione dei pacchetti nel file PackageProcessor.cs. In questo esempio il lavoro svolto comporta un utilizzo elevato delle risorse. Uno scenario reale potrebbe includere il calcolo dei tempi di consegna e degli itinerari di consegna e l'aggiornamento delle origini dati con queste informazioni.
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 });
}
}
Man mano che le richieste per questo servizio aumentano, l'utilizzo delle risorse aumenta, ma è limitato alle risorse fisiche allocate all'applicazione monolitica. Se questo servizio viene distribuito nel servizio app Azure, è possibile aumentarne e ridurne le dimensioni. Idealmente, si vuole che questa risorsa usata di frequente venga ridimensionata in modo indipendente per ottimizzare le prestazioni e i costi. A tale scopo, in questo scenario viene usato Funzioni di Azure.
Consegna con drone dopo le modifiche
Esaminiamo ora il codice dell'applicazione DroneDelivery-after prima di distribuirlo. Si noterà che la classe PackageProcessor
è stata modificata in una classe PackageServiceCaller
. Implementa comunque l'interfaccia IPackageProcessor, ma esegue una chiamata HTTP al microservizio.
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 };
}
}
Il microservizio viene distribuito in una funzione di Azure. Il codice è disponibile in PackageServiceFunction.cs e include quanto segue.
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));
}
}
Quando si inserisce questo codice in Funzioni di Azure, questo servizio può essere dimensionato in modo indipendente man mano che aumenta il carico utente. È possibile mantenere i servizi per il codice dell'applicazione rimanente ottimizzati per il resto dell'applicazione. Il servizio di gestione dei pacchetti viene ridimensionato man mano che vengono inviate al sistema altre richieste di consegne con drone.
Ridistribuire ora l'applicazione. Prima di tutto, si distribuisce il servizio sottoposto a refactoring in Funzioni di Azure. Quindi l'applicazione sottoposta a refactoring viene distribuita nel servizio app e associata alla funzione.
Distribuire l'app per le funzioni
Eseguire il comando seguente per configurare le variabili di ambiente che puntano ai servizi.
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)"
Compilare e comprimere il codice dell'applicazione per l'app per le funzioni.
cd ~/mslearn-microservices-architecture/src/after dotnet build ./PackageService/PackageService.csproj -c Release cd PackageService/bin/Release/netcoreapp2.2 zip -r PackageService.zip .
Eseguire il comando seguente per eseguire il push del codice all'app per le funzioni.
az functionapp deployment source config-zip \ --resource-group "<rgn>[sandbox resource group]</rgn>" \ --name $FUNCTIONAPPNAME \ --src PackageService.zip
Distribuire l'applicazione Drone Delivery aggiornata
Ora che il servizio è in esecuzione in Funzioni di Azure, è necessario associare l'applicazione di gestione dei droni all'app per le funzioni.
Prima di tutto è necessario ottenere il codice di accesso per l'app per le funzioni, in modo che sia possibile eseguire la chiamata dall'applicazione. Eseguire i comandi seguenti per recuperare questo codice. Vengono visualizzati il codice e il nome dell'app per le funzioni, da usare nei passaggi successivi.
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"
In Azure Cloud Shell eseguire i comandi seguenti per aprire appsettings.json nell'editor di codice.
cd ~/mslearn-microservices-architecture/src/after code ./DroneDelivery-after/appsettings.json
Nell'editor di codice sostituire i valori
PackageServiceUri
ePackageServiceFunctionCode
. InPackageServiceUri
sostituire<FunctionName>
con il nome dell'app per le funzioni.In
PackageServiceFunctionCode
sostituire<FunctionCode>
con il codice della funzione recuperato. Il file appsettings.json sarà simile a questo esempio:{ "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "PackageServiceUri": "https://packageservicefunction-abc.azurewebsites.net/api/packages/", "PackageServiceFunctionCode": "SvrbiyhjXJUdTPXrkcUtY6bQaUf7OXQjWvnM0Gq63hFUhbH2vn6qYA==" }
Premere CTRL+S per salvare il file e quindi CTRL+Q per chiudere l'editor di codice.
Eseguire il comando seguente per distribuire l'applicazione aggiornata nel servizio app.
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
Dopo aver ridistribuito il sito, aggiornare la pagina. Dovrebbe ora essere aggiornata.
Testare le prestazioni della nuova architettura
Ora che il servizio con risorse limitate è stato spostato in un microservizio in esecuzione in Funzioni di Azure, si esaminerà l'impatto sulle prestazioni dell'applicazione.
Nella home page del sito Web selezionare Send Requests (Invia richieste). Questa azione consente di inviare le richieste dall'app monolitica al microservizio in esecuzione in una funzione di Azure.
Il primo tentativo potrebbe restituire risultati simili all'applicazione monolitica. Aggiornare la pagina e inviare di nuovo la richiesta, se richiesto. Eseguire questo passaggio più volte fino a visualizzare il messaggio 100 messages sent in 1 second (100 messaggi inviati in 1 secondo).
Il tentativo iniziale è stato più lento perché era in corso l'avvio dell'app per le funzioni. Con l'applicazione in esecuzione il tempo di risposta è migliorato rispetto all'esecuzione del codice nell'architettura monolitica.
Questa parte dell'architettura può ora essere ampliata quasi all'infinito e continua a garantire le stesse prestazioni. Spostando il codice dell'applicazione in un microservizio, le prestazioni sono migliorate da cinque a dieci volte. Poiché Fabrikam ha un team di sviluppo dedicato per questo servizio, può anche eseguire l'iterazione del microservizio e sfruttare i vantaggi legati a una maggiore flessibilità e ai rilasci di funzionalità.