Monitoring: support for dynamic change of load-balancers list
This commit is contained in:
		
							parent
							
								
									24241010b7
								
							
						
					
					
						commit
						98a87bfd33
					
				@ -15,6 +15,7 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.monitoring.service;
 | 
			
		||||
 | 
			
		||||
import lombok.Getter;
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
@ -30,13 +31,17 @@ import org.thingsboard.monitoring.util.TbStopWatch;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.PostConstruct;
 | 
			
		||||
import javax.annotation.PreDestroy;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
@RequiredArgsConstructor
 | 
			
		||||
@Slf4j
 | 
			
		||||
public abstract class BaseHealthChecker<C extends MonitoringConfig, T extends MonitoringTarget> {
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    protected final C config;
 | 
			
		||||
    @Getter
 | 
			
		||||
    protected final T target;
 | 
			
		||||
 | 
			
		||||
    private Object info;
 | 
			
		||||
@ -48,6 +53,9 @@ public abstract class BaseHealthChecker<C extends MonitoringConfig, T extends Mo
 | 
			
		||||
    @Value("${monitoring.check_timeout_ms}")
 | 
			
		||||
    private int resultCheckTimeoutMs;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    private final Map<String, BaseHealthChecker<C, T>> associates = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    public static final String TEST_TELEMETRY_KEY = "testData";
 | 
			
		||||
 | 
			
		||||
    @PostConstruct
 | 
			
