|
| 1 | +--- |
| 2 | +title: "Tutorial: Scale a Java container app with Java metrics" |
| 3 | +description: Scale a Java container app with Java metrics. |
| 4 | +services: container-apps |
| 5 | +author: craigshoemaker |
| 6 | +ms.service: azure-container-apps |
| 7 | +ms.custom: devx-track-extended-java |
| 8 | +ms.topic: tutorial |
| 9 | +ms.date: 12/23/2024 |
| 10 | +ms.author: cshoe |
| 11 | +#customer intent: As a developer, I want to set up auto scale using Java metrics exposed from Azure Container Apps |
| 12 | +--- |
| 13 | + |
| 14 | +# Tutorial: Scale a Java container app with Java metrics |
| 15 | + |
| 16 | +Azure Container Apps manages automatic horizontal scaling through a set of declarative scaling rules. You can create your own scale rules with [customized event sources](./scale-app.md#custom). |
| 17 | + |
| 18 | +In this tutorial, you add a custom scale rule to scale your container app with Java metrics, and observe how your application scales. |
| 19 | + |
| 20 | +## Prerequisites |
| 21 | + |
| 22 | +* An Azure account with an active subscription. If you don't already have one, you can [can create one for free](https://azure.microsoft.com/free/). |
| 23 | +* [Azure CLI](/cli/azure/install-azure-cli). |
| 24 | +* [A Java application deployed in Azure Container Apps](java-get-started.md). |
| 25 | + |
| 26 | +## Set up the environment |
| 27 | + |
| 28 | +Use the following steps to define environment variables and set up the environment. |
| 29 | + |
| 30 | +1. Create variables to support your scale configuration. |
| 31 | + ```bash |
| 32 | + export LOCATION=eastus |
| 33 | + export TENANT_ID={tenant-id} |
| 34 | + export SUBSCRIPTION_ID={subscriprion-id} |
| 35 | + export RESOURCE_GROUP=my-resource-group |
| 36 | + export APP_NAME=my-aca-app |
| 37 | + ``` |
| 38 | + |
| 39 | + | Variable | Description | |
| 40 | + |-------------------------|------------------------------------------------------------------------------------| |
| 41 | + | `LOCATION` | The Azure region location where you create your Azure Container Apps. | |
| 42 | + | `TENANT_ID` | Your tenant's id. | |
| 43 | + | `SUBSCRIPTION_ID` | The subscription ID which you use to create your Azure Container Apps. | |
| 44 | + | `RESOURCE_GROUP` | The Azure resource group name for your Azure Container Apps. | |
| 45 | + | `APP_NAME` | The app name for your Azure Container Apps. | |
| 46 | + | `IDENTITY_NAME` | The name for your managed identity, which is assigned to your Azure Container Apps.| |
| 47 | + |
| 48 | + |
| 49 | +1. Log in to Azure with the Azure CLI. |
| 50 | + |
| 51 | + ```azurecli |
| 52 | + az login |
| 53 | + ``` |
| 54 | + |
| 55 | +1. Create a resource group. |
| 56 | + |
| 57 | + ```azurecli |
| 58 | + az group create --name $RESOURCE_GROUP --location $LOCATION |
| 59 | + ``` |
| 60 | + |
| 61 | +## Set up a managed identity for your Azure Container Apps |
| 62 | +To scale with Azure Container Apps platform metrics, you need a managed identity to access metrics from Azure Monitor. |
| 63 | + |
| 64 | +1. Create an user-assigned identity and assign to your Azure Container Apps, you can follow doc [Add a user-assigned identity](./managed-identity.md#add-a-user-assigned-identity). |
| 65 | +After you create the identity, run bellow CLI command to set the |
| 66 | + ```azurecli |
| 67 | + USER_ASSIGNED_IDENTITY_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $IDENTITY_NAME --query "id" --output tsv) |
| 68 | + ``` |
| 69 | +
|
| 70 | +
|
| 71 | +2. Grant `Monitoring Reader` role for your managed identity to read data from Azure Monitor. You can find more details aboute the RBAC for Azure Monitor in [Buil-in Role Monitoring Reader](../role-based-access-control/built-in-roles/monitor.md#monitoring-reader) |
| 72 | +
|
| 73 | + ```azurecli |
| 74 | + # Get the principal id for your managed identity |
| 75 | + PRINCIPAL_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $IDENTITY_NAME --query "principalId" --output tsv) |
| 76 | + |
| 77 | + az role assignment create --assignee $PRINCIPAL_ID --role "Monitoring Reader" --scope /subscriptions/$SUBSCRIPTION_ID |
| 78 | + ``` |
| 79 | + |
| 80 | +## Add a scale rule with Azure Monitor metrics |
| 81 | +To scale with Azure Monitor metrics, you can refer [Azure Monitor keda scaler](https://keda.sh/docs/2.16/scalers/azure-monitor/) to define your Container Apps scale rule. |
| 82 | + |
| 83 | +Here is a list of core meta data to set up the scale rule. |
| 84 | + |
| 85 | + |
| 86 | +| Metadata key | Description | |
| 87 | +|------------------------------------|-------------------------------------------------------------------------------------------------------| |
| 88 | +| tenantId | Id of the tenant that contains the Azure resource. This is used for authentication. | |
| 89 | +| subscriptionId | Id of Azure subscription that contains the Azure resource. This is used for determining the full resource URI. | |
| 90 | +| resourceGroupName | Name of the resource group for the Azure resource. | |
| 91 | +| resourceURI | Shortened URI to the Azure resource with format `<resourceProviderNamespace>/<resourceType>/<resourceName>`. | |
| 92 | +| metricName | Name of the metric to query. | |
| 93 | +| metricAggregationType | Aggregation method of the Azure Monitor metric. Options include Average, Total, Maximum. | |
| 94 | +| metricFilter | Name of the filter to be more specific by using dimensions listed in the official documentation. (Optional) | |
| 95 | +| metricAggregationInterval | Collection time of the metric in format "hh:mm:ss" (Default: "0:5:0", Optional) | |
| 96 | +| targetValue | Target value to trigger scaling actions. (This value can be a float) | |
| 97 | + |
| 98 | +### Example |
| 99 | + |
| 100 | +Add a scale rule with [metrics from Azure Container Apps](./metrics.md) for your application. |
| 101 | + |
| 102 | + # [Azure CLI](#tab/Azure CLI) |
| 103 | + |
| 104 | + ```azurecli |
| 105 | + az containerapp update \ |
| 106 | + --name $APP_NAME \ |
| 107 | + --resource-group $RESOURCE_GROUP \ |
| 108 | + --min-replicas 1 \ |
| 109 | + --max-replicas 10 \ |
| 110 | + --scale-rule-name scale-with-azure-monitor-metrics \ |
| 111 | + --scale-rule-type azure-monitor \ |
| 112 | + --scale-rule-metadata "tenantId=${TENANT_ID}" \ |
| 113 | + "subscriptionId=${SUBSCRIPTION_ID}" \ |
| 114 | + "resourceGroupName=${RESOURCE_GROUP}" \ |
| 115 | + "resourceURI=Microsoft.App/containerapps/${APP_NAME}" \ |
| 116 | + "metricName=JvmGcCount" \ |
| 117 | + "metricAggregationType=Total" \ |
| 118 | + "metricAggregationInterval=0:1:0" \ |
| 119 | + "targetValue=30" \ |
| 120 | + --scale-rule-identity $USER_ASSIGNED_IDENTITY_ID |
| 121 | + ``` |
| 122 | + |
| 123 | + |
| 124 | + |
| 125 | + # [ARM Template](#tab/ARM Template) |
| 126 | + |
| 127 | + ```json |
| 128 | + { |
| 129 | + "resources": { |
| 130 | + "properties": { |
| 131 | + "template": { |
| 132 | + "scale": { |
| 133 | + "minReplicas": 1, |
| 134 | + "maxReplicas": 10, |
| 135 | + "rules": [ |
| 136 | + { |
| 137 | + "name": "scale-with-azure-monitor-metrics", |
| 138 | + "custom": { |
| 139 | + "type": "azure-monitor", |
| 140 | + "metadata": { |
| 141 | + "metricAggregationInterval": "0:1:0", |
| 142 | + "metricAggregationType": "Total", |
| 143 | + "metricName": "JvmGcCount", |
| 144 | + "resourceGroupName": "<your-resource-group>", |
| 145 | + "resourceURI": "Microsoft.App/containerapps/<your-app>", |
| 146 | + "subscriptionId": "<your-subscription-id>", |
| 147 | + "targetValue": "30", |
| 148 | + "tenantId": "<your-tenant-id>" |
| 149 | + }, |
| 150 | + "identity": "<your-managed-identity-id>" |
| 151 | + } |
| 152 | + } |
| 153 | + ] |
| 154 | + } |
| 155 | + } |
| 156 | + } |
| 157 | + } |
| 158 | + } |
| 159 | + ``` |
| 160 | + |
| 161 | +This command adds a scale rule to your container app with name `scale-with-azure-monitor-metrics`, and scale type is set to `azure-monitor`. It uses the managed identity with resource id `USER_ASSIGNED_IDENTITY_ID` to autheticate with Azure Monitor and query metrics for your conatner app. In the example, keda queries metric `JvmGcCount`, and aggregate the metric values within 1 minute with aggregation type `Total`. The target value is set to `30`, which means keda calculates the `desiredReplicas` using `ceil(AggregatedMetricValue(JvmGcCount)/30)`. |
| 162 | + |
| 163 | +> [!NOTE] |
| 164 | +> The metric `JvmGcCount` is only used as an example. You can use any metric from Azure Monitor. Before setting up the scale rule, view the metrics in Azure portal to determine the appropriate metric, aggregation interval, and target value based on your application's requirements. Additionally, consider using the built-in [HTTP/TCP scale rules](./scale-app.md#http), which can meet most common scaling scenarios, before opting for a custom metric. |
| 165 | +
|
| 166 | + |
| 167 | +## View scaling in Azure portal (optional) |
| 168 | +Once your new revision is ready, [send requests](./tutorial-scaling.md#send-requests) to your container app to trigger auto scale with your Java metrics. |
| 169 | +1. Go to `Metric` blade in Azure Portal for your Azure Container Apps. |
| 170 | +1. Add your metric `jvm.gc.count`, with filter `Revision=<your-revision>` and Split by `Replica`. |
| 171 | +1. Add metric `Replica Count`, with filter `Revision=<your-revision>`. |
| 172 | + |
| 173 | +Here is a sample metric snapshot for the example scale rule. |
| 174 | + |
| 175 | +:::image type="content" source="media/java-metrics-keda/keda-auto-scale-java-gc-portal.png" alt-text="Screenshot of KEDA scale with JVM metrics" lightbox="media/java-metrics-keda/keda-auto-scale-java-gc-portal.png"::: |
| 176 | + |
| 177 | +1. Initially, there is 1 replica (the `minReplicas`) for the app. |
| 178 | +1. A spike in requests causes the replica to experience frequent JVM garbage collection (GC). |
| 179 | +1. KEDA observes the aggregated metric value for `jvm.gc.count` is increased to 140 and calculates desiredReplicas as `ceil(140/30)` = 5. |
| 180 | +1. KEDA scales out the container app's replica count to 5. |
| 181 | +1. The traffic is distributed across more replicas, reducing the average GC count. |
| 182 | +1. The GC count further decreases when no requests are coming in. |
| 183 | +1. After a cooldown period, KEDA scales the replica count down to `minReplicas=1`. |
| 184 | + |
| 185 | +## Scale Log |
| 186 | + |
| 187 | +To view the KEDA scale logs, you can run bellow query in `Logs`. |
| 188 | + |
| 189 | + ``` |
| 190 | + ContainerAppSystemLogs |
| 191 | + | where RevisionName == "<your-revision>" |
| 192 | + | where EventSource == "KEDA" |
| 193 | + | project TimeGenerated, Type, Reason, ContainerAppName, Log |
| 194 | + ``` |
| 195 | + |
| 196 | +:::image type="content" source="media/java-metrics-keda/keda-auto-scale-java-log.png" alt-text="Screenshot of KEDA scale log query" lightbox="media/java-metrics-keda/keda-auto-scale-java-log.png"::: |
| 197 | + |
| 198 | + |
| 199 | +## Clean up resources |
| 200 | + |
| 201 | +The resources created in this tutorial have an effect on your Azure bill. If you aren't going to use these services long-term, run the following command to remove everything created in this tutorial. |
| 202 | + |
| 203 | +```azurecli |
| 204 | +az group delete --resource-group $RESOURCE_GROUP |
| 205 | +``` |
| 206 | + |
| 207 | +## Related content |
| 208 | + |
| 209 | +> [!div class="nextstepaction"] |
| 210 | +> [ Set scaling rules in Azure Container Apps](./scale-app.md) |
| 211 | +> [ Java metrics for Azure Container Apps](./java-metrics.md) |
0 commit comments