checking whether spring boot application is running or not - java

I've created a spring boot project and deployed it on a vm. I've added a command in local.rc that starts the spring boot application on reboot. I want to check whether the command got executed and the application is running. How do I do that?

There are two ways
On system level - you can run your project as a service, which is documented in the Official documentation - Deployments. Then you can query the application status service myapp status.
On application level - include Spring Boot Actuator in your app and use the Actuator endpoints such as /actuator/health as per Official documentation - Production Ready Endpoints. These endpoints can be exposed via HTTP or JMX.
Note: prior to spring boot 2.0 the actuator endpoint is /health

If it's a web project, it makes sense to include spring-boot-actuator (just add a dependency in maven and start the microservice).
In this case, it will automatically expose the following endpoint (for example, its actually can be flexibly set up):
http://<HOST>:<PORT>/health
Just issue an HTTP GET request, and if you get 200 - it's up and running.
If using an actuator is not an option (although it should be really addressed as a first bet), then you can merely telnet to http://<HOST>:<PORT>
The ratio behind this is that that PORT is exposed and ready to "listen" to external connections only after the application context is really started.

Related

How to configure a Spring Boot Application that uses tomcat and has a dependency to another Application uses tomcat

I have a Spring Boot application (App1) that uses an embedded Tomcat. To specify the Port I added server.port=8080 to the application.properties in my main application
and it works fine.
Now I add a dependency to another Spring Boot application (App2) in the pom.xml (because in App1 I need access to the Beans from App2). App2 uses also an embedded Tomcat on a different port.
But when I run App1 it crashes because App2 want to also use the same server.port and configurations - that obviously cannot work.
Is this even possible what I want to achieve? And how would I do this that I can run both App2 in App1? If this is not possible, is it possible to access the Beans from App2 in App1?
I see two options, depending on which one suits your use case conceptually:
you have two Spring Boot applications that need to share the same code: extract this code to a separate project (a regular Java library), build it as a jar file and include into both projects as a dependency; an example could be found in the Creating a Multi Module Project guide;
you have two Spring Boot applications, one of them needs to access the functionality of another: provide and access this functionality as an API, instead of directly importing the beans. There are multiple ways to do this. For example, you could expose the bean functionality as a REST API using Spring's #RestController, and access them from the other side using RestTemplate. See the following guides: Building a RESTful Web Service, Consuming a RESTful Web Service

How to run the app with spring-cloud-starter-aws locally?

I need to run Spring Boot based app locally. It uses spring-cloud-starter-aws dependency.
The problem is that it tries to connect to EC2 metadata service always. Setting "cloud.aws.*" properties doesn't help.
I expect that default AWS credentials chain will be used, credentials and region will be read from one of AWS preferred way (e.g. ~/.aws/config and ~/.aws/credentials files).
I tried to set cloud.aws.credentials.useDefaultAwsCredentialsChain property but spring-cloud-starter-aws doesn't care
I found examples that use CloudFormation stack for very strange reason to run the app locally.
When I use AWS SDK for Java default AWS chain is used without any issues - I don't need to do anything specific for local running of the application (locally it reads credentials from files and on EC2 it uses instance metadata service). But with Spring Boot it doesn't work out of the box and I need to enable local running somehow.
I use 2.2.2.RELEASE version of Spring Boot and 2.2.1.RELEASE version of Spring Cloud. I have a feeling they introduced regression, because in previous versions it worked without problems.
Any ideas how to run the app locally?
Adding the following lines to configuration helps:
cloud.aws.region.static=my region
cloud.aws.stack.auto=false
spring.autoconfigure.exclude=org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration
So Spring uses AWS default chain but only for credentials. AWS SDK uses it for region and other configuration parameters too. So this is Spring bug for sure.
It still gives a warning about no connection to instance metadata service once during application start but more or less this solution can be used for local running.
If we don't have the last line with excluding CloudWatchExportAutoConfiguration, there will be many exceptions in stack trace while closing the app. I use CloudWatch metrics in my app.
I guess rationale behind excluding aws auto configuration is that it has conflicts with boot actuator but I'm not sure.

Different ports on spring actuator

We have following spring setup:
Our application is running on port 80, but our managment.server.port is set to 8081. And we use multiple checks of the management endpoints from this secured port already.
server.port=80
management.server.port=8081
management.endpoints.web.exposure.include=*
With this settings we can hide any sensitive information from the public interface on port 80.
But now our requirements changed: We need to display the version of our application on the public interface. This information is part of the info-endpoint of our management-server on /actuator/info
Is it possible to move only the info endpoint to port 80, and let all other management.server endpoints still on 8081?
Or is there any other suitable solution for our requirement to only open the info endpoint for external calls.
We prefer to not change any firewall setting: so one port is public, and the other is internal only
No you can't move only one endpoint to different port.
This about the actuator as an application that runs on one specific port (8081) in this case and exposes a bunch of services, so its all-or-nothing from this standpoint.
So you'll have to create a special rest controller that would read the file (or keep the memory) the data just like the info endpoint does.
Its a pretty staightforward code actually, it reads a file available in the spring boot artifact anyway and exposes its content.
You can checkout the source code of the info endpoint of the actuator here

