如何用 DriveInfo
检查磁盘剩余空间是否低于阈值
健康端点里最常被忽略的是「阈值合理性」——比如硬写
10GB,但生产环境可能跑在 500GB 或 2TB 的盘上,10GB 实际已属危险。正确做法是按百分比 + 绝对值双校验。
DriveInfo只能查本地挂载卷,网络驱动器(如
Z:\映射的 SMB)会抛
IOException,必须
try/catch推荐逻辑:
freeSpace ,两者任一成立即告警注意
AvailableFreeSpace和
TotalFreeSpace区别:前者扣除了系统保留空间(如 Windows 的 4GB),健康检查该用前者
文件可访问性检查为什么不能只靠 File.Exists()
File.Exists()返回
true不代表你能读——权限不足、文件被独占锁住、NTFS 加密或符号链接断裂都会导致后续
File.OpenRead()失败。健康端点要模拟真实使用路径。 必须组合检查:
File.Exists(path)→
File.GetAttributes(path)确认非
ReadOnly且非
Hidden→ 最后
using var _ = File.OpenRead(path)真实尝试打开 超时控制很关键:避免因 NFS 挂起或远程文件锁导致整个健康检查阻塞,建议用
CancellationTokenSource.CreateLinkedTokenSource(...).Token设 3 秒超时 路径中含空格或 Unicode 字符时,
File.Exists()在 .NET 5+ 默认支持,但旧版需确保
AppContext.SetSwitch("System.IO.UseLegacyPathHandling", false)
IWebHostEnvironment
下如何安全获取应用配置路径并检查
硬编码路径(如
"./logs/app.log")在容器或 IIS 部署时大概率失败——工作目录不等于应用根目录。必须通过注入的环境对象定位。 从
IWebHostEnvironment取
WebRootPath或
ContentRootPath,再拼接目标文件,例如:
Path.Combine(env.ContentRootPath, "appsettings.json")检查前先确认目录存在:
Directory.Exists(Path.GetDirectoryName(filePath)),否则
File.Exists()直接返回
false,掩盖了父目录缺失的问题 Linux 容器中要注意大小写敏感:
"AppSettings.json"和
"appsettings.json"是不同文件,开发机 Windows 不报错,上线就跪
健康端点响应体里要不要暴露具体错误细节
暴露
"Access to path 'X:\config' is denied"这类信息属于信息泄露,尤其当端点未加鉴权时。但完全隐藏又不利于运维定位。 生产环境响应体只返回结构化状态码和模糊原因,例如:
{"disk": "warn", "file": "error", "message": "Critical dependency unavailable"}
详细错误日志必须写入 ILogger,且包含
Activity.Current?.Id方便链路追踪 如果端点加了 Basic Auth 或 JWT,可对认证用户返回带
debug: true的详情字段,但绝不走默认路径
真正难处理的是并发场景:多个请求同时触发健康检查,而磁盘 I/O 或文件锁本身就会成为瓶颈。别在
GET /health里做重操作,要么预热缓存,要么异步采样——否则健康检查自己就成了故障源。
