init spring boot actuator service
This commit is contained in:
+302
@@ -0,0 +1,302 @@
|
||||
:toc:
|
||||
:gs-rest-service: link:/guides/gs/rest-service
|
||||
:spring_version: current
|
||||
:icons: font
|
||||
:source-highlighter: prettify
|
||||
:project_id: gs-actuator-service
|
||||
|
||||
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready[Spring Boot Actuator]
|
||||
is a subproject of Spring Boot. It adds several production grade services to your
|
||||
application with little effort on your part. In this guide, you will build an application
|
||||
and then see how to add these services.
|
||||
|
||||
== What You Will Build
|
||||
|
||||
This guide takes you through creating a "`Hello, world`" RESTful web service with Spring
|
||||
Boot Actuator. You will build a service that accepts the following HTTP GET request:
|
||||
|
||||
====
|
||||
[source,sh]
|
||||
----
|
||||
$ curl http://localhost:9000/hello-world
|
||||
----
|
||||
====
|
||||
|
||||
It responds with the following JSON:
|
||||
|
||||
====
|
||||
[source,json]
|
||||
----
|
||||
{"id":1,"content":"Hello, World!"}
|
||||
----
|
||||
====
|
||||
|
||||
There are also many features added to your application for managing the service in a
|
||||
production (or other) environment. The business functionality of the service you build is
|
||||
the same as in {gs-rest-service}[Building a RESTful Web Service]. You do not need to use
|
||||
that guide to take advantage of this one, although it might be interesting to compare the
|
||||
results.
|
||||
|
||||
=== What You need
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/main/prereq_editor_jdk_buildtools.adoc[]
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/main/how_to_complete_this_guide.adoc[]
|
||||
|
||||
[[scratch]]
|
||||
== Starting with Spring Initializr
|
||||
|
||||
You can use this https://start.spring.io/#!type=maven-project&groupId=com.example&artifactId=actuator-service&name=actuator-service&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.actuatorservice&dependencies=web,actuator[pre-initialized project] and click Generate to download a ZIP file. This project is configured to fit the examples in this tutorial.
|
||||
|
||||
To manually initialize the project:
|
||||
|
||||
. Navigate to https://start.spring.io.
|
||||
This service pulls in all the dependencies you need for an application and does most of the setup for you.
|
||||
. Choose either Gradle or Maven and the language you want to use. This guide assumes that you chose Java.
|
||||
. Click *Dependencies* and select *Spring Web* and *Spring Boot Actuator*.
|
||||
. Click *Generate*.
|
||||
. Download the resulting ZIP file, which is an archive of a web application that is configured with your choices.
|
||||
|
||||
NOTE: If your IDE has the Spring Initializr integration, you can complete this process from your IDE.
|
||||
|
||||
NOTE: You can also fork the project from Github and open it in your IDE or other editor.
|
||||
|
||||
== Run the Empty Service
|
||||
|
||||
The Spring Initializr creates an empty application that you can use to get started. The
|
||||
following shows the class created by the Spring Initializr:
|
||||
|
||||
====
|
||||
[source,java,tabsize=2]
|
||||
----
|
||||
include::initial/src/main/java/com/example/actuatorservice/ActuatorServiceApplication.java[]
|
||||
----
|
||||
====
|
||||
|
||||
The `@SpringBootApplication` annotation provides a load of defaults (like the embedded
|
||||
servlet container), depending on the contents of your classpath and other things. It also
|
||||
turns on Spring MVC's `@EnableWebMvc` annotation, which activates web endpoints.
|
||||
|
||||
There are no endpoints defined in this application, but there is enough to launch things
|
||||
and see some of Actuator's features. The `SpringApplication.run()` command knows how to
|
||||
launch the web application. All you need to do is run the following command:
|
||||
|
||||
====
|
||||
[source,bash,subs="attributes"]
|
||||
----
|
||||
$ ./gradlew clean build && java -jar build/libs/{project_id}-0.0.1-SNAPSHOT.jar
|
||||
----
|
||||
====
|
||||
|
||||
You have yet to write any code, so what is happening? To see the answer, wait for the
|
||||
server to start, open another terminal, and try the following command (shown with its
|
||||
output):
|
||||
|
||||
====
|
||||
[source,bash]
|
||||
----
|
||||
$ curl localhost:8080
|
||||
{"timestamp":1384788106983,"error":"Not Found","status":404,"message":""}
|
||||
----
|
||||
====
|
||||
|
||||
The output of the preceding command indicates that the server is running but that you have
|
||||
not defined any business endpoints yet. Instead of a default container-generated HTML
|
||||
error response, you see a generic JSON response from the Actuator `/error` endpoint. You
|
||||
can see in the console logs from the server startup which endpoints are provided out of
|
||||
the box. You can try a few of those endpoints, including the `/health` endpoint. The
|
||||
following example shows how to do so:
|
||||
|
||||
====
|
||||
[source,bash]
|
||||
----
|
||||
$ curl localhost:8080/actuator/health
|
||||
{"status":"UP"}
|
||||
----
|
||||
====
|
||||
|
||||
The status is `UP`, so the actuator service is running.
|
||||
|
||||
See Spring Boot's
|
||||
https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator[Actuator Project]
|
||||
for more details.
|
||||
|
||||
[[initial]]
|
||||
== Create a Representation Class
|
||||
|
||||
First, you need to give some thought to what your API will look like.
|
||||
|
||||
You want to handle GET requests for `/hello-world`, optionally with a name query
|
||||
parameter. In response to such a request, you want to send back JSON, representing a
|
||||
greeting, that looks something like the following:
|
||||
|
||||
====
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"id": 1,
|
||||
"content": "Hello, World!"
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
The `id` field is a unique identifier for the greeting, and `content` contains the textual
|
||||
representation of the greeting.
|
||||
|
||||
To model the greeting representation, create a representation class. The following listing
|
||||
(from `src/main/java/com/example/actuatorservice/Greeting.java`) shows the `Greeting`
|
||||
class:
|
||||
|
||||
====
|
||||
[source,java,tabsize=2]
|
||||
----
|
||||
include::complete/src/main/java/com/example/actuatorservice/Greeting.java[]
|
||||
----
|
||||
====
|
||||
|
||||
Now that you need to create the endpoint controller that will serve the representation
|
||||
class.
|
||||
|
||||
== Create a Resource Controller
|
||||
|
||||
In Spring, REST endpoints are Spring MVC controllers. The following Spring MVC controller
|
||||
(from `src/main/java/com/example/actuatorservice/HelloWorldController.java`) handles a GET
|
||||
request for the `/hello-world` endpoint and returns the `Greeting` resource:
|
||||
|
||||
====
|
||||
[source,java,tabsize=2]
|
||||
----
|
||||
include::complete/src/main/java/com/example/actuatorservice/HelloWorldController.java[]
|
||||
----
|
||||
====
|
||||
|
||||
The key difference between a human-facing controller (`Controller`) and a REST endpoint
|
||||
controller (`RestController`) is in how the response is created. Rather than rely on a
|
||||
view (such as JSP) to render model data in HTML, an endpoint controller returns the data
|
||||
to be written directly to the body of the response.
|
||||
|
||||
The response is written using one of Spring's message converters. Because Jackson is in the classpath,
|
||||
https://docs.spring.io/spring/docs/{spring_version}/javadoc-api/org/springframework/http/converter/json/JacksonJsonHttpMessageConverter.html[`JacksonJsonHttpMessageConverter`]
|
||||
will handle the conversion of a `Greeting` object to JSON if the request's `Accept` header
|
||||
specifies that JSON should be returned.
|
||||
|
||||
NOTE: How do you know Jackson is on the classpath? Either run `mvn dependency:tree` or
|
||||
`./gradlew dependencies`, and you get a detailed tree of dependencies that includes
|
||||
Jackson. You can also see that it comes from
|
||||
https://github.com/spring-projects/spring-boot/tree/main/starter/spring-boot-starter-json[/spring-boot-starter-json],
|
||||
itself imported by
|
||||
https://github.com/spring-projects/spring-boot/tree/main/starter/spring-boot-starter-webmvc[spring-boot-starter-webmvc].
|
||||
|
||||
== Run the Application
|
||||
|
||||
You can run the application from a custom main class or directly from one of the
|
||||
configuration classes. For this simple example, you can use the `SpringApplication` helper
|
||||
class. Note that this is the application class that the Spring Initializr created for you,
|
||||
and you need not even modify it for it to work for this simple application. The following
|
||||
listing (from `src/main/java/com/example/actuatorservice/HelloWorldApplication.java`)
|
||||
shows the application class:
|
||||
|
||||
====
|
||||
[source,java,tabsize=2]
|
||||
----
|
||||
include::complete/src/main/java/com/example/actuatorservice/HelloWorldApplication.java[]
|
||||
----
|
||||
====
|
||||
|
||||
In a conventional Spring MVC application, you would add `@EnableWebMvc` to turn on key
|
||||
behaviors, including configuration of a `DispatcherServlet`. But Spring Boot turns on this
|
||||
annotation automatically when it detects *spring-webmvc* on your classpath. This sets you
|
||||
up to build a controller in an upcoming step.
|
||||
|
||||
The `@SpringBootApplication` annotation also brings in a
|
||||
https://docs.spring.io/spring/docs/{spring_version}/javadoc-api/org/springframework/context/annotation/ComponentScan.html[`@ComponentScan`]
|
||||
annotation, which tells Spring to scan the `com.example.actuatorservice` package for those
|
||||
controllers (along with any other annotated component classes).
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/main/build_an_executable_jar_mainhead.adoc[]
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/main/build_an_executable_jar_with_both.adoc[]
|
||||
|
||||
Once the service is running (because you ran `spring-boot:run` in a terminal), you can test it by running the following command in a separate terminal:
|
||||
|
||||
====
|
||||
[source,bash]
|
||||
----
|
||||
$ curl localhost:8080/hello-world
|
||||
{"id":1,"content":"Hello, Stranger!"}
|
||||
----
|
||||
====
|
||||
|
||||
== Switch to a Different Server Port
|
||||
|
||||
Spring Boot Actuator defaults to running on port 8080. By adding an
|
||||
`application.properties` file, you can override that setting. The following listing (from
|
||||
`src/main/resources/application.properties`)shows that file with the necessary changes:
|
||||
|
||||
====
|
||||
[source,properties]
|
||||
----
|
||||
include::complete/src/main/resources/application.properties[]
|
||||
----
|
||||
====
|
||||
|
||||
Run the server again by running the following command in a terminal:
|
||||
|
||||
====
|
||||
[subs="attributes"]
|
||||
----
|
||||
$ ./gradlew clean build && java -jar build/libs/{project_id}-0.0.1-SNAPSHOT.jar
|
||||
----
|
||||
====
|
||||
|
||||
The service now starts on port 9000 and actuator endpoints on port 9001.
|
||||
|
||||
You can test that it is working on port 9000 by running the following commands in a
|
||||
terminal:
|
||||
|
||||
====
|
||||
[source,bash]
|
||||
----
|
||||
$ curl localhost:8080/hello-world
|
||||
curl: (52) Empty reply from server
|
||||
$ curl localhost:9000/hello-world
|
||||
{"id":1,"content":"Hello, Stranger!"}
|
||||
$ curl localhost:9001/actuator/health
|
||||
{"status":"UP"}
|
||||
----
|
||||
====
|
||||
|
||||
== Test Your Application
|
||||
|
||||
To check whether your application works, you should write unit and integration tests for
|
||||
your application.
|
||||
The test class in
|
||||
`src/test/java/com/example/actuatorservice/HelloWorldApplicationTests.java`
|
||||
ensures that
|
||||
|
||||
* Your controller is responsive.
|
||||
* Your management endpoint is responsive.
|
||||
|
||||
Note that the tests start the application on a random port.
|
||||
The following listing shows the test class:
|
||||
|
||||
====
|
||||
[source,java,tabsize=2]
|
||||
----
|
||||
include::complete/src/test/java/com/example/actuatorservice/ActuatorServiceApplicationTests.java[]
|
||||
----
|
||||
====
|
||||
|
||||
== Summary
|
||||
|
||||
Congratulations! You have just developed a simple RESTful service by using Spring, and you
|
||||
added some useful built-in services with Spring Boot Actuator.
|
||||
|
||||
== See Also
|
||||
|
||||
The following guides may also be helpful:
|
||||
|
||||
* https://spring.io/guides/gs/spring-boot/[Building an Application with Spring Boot]
|
||||
* https://spring.io/guides/gs/serving-web-content/[Serving Web Content with Spring MVC]
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/main/footer.adoc[]
|
||||
Reference in New Issue
Block a user