• Spring Cloud health节点通过注册中心扫描状态的简单实现


    package com.zjs.web;
    
    import com.netflix.appinfo.InstanceInfo;
    import com.zjs.FallbackApiApplication;
    import lombok.Data;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.cloud.client.discovery.DiscoveryClient;
    import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClient;
    import org.springframework.http.client.SimpleClientHttpRequestFactory;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.util.StringUtils;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.Date;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * @author 李文
     * @create 2019-05-27 11:42
     **/
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = FallbackApiApplication.class)
    public class EurekaUrlTest
    {
        Logger logger = LoggerFactory.getLogger(this.getClass());
        private static Map<String, ExceptionCount> maps = new ConcurrentHashMap<>();
    
        @Autowired
        private DiscoveryClient discoveryClient;
        private RestTemplate restTemplate;
    
        public EurekaUrlTest() {
            SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
            requestFactory.setConnectTimeout(1000);
            requestFactory.setReadTimeout(1000);
            restTemplate = new RestTemplate(requestFactory);
        }
    
    
        @Test
        public void test_1() {
            List<String> services = discoveryClient.getServices();
            for (String service : services) {
                List<ServiceInstance> sis = discoveryClient.getInstances(service);
                for (ServiceInstance si : sis) {
                    EurekaDiscoveryClient.EurekaServiceInstance s = (EurekaDiscoveryClient.EurekaServiceInstance) si;
                    InstanceInfo instanceInfo = s.getInstanceInfo();
                    String body = isTheServiceAbnormal(instanceInfo);
                    exceptionServiceHandling(instanceInfo, body);
                }
            }
        }
    
        @Test
        public void test_2() {
            for (int i = 0; i < 3; i++) {
                test_1();
            }
        }
    
        private void exceptionServiceHandling(InstanceInfo instanceInfo, String body) {
            if (!StringUtils.isEmpty(body)) {
                ExceptionCount count = maps.get(instanceInfo.getInstanceId());
                if (count == null) {
                    maps.put(instanceInfo.getInstanceId(), new ExceptionCount(instanceInfo, body));
                } else {
                    if (count.continuousAnomalies()) {
                        count.setData(body);
                        //TODO 推送消息  清空计量 重新开始
                        System.out.println(instanceInfo.getInstanceId() + "  触发异常推送  ");
                        maps.remove(instanceInfo.getInstanceId());
                    } else {
                        maps.put(instanceInfo.getInstanceId(), count);
                    }
                }
            }
        }
    
        private String isTheServiceAbnormal(InstanceInfo health) {
            String body = null;
            try {
                //body = restTemplate.getForObject(health, String.class);
                // 直接获取health路径会出现 主机名+health 的情况,虽然是由于配置不规范照成的,
                // 但是还是劲量保证地址的正确性 通过IP 和 端口 来替换掉原先的
                String healthURL = health.getHealthCheckUrl();
                java.net.URL url = new java.net.URL(healthURL);
                String httpUlr = healthURL.replace(url.getHost(), health.getIPAddr())
                        .replace(String.valueOf(url.getPort()), String.valueOf(health.getPort()));
                String data = restTemplate.getForObject(httpUlr, String.class);
                logger.info(data);
            } catch (Exception e) {
                body = e.getMessage();
                logger.info(body);
            }
            return body;
            //if (body.contains("DOWN")) {
            //    return body;
            //} else {
            //    return null;
            //}
        }
    
        @Data
        public class ExceptionCount
        {
            ExceptionCount(InstanceInfo i, String body) {
                this.data = body;
                this.date = new Date();
                this.frequency = 1;
                this.instanceId = i.getInstanceId();
                this.appName = i.getInstanceId();
                this.appGroupName = i.getAppGroupName();
                this.ipAddr = i.getIPAddr();
                this.homePageUrl = i.getHomePageUrl();
                this.statusPageUrl = i.getStatusPageUrl();
                this.healthCheckUrl = i.getHealthCheckUrl();
                this.secureHealthCheckUrl = i.getSecureHealthCheckUrl();
                this.vipAddress = i.getVIPAddress();
            }
    
            private String data;
            private Date date;
            private Integer frequency;
            private String instanceId;
            private String appName;
            private String appGroupName;
            private String ipAddr;
            private String homePageUrl;
            private String statusPageUrl;
            private String healthCheckUrl;
            private String secureHealthCheckUrl;
            private String vipAddress;
    
            boolean continuousAnomalies() {
                Date newDate = new Date();
                long time = newDate.getTime() - date.getTime();
                //判断时间 是否小于等于 3分钟
                if (time <= (180 * 1000)) {
                    date = new Date();
                    ++frequency;
                } else {
                    // 大于 3分钟 说明不是连续的错误
                    frequency = 1;
                }
                return frequency >= 3;
            }
        }
    }
  • 相关阅读:
    Python3.x和Python2.x的区别
    urllib库python2和python3具体区别
    Oracle实现自增方式:序列+触发器
    菜单
    visual studio 2013连接Oracle 11g并获取数据:(二:实现)
    Oracle连接出现TNS:no listener或者ORA-12514: TNS:listener does not currently know
    visual studio 2013连接Oracle 11g并获取数据:(一:环境搭建)
    C#编程
    Oracle 11g 安装
    Android在Eclipse上的环境配置
  • 原文地址:https://www.cnblogs.com/atliwen/p/10935271.html
Copyright © 2020-2023  润新知