Tutorial: Scaling a Spring App Using a Custom Scaling Metric
Page last updated:
This tutorial describes how to configure App Autoscaler to scale a sample Spring app, java-spring-security
, based on a custom scaling metric.
Overview
In a VMware Tanzu Application Service for VMs (TAS for VMs) deployment, Autoscaler can automatically scale apps based on the custom scaling metrics you configure.
The following table describes the main components involved in this workflow, as well as the steps in which you use them in this tutorial:
Component | Description | Related Tutorial Steps |
---|---|---|
App | The app must emit custom scaling metrics that you create with Prometheus. This tutorial includes a sample Spring app,
java-spring-security , that emits such metrics. For more information about Prometheus, see the
Prometheus documentation. |
Review the Sample App and Push the Sample App |
Metric Registrar | The Metric Registrar is a component of TAS for VMs that allows you to export custom app metrics to Loggregator. You issue commands to the Metric Registrar through the Metric Registrar CLI plug-in. For more information about the Metric Registrar, see Metric Registrar and Custom App Metrics. | Register a Custom Metrics Endpoint |
App Autoscaler | Autoscaler is a service integrated with Apps Manager that automatically scales apps in your TAS for VMs deployment based on the scaling metrics or schedule that you configure. For more information, see Scaling an App Using App Autoscaler. | Create and Autoscaling Rule and Trigger Scaling |
Prerequisites
Before you begin this tutorial, ensure that you have the following prerequisites:
A TAS for VMs deployment in which the Metric Registrar is activated. To configure the Metric Registrar, see Configure the Metric Registrar in Metric Registrar and Custom App Metrics.
Access to Apps Manager in the TAS for VMs deployment. To access Apps Manager, see Logging In to Apps Manager.
The ability to push an app to the TAS for VMs deployment. For more information, see Prerequisites in Pushing an App and Manage Users and Roles in Getting Started with the cf CLI.
Note: You must have
SpaceDeveloper
permissions in at least one space.An installation of the Cloud Foundry Command-Line Interface (cf CLI). To install the cf CLI, see Installing the cf CLI.
A terminal.
Review the Sample App
To review the code for the sample app, java-spring-security
, see the metric-registrar-examples
repository on GitHub. This sample app is a Spring app with a simple user interface (UI) that includes several buttons to call different endpoints. Some of
these endpoints are instrumented to produce metrics.
For more details about the code, see the sections below:
Dependencies
In the code for the java-spring-security
app, the build.gradle
file lists the following app dependencies:
dependencies {
implementation('io.micrometer:micrometer-registry-prometheus')
implementation('org.springframework.boot:spring-boot-starter-actuator')
implementation('org.springframework.boot:spring-boot-starter-security')
implementation('org.springframework.boot:spring-boot-starter-web')
testImplementation('org.springframework.boot:spring-boot-starter-test')
testImplementation('org.springframework.security:spring-security-test')
}
The above list includes the following dependencies:
The Micrometer Prometheus library, which does the following:
- Creates a metrics endpoint at
/actuator/prometheus
in a format that the Metric Registrar supports. - Allows you to instrument the
java-spring-security
app by creating new metrics. For more information, see Instrumentation below.
- Creates a metrics endpoint at
The Spring Security dependency, which exposes the metric endpoints so that Metric Registrar can access them.
To view the build.gradle
file, see build.gradle on
GitHub.
For more information about the Micrometer Prometheus library, see the Micrometer documentation.
Instrumentation
This section describes how the java-spring-security
app is instrumented. Instrumentation refers to code that is included in an app to measure performance.
In the code for the java-spring-security
app, the ExampleController.java
file includes the following parts:
The following
MeterRegistry
object in theExampleController
class:private MeterRegistry registry; private AtomicLong custom; public ExampleController(MeterRegistry registry) { this.registry = registry; this.custom = new AtomicLong(0L); }
The
MeterRegistry
object is passed and set in the constructor.A
custom
variable that is initialized in the constructor:public ResponseEntity<String> customMetric(@RequestParam(value="inc", defaultValue="") String increment) { AtomicLong customGauge = registry.gauge("custom", this.custom); if (!"".equals(increment)) { customGauge.incrementAndGet(); } else { customGauge.decrementAndGet(); }
In the
customMetric
handler, thecustom
variable is passed to the registry and either incremented or decremented. For more information, see customMetric on GitHub.Note: Autoscaler can only use gauge metrics, or metrics that can go up and down, as scaling metrics. Metrics such as CPU, disk, HTTP throughput, and HTTP latency are all gauge metrics.
To view the ExampleController.java
file, see
ExampleController.java
on GitHub.
Push the Sample App
To push the java-spring-security
app:
In a terminal window, clone the Git repository that contains the
java-spring-security
app by running:git clone git@github.com:pivotal-cf/metric-registrar-examples.git
Navigate to the
java-spring-security
app directory by running:cd metric-registrar-examples/java-spring-security
Build the
java-spring-security
app by running:./gradlew build
Push the
java-spring-security
app with a random route by running:cf push --random-route
The above command returns output similar to the following example:
Waiting for app to start... Uploaded droplet (60.5M) Uploading complete Cell 333e7fdf-806e-424d-b3a0-78967ecb6d28 stopping instance 6f345835-8beb-48a5-b578-921f5de442c6
name: tutorial-example requested state: started routes: tutorial-example-random-route.cfapps.io last uploaded: Wed 28 Aug 11:02:33 PDT 2019
From the
routes
section of the terminal output, record the URL of thejava-spring-security
app. In the example output in the previous step, this URL istutorial-example-random-route.cfapps.io
.In a browser window, navigate to the URL you recorded in the previous step. The following screenshot shows the UI of the
java-spring-security
app:
Thejava-spring-security
app UI includes the following buttons:- Increment Custom gauge: Causes the
custom
metric to increase by a value of1
. You use this button in Trigger Scaling below. - Decrement custom gauge: Causes the
custom
metric to decrease by a value of1
. - See the metrics: Opens
/actuator/prometheus
in your browser. The Metric Registrar uses this page to collect metrics. You can use this page to view the values of thecustom
metric and all metrics from the Micrometer Prometheus library. - Increment Simple counter and Call an endpoint with high latency: These buttons are not used in this tutorial. To learn more about the functions of these buttons, see java-spring-security on GitHub.
- Increment Custom gauge: Causes the
Register a Custom Metrics Endpoint
In order for an app to emit custom metrics, you must first register the app as a metric source with the Metric Registrar.
To register a custom metrics endpoint for the java-spring-security
app:
Install the Metric Registrar CLI by running:
cf install-plugin -r CF-Community "metric-registrar"
Register the metrics endpoint of the
java-spring-security
app by running:cf register-metrics-endpoint java-spring-security /actuator/prometheus --insecure
Because the app dependencies include the Micrometer Prometheus library, there is automatically a metrics endpoint at
/actuator/prometheus
.Warning: When you include the
--insecure
flag in the above command, the Metric Registrar scrapes the metrics endpoint on the default app port. Exposing metrics on the default app port makes the metrics available to anyone with access to the app. VMware strongly recommends that you do not use the--insecure
flag in a production environment. Instead, specify an alternative port by including the--internal-port
flag. Specifying an alternative port the--internal-port
flag exposes the metrics endpoint on that port and limits access to the app.Install the Log Cache CLI by running:
cf install-plugin -r CF-Community "log-cache"
Log Cache is a component of TAS for VMs that allows you to filter and query app logs.
View the app metrics as they are emitted by running:
cf tail java-spring-security --envelope-class metrics --follow
When you include the
--follow
flag in the above command, the return output is appended to metrics as they are emitted, similar to the following example:Retrieving logs for app tutorial-example in org sandbox / space development as example@user...
2019-08-28T09:17:56.28-0700 [tutorial-example/1] GAUGE cpu:0.289158 percentage disk:135716864.000000 bytes disk_quota:1073741824.000000 bytes memory:399979315.000000 bytes memory_quota:2147483648.000000 bytes 2019-08-28T09:17:56.50-0700 [tutorial-example/0] GAUGE custom:1.000000
Notes:- In the
java-spring-security
app UI, you must click Increment Custom gauge at least one time to cause the app to emit thecustom
metric. - If you do not see output similar to the above example, the Metric Registrar might not exist in your TAS for VMs deployment. To determine this, consult the operator of your TAS for VMs deployment.
- In the
Create an Autoscaling Rule
Autoscaler is integrated with Apps Manager. You can create autoscaling rules in Apps Manager.
To create an autoscaling rule for the java-spring-security
app that uses the custom
metric as its scaling metric:
Log in to Apps Manager. For more information, see Logging In to Apps Manager.
In Apps Manager, navigate to the
java-spring-security
app overview. For more information, see View App Overview in Managing Apps and Service Instances Using Apps Manager.Click Autoscaling Disabled.
Click Enable Autoscaling. The Manage Autoscaling window appears.
Under Instance Limits, configure upper and lower scaling limits for the
java-spring-security
app:- For Minimum, enter
1
. - For Maximum, enter
5
. - Click Apply Changes.
- For Minimum, enter
To create an autoscaling rule:
- Next to Scaling Rules, click Edit. The Edit Scaling Rules window appears.
- Click Add rule. The Select type dropdown appears.
- From the Select type dropdown, select Custom. More configuration fields appear below.
- For Scale down if less than, enter
2
. If the average value of thecustom
metric falls below this number, Autoscaler scales the number of app instances down. - For Scale up if more than, enter
5
. If the average value of thecustom
metric rises above this number, Autoscaler scales the number of app instances up. - For Metric, enter
custom
. - Click Save.
Trigger Scaling
Now that you have pushed the java-spring-security
app, configured the app to emits the custom
metric, and configured Autoscaler to scale the number of app
instances up or down using the custom
metric as its scaling metric, you can trigger a scaling action. Autoscaler scales the app when the custom
metric
goes above the upper scaling limit or below the lower scaling limit that you configured in Create an Autoscaling Rule above.
To trigger a scaling action:
In a browser window, enter the URL of the
java-spring-security
app UI that you retrieved in Push the Sample App above.Click Increment Custom gauge enough times to bring the
custom
metric over the upper scaling limit of5
that you configured in Create an Autoscaling Rule above. You can verify the value of thecustom
metric by clicking See the metrics.In Apps Manager, monitor the
java-spring-security
app overview for about two minutes. Autoscaler begins to scale the app up, creating one app instance at a time until the number of instances reaches5
.
Next Steps
Now that you have completed this tutorial, you can create custom scaling metrics and autoscaling rules with your own app. For more information, review the resources listed in Overview above. After you have configured your app to emit custom metrics, you can follow the steps outlined in this tutorial to scale based on those metrics.