		||||
@ -84,6 +92,10 @@ public abstract class BaseHealthChecker<C extends MonitoringConfig, T extends Mo
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            reporter.serviceFailure(MonitoredServiceKey.GENERAL, e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        associates.values().forEach(healthChecker -> {
 | 
			
		||||
            healthChecker.check(wsClient);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void checkWsUpdate(WsClient wsClient, String testValue) {
 | 
			
		||||
@ -99,7 +111,6 @@ public abstract class BaseHealthChecker<C extends MonitoringConfig, T extends Mo
 | 
			
		||||
        reporter.reportLatency(Latencies.wsUpdate(getKey()), stopWatch.getTime());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    protected abstract void initClient() throws Exception;
 | 
			
		||||
 | 
			
		||||
    protected abstract String createTestPayload(String testValue);
 | 
			
		||||
 | 
			
		||||
@ -32,9 +32,12 @@ import org.thingsboard.monitoring.util.TbStopWatch;
 | 
			
		||||
import javax.annotation.PostConstruct;
 | 
			
		||||
import java.net.InetAddress;
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
import java.net.URISyntaxException;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.LinkedList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
@ -66,34 +69,24 @@ public abstract class BaseMonitoringService<C extends MonitoringConfig<T>, T ext
 | 
			
		||||
        tbClient.logIn();
 | 
			
		||||
        configs.forEach(config -> {
 | 
			
		||||
            config.getTargets().forEach(target -> {
 | 
			
		||||
                initHealthChecker(target, config);
 | 
			
		||||
                BaseHealthChecker<C, T> healthChecker = initHealthChecker(target, config);
 | 
			
		||||
                healthCheckers.add(healthChecker);
 | 
			
		||||
 | 
			
		||||
                if (target.isCheckDomainIps()) {
 | 
			
		||||
                    initIpsHealthCheckers(target, config);
 | 
			
		||||
                    getAssociatedUrls(target.getBaseUrl()).forEach(url -> {
 | 
			
		||||
                        healthChecker.getAssociates().put(url, initHealthChecker(createTarget(url), config));
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void initHealthChecker(T target, C config) {
 | 
			
		||||
    private BaseHealthChecker<C, T> initHealthChecker(T target, C config) {
 | 
			
		||||
        BaseHealthChecker<C, T> healthChecker = (BaseHealthChecker<C, T>) createHealthChecker(config, target);
 | 
			
		||||
        log.info("Initializing {} for {}", healthChecker.getClass().getSimpleName(), target.getBaseUrl());
 | 
			
		||||
        healthChecker.initialize(tbClient);
 | 
			
		||||
        devices.add(target.getDeviceId());
 | 
			
		||||
        healthCheckers.add(healthChecker);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SneakyThrows
 | 
			
		||||
    private void initIpsHealthCheckers(T target, C config) {
 | 
			
		||||
        URI baseUrl = new URI(target.getBaseUrl());
 | 
			
		||||
        String domain = baseUrl.getHost();
 | 
			
		||||
 | 
			
		||||
        Set<String> ips = Arrays.stream(InetAddress.getAllByName(domain))
 | 
			
		||||
                .map(InetAddress::getHostAddress)
 | 
			
		||||
                .collect(Collectors.toSet());
 | 
			
		||||
        for (String ip : ips) {
 | 
			
		||||
            String url = new URI(baseUrl.getScheme(), null, ip, baseUrl.getPort(), "", null, null).toString();
 | 
			
		||||
            initHealthChecker(createTarget(url), config);
 | 
			
		||||
        }
 | 
			
		||||
        return healthChecker;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public final void runChecks() {
 | 
			
		||||
@ -108,9 +101,8 @@ public abstract class BaseMonitoringService<C extends MonitoringConfig<T>, T ext
 | 
			
		||||
 | 
			
		||||
            try (WsClient wsClient = wsClientFactory.createClient(accessToken)) {
 | 
			
		||||
                wsClient.subscribeForTelemetry(devices, TransportHealthChecker.TEST_TELEMETRY_KEY).waitForReply();
 | 
			
		||||
 | 
			
		||||
                for (BaseHealthChecker<C, T> healthChecker : healthCheckers) {
 | 
			
		||||
                    healthChecker.check(wsClient);
 | 
			
		||||
                    check(healthChecker, wsClient);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            reporter.reportLatencies(tbClient);
 | 
			
		||||
@ -124,6 +116,57 @@ public abstract class BaseMonitoringService<C extends MonitoringConfig<T>, T ext
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void check(BaseHealthChecker<C, T> healthChecker, WsClient wsClient) throws Exception {
 | 
			
		||||
        healthChecker.check(wsClient);
 | 
			
		||||
 | 
			
		||||
        T target = healthChecker.getTarget();
 | 
			
		||||
        if (target.isCheckDomainIps()) {
 | 
			
		||||
            Set<String> associatedUrls = getAssociatedUrls(target.getBaseUrl());
 | 
			
		||||
            Map<String, BaseHealthChecker<C, T>> associates = healthChecker.getAssociates();
 | 
			
		||||
            Set<String> prevAssociatedUrls = new HashSet<>(associates.keySet());
 | 
			
		||||
 | 
			
		||||
            boolean changed = false;
 | 
			
		||||
            for (String url : associatedUrls) {
 | 
			
		||||
                if (!prevAssociatedUrls.contains(url)) {
 | 
			
		||||
                    BaseHealthChecker<C, T> associate = initHealthChecker(createTarget(url), healthChecker.getConfig());
 | 
			
		||||
                    associates.put(url, associate);
 | 
			
		||||
                    changed = true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            for (String url : prevAssociatedUrls) {
 | 
			
		||||
                if (!associatedUrls.contains(url)) {
 | 
			
		||||
                    stopHealthChecker(healthChecker);
 | 
			
		||||
                    associates.remove(url);
 | 
			
		||||
                    changed = true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (changed) {
 | 
			
		||||
                log.info("Updated IPs for {}: {} (old list: {})", target.getBaseUrl(), associatedUrls, prevAssociatedUrls);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SneakyThrows
 | 
			
		||||
    private Set<String> getAssociatedUrls(String baseUrl) {
 | 
			
		||||
        URI url = new URI(baseUrl);
 | 
			
		||||
        return Arrays.stream(InetAddress.getAllByName(url.getHost()))
 | 
			
		||||
                .map(InetAddress::getHostAddress)
 | 
			
		||||
                .map(ip -> {
 | 
			
		||||
                    try {
 | 
			
		||||
                        return new URI(url.getScheme(), null, ip, url.getPort(), "", null, null).toString();
 | 
			
		||||
                    } catch (URISyntaxException e) {
 | 
			
		||||
                        throw new RuntimeException(e);
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
                .collect(Collectors.toSet());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void stopHealthChecker(BaseHealthChecker<C, T> healthChecker) throws Exception {
 | 
			
		||||
        healthChecker.destroyClient();
 | 
			
		||||
        devices.remove(healthChecker.getTarget().getDeviceId());
 | 
			
		||||
        log.info("Stopped {} for {}", healthChecker.getClass().getSimpleName(), healthChecker.getTarget().getBaseUrl());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected abstract BaseHealthChecker<?, ?> createHealthChecker(C config, T target);
 | 
			
		||||
 | 
			
		||||
    protected abstract T createTarget(String baseUrl);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user