4848import org .slf4j .Logger ;
4949import org .slf4j .LoggerFactory ;
5050import org .springframework .beans .factory .annotation .Autowired ;
51+ import org .springframework .beans .factory .annotation .Value ;
5152import org .springframework .data .redis .core .RedisTemplate ;
5253import org .springframework .stereotype .Service ;
5354
55+ import java .util .concurrent .atomic .AtomicInteger ;
56+
5457@ Service
5558public class HealthService {
5659
@@ -87,13 +90,23 @@ public class HealthService {
8790 private final ReentrantReadWriteLock advancedCheckLock = new ReentrantReadWriteLock ();
8891 private final AtomicBoolean advancedCheckInProgress = new AtomicBoolean (false );
8992
90- private static final boolean ADVANCED_HEALTH_CHECKS_ENABLED = true ;
93+ @ Value ("${health.advanced.checks.enabled:true}" )
94+ private boolean advancedHealthChecksEnabled ;
9195
9296 public HealthService (DataSource dataSource ,
9397 @ Autowired (required = false ) RedisTemplate <String , Object > redisTemplate ) {
9498 this .dataSource = dataSource ;
9599 this .redisTemplate = redisTemplate ;
96- this .executorService = Executors .newFixedThreadPool (6 );
100+ this .executorService = Executors .newFixedThreadPool (2 , new java .util .concurrent .ThreadFactory () {
101+ private final AtomicInteger threadCounter = new AtomicInteger (0 );
102+
103+ @ Override
104+ public Thread newThread (Runnable r ) {
105+ Thread t = new Thread (r , "health-check-" + threadCounter .incrementAndGet ());
106+ t .setDaemon (true );
107+ return t ;
108+ }
109+ });
97110 }
98111
99112 @ PreDestroy
@@ -184,11 +197,10 @@ private void cancelFutures(Future<?> mysqlFuture, Future<?> redisFuture) {
184197 }
185198
186199 private void ensurePopulated (Map <String , Object > status , String componentName ) {
187- if (!status .containsKey (STATUS_KEY )) {
188- status .put (STATUS_KEY , STATUS_DOWN );
189- status .put (SEVERITY_KEY , SEVERITY_CRITICAL );
190- status .put (ERROR_KEY , componentName + " health check did not complete in time" );
191- }
200+
201+ status .putIfAbsent (STATUS_KEY , STATUS_DOWN );
202+ status .putIfAbsent (SEVERITY_KEY , SEVERITY_CRITICAL );
203+ status .putIfAbsent (ERROR_KEY , componentName + " health check did not complete in time" );
192204 }
193205
194206 private HealthCheckResult checkMySQLHealthSync () {
@@ -199,17 +211,19 @@ private HealthCheckResult checkMySQLHealthSync() {
199211
200212 try (ResultSet rs = stmt .executeQuery ()) {
201213 if (rs .next ()) {
202- boolean isDegraded = performAdvancedMySQLChecksWithThrottle ();
203- return new HealthCheckResult ( true , null , isDegraded );
214+ // Connection is auto-closed by try-with-resources here
215+ // Advanced checks will open a separate connection if needed
204216 }
205217 }
206218
207- return new HealthCheckResult (false , "No result from health check query" , false );
208-
209219 } catch (Exception e ) {
210220 logger .warn ("MySQL health check failed: {}" , e .getMessage (), e );
211221 return new HealthCheckResult (false , "MySQL connection failed" , false );
212222 }
223+
224+
225+ boolean isDegraded = performAdvancedMySQLChecksWithThrottle ();
226+ return new HealthCheckResult (true , null , isDegraded );
213227 }
214228
215229 private HealthCheckResult checkRedisHealthSync () {
@@ -325,7 +339,7 @@ private String computeOverallStatus(Map<String, Map<String, Object>> components)
325339 }
326340
327341 private boolean performAdvancedMySQLChecksWithThrottle () {
328- if (!ADVANCED_HEALTH_CHECKS_ENABLED ) {
342+ if (!advancedHealthChecksEnabled ) {
329343 return false ;
330344 }
331345
0 commit comments