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. 利用python deque的extend特性实现列表元素查重

    from collections import deque mydquene = deque() mylist = [0,1,1,2,2,3,3,3,3,4,5,6,7,7,8,8,9,10,10,1 ...

  2. Educational Codeforces Round 50 (Rated for Div. 2) F - Relatively Prime Powers(数学+容斥)

    题目链接:http://codeforces.com/contest/1036/problem/F 题意: 题解:求在[2,n]中,x != a ^ b(b >= 2 即为gcd)的个数,那么实 ...

  3. MyBatis中#{}和${}的不同和${}的妙用(转)

        突然意识到sql语句的独特语义要和代码分离,我们就不能够在代码中写sql语句!!比如我要用${}在MyBatis的sql中拼接排序类型的时候,我就不能够在Java代码中直接写参数字符串为Ord ...

  4. 【Android-网络通讯】 客户端与.Net服务端Http通讯

    以登陆系统为例: 一.创建服务端程序 1.打开VS2012,新建项目,创建ASP.NET WEB应用程序 ,命名为MyApp 2.添加新建项,选择一般处理程序,创建Login.ashx C# Code ...

  5. DPC究竟是什么

    DPC究竟是什么 DPC是“Deferred Procedure Call”的缩写,意为推迟了的过程(函数)调用.这是因为,逻辑上应该放在中断服务程序中完成的操作并非都是那么紧迫,其中有一部分可能相对 ...

  6. 数据结构实验之链表三:链表的逆置(SDUT 2118)

    题目链接 #include <bits/stdc++.h> using namespace std; struct node { int data; struct node *next; ...

  7. 权势二进制(51Nod 1413)

    一个十进制整数被叫做权势二进制,当他的十进制表示的时候只由0或1组成.例如0,1,101,110011都是权势二进制而2,12,900不是. 当给定一个n的时候,计算一下最少要多少个权势二进制相加才能 ...

  8. SecureCRT的安装与破解,详细过程

    使用SecureCRT可以方便用户在windows环境下对linux主机进行管理,这里为大家讲一下SecureCRT的破解方法,仅供大家参考学习: 1.首先在本站下载SecureCRT 7.3.6最新 ...

  9. Spring创建对象的方法

    1.利用无参构造器创建对象. 在代码中有一个学生类Student.java package no1; public class Student { public Student(){ System.o ...

  10. 转载 AMI方案和Insyde方案

    闲来无事回头看看,自毕业以来一直都在BIOS这个行业打转,目前的各种新闻来看全球的IT行业都似乎不太景气,PC出货量一泻千里,想要有所转机看起来不是一天两天的事情,想来无事来看看做过的几个UEFI B ...