如果注册中心为nacos,怎样将springcloud项目中的所有注册服务的健康状态进行监控,并在不健康时发送邮件?
假设springcloud项目中服务有service-a,serivce-b,service-c,
并使用nacos做为注册中心,那么有什么办法可以监测所有服务的健康状态并在健康状态DOWN时发送邮件预警?
后脑勺当初想的是,将所有注册服务作为一个常量类管理或者通过zuul,getway配置文件拿到相关注册服务的路径/名称等并统一设置actuator,并对这些服务设定定时任务获取/health接口status状态.
但是这样做的问题可能会对相关服务造成影响,毕竟定时任务和接口调用如果想及时,也会对原本的服务做了一次浪费的接口调用,而且当扩展到了service-abcd-1112等这样有更多的服务注册到nacos后,对这些接口的调用/health以及状态判断就有些资源浪费.
所以最好的方式还是通过nacos自身提供的相关API或者接口重写能实现这个功能就最好了.
当然这是最好的,因为本来nacos就和eureka等注册中心会向注册的服务发送心跳检测,检测服务是否存活或者健康,但是没有发邮件这一说嘛.
所以就在相关nacos或eureka发送心跳检测的同时,在判断健康状态的那个逻辑中加入邮件发送的服务就应该可以实现.
后来查了下有相关的nacos里的Task类中设定了健康检查,ClientBeatCheckTask
服务端接受到客户端的服务注册请求后,在创建空的Service后,就会开启健康检查任务,代码在com.alibaba.nacos.naming.core.ServiceManager#putServiceAndInit:
上面Init方法中的包含的service.init()方法中的HealthCheckReactor.scheduleCheck(clientBeatCheckTask);
是对应开启健康检查任务的代码.
private void putServiceAndInit(Service service) throws NacosException {
putService(service);
//初始化service,会开启健康检查任务
service.init();
consistencyService
.listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), true), service);
consistencyService
.listen(KeyBuilder.buildInstanceListKey(service.getNamespaceId(), service.getName(), false), service);
Loggers.SRV_LOG.info("[NEW-SERVICE] {}", service.toJson());
}
public void init() {
//健康检测任务
HealthCheckReactor.scheduleCheck(clientBeatCheckTask);
for (Map.Entry<String, Cluster> entry : clusterMap.entrySet()) {
entry.getValue().setService(this);
entry.getValue().init();
}
}
实际nacos代码在这一行:
不过init()方法好像在新版本中去除了,搜了下1.21版本的还存在
并且这个是在Test测试类里.
而最新的issue也是2021年4月份的
而实际的类在这里:(不知道为什么github搜没有直接先展示这个类)
https://github.com/alibaba/na...
而其实在这个healthcheck包下的都与健康检测有关:
https://github.com/zmyouknow/...
具体:
HTTP检查,checkFail会报错
MYSQL检查,checkFail会捕获
那如果数据库是Oracle怎么办呢?答,可能要写一个OracleHealthCheckProcessor
继续查看两个类判断时用到的HealthCheckCommon
https://github.com/zmyouknow/...
那这里面的
checkFile(..)
checkFileNow(...)
具体有何区别?
/**
* Health check fail, when instance check failed count more than max failed time, set unhealthy.
*
* @param ip instance
* @param task health check task
* @param msg message
*/
public void checkFail(Instance ip, HealthCheckTask task, String msg) {
一个是当实例检查统计超过最大设定的failed time,设置unhealthy
/**
* Health check fail, set instance unhealthy directly.
*
* @param ip instance
* @param task health check task
* @param msg message
*/
public void checkFailNow(Instance ip, HealthCheckTask task, String msg) {
而这个是直接设定该实例unhealthy
可以看到checkFileNow有3处引用
!
checkFile暂时没有点开,无法看到
checkOk也有4处引用
初始化健康检查的代码,看起来像用全局的线程进行同步执行一个post请求
private static LinkedBlockingDeque<HealthCheckResult> healthCheckResults = new LinkedBlockingDeque<>(1024 * 128);
/**
* Init Health check.
*/
public void init() {
GlobalExecutor.scheduleNamingHealthCheck(() -> {
List list = Arrays.asList(healthCheckResults.toArray());
healthCheckResults.clear();
Collection<Member> sameSiteServers = memberManager.allMembers();
if (sameSiteServers == null || sameSiteServers.size() <= 0) {
return;
}
for (Member server : sameSiteServers) {
if (server.getAddress().equals(NetUtils.localServer())) {
continue;
}
Map<String, String> params = new HashMap<>(10);
params.put("result", JacksonUtils.toJson(list));
if (Loggers.SRV_LOG.isDebugEnabled()) {
Loggers.SRV_LOG.debug("[HEALTH-SYNC] server: {}, healthCheckResults: {}", server,
JacksonUtils.toJson(list));
}
RestResult<String> httpResult = HttpClient.httpPost(
"http://" + server.getAddress() + EnvUtil.getContextPath()
+ UtilsAndCommons.NACOS_NAMING_CONTEXT + "/api/healthCheckResult", null, params);
if (!httpResult.ok()) {
Loggers.EVT_LOG.warn("[HEALTH-CHECK-SYNC] failed to send result to {}, result: {}", server,
JacksonUtils.toJson(list));
}
}
}, 500, TimeUnit.MILLISECONDS);
}
时间间隔是500毫秒
虽然没有执行相关代码
如果将nacos的健康检查加入健康检查unhealthy时发送邮件,
那大致的方式就是在
https://github.com/zmyouknow/...
的checkFail,checkFailNow重写,加入邮件发送,如果数据库不同就写一个类继承Mysql Health...实现的process接口,并配置初始化?即可。
也希望思否的大佬们提供建议!谢谢咯!
虽然还没有实践,但是健康检测的原理其实很简单,就是看请求有没有超时,从http请求到sql请求,超时超过最大限制时长则记录为unhealthy。
不过没有发现这里和actuator端点检测有什么区别。
上面有个代码贴的版本低了,其实有了v2的相关代码。
也许做一个针对该checkFail方法的切面就更简单易行。
查看资料:
https://blog.csdn.net/jb84006...
github nacos源码
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论