Using Prometheus to monitor Spring Boot Applications in Kubernetes Cluster

I have spring boot powered microservices deployed in my local kubernetes cluster. The microservices are using micrometer and prometheus registry but due to our company policy the actuator is available on another port:
8080 for "business" http requests
8081/manage for actuator. So, I can access http://host:8081/manage/prometheus and see the metrics when running the process locally (without kubernetes).
Now, I'm a beginner in Prometheus and have a rather limited knowledge in kubernetes (I'm coming with a Java developer background).
I've created a POD with my application and succesfully run it in kubernetes. It works and I can access it (for 8080 I've created a service to map the ports) and I can execute "business" level http requests it from the same PC.
But I haven't find any examples of adding a prometheus into the picture. Prometheus is supposed to be deployed in the same kubernetes cluster just as another pod. So I've started with:
FROM #docker.registry.address#/prom/prometheus:v2.15.2
COPY entrypoint.sh /
USER root
RUN chmod 755 /entrypoint.sh
ADD ./prometheus.yml /etc/prometheus/
ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh looks like:
#!/bin/sh
echo "About to run prometheus"
/bin/prometheus --config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/prometheus \
--storage.tsdb.retention.time=3d \
--web.console.libraries=/etc/prometheus/console_libraries \
--web.console.templates=/etc/prometheus/consoles
My question is about how exactly I should define prometheus.yml so that it will get the metrics from my spring boot pod (and other microservices that I have, all spring boot driven with the same actuator setup).
I've started with (prometheus.yml):
global:
scrape_interval: 10s
evaluation_interval: 10s
scrape_configs:
- job_name: 'prometheus'
metrics_path: /manage/prometheus
kubernetes_sd_configs:
- role: pod
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
action: keep
regex: sample-pod-app(.*)|another-pod-app(.*)
But apparently it doesn't work, so I've asking for the advices:
If someone has a working example it would be the best :)
Intuitively I understand I need to specify the port mapping for my 8081 port but I'm not exactly know how
Since prometheus is supposed to run on another port am I supposed to expose a kubernetes service for port 8081 at the kubernetes level?
Do I need any security related resources in kubernetes to be defined?
As a side note. At this point I don't care about scalability issues, I believe one prometheus server will do the job, but I'll have to add Grafana into the picture.
Rather than hardcoding it in prometheus config you need to make use of annotations on your pods to to tell prometheus which pods, what path and which port Prometheus should scrape.
prometheus.io/scrape: "true"
prometheus.io/path=/manage/prometheus
prometheus.io/port=8081
prometheus.io/scheme=http
Spring boot micrometer example with Prometheus on kubernetes.
Prometheus deployment guide.
In order to let Prometheus collect metrics from your Spring Boot Application you need to add a specific dependencies to it. Here you can find a guide showing how to make it done: Spring Boot metrics monitoring using Prometheus & Grafana. Here is an example:
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_spring_boot</artifactId>
<version>0.1.0</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_hotspot</artifactId>
<version>0.1.0</version>
</dependency>
If you would like to use a bit different strategy you can also check out this one: Monitoring Spring Boot applications with Prometheus and Grafana:
In order to compare the performance of different JDKs for reactive
Spring Boot services, I made a setup in which a Spring Boot
application is wrapped in a Docker container. This makes it easy to
create different containers for different JDKs with the same Spring
Boot application running in it. The Spring Boot application exposes
metrics to Prometheus. Grafana can read these metrics and allows to
make nice visualizations from it. This blog post describes a setup to
get you up and running in minutes.
Please let me know if that helped.

Spring boot application shutting down on AWS

I have a Spring boot web application running on Production deployed on Amazon Web Servers. I have create two instances of my Web applications. But sometimes one/both instance(s) automatically stops. I can't understand how the process are killed automatically.
This issue is affecting many users experience. I am using Spring Boots default properties for tomcat.
Check your application.properties for endpoints.shutdown.enabled=true.
Perhaps the shutdown endpoint is getting called by someone.
Also, scan your code for any 'System.exit'
Also, the jvm may be crashing...
Is it stopping gracefully? Are there any logs?
Found the problem:
springBoot {
mainClass = ''
executable = true
buildInfo()
}
executable needs to be changed to false

Categories

Resources