fix: 修复server模式心跳检测的两个关键缺陷 - #242
Open
animacaeli wants to merge 1 commit into
Open
Conversation
1. LastHeartBeat 在每次健康检查后都更新,不再仅在Healthy时更新。 修复前:健康检查失败时 LastHeartBeat 冻结在注册时间,管理后台看起来像 心跳检测从未运行过,且 removeServiceInterval 可能因此误删服务。 2. 健康检查后台循环增加 try-catch 异常保护。 修复前:while 循环中任何未捕获异常(如数据库查询失败)都会静默杀死 整个健康检查任务,导致所有 server 模式服务永久失去心跳检测。 3. 优化: - CheckInterval 取值提前到循环外,防止 getter 抛异常杀循环 - CheckAService 新增成功日志和失败时的 HTTP 状态码 - Task.Run 内的健康检查任务增加独立异常保护 - 启动时打印健康检查间隔,便于运维确认配置 Co-Authored-By: Claude <noreply@anthropic.com>
Collaborator
|
最后响应时间,是说最后一次成功心跳的时间啊。 |
Author
|
我这边遇到的业务场景是服务注册成功,检测 url 中的端口未开放,状态为异常。端口开放后,状态也不会变为健康,就一直是异常状态。主要针对管理后台的显示问题 |
Collaborator
先看日志,确定健康监测是否在运行。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题描述
一个典型场景可以复现该问题:
server,注册时提供的 IP+Port 在云服务器上端口未开放经过代码审查,定位到两个核心缺陷。
根因分析
缺陷一:
LastHeartBeat只在健康检查成功时更新文件:
src/.../Service/ServiceInfoService.cs:101server 模式的健康检查失败(端口不通)时,状态被设为
Unhealthy,条件status != Unhealthy为false,LastHeartBeat不更新,始终停留在注册时间。管理后台看到"最后响应时间"从未变化,用户误以为健康检查没有运行。缺陷二:健康检查后台循环可能静默崩溃
文件:
src/.../Service/ServiceHealthCheckService.cs:99-157整个
while(true)循环体没有任何 try-catch 保护,且通过_ = ...StartCheckAsync()fire-and-forget 启动。如果QueryAsync等数据库操作抛出异常,整个后台任务静默终止,所有 server 模式服务永久失去心跳检测。此时即使端口开放,状态也永远不会恢复。修改文件
ServiceInfoService.csLastHeartBeat更新的条件判断,每次检查后都更新时间戳ServiceHealthCheckService.cs效果对比
LastHeartBeat冻结在注册时间 → 看起来"检查没在运行"LastHeartBeat每次检查后更新 → 确认检查持续运行removeServiceInterval > 0LastHeartBeat冻结可能导致服务被误删风险
LastHeartBeat语义从"最后一次成功心跳"变为"最后一次检查时间",新语义更匹配管理后台"最后响应时间"的含义