Exercício – refatorizar um serviço dentro do monólito como um microsserviço

Concluído

Agora que a Fabrikam terminou de analisar seu aplicativo, eles estão prontos para iniciar o processo de refatoração para mover serviços de sua arquitetura monolítica para microsserviços. Vamos modificar a aplicação para mover o serviço de processamento de pacotes para um microsserviço.

Visualization of the resources for the Drone Delivery application.

Refatorizar a aplicação

Antes de implementarmos a aplicação atualizada, vamos ver a forma como foi atualizada. A aplicação monolítica dispõe de um serviço para processar pacotes, PackageProcessor.cs. Depois de o desempenho da aplicação ter sido analisado, este serviço foi identificado como um estrangulamento de desempenho. À medida que os clientes aumentam a procura por entregas por drone, este serviço torna-se muito carregado enquanto processa o agendamento e a logística das entregas por drone. Uma equipe dedicada gerencia totalmente esse serviço, portanto, movê-lo para um microsserviço ajuda no desempenho e fornece maior agilidade de desenvolvimento.

Vamos analisar mais detalhadamente as alterações que foram feitas.

Entrega por drone antes

A PackageProcessor classe lida com a funcionalidade principal do processamento do pacote no arquivo PackageProcessor.cs . Neste exemplo, executa algum trabalho que consome muitos recursos. Um cenário do mundo real pode ser o cálculo de tempos de entrega e rotas de entrega ou a atualização de origens de dados com estas informações.

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

À medida que os pedidos deste serviço aumentam, a utilização de recursos aumenta e é limitada aos recursos físicos alocados à aplicação monolítica. Se esse serviço for implantado no Serviço de Aplicativo do Azure, poderemos dimensioná-lo para cima e para fora. Idealmente, você deseja que esse recurso muito usado seja dimensionado de forma independente para otimizar o desempenho e os custos. Neste cenário, vamos utilizar as Funções do Azure para esse propósito.

Entrega por drone depois

Vamos dar uma olhada no código do aplicativo DroneDelivery-after antes de implantá-lo. Você pode ver que a PackageProcessor classe foi alterada para uma PackageServiceCaller classe. Continua a implementar a interface IPackageProcessor, mas em vez disso faz uma chamada HTTP para o microsserviço.

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

O microsserviço é implantado em uma função do Azure. O código pode ser encontrado em PackageServiceFunction.cs e contém o seguinte código.

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 você coloca esse código no Azure Functions, esse serviço pode ser dimensionado independentemente à medida que a carga do usuário aumenta. Pode manter os serviços para o restante código de aplicação otimizado para o resto da aplicação. O serviço de pacote é ampliado à medida que mais pedidos para entregas por drone entram no sistema.

Agora, vamos reimplantar o aplicativo. Primeiro, implementamos o nosso serviço refatorizado nas Funções do Azure. Em seguida, implantamos o aplicativo refatorado no Serviço de Aplicativo e o apontamos para a função.

Implementar a aplicação de funções

  1. Execute o seguinte comando para configurar as variáveis de ambiente apontadas para os nossos serviços.

    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. Vamos compilar e compactar o código da aplicação para a aplicação de funções.

    cd ~/mslearn-microservices-architecture/src/after
    dotnet build ./PackageService/PackageService.csproj -c Release
    cd PackageService/bin/Release/netcoreapp2.2
    zip -r PackageService.zip .
    
  3. Execute o seguinte comando para enviar o código para o aplicativo de função.

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

Implementar a aplicação de Entrega por Drone atualizada

Agora que o nosso serviço está a ser executado nas Funções do Azure, precisamos de apontar a nossa aplicação de drone para essa aplicação de funções.

  1. Primeiro, precisamos de obter o código de acesso da aplicação de funções, para que possamos chamá-la com êxito a partir da aplicação. Execute os seguintes comandos para obter este código. Visualiza o nome e o código da aplicação de funções, para utilização nos próximos passos.

    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. No Azure Cloud Shell, execute os seguintes comandos para abrir appsettings.json no editor de códigos.

    cd ~/mslearn-microservices-architecture/src/after
    code ./DroneDelivery-after/appsettings.json
    
  3. No editor de código, substitua os valores PackageServiceUri e PackageServiceFunctionCode. Em PackageServiceUri, substitua <FunctionName> pelo nome da aplicação de funções.

    Em PackageServiceFunctionCode, substitua <FunctionCode> pelo código de função obtido. Seu arquivo appsettings.json deve ser semelhante a este exemplo:

    {
        "Logging": {
        "LogLevel": {
            "Default": "Warning"
        }
        },
        "AllowedHosts": "*",
        "PackageServiceUri": "https://packageservicefunction-abc.azurewebsites.net/api/packages/",
        "PackageServiceFunctionCode": "SvrbiyhjXJUdTPXrkcUtY6bQaUf7OXQjWvnM0Gq63hFUhbH2vn6qYA=="
    }
    
  4. Prima Ctrl+S para guardar o ficheiro e, em seguida , Ctrl+Q para fechar o editor de códigos.

  5. Execute o seguinte comando para implantar o aplicativo atualizado no seu Serviço de Aplicativo.

    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. Com o site reimplantado, atualize sua página. Deve agora ser atualizado.

    Screenshot of the redeployed Drone Delivery website.

Testar o desempenho da nova arquitetura

Agora que o serviço com restrição de recursos foi movido para um microsserviço executado no Azure Functions, vamos ver como essa alteração afetou o desempenho do aplicativo.

  1. Na home page do site, selecione Enviar Pedidos. Esta ação envia pedidos da aplicação monolítica para o microsserviço em execução numa função do Azure.

  2. A primeira tentativa pode fornecer resultados semelhantes aos da aplicação monolítica. Atualize a página e reenvie o pedido, se solicitado. Realize este passo várias vezes e deverá ver 100 mensagens enviadas durante 1 segundo.

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

A tentativa inicial foi mais lenta enquanto a aplicação de funções era iniciada. Depois que ele estava instalado e funcionando, o tempo de resposta era melhor do que quando esse código estava sendo executado na arquitetura monolítica.

Esta parte da arquitetura pode agora ser ampliada quase infinitamente enquanto continua a fornecer o mesmo desempenho. Ao mover esse código de aplicativo para um microsserviço, melhoramos o desempenho em 5 a 10 vezes. Uma vez que a Fabrikam tem uma equipa de desenvolvimento dedicada a este serviço, também pode iterar neste microsserviço e compreender os benefícios da melhoria da agilidade e das versões dos recursos.