Description
Spring Boot Admin Server information
-
Version: 3.5.0
-
Spring Boot version: 3.5.0
-
Configured Security: None
-
Webflux or Servlet application: WebFlux
Client information
-
Spring Boot versions: 3.5.0
-
Used discovery mechanism: Eureka
-
Webflux or Servlet application: Servlet
Description
Hello.
In the log files of my applications under monitoring I see multiple entries like
2025-06-06T04:26:47,WARN,HealthEndpointSupport:181,Health contributor org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator (db) took 13859ms to respond
To be more precise, I see exactly 2 of them at the exact same time.
Given that I've 2 SBA instances running, I've the impression they're both pinging for the health even if I've the clustering with Hazelcast configured as follows:
import jakarta.annotation.Nullable;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.DefaultValue;
import org.springframework.validation.annotation.Validated;
import static com.hazelcast.config.Config.DEFAULT_CLUSTER_NAME;
import static com.hazelcast.config.NetworkConfig.DEFAULT_PORT;
import static de.codecentric.boot.admin.server.config.AdminServerHazelcastAutoConfiguration.DEFAULT_NAME_EVENT_STORE_MAP;
import static de.codecentric.boot.admin.server.config.AdminServerHazelcastAutoConfiguration.DEFAULT_NAME_SENT_NOTIFICATIONS_MAP;
@Validated
@ConfigurationProperties(HazelcastSbaProperties.PREFIX)
public record HazelcastSbaProperties(
@Nullable String dnsName,
@Nullable String instanceName,
@DefaultValue(ENABLED_DEFAULT_VALUE) boolean enabled,
@Min(0) @DefaultValue(HAZELCAST_DEFAULT_PORT) int port,
@NotBlank @DefaultValue(DEFAULT_CLUSTER_NAME) String clusterName,
@NotBlank @DefaultValue(DEFAULT_NAME_EVENT_STORE_MAP) String eventStore,
@NotBlank @DefaultValue(DEFAULT_NAME_SENT_NOTIFICATIONS_MAP) String sentNotifications
) {
private static final String ENABLED_DEFAULT_VALUE = "true";
private static final String HAZELCAST_DEFAULT_PORT = "" + DEFAULT_PORT;
static final String PREFIX = "spring.boot.admin.hazelcast";
}
import com.hazelcast.config.Config;
import com.hazelcast.config.EvictionConfig;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.MergePolicyConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.InetAddress;
import static com.hazelcast.config.InMemoryFormat.OBJECT;
import static com.hazelcast.config.MaxSizePolicy.PER_NODE;
import static com.hazelcast.internal.diagnostics.HealthMonitorLevel.OFF;
import static com.hazelcast.kubernetes.KubernetesProperties.SERVICE_DNS;
import static com.hazelcast.spi.properties.ClusterProperty.HEALTH_MONITORING_LEVEL;
import static com.hazelcast.spi.properties.ClusterProperty.SOCKET_BIND_ANY;
import static com.sixgroup.cit.fmd.zookeepers.monitoring.config.HazelcastSbaProperties.PREFIX;
import static java.lang.Boolean.FALSE;
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(HazelcastSbaProperties.class)
public class HazelcastSbatConfig {
// See https://docs.spring-boot-admin.com/3.4.5/docs/server/server#clustering
@Bean
@ConditionalOnProperty(prefix = PREFIX, name = "enabled", matchIfMissing = true)
public Config hazelcastConfig(HazelcastSbaProperties properties) {
MergePolicyConfig mergePolicyConfig = new MergePolicyConfig();
Config config = new Config();
config
.setClusterName(properties.clusterName())
.setInstanceName(properties.instanceName())
.addMapConfig(new MapConfig(properties.eventStore()).setInMemoryFormat(OBJECT).setMergePolicyConfig(mergePolicyConfig))
.addMapConfig(new MapConfig(properties.sentNotifications()).setInMemoryFormat(OBJECT).setEvictionConfig(new EvictionConfig().setMaxSizePolicy(PER_NODE)).setMergePolicyConfig(mergePolicyConfig))
.getNetworkConfig()
.setPort(properties.port())
.getJoin().getMulticastConfig().setEnabled(false);
config.getJetConfig().setEnabled(true);
if(properties.dnsName() == null) {
config.setProperty(SOCKET_BIND_ANY.getName(), FALSE.toString());
config.getNetworkConfig().getInterfaces().setEnabled(true).addInterface(InetAddress.getLoopbackAddress().getHostAddress());
} else {
config.setProperty(HEALTH_MONITORING_LEVEL.getName(), OFF.toString());
config.getNetworkConfig().getJoin().getKubernetesConfig()
.setEnabled(true)
.setProperty(SERVICE_DNS.key(), properties.dnsName());
}
return config;
}
}
# Source: monitoring/templates/configmaps/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: demo
labels:
helm.sh/chart: monitoring-1.1.1-SNAPSHOT
app.kubernetes.io/name: monitoring
app.kubernetes.io/instance: demo
app.kubernetes.io/version: "1.1.1-SNAPSHOT"
app.kubernetes.io/managed-by: Helm
data:
application-dev.yaml: |-
server.port: 8080
spring.boot.admin:
ui:
title: ${spring.application.name} (DEV)
discovery.ignored-services: ["zookeepers service registry"]
hazelcast:
instance-name: "${HOSTNAME}"
port: 5701
cluster-name: dev
dns-name: demo-headless
and in the logs I can see:
2025-06-04T07:20:43.903Z INFO 1 --- [Zookeepers Monitoring] [cached.thread-4] c.h.internal.cluster.ClusterService : [<IP>]:5701 [dev] [5.5.0]
Members {size:2, ver:12} [
Member [<IP>]:5701 - 8413e9a5-1fcd-4d9b-8d0b-b1912a5d5dc2 this
Member [<IP>]:5701 - 11dd2539-d4fe-4efd-8d57-995d12ac32ac
]
2025-06-04T07:20:43.904Z INFO 1 --- [Zookeepers Monitoring] [cached.thread-4] c.h.i.cluster.impl.MembershipManager : [<IP>]:5701 [dev] [5.5.0] Mastership is claimed with: MembersView{version=12, members=[MemberInfo{address=[<IP>]:5701, uuid=8413e9a5-1fcd-4d9b-8d0b-b1912a5d5dc2, cpMemberUUID=null, liteMember=false, memberListJoinVersion=9}, MemberInfo{address=[<IP>]:5701, uuid=11dd2539-d4fe-4efd-8d57-995d12ac32ac, cpMemberUUID=null, liteMember=false, memberListJoinVersion=11}]}
Can you please provide some support about it?