演習 - モノリシック内のサービスをマイクロサービスとしてリファクタリングする
Fabrikam は、アプリケーションの分析が済んだので、リファクタリング プロセスを始めてサービスをモノリシック アーキテクチャからマイクロサービスに移行する準備ができました。 アプリケーションを変更して、荷物処理サービスをマイクロサービスに移行しましょう。
アプリケーションをリファクタリングする
更新されたアプリケーションをデプロイする前に、どのように更新されたかを見てみましょう。 このモノリシック アプリには、荷物を処理する 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 にデプロイして、それを関数にポイントします。
関数アプリをデプロイする
次のコマンドを実行して、サービスをポイントする環境変数を設定します。
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)"
関数アプリのアプリケーション コードをビルドして、zip 形式にしましょう。
cd ~/mslearn-microservices-architecture/src/after dotnet build ./PackageService/PackageService.csproj -c Release cd PackageService/bin/Release/netcoreapp2.2 zip -r PackageService.zip .
次のコマンドを実行して、コードを関数アプリにプッシュします。
az functionapp deployment source config-zip \ --resource-group "<rgn>[sandbox resource group]</rgn>" \ --name $FUNCTIONAPPNAME \ --src PackageService.zip
更新されたドローン配送アプリケーションをデプロイする
サービスが Azure Functions で実行されるようになったため、ドローン アプリケーションをその関数アプリにポイントする必要があります。
まず、アプリケーションから正常に呼び出すことができるように、関数アプリのアクセス コードを取得します。 このコードを取得するには、次のコマンドを実行します。 関数アプリ名とコードが表示されます。これは、次の手順で使用します。
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"
Azure Cloud Shell で次のコマンドを実行して、コード エディターで appsettings.json を開きます。
cd ~/mslearn-microservices-architecture/src/after code ./DroneDelivery-after/appsettings.json
コードエディターで、
PackageServiceUri
とPackageServiceFunctionCode
の値を置き換えます。PackageServiceUri
で、<FunctionName>
を、お使いの関数アプリの名前に置き換えます。PackageServiceFunctionCode
で、<FunctionCode>
を、取得した関数コードに置き換えます。 appsettings.json ファイルは次の例のようになります。{ "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "PackageServiceUri": "https://packageservicefunction-abc.azurewebsites.net/api/packages/", "PackageServiceFunctionCode": "SvrbiyhjXJUdTPXrkcUtY6bQaUf7OXQjWvnM0Gq63hFUhbH2vn6qYA==" }
Ctrl + S キーを押してファイルを保存してから、Ctrl + Q キーを押してコード エディターを閉じます。
次のコマンドを実行して、更新したアプリケーションを 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
サイトが再デプロイされたら、ページを更新します。 これで更新されます。
新しいアーキテクチャのパフォーマンスをテストする
リソースに制約のあるサービスが、Azure Functions で実行されるマイクロサービスに移行されたので、この変更によってアプリケーションのパフォーマンスがどのような影響を受けたか見てみましょう。
Web サイトのホームページで、[要求の送信] を選択します。 このアクションにより、モノリシック アプリから Azure 関数で実行されるマイクロサービスに要求が送信されます。
最初の試行では、モノリシック アプリケーションと同様の結果になる場合があります。 ページを更新し、メッセージが表示されたら要求を再送信します。 この手順を何回か行うと、100 messages sent in 1 second (1 秒間に 100 個のメッセージが送信されました) と表示されます。
最初の試行では、関数アプリの起動時に時間がかかりました。 それが稼働した後は、このコードがモノリシック アーキテクチャで実行されていたときより、応答時間が短縮されました。
アーキテクチャのこの部分は、同じパフォーマンスを実現したまま、ほぼ無限にスケールアウトできるようになりました。 このアプリケーション コードをマイクロサービスに移行したことで、パフォーマンスが 5 倍から 10 倍向上しました。 Fabrikam には、このサービスに対する専任の開発チームがあるため、このマイクロサービスで反復処理を行い、機敏性と機能のリリースが増加する利点も得られます。