健康检查:在 .NET 微服务模板中优雅配置 Health Checks
🚀 健康检查:在 .NET 微服务模板中优雅配置 Health Checks
📚 目录
- 🚀 健康检查:在 .NET 微服务模板中优雅配置 Health Checks
- 一、背景与意义 🔍
- 二、核心配置 🔧
- 2.1 引入必要的 NuGet 依赖 📦
- 2.2 注册 Health Checks 服务 ⚙️
- 2.3 集成 HealthChecks UI 🖥️
- 2.4 自定义健康端点响应 📋
- 三、实战演示 🚀
- 3.1 Gateway 端整合示例 🔗
- 3.2 Health Check 整体流程示意图 📈
- 四、Kubernetes 集成 🐳
- 4.1 Kubernetes 整体流程示意图 🌐
- 五、安全性与健壮性 🔐
- 六、性能与可用性考量 🚀
- 完整示例项目结构概览(摘录) 📂
一、背景与意义 🔍
在微服务架构下,各组件、服务分散部署,互相依赖性增加,单纯依靠人工巡检难以及时发现故障。健康检查(Health Check)作为监控与自愈机制的基石,能够让我们:
- 实时检测关键依赖(如数据库、缓存、中间件、外部 API)是否“在线” ✅
- 向 Kubernetes 或服务网关暴露健康端点,自动触发重启或流量调整 🔄
- 为运维团队提供统一可视化界面,便于快速定位问题 🎛️
本节要点:为什么微服务需要健康检查?Health Checks 在分布式系统里有哪些主要用途?
二、核心配置 🔧
在 .NET 中,Health Checks 基于 Microsoft.Extensions.Diagnostics.HealthChecks
扩展,由 ASP.NET Core 提供一整套健康检查接口与中间件。下面我们依次展示如何引入依赖、注册各类检查、集成 HealthChecks UI、并自定义响应格式。
2.1 引入必要的 NuGet 依赖 📦
要使用 SQL Server、Redis、外部 HTTP 等检查,需要先安装对应的 NuGet 包。例如,在项目根目录执行:
# 核心健康检查包
dotnet add package Microsoft.Extensions.Diagnostics.HealthChecks# SQL Server 健康检查扩展
dotnet add package AspNetCore.HealthChecks.SqlServer# Redis 健康检查扩展
dotnet add package AspNetCore.HealthChecks.Redis# HTTP/URL 健康检查扩展
dotnet add package AspNetCore.HealthChecks.System# HealthChecks UI(可视化界面)
dotnet add package AspNetCore.HealthChecks.UI
dotnet add package AspNetCore.HealthChecks.UI.InMemory.Storage # 演示或开发环境
# 若需持久化存储,可替换为 SqlServer/PostgreSQL 存储包
提示:在生产环境,建议将 HealthChecks UI 的存储改为持久化存储(如 SQL Server、PostgreSQL),否则重启后历史记录会丢失。💾
2.2 注册 Health Checks 服务 ⚙️
在 Program.cs
(或 Startup.cs
)中,先将 IConfiguration
拿到本地,然后通过 AddHealthChecks()
注册各类检查项。示例代码如下:
var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration;
var services = builder.Services;// 1. 注册基本健康检查
services.AddHealthChecks()// 自检项:确保应用启动后至少返回 Healthy.AddCheck("Self", () => HealthCheckResult.Healthy("I'm alive"))// SQL Server 检查:超时 3s,失败返回 Unhealthy,带上 tags 便于筛选.AddSqlServer(configuration["ConnectionStrings:Default"], name: "SqlServer",failureStatus: HealthStatus.Unhealthy,tags: new[] { "db", "sql" },timeout: TimeSpan.FromSeconds(3))// Redis 检查:超时 2s,失败返回 Degraded.AddRedis(configuration["ConnectionStrings:Redis"], name: "Redis",failureStatus: HealthStatus.Degraded,tags: new[] { "cache", "redis" },timeout: TimeSpan.FromSeconds(2))// 外部 HTTP/URL 检查:超时 1s,失败返回 Unhealthy.AddUrlGroup(new Uri(configuration["ExternalServices:PingUrl"]), name: "ExternalAPI",failureStatus: HealthStatus.Unhealthy,tags: new[] { "http", "external" },timeout: TimeSpan.FromSeconds(1));
要点:
- 🔖 AddCheck(“Self”, …):自检项,保持应用启动后能返回健康;
- 🏷️ tags:为每个检查项打标签,后续在 UI 或 Gateway 可以根据标签筛选;
- ⏱️ timeout:超过该时长视为检查失败。
2.3 集成 HealthChecks UI 🖥️
HealthChecks UI 提供可视化界面,帮助运维团队查看各个端点历史状态。示例注册如下:
// 2.3.1 注册 UI 服务
services.AddHealthChecksUI(setup =>
{setup.SetEvaluationTimeInSeconds(60); // 每 60s 重新评估一次setup.MaximumHistoryEntriesPerEndpoint(50); // 每个端点保留 50 条历史记录// 仅监控 /health-status 这个端点setup.AddHealthCheckEndpoint("MicroservicesHealth", "/health-status");
})
// 开发环境或演示环境使用内存存储
.AddInMemoryStorage();// 若要生产环境使用 SQL Server 存储,请替换为:
// .AddSqlServerStorage(configuration["ConnectionStrings:HealthChecksUI"]);
安全性提示:
- 建议对 UI 界面添加授权策略(如“AdminOnly”),否则任何人都能查看或篡改数据。🛡️
2.4 自定义健康端点响应 📋
默认情况下,MapHealthChecks
只会返回 HTTP 200 和简单的“Healthy/Unhealthy”文本。通常我们希望输出更丰富的 JSON,并根据总体健康状态设置 HTTP 状态码,还要对异常进行日志告警。示例如下:
var app = builder.Build();
var logger = app.Services.GetRequiredService<ILogger<Program>>();// 将 Health Checks 映射到 /health-status
app.MapHealthChecks("/health-status", new HealthCheckOptions
{// 允许在端点调用失败时返回 503ResultStatusCodes ={[HealthStatus.Healthy] = StatusCodes.Status200OK,[HealthStatus.Degraded] = StatusCodes.Status503ServiceUnavailable,[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable},ResponseWriter = async (context, report) =>{// 若请求取消,提前返回context.RequestAborted.ThrowIfCancellationRequested();// 遍历所有检查结果,如果有非 Healthy,写警告日志foreach (var entry in report.Entries){if (entry.Value.Status != HealthStatus.Healthy){logger.LogWarning("Health Check '{Name}' status: {Status}. Error: {Error}",entry.Key,entry.Value.Status,entry.Value.Exception?.Message);}}// 自定义 JSON 格式var response = new{status = report.Status.ToString(),totalDuration = report.TotalDuration.TotalMilliseconds + " ms",results = report.Entries.Select(e => new{name = e.Key,status = e.Value.Status.ToString(),duration = e.Value.Duration.TotalMilliseconds + " ms",error = e.Value.Exception != null ? "Error occurred, see logs for details" : null})};context.Response.ContentType = "application/json; charset=utf-8";var options = new JsonSerializerOptions{WriteIndented = true,PropertyNamingPolicy = JsonNamingPolicy.CamelCase};await context.Response.WriteAsync(JsonSerializer.Serialize(response, options));}
})
.RequireAuthorization("HealthCheckPolicy"); // 仅允许特定角色访问
要点:
- 将 Degraded/Unhealthy 状态映射为 HTTP 503 ⚠️;
- 在
ResponseWriter
中遍历每个检查项,若非 Healthy,就写警告日志 📝;- 不直接将
Exception.Message
返回客户端,避免泄露内部实现 🔒;- 使用
JsonSerializerOptions
美化 JSON 🎨。
三、实战演示 🚀
下面以一个 API Gateway 为例,演示如何聚合多个微服务的 /health-status
,并在本地提供一个“聚合健康状态”端点。
3.1 Gateway 端整合示例 🔗
// 在 Program.cs 中继续配置
builder.Services.AddAuthorization(options =>
{options.AddPolicy("GatewayHealthPolicy", policy =>policy.RequireRole("GatewayAdmin"));
});var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();// 注入 HttpClient,用于调用下游服务
builder.Services.AddHttpClient("HealthClient").ConfigureHttpClient(client =>{client.Timeout = TimeSpan.FromSeconds(2); // 每个请求超时 2s});app.MapGet("/aggregate-health", async (IHttpClientFactory httpFactory) =>
{var urls = new[]{"http://serviceA/health-status","http://serviceB/health-status","http://serviceC/health-status"};var client = httpFactory.CreateClient("HealthClient");var tasks = urls.Select(async url =>{try{var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2));var resp = await client.GetStringAsync(url, cts.Token);// 简单判断下游状态是否包含 "Unhealthy"var isUnhealthy = resp.Contains("\"status\":\"Unhealthy\"");return new { Url = url, IsUnhealthy = isUnhealthy };}catch{// 调用失败,视为 Unhealthyreturn new { Url = url, IsUnhealthy = true };}});var results = await Task.WhenAll(tasks);// 若任一服务不可用,则聚合状态为 Unhealthyvar aggregateStatus = results.Any(r => r.IsUnhealthy) ? "Unhealthy" : "Healthy";var response = new{aggregateStatus,details = results.Select(r => new{service = r.Url,status = r.IsUnhealthy ? "Unhealthy" : "Healthy"})};return Results.Json(response);
})
.RequireAuthorization("GatewayHealthPolicy");
说明:
- 使用
IHttpClientFactory
创建带超时设置的 HttpClient ⏲️;- 并发调用各下游
/health-status
,若任一返回中包含"Unhealthy"
,则认为该服务不可用 🚫;- 最后再聚合结果,返回一个整体状态及每个服务的健康情况。
3.2 Health Check 整体流程示意图 📈
四、Kubernetes 集成 🐳
在 Kubernetes 环境中,我们通常要配置两个探针:
- livenessProbe:检测应用进程是否“活着”,若失败则重启 Pod 🔄
- readinessProbe:检测服务是否已“准备就绪”并能正常对外提供流量 ✅
因为 /health-status
包含了对数据库/Redis/外部 API 的检查,不建议直接当作 livenessProbe,否则只要依赖短暂不可用就会不断重启。最佳实践如下:
apiVersion: apps/v1
kind: Deployment
metadata:name: my-microservice
spec:replicas: 3selector:matchLabels:app: my-microservicetemplate:metadata:labels:app: my-microservicespec:containers:- name: webimage: myregistry/my-microservice:latestports:- containerPort: 80# livenessProbe:只检查应用自检 ping 接口livenessProbe:httpGet:path: /health/pingport: 80initialDelaySeconds: 30periodSeconds: 10timeoutSeconds: 2failureThreshold: 3# readinessProbe:检查完整的 /health-statusreadinessProbe:httpGet:path: /health-statusport: 80initialDelaySeconds: 15periodSeconds: 20timeoutSeconds: 5failureThreshold: 2# 环境变量或 ConfigMap 挂载可灵活配置连接字符串env:- name: ConnectionStrings__DefaultvalueFrom:secretKeyRef:name: my-secretskey: SqlConnectionString- name: ConnectionStrings__RedisvalueFrom:secretKeyRef:name: my-secretskey: RedisConnectionString- name: ExternalServices__PingUrlvalue: "https://api.external.com/ping"
要点:
- 📌
/health/ping
端点仅检查自检项(见 2.2 中.AddCheck("Self", …)
),保证应用运行即可;- 📌
/health-status
端点同时检查数据库、Redis、外部 API,仅当所有依赖都可用时才返回 Healthy;- 📌 合理设置
initialDelaySeconds
、periodSeconds
、timeoutSeconds
与failureThreshold
,避免频繁误判;- 🔒 如果探针端点公开在公网上,一定要在 Ingress 或 Service 层面添加 IP 白名单或身份验证。
4.1 Kubernetes 整体流程示意图 🌐
五、安全性与健壮性 🔐
-
不要泄露异常细节
- 在自定义响应时,将
Exception.Message
只写入日志,不直接返回给客户端,防止敏感信息泄露。
- 在自定义响应时,将
-
鉴权与授权
- 对
/health-status
和/hc-ui
端点均要加上授权策略。例如在Program.cs
中:
builder.Services.AddAuthorization(options => {options.AddPolicy("HealthCheckPolicy", policy =>policy.RequireRole("HealthAdmin"));options.AddPolicy("UIAccessPolicy", policy =>policy.RequireRole("OpsUser")); });app.UseAuthentication(); app.UseAuthorization();app.MapHealthChecks("/health-status", new HealthCheckOptions { … }).RequireAuthorization("HealthCheckPolicy");app.MapHealthChecksUI(options => {options.UIPath = "/hc-ui"; }).RequireAuthorization("UIAccessPolicy");
说明:🔒 只有拥有对应角色的用户才可访问健康检查端点和 UI 界面。
- 对
-
日志告警与追踪 📣
- 将非 Healthy 检查项的异常写入告警日志,并结合 Prometheus、Grafana 等工具配置告警规则。例如:
foreach (var entry in report.Entries) {if (entry.Value.Status != HealthStatus.Healthy){logger.LogError("【HealthCheck告警】{Name} 状态: {Status},详细: {Exception}",entry.Key,entry.Value.Status,entry.Value.Exception?.ToString());} }
- 配合
ILogger
将日志发送到 Elasticsearch / Seq / Kibana 等日志分析平台。
- 将非 Healthy 检查项的异常写入告警日志,并结合 Prometheus、Grafana 等工具配置告警规则。例如:
-
Graceful Shutdown(优雅下线) 🌅
- 在程序关闭时,将 Pod 状态先置为 NotReady,再执行清理逻辑。可以在
Program.cs
中订阅ApplicationStopping
事件:var lifetime = app.Services.GetRequiredService<IHostApplicationLifetime>(); lifetime.ApplicationStopping.Register(() => {// 将自检状态置为 Unhealthy,通知 Kubernetes 不再发流量// 具体实现可将“Self”检查改为动态返回 Unhealthy });
- 在程序关闭时,将 Pod 状态先置为 NotReady,再执行清理逻辑。可以在
六、性能与可用性考量 🚀
-
监控健康检查耗时 ⏱️
- 使用 Prometheus Client 库,将每个健康检查项的耗时上报到 Prometheus:
// 在自定义 ResponseWriter 中添加 var gauge = Metrics.CreateGauge("health_check_duration_seconds", "健康检查耗时(秒)", "dependency"); foreach (var entry in report.Entries) {gauge.WithLabels(entry.Key).Set(entry.Value.Duration.TotalSeconds); }
- Grafana 可据此画出每个依赖的响应曲线,帮助发现性能瓶颈。📊
- 使用 Prometheus Client 库,将每个健康检查项的耗时上报到 Prometheus:
-
抖动过滤与熔断 ⚡
- 若数据库偶发抖动,会在
/health-status
上触发短暂 Unhealthy,造成 Pod 频繁重启。可使用“熔断+滑动窗口”策略,将检查结果在内存中缓存一定时长:- 使用 Polly 的 CircuitBreaker 在检测到连续 3 次失败后,将后续 30s 直接判定为 Unhealthy,避免频繁触发探针。
- 示例:
using Polly; using Polly.CircuitBreaker;// 定义熔断策略 var breakerPolicy = Policy.Handle<Exception>().CircuitBreakerAsync(exceptionsAllowedBeforeBreaking: 3,durationOfBreak: TimeSpan.FromSeconds(30));services.AddHealthChecks().AddCheck("SqlServerWithBreaker", async () =>{return await breakerPolicy.ExecuteAsync(async () =>{// 这里实际调用 SQL Server 做检查// …return HealthCheckResult.Healthy();});});
- 这样在连续失败后,短时间内不再实际调用数据库,只把健康状态返回为 Unhealthy,等熔断解除后再恢复正常调用。🔄
- 若数据库偶发抖动,会在
-
水平扩展与缓存 ☁️
- 当微服务水平扩展后,如果每个实例都直接去访问数据库检查,容易造成短时压力;可考虑:
- 统一在一个“侧车”(Sidecar)或中间层进行数据库探测,主实例直接从侧车获取结果。
- 将某些常驻的健康检查(如 Redis)结果缓存在内存 30 秒,每次请求
/health-status
时先读取缓存。
- 当微服务水平扩展后,如果每个实例都直接去访问数据库检查,容易造成短时压力;可考虑:
完整示例项目结构概览(摘录) 📂
MicroserviceDemo
├─ Program.cs
├─ appsettings.json
├─ Controllers
│ └─ WeatherController.cs
├─ HealthChecks
│ └─ CustomHealthChecks.cs # 可放置自定义熔断/滑动窗口检查逻辑
├─ Properties
│ └─ launchSettings.json
└─ Dockerfile
- Program.cs:包含上述健康检查与 UI 的注册、映射、授权逻辑。
- appsettings.json:存储连接字符串与配置项,例如:
{"ConnectionStrings": {"Default": "Server=.;Database=MyDb;User Id=sa;Password=Your_password;","Redis": "localhost:6379"},"ExternalServices": {"PingUrl": "https://api.external.com/ping"},"HealthChecksUI": {"HealthChecks-UI": [{"Name": "MicroservicesHealth","Uri": "/health-status"}],"EvaluationTimeOnSeconds": 60,"MinimumSecondsBetweenFailureNotifications": 50},"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}} }
注意:示例仅供参考,请根据实际项目需求调整配置项及命名规范。
相关文章:
健康检查:在 .NET 微服务模板中优雅配置 Health Checks
🚀 健康检查:在 .NET 微服务模板中优雅配置 Health Checks 📚 目录 🚀 健康检查:在 .NET 微服务模板中优雅配置 Health Checks一、背景与意义 🔍二、核心配置 🔧2.1 引入必要的 NuGet 依赖 &…...
【Pytorch学习笔记】模型模块08——AlexNet模型详解
AlexNet模型详解:结构、算法与PyTorch实现 一、AlexNet模型结构 AlexNet是2012年ImageNet竞赛冠军模型,由Alex Krizhevsky等人提出,标志着深度学习在计算机视觉领域的突破。 网络结构(5卷积层 3全连接层)ÿ…...

LabVIEW自感现象远程实验平台
LabVIEW开发自感现象远程实验平台,通过整合 NI数据采集设备、菲尼克斯(Phoenix Contact)继电器模块及罗技(Logitech)高清摄像头,实现远程数据采集、仪器控制与实时监控三大核心功能。平台突破传统实验装置局…...
AppTrace 视角下 App 一键拉起:提升应用转化率的高效方案
官网地址:AppTrace - 专业的移动应用推广追踪平台 在大规模开展 App 推广、用户召回、广告投放、邀请传播等活动时,高效的深度链接方案至关重要。它不仅能缩短用户路径,带来无缝、流畅的跳转体验,更核心的是通过参数传递打通 web…...
梯度下降:机器学习优化的核心算法
梯度下降算法原理及其在机器学习中的实践应用 引言 在机器学习领域,优化算法扮演着核心角色。其中梯度下降法作为最基础的优化方法,为神经网络、支持向量机等模型提供了参数优化解决方案。本文将深入解析梯度下降的数学原理,探讨其多种变体实现,并通过Python代码演示具体…...
Vue-6-前端框架Vue之基于Plotly.js绘制曲线
文章目录 1 安装Plotly.js2 折线图2.1 创建一个Vue组件来绘制图表2.1.1 Vue模板部分template2.1.2 Vue脚本部分script2.1.3 Vue样式部分style2.2 使用这个组件APP.vue3 动态更新图表3.1 创建一个Vue组件来绘制图表3.1.1 Vue模板部分template3.1.2 Vue脚本部分script3.1.3 Vue样…...

Python----目标检测(《YOLOv3:AnIncrementalImprovement》和YOLO-V3的原理与网络结构)
一、《YOLOv3:AnIncrementalImprovement》 1.1、基本信息 标题:YOLOv3: An Incremental Improvement 作者:Joseph Redmon, Ali Farhadi 机构:华盛顿大学(University of Washington) 发表时间:2018年 代…...
Redux:不可变数据与纯函数的艺术
Redux:不可变数据与纯函数的艺术 状态管理的困境 随着现代 Web 应用功能的不断扩展,前端开发者面临着日益复杂的状态管理挑战。当应用从简单的表单交互发展到复杂的单页应用时,组件间共享状态的问题变得尤为突出。想象一个电商平台…...

算法篇 八大排序(冒泡 插入 选择 堆 希尔 快排 归并 计数)
目录 引言 1.冒泡排序 思路 代码实现 2.选择排序 思路 代码实现(存在易错点) 3.插入排序 思路 代码实现 4.希尔排序 思路 代码实现 5.堆排序 思路 代码实现 6.快速排序(快排) 一.三路划分 思路 代码实现 二.自…...
技术文档写作全攻略
一、引言 在快速迭代的软件开发中,技术文档早已不只是附属品,而是与代码同等重要的交付物: 帮助新成员 T0 → T1 学习曲线指数下降;降低支持成本,将重复性问答前移到自助文档;为合规审计、知识传承及商业…...
网络安全全景解析
引言 在数字化时代,网络已深度融入社会生产生活的各个领域,成为推动经济发展和社会进步的关键力量。然而,随着网络应用的日益复杂,网络安全问题也呈现出多样化、复杂化的趋势。从个人隐私泄露到企业核心数据被盗,从基础…...

音视频之视频压缩编码的基本原理
系列文章: 1、音视频之视频压缩技术及数字视频综述 2、音视频之视频压缩编码的基本原理 一、预测编码: 1、预测编码的基本概念: 预测法是最简单、实用的视频压缩编码方法,经过压缩编码后传输的并不是像素本身的取样值࿰…...

IDEA 包分层显示设置
方法一(用的IntelliJ IDEA 2024.1.4版本): 找到项目视图设置入口:在左侧Project(项目)面板的顶部,有个三个点...的按钮 ,点击它。 进入树形外观配置:在弹出的菜单中&…...
书籍将正方形矩阵顺时针转动90°(8)0605
题目 给定一个N x N的矩阵matrix,把这个矩阵调整成顺时针转动90后的形式。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 顺时针转动90后为: 13 9 5 1 14 …...
【docker】容器技术如何改变软件开发与部署格局
在当今数字化时代,软件开发与部署的效率和灵活性至关重要。就像古人云:“工欲善其事,必先利其器。”Docker 作为一款强大的容器技术,正如同软件开发领域的一把利器,极大地改变了应用的开发、交付和运行方式。本文将深入…...
C#抽象类深度解析 _ 核心特性与实战指南
—— 面向对象设计的基石 🔍抽象类核心定义 abstract class AbClass { ... } // abstract修饰符声明 不可实例化:new AbClass() 将触发编译错误继承专用:仅能作为其他类的基类存在混合成员组合:可同时包含抽象方法和已实现方法…...
时序数据库IoTDB的UDF Sample算法在数据监控、故障预防的应用
一、数据监控在工业物联网中的重要性 设备数据监控是工业物联网(IoT)中最为广泛应用的领域之一。通过实时监控工厂机械设备的运行状态,企业能够提前发现设备的潜在故障,从而实现预防性维护与可预测性维护。这一做法不仅能有效提升…...
Flask-SQLAlchemy使用小结
链表查询 join方法允许你指定两个或多个表之间的连接条件,并返回一个新的查询对象,该对象包含了连接后的结果。 内连接 from sqlalchemy import join # 使用join函数 query db.session.query(User, Order).join(Order, User.id Order.user_id) res…...

深度学习和神经网络 卷积神经网络CNN
1.什么是卷积神经网络 一种前馈神经网络;受生物学感受野的机制提出专门处理网格结构数据的深度学习模型 核心特点:通过卷积操作自动提取空间局部特征(如纹理、边缘),显著降低参数量 2.CNN的三个结构特征 局部连接&a…...
用 NGINX 构建高效 POP3 代理`ngx_mail_pop3_module`
一、模块定位与作用 协议代理 ngx_mail_pop3_module 让 NGINX 能够充当 POP3 代理:客户端与后端 POP3 服务器之间的所有请求均转发到 NGINX,由 NGINX 负责与后端会话逻辑。认证方式控制 通过 pop3_auth 指令指定允许客户端使用的 POP3 认证方法…...
解决:如何在Windows adb使用dmesg | grep检查内核日志
首先: C:\Users\TF> adb shell 再 rk3568_r:/ $ dmesg | grep -i “goodix” 显示 130|rk3568_r:/ $ dmesg | grep -i “goodix” [ 0.764071] goodix_ts_probe() start111 [ 0.764108] goodix_ts_probe() start222 [ 0.764181] Goodix-TS 1-0014: Linked as a c…...

PlayWright | 初识微软出品的 WEB 应用自动化测试框架
Playwright是微软大厂背书的跨平台 WEB 应用自动化测试框架,支持多开发语言(TypeScript、JavaScript、.Net、Python、Java)及多浏览器(Chromium、WebKit、Firefox),同时支持移动端测试。 安装 playwright …...

Mac电脑_钥匙串操作选项变灰的情况下如何删除?
Mac电脑_钥匙串操作选项变灰的情况下如何删除? 这时候 可以使用相关的终端命令进行操作。 下面附加文章《Mac电脑_钥匙串操作的终端命令》。 《Mac电脑_钥匙串操作的终端命令》 (来源:百度~百度AI 发布时间:2025-06)…...
Git Patch 使用详解:生成、应用与多提交合并导出
在多人协作、代码审查、离线提交或跨仓库迁移的场景中,git patch 是非常实用的技术。本文将系统地介绍如何使用 Git 的补丁机制导出和应用修改内容。 📖 什么是 Git Patch? 严格来说,git patch 并不是一个 Git 命令,而…...

2025前端微服务 - 无界 的实战应用
遇饮酒时须饮酒,得高歌处且高歌 文章目录 什么是前端微服务主流框架概述无界 - 腾讯乾坤 - 阿里Micro-app Vue3项目引用⑴. 项目依赖安装⑵. main.ts 文件配置⑶. 路由配置⑷. 页面设置 隐藏子应用菜单及顶部信息栏子应用样式冲突问题虚拟路由⑴. 路由⑵. 页面 跨域…...
Spring Boot 缓存注解详解:@Cacheable、@CachePut、@CacheEvict(超详细实战版)
💡 前言 在高并发、高性能的系统开发中,缓存是提升接口响应速度和降低数据库压力的重要手段。Spring Boot 提供了强大的缓存抽象层 —— spring-context-support,并结合 JSR-107 标准,提供了多个缓存注解,如ÿ…...

【设计模式-4.8】行为型——中介者模式
说明:本文介绍行为型设计模式之一的中介者模式 定义 中介者模式(Mediator Pattern)又叫作调节者模式或调停者模式。用一个中介对象封装一系列对象交互,中介者使各对象不需要显式地互相作用,从而使其耦合松散…...
SpringCloud-基于SpringAMQP实现消息队列
在微服务架构中,使用消息队列进行异步通信是一种常见而有效的方法。Spring Cloud提供了一个强大的工具集,用于构建分布式系统,而Spring AMQP是其支持高级消息队列协议(AMQP)的组件,广泛应用于消息队列的场景中,尤其是与…...
ObjectMapper 在 Spring 统一响应处理中的作用详解
ObjectMapper 是 Jackson 库的核心类,专门用于处理 JSON 数据的序列化(Java 对象 → JSON)和反序列化(JSON → Java 对象)。在你提供的代码中,它解决了字符串响应特殊处理的关键问题。 一、为什么需要 Obj…...
H5移动端性能优化策略(渲染优化+弱网优化+WebView优化)
一、渲染优化:首屏速度提升的核心 1. 关键页面采用SSR或Native渲染 适用场景:首页、列表页、详情页等强内容展示页面 优化原理: SSR(服务端渲染):在服务端生成完整…...