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;
}
}
}
Spring Cloud health节点通过注册中心扫描状态的简单实现的更多相关文章
- Spring Cloud 系列之 Consul 注册中心(二)
本篇文章为系列文章,未读第一集的同学请猛戳这里:Spring Cloud 系列之 Consul 注册中心(一) 本篇文章讲解 Consul 集群环境的搭建. Consul 集群 上图是一个简单的 Co ...
- spring cloud实战 1-高可用注册中心
创建父maven项目 提交代码至GitHub 创建eureka-server-1 项目搭建两种方式: 父pom中继承spring-boot-starter-parent,子pom中直接结成父pom.该 ...
- Spring Cloud Eureka 高可用注册中心
参考:<<spring cloud 微服务实战>> 在微服务架构这样的分布式环境中,各个组件需要进行高可用部署. Eureka Server 高可用实际上就是将自己作为服务向其 ...
- Spring Cloud 系列之 Consul 注册中心(一)
Netflix Eureka 2.X https://github.com/Netflix/eureka/wiki 官方宣告停止开发,但其实对国内的用户影响甚小,一方面国内大都使用的是 Eureka ...
- Spring Cloud 系列之 ZooKeeper 注册中心
什么是注册中心 服务注册中心是服务实现服务化管理的核心组件,类似于目录服务的作用,主要用来存储服务信息,譬如提供者 url 串.路由信息等.服务注册中心是微服务架构中最基础的设施之一. 注册中心可以说 ...
- Spring Cloud Netflix Eureka(注册中心)
Eureka简介 Eureka是Netflix开发的一个Service Discovery组件,spring cloud将其整合用来做服务注册中心,Eureka包括两部分Eureka Server 和 ...
- 笔记:Spring Cloud Eureka 高可用注册中心
在微服务架构这样的分布式环境中,我们需要充分考虑发生故障的情况,所以在生产环境中必须对各个组件进行高可用部署,对与微服务和服务注册中心都需要高可用部署,Eureka 高可用实际上就是将自己作为服务向其 ...
- Spring Cloud(Dalston.SR5)--Eureka 注册中心搭建
基于 Netflix Eureka 做了二次封装,主要负责完成微服务架构中的服务治理功能,服务治理可以说是微服务架构中最为核心和基础的模块,他主要用来实现各个微服务实例的自动化注册与发现 服务注册:在 ...
- Spring Cloud Alibaba 使用nacos 注册中心
### 背景 上一文我们讲到了如何去搭建注册中心,这一次我们讲述如何使用nacos作为注册中心 ### spring-cloud-alibaba-basis 创建基础依赖 首先我们创建一个spring ...
随机推荐
- Filter和interceptor比较
作为一个备忘,有时间补充 https://www.cnblogs.com/learnhow/p/5694876.html 先说一个题外话,Filter是过滤器,interceptor是拦截器.前者基于 ...
- Verilog从文件读数据
reg start;reg [17:0] counter;always @(posedge i_clk)//置rst.startbegin //产生读数据地址 if(counter==171519|| ...
- Go中&和*的区别
& 返回变量的内存地址 * 返回变量的值, * 只能作用在指针上 package main import "fmt" func main() { var a = 5 var ...
- 【CUDA 基础】5.3 减少全局内存访问
title: [CUDA 基础]5.3 减少全局内存访问 categories: - CUDA - Freshman tags: - 共享内存 - 归约 toc: true date: 2018-06 ...
- C#实现代码生成器
最近在用layui做后台管理,增删改查这些一成不变的东西写起来浪费大量时间,于是做了个简单的代码生成器快速生成 代码生成器的原理其实很简单,都是基于模板实现替换,Razor是个不错的选择(或者Nvel ...
- Django基础之cookie
1. Cookie 1.1 Cookie的由来 大家都知道HTTP协议是无状态的.无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系, 它不会受前面的请求响应情况 ...
- AcWing:237. 程序自动分析(离散化 + 并查集)
在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3,…x1,x2,x3,…代表程序中出现的变量,给定n个形如xi=xjxi=x ...
- Selenium Firefox 官方Webdriver -- Geckodriver
下载地址: https://github.com/mozilla/geckodriver/releases 配置环境: 直接将解压的geckodriver.exe放到python的Scripts中 比 ...
- Linux设备驱动程序 之 原子操作
原子整数操作 当共享资源是一个简单的整数值时,可以使用内核提供的一种原子的整数类型,称为atomic_t,定义在<linux/types.h>中,操作定义在<linux/atomic ...
- python 普通继承方式和super继承方式
Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递. 举一个很常见的例子: >> ...