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. 灵活部署django缓存,并使用

    使用django内置的redis=============>pip3 install django-redisCACHES = { 'default':{ 'BACKEND':'django_r ...

  2. BZOJ 1845: [Cqoi2005] 三角形面积并 (辛普森积分)

    大力辛普森积分 精度什么的搞了我好久- 学到了Simpson的一个trick 深度开11,eps开1e-4.跑的比有些扫描线还快- CODE #include <bits/stdc++.h> ...

  3. Tomcat配置多站点

    tomcat配置多个站点.可以这样. 在conf文件夹下创建文件:..conf\Catalina\localhost\aa.xml aa.xml的内容.如: <?xml version=&quo ...

  4. 【Android-关闭所有Activity】关闭activity之前的所有activity,重启actibity

    Android关闭activity之前的所有activity,重启actibity 直接关闭一个activity之前的所有Activity页面 解决方法:清理activity堆栈 Intent ine ...

  5. hybird(h5)页面自动化测试

  6. Appium Python测试环境搭建

    详细参考地址:https://www.cnblogs.com/amoyshmily/p/10500687.html 1,Appium安装:https://github.com/appium/appiu ...

  7. The Reset Method of Te Philips VTR 5210

    Pull down and hold the ON/OFF buttun, Then press the play button

  8. C++中时间转换

    所需头文件 #include <chrono> #include <time.h> auto now = std::chrono::system_clock::now(); s ...

  9. mac使用brew安装mysql报RROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

    使用mac安装mysql安装完后运行 mysql -uroot -p 报了 ERROR 2002 (HY000): Can't connect to local MySQL server throug ...

  10. 两个字说清楚编程语言实质-Python基础前传(3)

    大家都知道Python对于数据分析而言,意义重大.但对于运用Python来做数据分析的我们来说,学习一门编程语言,却有不小的难度:首先大部分伙伴不是计算机相关专业的科班出身,其次我们基本上也都没有程序 ...