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;
}
}
}

Spring Cloud health节点通过注册中心扫描状态的简单实现的更多相关文章

  1. Spring Cloud 系列之 Consul 注册中心(二)

    本篇文章为系列文章,未读第一集的同学请猛戳这里:Spring Cloud 系列之 Consul 注册中心(一) 本篇文章讲解 Consul 集群环境的搭建. Consul 集群 上图是一个简单的 Co ...

  2. spring cloud实战 1-高可用注册中心

    创建父maven项目 提交代码至GitHub 创建eureka-server-1 项目搭建两种方式: 父pom中继承spring-boot-starter-parent,子pom中直接结成父pom.该 ...

  3. Spring Cloud Eureka 高可用注册中心

    参考:<<spring cloud 微服务实战>> 在微服务架构这样的分布式环境中,各个组件需要进行高可用部署. Eureka Server 高可用实际上就是将自己作为服务向其 ...

  4. Spring Cloud 系列之 Consul 注册中心(一)

    Netflix Eureka 2.X https://github.com/Netflix/eureka/wiki 官方宣告停止开发,但其实对国内的用户影响甚小,一方面国内大都使用的是 Eureka ...

  5. Spring Cloud 系列之 ZooKeeper 注册中心

    什么是注册中心 服务注册中心是服务实现服务化管理的核心组件,类似于目录服务的作用,主要用来存储服务信息,譬如提供者 url 串.路由信息等.服务注册中心是微服务架构中最基础的设施之一. 注册中心可以说 ...

  6. Spring Cloud Netflix Eureka(注册中心)

    Eureka简介 Eureka是Netflix开发的一个Service Discovery组件,spring cloud将其整合用来做服务注册中心,Eureka包括两部分Eureka Server 和 ...

  7. 笔记:Spring Cloud Eureka 高可用注册中心

    在微服务架构这样的分布式环境中,我们需要充分考虑发生故障的情况,所以在生产环境中必须对各个组件进行高可用部署,对与微服务和服务注册中心都需要高可用部署,Eureka 高可用实际上就是将自己作为服务向其 ...

  8. Spring Cloud(Dalston.SR5)--Eureka 注册中心搭建

    基于 Netflix Eureka 做了二次封装,主要负责完成微服务架构中的服务治理功能,服务治理可以说是微服务架构中最为核心和基础的模块,他主要用来实现各个微服务实例的自动化注册与发现 服务注册:在 ...

  9. Spring Cloud Alibaba 使用nacos 注册中心

    ### 背景 上一文我们讲到了如何去搭建注册中心,这一次我们讲述如何使用nacos作为注册中心 ### spring-cloud-alibaba-basis 创建基础依赖 首先我们创建一个spring ...

随机推荐

  1. Java中的集合List、ArrayList、Vector、Stack(三)

    List接口 List集合代表一个有序集合,集合中每一个元素都有其对应的顺序索引.List集合容许使用重复元素,可以通过索引来访问指定位置的集合对象. ArrayList和Vector实现类 Arra ...

  2. webuploader+上传文件夹

    在web项目中上传文件夹现在已经成为了一个主流的需求.在OA,或者企业ERP系统中都有类似的需求.上传文件夹并且保留层级结构能够对用户行成很好的引导,用户使用起来也更方便.能够提供更高级的应用支撑. ...

  3. linux command pushd popd

    Linux command pushd popd [Purpose]        Learning linux command  pushd popd   [Eevironment]        ...

  4. 多线程中volatile关键字的作用

    原文链接:https://blog.csdn.net/xuwentao37x/article/details/27804169 多线程的程序是出了名的难编写.难验证.难调试.难维护,这通常是件苦差事. ...

  5. HTML JS 弹层后底部页面禁止滚动处理

    1.打开新页面时需要禁止鼠标滚轮,禁止页面滑动: 1 2 3 4 在调用显示层时加上这句js代码就可以了: document.documentElement.style.overflow = &quo ...

  6. noi 2011

    描述 已知长度最大为200位的正整数n,请求出2011^n的后四位. 输入 第一行为一个正整数k,代表有k组数据,k<=200接下来的k行, 每行都有一个正整数n,n的位数<=200 输出 ...

  7. [Vue] : vue-resource 实现 get, post, jsonp请求

    vue-resource 实现 get, post, jsonp请求 常见的数据请求类型:get,post,jsonp 除了vue-resource之外,还可以使用axios的第三方包实现实现数据的请 ...

  8. 使用 kubeadm 安装 kubernetes v1.16.0

    近日通过kubeadm 安装 kubernetes v1.16.0,踩过不少坑,现记录下安装过程. 安装环境: 系           统:CentOS Linux release 7.6 Docke ...

  9. CF981D

    CF981D 题意: 给你n个数,要求你分成k堆.每堆的内部加和,每堆之间是相与.问最大的值. 解法: 二进制下最大的数的所有位一定是1,所以贪心去找是否最大一定是正确的. 然后DP记录+贪心就可以A ...

  10. Nginx之搭建反向代理实现tomcat分布式集群

    参考博文: Nginx反向代理实现Tomcat分布式集群 1. jdk 安装 jdk 下载网址: http://www.oracle.com/technetwork/java/javase/downl ...