358 lines
14 KiB
Plaintext
358 lines
14 KiB
Plaintext
[[geode-samples-boot-actuator]]
|
|
= Spring Boot Actuator for Apache Geode & Pivotal GemFire
|
|
:apache-geode-version: 16
|
|
:apache-geode-docs:https://geode.apache.org/docs/guide/{apache-geode-version}
|
|
:images-dir: ../images
|
|
:spring-boot-docs: https://docs.spring.io/spring-boot/docs/current/reference/html
|
|
:spring-framework-docs: https://docs.spring.io/spring/docs/current/spring-framework-reference
|
|
|
|
This guide walks through using {spring-boot-docs}/production-ready.html[Spring Boot Actuator] to assess the state
|
|
of your running Apache Geode or Pivotal GemFire, Spring Boot application.
|
|
|
|
The goal for SBDG's Spring Boot Actuator integration is to enable users to effectively manage and monitor their
|
|
Spring Boot applications using Apache Geode or Pivotal GemFire in a production environment.
|
|
|
|
In particular, SBDG's integration with Spring Boot Actuator currently focuses on enabling
|
|
{spring-boot-docs}/production-ready-endpoints.html#production-ready-health[Health Information]
|
|
for your application. In the future, SBDG will provide dedicated support for http://micrometer.io/[Micrometer] metrics.
|
|
|
|
This guide assumes you are already familiar with Spring Boot and Apache Geode (or Pivotal GemFire).
|
|
|
|
link:../index.html#geode-samples[Back]
|
|
|
|
[[geode-samples-boot-actuator-example]]
|
|
== Example Application
|
|
|
|
This guide additionally provides a working {github-samples-url}/boot/actuator[example application] to review some of
|
|
the Actuator Health Endpoints.
|
|
|
|
The example application is a simple Temperature Monitoring Service, simulating a real-world, Internet of Things (IOT)
|
|
Use Case (UC). Essentially, the application collects temperature readings from different temperature sensors (devices)
|
|
and uses the readings to monitor fluctuations in temperatures so that someone or something can respond accordingly.
|
|
The sensor devices could be located around the world in multiple locations in the planet's oceans.
|
|
|
|
[[geode-samples-boot-actuator-example-temperaturereading]]
|
|
=== TemperatureReading
|
|
|
|
First, we start by modeling a temperature reading, which stores the temperature in Fahrenheit along with a timestamp
|
|
for when the reading was measured.
|
|
|
|
Clearly, a more practical example would store the temperature measurement as a `double` or `BigDecimal` along with
|
|
the ability to support different scales (Celsius, Fahrenheit, Kelvin).
|
|
|
|
However in this case, we simply model the `TemperatureReading` as:
|
|
|
|
.TemperatureReading class
|
|
[source,java]
|
|
----
|
|
include::{samples-dir}/boot/actuator/src/main/java/example/app/temp/model/TemperatureReading.java[tags=class]
|
|
----
|
|
|
|
The `TemperatureReading` class is annotated with SDG's `@Region` mapping annotation to declare the Apache Geode Region
|
|
in which `TemperatureReadings` will be persisted.
|
|
|
|
[[geode-samples-boot-actuator-example-temperatureevent]]
|
|
=== TemperatureEvent
|
|
|
|
A key concern of our application is to "monitor" temperature readings. Therefore, we need some way to capture
|
|
temperature change events.
|
|
|
|
For that, we introduce the simple `TemperatureEvent` base class:
|
|
|
|
.TemperatureEvent class
|
|
[source,java]
|
|
----
|
|
include::{samples-dir}/boot/actuator/src/main/java/example/app/temp/event/TemperatureEvent.java[tags=class]
|
|
----
|
|
|
|
`TemperatureEvent` is a Spring `ApplicationEvent` capable of being published to to Spring `@EventListeners` registered
|
|
in the Spring application context.
|
|
|
|
Additionally, we provide 2 subclasses: `BoilingTemperatureEvent` and `FreezingTemperatureEvent` to further classify
|
|
temperature changes.
|
|
|
|
[[geode-samples-boot-actuator-example-temperaturereadingrepository]]
|
|
=== TemperatureReadingRepository
|
|
|
|
To perform basic data access operations (e.g. CRUD) and simple queries on `TemperatureReadings`, we create
|
|
a Spring Data _Repository_:
|
|
|
|
.TemperatureReadingRepository interface
|
|
[source,java]
|
|
----
|
|
include::{samples-dir}/boot/actuator/src/main/java/example/app/temp/repo/TemperatureReadingRepository.java[tags=class]
|
|
----
|
|
|
|
The _Repository_ showcases a an example, derived query methods, `findByTimestampGreaterThanAndTimestampLessThan(..)`
|
|
along with 2 `@Query` annotated query methods using raw OQL queries.
|
|
|
|
[[geode-samples-boot-actuator-example-temperaturemonitor]]
|
|
=== TemperatureMonitor service class
|
|
|
|
To receive temperature change events, we need a class to monitor changes. This capability is built on Apache Geode's
|
|
{apache-geode-docs}/developing/continuous_querying/chapter_overview.html[Continuous Query (CQ)] functionality.
|
|
|
|
With Apache Geode (or Pivotal GemFire) you can register an (OQL) Query with the servers in the cluster that runs
|
|
continuously, sending notifications back to the client anytime data changes to match the predicate in our query,
|
|
or queries.
|
|
|
|
For our purposes, we will simply monitor the temperature anytime it rises above boiling (212 °F)
|
|
or drops below freezing (32 °F):
|
|
|
|
.TemperatureMonitor class
|
|
[source,java]
|
|
----
|
|
include::{samples-dir}/boot/actuator/src/main/java/example/app/temp/service/TemperatureMonitor.java[tags=class]
|
|
----
|
|
|
|
When the temperature changes, triggering our queries, we receive an event and publish an appropriate `TemperatureEvent`
|
|
by using the Spring container's `ApplicationEventPublisher`, which has been injected into the monitor class.
|
|
|
|
The 2 OQL queries have been defined to query the "TemperatureReadings" Region and fire anytime the temperature
|
|
rises is above boiling (212 °F) or drops below freezing (32 °F).
|
|
|
|
[[geode-samples-boot-actuator-example-temperaturesensor]]
|
|
=== TemperatureSensor service class
|
|
|
|
Of course, we need a simulator to generate temperatures.
|
|
|
|
For that we have the `TemperatureSensor` class:
|
|
|
|
.TemperatureSensor class
|
|
[source,java]
|
|
----
|
|
include::{samples-dir}/boot/actuator/src/main/java/example/app/temp/service/TemperatureSensor.java[tags=class]
|
|
----
|
|
|
|
To generate a stream of temperatures, we use Spring's {spring-framework-docs}/integration.html#scheduling[Scheduling Service]
|
|
along with a `Random` stream of `ints` provided via an `Iterator`, as seen in the `readTemperature()` method.
|
|
|
|
The `readTemperature()` method is then storing the *new* `TemperatureReading` in the "TemperatureReadings" Region
|
|
as designated by our `TemperatureReading` model class's, `@Region` annotation declaration:
|
|
|
|
.@Region declaration
|
|
[source,java]
|
|
----
|
|
@Region("TemperatureReadings")
|
|
public class TemperatureReading { ... }
|
|
----
|
|
|
|
Additionally, the `readTempeature()` method uses our `TemperatureReadingRepository` to perform the necessary
|
|
data access operations.
|
|
|
|
[[geode-samples-boot-actuator-example-server]]
|
|
=== Server
|
|
|
|
Now, we need a couple of main application classes to actually have the application do something useful.
|
|
|
|
We start with an Spring Boot, Apache Geode Server application functioning as the temperature sensor (device)
|
|
using the `TemperatureSensor` class:
|
|
|
|
.BootGeodeServerApplication main class
|
|
[source,java]
|
|
----
|
|
include::{samples-dir}/boot/actuator/src/main/java/example/app/temp/geode/server/BootGeodeServerApplication.java[tags=class]
|
|
----
|
|
|
|
This class is annotated with `@SpringBootApplication` making it a proper Spring Boot application. It uses Spring Boot's
|
|
`SpringApplicationBuilder` to configure and bootstrap the server application.
|
|
|
|
This class is also annotated with SDG's `@CacheServerApplication` making it a proper Apache Geode Server with a peer
|
|
`Cache` instance along with a `CacheServer` to accept client connections. This effectively overrides SBDG's default
|
|
`ClientCache` instance.
|
|
|
|
Additionally, the class enables several other features, such as Spring's _Scheduling Service_, Apache Geode Statistics,
|
|
and entity-defined Regions making the creation of our server-side, partitioned "TemperatureReadings" Region simple.
|
|
|
|
By enabling Apache Geode statistics, we allow Spring Boot's Actuator, `HealthIndicators` to collect metrics about
|
|
our running Apache Geode Server as well.
|
|
|
|
Because we have enabled scheduling (with `@EnableScheduling`) and declared the `TemperatureSensor` class as a bean
|
|
in the Spring application context, the application will immediately start generating temperature readings, which are
|
|
recorded to the "TemperatureReadings" Region.
|
|
|
|
Finally, our class registers a couple Apache Geode Region Indexes to make the Actuator `HealthIndicator` information
|
|
more interesting, particularly since we are running continuous queries.
|
|
|
|
This is a Servlet-based application as well since our Actuator, `HealthIndicator` endpoints are exposed via HTTP.
|
|
|
|
TIP: There are multiple ways to configure and bootstrap an Apache Geode Server, and the server-side of our application.
|
|
Using Spring Boot is one of the easier ways.
|
|
|
|
[[geode-samples-boot-actuator-example-client]]
|
|
=== Client
|
|
|
|
Next, we need a client functioning as the "monitor" in our Temperature Service application.
|
|
|
|
.BootGeodeClientApplication main class
|
|
[source,java]
|
|
----
|
|
include::{samples-dir}/boot/actuator/src/main/java/example/app/temp/geode/client/BootGeodeClientApplication.java[tags=class]
|
|
----
|
|
|
|
Again, this class is also annotated with `@SpringBootApplication` making it a proper Spring Boot application. It too
|
|
uses Spring Boot's `SpringApplicationBuilder` class to configure and bootstrap the client application.
|
|
|
|
Unlike our server, this class is not annotated with any SDG `@*Cache*Application` annotations since SBDG provides us
|
|
a `ClientCache` instance by default. We want this application to be a client in our setup.
|
|
|
|
Like our server, we enable entity-defined Regions to easily and quickly create the client `PROXY` Region
|
|
for "TemperatureReadings", which will send/receive data to/from the server-side Region by the same name.
|
|
|
|
And, like our server application, we declare a bean of type `TemperatureMonitor` in the Spring application context
|
|
to receive the `TemperatureReading` events. This enables the CQ registration and event handlers
|
|
to sets things in motion.
|
|
|
|
Probably the most interesting part is that we an `@EventListener` to receive the `TemperatureEvents` to log
|
|
the `TemperatureReadings` to `System.err`.
|
|
|
|
[[geode-samples-boot-actuator-example-run]]
|
|
== Run the Example
|
|
|
|
It is time to run the example.
|
|
|
|
First, we start the server:
|
|
|
|
.Run the server
|
|
[source,txt]
|
|
----
|
|
/Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/bin/java -server -ea -Dspring.profiles.active=server
|
|
... example.app.temp.geode.server.BootGeodeServerApplication
|
|
|
|
. ____ _ __ _ _
|
|
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
|
|
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
|
|
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
|
|
' |____| .__|_| |_|_| |_\__, | / / / /
|
|
=========|_|==============|___/=/_/_/_/
|
|
:: Spring Boot :: (v2.0.9.RELEASE)
|
|
|
|
TEMPERATURE READING [99 °F]
|
|
TEMPERATURE READING [-17 °F]
|
|
TEMPERATURE READING [67 °F]
|
|
TEMPERATURE READING [9 °F]
|
|
TEMPERATURE READING [102 °F]
|
|
TEMPERATURE READING [10 °F]
|
|
...
|
|
----
|
|
|
|
After the server starts and begins to log temperature readings (as shown above), then start the client:
|
|
|
|
.Run the client
|
|
[source,txt]
|
|
----
|
|
/Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/bin/java -server -ea -Dspring.profiles.active=client
|
|
... example.app.temp.geode.client.BootGeodeClientApplication
|
|
|
|
. ____ _ __ _ _
|
|
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
|
|
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
|
|
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
|
|
' |____| .__|_| |_|_| |_\__, | / / / /
|
|
=========|_|==============|___/=/_/_/_/
|
|
:: Spring Boot :: (v2.0.9.RELEASE)
|
|
|
|
COLD TEMPERATURE READING [-22 °F]
|
|
COLD TEMPERATURE READING [25 °F]
|
|
HOT TEMPERATURE READING [305 °F]
|
|
COLD TEMPERATURE READING [-82 °F]
|
|
HOT TEMPERATURE READING [295 °F]
|
|
HOT TEMPERATURE READING [326 °F]
|
|
HOT TEMPERATURE READING [378 °F]
|
|
COLD TEMPERATURE READING [-4 °F]
|
|
...
|
|
----
|
|
|
|
You should only see boiling and freezing temperatures logged to the client's console. This is because our client
|
|
only "monitors" and logs temperature readings above or below our thresholds (boiling/freezing), as defined by
|
|
the Continuous Queries (CQ).
|
|
|
|
Both the server and client will continue to run, generating and logging temperatures, until you stop the JVM processes.
|
|
|
|
[[geode-samples-boot-actuator-example-monitor]]
|
|
== Monitoring our Example with Spring Boot Actuator, HealthIndicator Endpoints
|
|
|
|
After the application has been running for some time, we can inspect the Spring Boot Actuator, HealthIndicator Endpoints
|
|
provided by SBDG to monitor our application's health and runtime performance in addition to basic configuration
|
|
meta-data used to configure Apache Geode at runtime.
|
|
|
|
[[geode-samples-boot-actuator-example-monitor-client]]
|
|
=== Client Health Information
|
|
|
|
To navigate to the client applications Actuator Health endpoints, open a Web Browser (e.g. Google Chrome) to:
|
|
|
|
`http://localhost:9191/actuator/health`
|
|
|
|
This will output a JSON document similar to:
|
|
|
|
image::{images-dir}/client-actuator-health-endpoints.png[]
|
|
|
|
We can see details on our client "TemperatureReadings" Region:
|
|
|
|
image::{images-dir}/client-actuator-health-region-endpoint.png[]
|
|
|
|
As well as our CQs:
|
|
|
|
image::{images-dir}/client-actuator-health-cq-endpoint.png[]
|
|
|
|
When you hit refresh, the metrics will update.
|
|
|
|
[[geode-samples-boot-actuator-example-monitor-server]]
|
|
=== Server Health Information
|
|
|
|
To navigate to the server applications Actuator Health endpoint, open a Web Browser (e.g. Google Chrome) to:
|
|
|
|
`http://localhost:8181/actuator/health`
|
|
|
|
This will output a JSON document similar to:
|
|
|
|
image::{images-dir}/server-actuator-health-endpoints.png[]
|
|
|
|
We can see details of the server "TemperatureReadings" Region:
|
|
|
|
image::{images-dir}/server-actuator-health-region-endpoint.png[]
|
|
|
|
As well as our Indexes:
|
|
|
|
image::{images-dir}/server-actuator-health-indexes-endpoint.png[]
|
|
|
|
And our CacheServer serving clients:
|
|
|
|
image::{images-dir}/server-actuator-health-cacheserver-endpoint.png[]
|
|
|
|
When you hit refresh, the metrics will update.
|
|
|
|
[[geode-samples-boot-actuator-enabling]]
|
|
== Enabling Spring Boot Actuator
|
|
|
|
All of this was made possible by including the following dependency on our application classpath:
|
|
|
|
.Maven POM
|
|
[source,xml]
|
|
----
|
|
<dependency>
|
|
<groupId>org.springframework.geode</groupId>
|
|
<artifactId>spring-geode-starter-actuator</artifactId>
|
|
</dependency
|
|
----
|
|
|
|
Additionally, in Spring Boot `application.properties`, you must enable the following:
|
|
|
|
.Spring Boot `application.properties`
|
|
[source,txt]
|
|
----
|
|
management.endpoint.health.show-details=always
|
|
----
|
|
|
|
[[geode-samples-boot-actuator-conclusion]]
|
|
== Conclusion
|
|
|
|
Hopefully this guide has shown you how to use the Spring Boot Actuator feature for Apache Geode and Pivotal GemFire.
|
|
|
|
You are encouraged to read more about {spring-boot-docs}/production-ready.html[Spring Boot's Actuator] functionality.
|
|
|
|
Additonally, you can find out more about Apache Geode Statistics
|
|
in the {apache-geode-docs}/managing/statistics/chapter_overview.html[User Guide].
|
|
|
|
link:../index.html#geode-samples[Back]
|