I'd like to have a new on-demand health check endpoint for my service through implementation of indicator. The problem was the on-demand one would be called by default `/actuator/health`, so I have split the default health endpoint into two health groups `/actuator/health/default & /actuator/health/on-demand` as I didn't find any way to remove the on-demand directly from `/actuator/health`.
Now a new issue emerged, by default, spring boot admin will hit /actuator/health to get corresponding info, I was wondering it's possible to ask him to hit /actuator/health/default instead?
BTW, I only have admin client, without any recovery service
haha, this config is the answer: spring.boot.admin.client.instance.health-url
Related
First time I'm trying out the actuator dependency, I configured it to be opt-in
management.endpoints.enabled-by-default=false
management.endpoint.info.enabled=true
management.endpoint.health.enabled=true
When I call /actuator/health locally it takes around 1.4 seconds to respond. Keep in mind this is a local call, from the same machine of the server.
If I create a regular endpoint that replies with an empty response, the request would take just a couple of milliseconds.
Is this normal? Can I make it reply faster?
Original Answer: https://stackoverflow.com/a/63666118/1861769
Basically health endpoint is implemented in a way that it contains a
list of all Spring beans that implement the interface HealthIndicator.
Each health indicator is responsible for supplying a health
information about one subsystem (examples of such subsystem are:disk,
postgres, mongo, etc.), spring boot comes with some predefined
HealthIndicators.
So that when the health endpoint is invoked, it iterates through this
list and gets the information about each subsystem and then constructs
the answer.
Hence you can place a break point in relevant health indicators
(assuming you know which subsystems are checked) and see what happens.
If you're looking for the HTTP entry point - the code that gets called
when you call http:///actuator/health (can vary depending
on your settings but you get the idea)`, it can be found here
Yet another approach that comes to mind is disabling "suspicious"
health check and finding the slow one by elimination.
For example, if you have an elastricsearch and would like to disable
it, use in the application.properties:
management.health.elasticsearch.enabled = false
Up to spring-boot 2.1.9, I used to set management.health.defaults.enabled = false to decouple the /health endpoint overall status from the database status.
As of 2.2.0, that specific setting no longer works that way (see: SpringBoot 2.1.9 -> 2.2.0 - health endpoint no longer works).
Is there a way to configure spring-boot to decouple the overall status of the /health endpoint from whether or not the datasource is up?
I'm inclined to just make my own endpoint hardcoded to return a status of 200.
I don't really understand what you're trying to do and how disabling all defaults achieved what you've described.
What would be the point of having an endpoint that returns 200 unconditionally? That's seriously misleading IMO.
If you do not want the datasource health indicator, then you can disable that (and only that) using management.health.db.enabled=false.
If you want the datasource health check but want to be able to ignore it, create a group that exclude the db health check and use that for monitoring. See the documentation for more details
Is there any way to support multiple health endpoints on a Spring Boot application?
Here's why: The standard actuator health check is great, built in checks are great, customization options are great - for a single use case: reporting on general application health.
But I'd like something I can call from an AWS Elastic Load Balancer / AutoScaling Group. By default, if an instance fails a health check, the ELB/ASG will terminate it and replace it with a fresh instance. The problem is some of the health checks, like DataSourceHealthIndicator, will report DOWN if the database is down, but my application instance is otherwise perfectly healthy. If I use the default behavior, AWS will throw out perfectly healthy instances until the database comes back up, and this will run up my bill.
I could get rid of the DataSourceHealthIndicator, but I like having it around for general health checking purposes. So what I really want is two separate endpoints for two different purposes, such as:
/health - General application health
/ec2Health - Ignores aspects unrelated to the EC2 instance, such as a DB outage.
Hope that makes sense.
Spring Boot Actuator has a feature called Health Groups which allows you to configure multiple health indicators.
In application.properties you configure the groups that you want:
management.endpoints.web.path-mapping.health=probes
management.endpoint.health.group.health.include=*
management.endpoint.health.group.health.show-details=never
management.endpoint.health.group.detail.include=*
management.endpoint.health.group.detail.show-details=always
management.endpoint.health.group.other.include=diskSpace,ping
management.endpoint.health.group.other.show-details=always
Output:
$ curl http://localhost:8080/actuator/probes
{"status":"UP","groups":["detail","health","other"]}
$ curl http://localhost:8080/actuator/probes/health
{"status":"UP"}
$ curl http://localhost:8080/actuator/probes/detail
{"status":"UP","components":{"diskSpace":{"status":"UP","details":{"total":0,"free":0,"threshold":0,"exists":true}},"ping":{"status":"UP"},"rabbit":{"status":"UP","details":{"version":"3.6.16"}}}}
$ curl http://localhost:8080/actuator/probes/other
{"status":"UP","components":{"diskSpace":{"status":"UP","details":{"total":0,"free":0,"threshold":0,"exists":true}},"ping":{"status":"UP"}}}
We are in the process of standing up a new microservices architecture with Zuul at the front-end and a bunch of tomcat enabled microservices at the backend. Each service as it starts up, will register itself with Eureka and any client that wants to call those service will do so through Zuul. We've got this all wired in and everything is working fine.
However, I have a couple questions as to how we can make this architecture much more dynamic.
One thing that we assumed was there out of the box with Ribbon/Eureka, but have yet to find a solution for is that as we add more services to the backend, that somehow (via Archiaus and update to Zuul's eureka-client.properties file) Zuul's Ribbon client would update itself with the new service details (e.g. vipaddress, load balancing algorithm, etc). So far, the only thing that works is to update the properties file and restart Zuul (ughhh).
For example, let's say today we have 2 microservices at the backend, therefore, Zuul's eureka/ribbon client configuration would include the below:
ribbon.client.niws.clientlist=service1|service2
zuul.ribbon.namespace=zuul.client
service1.zuul.client.DeploymentContextBasedVipAddresses=myService1
service1.zuul.client.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
service2.zuul.client.DeploymentContextBasedVipAddresses=myService2
service2.zuul.client.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
Now tomorrow, let's assume we need to add service3. What we have observed is that if we add those details to the same configuration (see below), they only become available to Zuul after a restart. Is there some other configuration parameter we are missing that would allow us to dynamically introduce the new service details or do we have to roll our own Eureka/Ribbon client to do this?
ribbon.client.niws.clientlist=service1|service2|service3
zuul.ribbon.namespace=zuul.client
service1.zuul.client.DeploymentContextBasedVipAddresses=myService1
service1.zuul.client.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
service2.zuul.client.DeploymentContextBasedVipAddresses=myService2
service2.zuul.client.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
service3.zuul.client.DeploymentContextBasedVipAddresses=myService3
service3.zuul.client.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
My other question is related and that is do we really need to add a client configuration (in eureka-client.properties) for every service that Zuul could possibly route to? At some point, we may have 100's of services running and trying to maintain all the related client configurations in Zuul seems a bit clumsy. Is there a way to globally configure Zuul to load all services into its client list from Eureka (or based on some service metadata in Eureka) and dynamically update this list as new services register themselves with Eureka?
Thanks!
The issue is with namespaces.If we use the default namespace it should be able to pick up the new properties addedd by default.
I setup an Eureka cluster composed of 3 replicas.
I got the nice dashboard which is automatically populated with the instances currently registered with Eureka and the DS Replicas.
However the DS Replicas links seems to point to the value I set as eureka.client.serviceUrl.defaultZone. In my case this value is something similar to http://node-01:8761/eureka/ which in reality returns a 404. Is there a way I could configure the dashboard to strip out the /eureka/ part so when I follow the links I end up in the other dashboards or am I misunderstanding the use of those links?
There is no easy way to alter the link as you ask.
However, the UI part of the Eureka server is a standard Spring MVC #Controller. An instance of it is created by org.springframework.cloud.netflix.eureka.server.EurekaServerConfiguration. Have a look at the current implementation... it shouldn't be too hard to provide your own customized version instead.