演習 - モノリシック内のサービスをマイクロサービスとしてリファクタリングする

完了

Fabrikam は、アプリケーションの分析が済んだので、リファクタリング プロセスを始めてサービスをモノリシック アーキテクチャからマイクロサービスに移行する準備ができました。 アプリケーションを変更して、荷物処理サービスをマイクロサービスに移行しましょう。

Visualization of the resources for the Drone Delivery application.

アプリケーションをリファクタリングする

更新されたアプリケーションをデプロイする前に、どのように更新されたかを見てみましょう。 このモノリシック アプリには、荷物を処理する PackageProcessor.cs サービスがあります。 アプリケーションのパフォーマンスを分析したところ、このサービスがパフォーマンスのボトルネックとして確認されました。 ドローン配送の顧客需要が高まっており、ドローン配送のスケジューリングと物流を処理する間、このサービスの負荷は増大します。 専任チームがこのサービスを完全に管理しているので、それをマイクロサービスに移行すると、パフォーマンスと開発の機敏性が向上します。

加えられた変更について詳しく見てみましょう。

更新前のドローン配送

PackageProcessor.cs ファイルの PackageProcessor クラスが、荷物処理のコア機能を処理します。 この例では、リソースを集中的に使用する作業が実行されています。 実際のシナリオでは、この情報を使用して、配送時間や配送ルートが計算されたり、データ ソースが更新されたりします。

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

このサービスに対する要求が高まるにつれて、リソース使用率が増加し、モノリシック アプリケーションに割り当てられた物理リソースが上限に達します。 このサービスが Azure App Service にデプロイされている場合は、スケールアップとスケールアウトが可能です。このように頻繁に使用されるリソースは、パフォーマンスとコストを最適化するために、個別にスケーリングすることが理想的です。 このシナリオでは、それのみを目的として、Azure Functions を使用します。

更新後のドローン配送

デプロイする前に、DroneDelivery-after のアプリケーション コードを見てみましょう。 PackageProcessor クラスが PackageServiceCaller クラスに変更されたことがわかります。 IPackageProcessor インターフェイスが引き続き実装されますが、代わりにマイクロサービスへの HTTP 呼び出しが行われます。

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

マイクロサービスは、Azure 関数にデプロイされます。 そのコードは PackageServiceFunction.cs にあり、次のコードが含まれます。

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

このコードを Azure Functions に配置すると、ユーザーの負荷が増えたら、このサービスを個別にスケーリングできます。 アプリケーションの残りの部分に向けて、残りのアプリケーション コードに対するサービスを最適化し続けることができます。 ドローン配送に対する要求がシステムにさらに追加されると、荷物サービスがスケールアウトします。

ここで、アプリケーションを再デプロイしましょう。 まず、リファクタリングされたサービスを Azure Functions にデプロイします。 その後、リファクタリングされたアプリケーションを App Service にデプロイして、それを関数にポイントします。

関数アプリをデプロイする

  1. 次のコマンドを実行して、サービスをポイントする環境変数を設定します。

    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. 関数アプリのアプリケーション コードをビルドして、zip 形式にしましょう。

    cd ~/mslearn-microservices-architecture/src/after
    dotnet build ./PackageService/PackageService.csproj -c Release
    cd PackageService/bin/Release/netcoreapp2.2
    zip -r PackageService.zip .
    
  3. 次のコマンドを実行して、コードを関数アプリにプッシュします。

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

更新されたドローン配送アプリケーションをデプロイする

サービスが Azure Functions で実行されるようになったため、ドローン アプリケーションをその関数アプリにポイントする必要があります。

  1. まず、アプリケーションから正常に呼び出すことができるように、関数アプリのアクセス コードを取得します。 このコードを取得するには、次のコマンドを実行します。 関数アプリ名とコードが表示されます。これは、次の手順で使用します。

    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. Azure Cloud Shell で次のコマンドを実行して、コード エディターで appsettings.json を開きます。

    cd ~/mslearn-microservices-architecture/src/after
    code ./DroneDelivery-after/appsettings.json
    
  3. コードエディターで、PackageServiceUriPackageServiceFunctionCode の値を置き換えます。 PackageServiceUri で、<FunctionName> を、お使いの関数アプリの名前に置き換えます。

    PackageServiceFunctionCode で、<FunctionCode> を、取得した関数コードに置き換えます。 appsettings.json ファイルは次の例のようになります。

    {
        "Logging": {
        "LogLevel": {
            "Default": "Warning"
        }
        },
        "AllowedHosts": "*",
        "PackageServiceUri": "https://packageservicefunction-abc.azurewebsites.net/api/packages/",
        "PackageServiceFunctionCode": "SvrbiyhjXJUdTPXrkcUtY6bQaUf7OXQjWvnM0Gq63hFUhbH2vn6qYA=="
    }
    
  4. Ctrl + S キーを押してファイルを保存してから、Ctrl + Q キーを押してコード エディターを閉じます。

  5. 次のコマンドを実行して、更新したアプリケーションを App Service にデプロイします。

    zip -r DroneDelivery-after.zip . -x \*/obj/\* \*/bin/\*
    az webapp deployment source config-zip \
        --resource-group "<rgn>[sandbox resource group]</rgn>" \
        --name $APPSERVICENAME \
        --src DroneDelivery-after.zip
    
  6. サイトが再デプロイされたら、ページを更新します。 これで更新されます。

    Screenshot of the redeployed Drone Delivery website.

新しいアーキテクチャのパフォーマンスをテストする

リソースに制約のあるサービスが、Azure Functions で実行されるマイクロサービスに移行されたので、この変更によってアプリケーションのパフォーマンスがどのような影響を受けたか見てみましょう。

  1. Web サイトのホームページで、[要求の送信] を選択します。 このアクションにより、モノリシック アプリから Azure 関数で実行されるマイクロサービスに要求が送信されます。

  2. 最初の試行では、モノリシック アプリケーションと同様の結果になる場合があります。 ページを更新し、メッセージが表示されたら要求を再送信します。 この手順を何回か行うと、100 messages sent in 1 second (1 秒間に 100 個のメッセージが送信されました) と表示されます。

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

最初の試行では、関数アプリの起動時に時間がかかりました。 それが稼働した後は、このコードがモノリシック アーキテクチャで実行されていたときより、応答時間が短縮されました。

アーキテクチャのこの部分は、同じパフォーマンスを実現したまま、ほぼ無限にスケールアウトできるようになりました。 このアプリケーション コードをマイクロサービスに移行したことで、パフォーマンスが 5 倍から 10 倍向上しました。 Fabrikam には、このサービスに対する専任の開発チームがあるため、このマイクロサービスで反復処理を行い、機敏性と機能のリリースが増加する利点も得られます。