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.
  • 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 the ExampleController 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, the custom 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:

  1. 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
    
  2. Navigate to the java-spring-security app directory by running:

    cd metric-registrar-examples/java-spring-security
    
  3. Build the java-spring-security app by running:

    ./gradlew build
    
  4. 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

  5. From the routes section of the terminal output, record the URL of the java-spring-security app. In the example output in the previous step, this URL is tutorial-example-random-route.cfapps.io.

  6. 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: The text following the image describes the details of the UI.
    The java-spring-security app UI includes the following buttons:

    • Increment Custom gauge: Causes the custom metric to increase by a value of 1. You use this button in Trigger Scaling below.
    • Decrement custom gauge: Causes the custom metric to decrease by a value of 1.
    • 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 the custom 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.

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:

  1. Install the Metric Registrar CLI by running:

    cf install-plugin -r CF-Community "metric-registrar"
    
  2. 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.

  3. 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.

  4. 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 the custom 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.

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:

  1. Log in to Apps Manager. For more information, see Logging In to Apps Manager.

  2. 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.

  3. Click Autoscaling Disabled.

  4. Click Enable Autoscaling. The Manage Autoscaling window appears.

  5. Under Instance Limits, configure upper and lower scaling limits for the java-spring-security app:

    1. For Minimum, enter 1.
    2. For Maximum, enter 5.
    3. Click Apply Changes.
  6. To create an autoscaling rule:

    1. Next to Scaling Rules, click Edit. The Edit Scaling Rules window appears.
    2. Click Add rule. The Select type dropdown appears.
    3. From the Select type dropdown, select Custom. More configuration fields appear below.
    4. For Scale down if less than, enter 2. If the average value of the custom metric falls below this number, Autoscaler scales the number of app instances down.
    5. For Scale up if more than, enter 5. If the average value of the custom metric rises above this number, Autoscaler scales the number of app instances up.
    6. For Metric, enter custom.
    7. 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:

  1. In a browser window, enter the URL of the java-spring-security app UI that you retrieved in Push the Sample App above.

  2. Click Increment Custom gauge enough times to bring the custommetric over the upper scaling limit of 5 that you configured in Create an Autoscaling Rule above. You can verify the value of the custom metric by clicking See the metrics.

  3. 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 reaches 5.

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.