当前位置: 首页 > article >正文

在 ABP VNext 中集成 Serilog:打造可观测、结构化日志系统

🚀 在 ABP VNext 中集成 Serilog:打造可观测、结构化日志系统


📚 目录

  • 🚀 在 ABP VNext 中集成 Serilog:打造可观测、结构化日志系统
    • 1. 为什么要使用结构化日志? 🤔
    • 2. 核心集成步骤 🛠
      • 2.1 流程图示例
    • 3. NuGet 包安装 📦
    • 4. appsettings.json 配置 📝
    • 5. Program.cs 全局日志初始化 💻
      • 5.1 代码流程图
    • 6. ABP 模块注册 🏗
    • 7. 上下文信息添加 🧩
      • 7.1 UseAbpSerilogEnrichers() 自动插入
      • 7.2 LogContext.PushProperty 自定义属性
    • 8. 对接平台:Seq & ELK & Grafana Loki 🌐
      • 8.1 部署 Seq(推荐开发阶段)
      • 8.2 部署 ELK(推荐生产环境)
        • 8.2.1 在 Kibana 中创建 Index Pattern 🔍
      • 8.3 对接 Grafana Loki(可选)🔗
    • 9. 总结 📋
    • 📎 推荐阅读 📚


1. 为什么要使用结构化日志? 🤔

相比于简单的文本日志,结构化日志有以下优势:

  • ❌ 传统文本日志无法根据 TraceId、UserId 等字段方便地检索
  • ❌ 无法像 SQL 那样对日志字段进行过滤与聚合
  • ❌ 不易在可视化平台(如 Kibana、Seq、Grafana Loki)上进行联动分析

而 Serilog 以原生的 JSON 日志形式输出,能够轻松处理上下文、分析调用链,方便与 ELK / Seq / Loki 等平台集成,做到精准定位故障点。


2. 核心集成步骤 🛠

步骤内容
1⃣️安装 Volo.Abp.AspNetCore.Serilog
2⃣️配置 Serilog Sink(Console、File、Seq、Elasticsearch、Loki)
3⃣️Program.cs 中初始化 Serilog
4⃣️在 ABP 模块中启用 UseAbpSerilogEnrichers() 插入上下文

2.1 流程图示例

启动项目
读取 appsettings.json 中 Serilog 配置
Program.cs 中 UseSerilog 初始化 Logger
创建 ABP 应用并调用 UseAbpSerilogEnrichers
HTTP 请求进入 → Enrichers 插入上下文
业务代码调用 ILogger 输出日志
Serilog 将日志写入 Console/File/Seq/ES/Loki
  • 通过 “Enrichers” 阶段,可以自动将 TraceId、UserId、MachineName 等信息注入到每条日志。

3. NuGet 包安装 📦

在项目根目录下执行以下命令,添加所需依赖包。为了避免版本不一致,建议指定版本号:

dotnet add package Volo.Abp.AspNetCore.Serilog 
dotnet add package Serilog.Sinks.Console          
dotnet add package Serilog.Sinks.File              
dotnet add package Serilog.Sinks.Seq               
dotnet add package Serilog.Sinks.Elasticsearch     # 如想支持 Grafana Loki:
dotnet add package Serilog.Sinks.Grafana.Loki      

4. appsettings.json 配置 📝

appsettings.json 文件中,添加或修改 Serilog 节点,如下所示:

{"Serilog": {"Using": ["Serilog.Sinks.Console","Serilog.Sinks.File","Serilog.Sinks.Seq","Serilog.Sinks.Elasticsearch","Serilog.Sinks.Grafana.Loki"],"MinimumLevel": {"Default": "Information","Override": {"Microsoft": "Warning","Microsoft.EntityFrameworkCore": "Error","Volo.Abp": "Information"}},"WriteTo": [{"Name": "Console"},{"Name": "File","Args": {"path":                 "Logs/log-.log","rollingInterval":      "Day","retainedFileCountLimit": 14,"fileSizeLimitBytes":   104857600,"buffered":             true,"flushToDiskInterval":  "00:00:05"}},{"Name": "Seq","Args": {"serverUrl": "http://localhost:5341"}},{"Name": "Elasticsearch","Args": {"nodeUris":                  "http://localhost:9200","indexFormat":               "myapp-logs-{0:yyyy.MM.dd}","autoRegisterTemplate":      true,"autoRegisterTemplateVersion": "ESv7","numberOfReplicas":          1,"numberOfShards":            5,"batchPostingLimit":         50,"period":                    "00:00:05","failureCallback":           "e => Console.WriteLine(\"Unable to submit event to Elasticsearch: \" + e.Message)"}},{"Name": "GrafanaLoki","Args": {"uri":                 "http://localhost:3100/loki/api/v1/push","batchPostingLimit":   50,"period":              "00:00:05","labels":              "{\"Application\":\"MyAbpApp\",\"Environment\":\"${env:ASPNETCORE_ENVIRONMENT}\"}"}}],"Enrich": ["FromLogContext","WithMachineName","WithThreadId","WithEnvironmentName"]}
}
  • Using:要加载的 Sink 包列表,包括 Console、File、Seq、Elasticsearch、Grafana Loki。
  • MinimumLevel:全局最低日志级别及对各命名空间的 Override。
  • WriteTo:各个输出通道的配置:
    • 📟 Console:控制台直接输出,适合开发与容器模式下采集标准输出。
    • 📂 File:写入本地文件,rollingInterval: Day 按天滚动;retainedFileCountLimit: 14 最多保留 14 天日志;fileSizeLimitBytes: 100MB,超出则滚动。
    • 📊 Seq:访问地址为 http://localhost:5341 的本地 Seq 服务。
    • 🔍 Elasticsearch:连接到 http://localhost:9200,索引名称按天命名;批量发送 50 条 / 5 秒;失败回调打印到控制台。
    • 📈 GrafanaLoki:连接本地 Loki(端口 3100)并打上标签,一旦在 Grafana 中按标签筛选,方便定位。
  • Enrich:注入常见上下文字段(如 TraceId、MachineName、ThreadId、Environment)。

Tip:如需在开发/生产环境区分配置,可分别在 appsettings.Development.jsonappsettings.Production.json 中覆盖 MinimumLevelWriteTo 节点。例如:

  • Development:将 MinimumLevel.Default 设置为 Debug,仅启用 Console Sink;
  • Production:将 MinimumLevel.Default 设置为 Information,启用 File、Seq、Elasticsearch、Loki Sink;并关闭 Console 输出以减少 I/O 压力。

5. Program.cs 全局日志初始化 💻

Program.cs 文件里,使用 Serilog 提供的“Bootstrap Logger”+“配置读取”模版,示例如下:

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using Volo.Abp.Serilog;namespace MyAbpApp
{public class Program{public static async Task Main(string[] args){// 1. 创建 Bootstrap Logger(只输出到 Console,用于捕获最早期的日志)Log.Logger = new LoggerConfiguration().MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Warning).WriteTo.Console().CreateBootstrapLogger();try{// 2. 构建 Host 并读取 appsettings.json 中的 Serilog 配置var builder = WebApplication.CreateBuilder(args);builder.Host.UseSerilog((ctx, services, config) =>{config.ReadFrom.Configuration(ctx.Configuration)    // 读取 appsettings.json 的 Serilog 设置.ReadFrom.Services(services)                  // 读取 DI 容器中注册的 ILogEventEnricher.Enrich.FromLogContext()                      // 从 LogContext 拉取附加属性.Enrich.WithProperty("Application", "MyAbpApp").Enrich.WithProperty("Environment", ctx.HostingEnvironment.EnvironmentName);});// 3. 添加 ABP 应用及所需模块builder.Services.AddApplication<MyAbpAppModule>();// 4. 构建应用var app = builder.Build();// 5. 注入 Serilog Enrichers(TraceId、UserId、TenantId 等)app.UseAbpSerilogEnrichers();// 6. 初始化 ABP 模块(包括 Routing、Authentication、Authorization 等)await app.InitializeApplicationAsync();// 7. 启动 HTTP 服务并阻塞await app.RunAsync();}catch (Exception ex){// 8. 捕获主机启动时的异常并记录 Fatal 日志Log.Fatal(ex, "Application start-up failed");Environment.ExitCode = 1;}finally{// 9. 应用退出时刷新并关闭日志Log.CloseAndFlush();}}}
}

5.1 代码流程图

Main 方法开始
创建 Bootstrap Logger
构建 WebHostBuilder
UseSerilog 读取配置并初始化 Logger
Services.AddApplication
Build 应用
UseAbpSerilogEnrichers 注入上下文
InitializeApplicationAsync 初始化 ABP 模块
RunAsync 启动 Kestrel 并监听请求
请求到达 → Enrichers 插入 TraceId 等
业务代码调用 ILogger 输出日志 → Serilog 写入 Sink
  • 该图展示了 Program.cs 中从 Main 开始,到最终应用启动并接收请求,日志如何一步步初始化并插入上下文的执行路径。

6. ABP 模块注册 🏗

MyAbpAppModule.cs 中声明所需的依赖模块,例如:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.DistributedEventBus;
using Volo.Abp.Modularity;
using Volo.Abp.TenantManagement;namespace MyAbpApp
{[DependsOn(typeof(AbpAspNetCoreSerilogModule),    // Serilog 集成模块typeof(AbpAspNetCoreMvcModule),        // MVC/Web API 基础模块typeof(AbpBackgroundWorkersModule),    // 后台任务模块(示例)typeof(AbpDistributedEventBusModule),  // 分布式事件总线模块(示例)typeof(AbpTenantManagementModule)      // 多租户管理模块(如需多租户场景))]public class MyAbpAppModule : AbpModule{public override void OnApplicationInitialization(ApplicationInitializationContext context){var logger = context.ServiceProvider.GetRequiredService<ILogger<MyAbpAppModule>>();logger.LogInformation("🔥 ABP 模块已启动!");}public override void OnApplicationShutdown(ApplicationShutdownContext context){var logger = context.ServiceProvider.GetRequiredService<ILogger<MyAbpAppModule>>();logger.LogInformation("💤 ABP 模块已关闭!");}}
}
  • 说明
    1. AbpAspNetCoreSerilogModule 会将 ABP 框架内部的日志重定向到 Serilog。
    2. 如果您的业务需要后台任务或分布式事件,请在 DependsOn 一并引入对应模块。
    3. 如果项目启用多租户,一定要引入 AbpTenantManagementModule 等租户相关模块。
    4. OnApplicationInitialization 中写一条“ABP 模块已启动”日志方便确认模块加载成功;在 OnApplicationShutdown 中写一条“ABP 模块已关闭”日志方便确认优雅退出。

7. 上下文信息添加 🧩

7.1 UseAbpSerilogEnrichers() 自动插入

Program.cs 中调用 app.UseAbpSerilogEnrichers(); 后,Serilog 会自动注入以下常见上下文字段到每条日志中:

  • 🔗 TraceId:分布式链路追踪 ID(需配合 OpenTelemetry/Jaeger 等链路追踪服务)
  • 👤 UserId、UserName:当前登录用户信息(需在请求上下文中有认证信息)
  • 🏷️ TenantId:当前多租户系统的租户 ID(如启用了多租户模块)
  • 🖥️ MachineName:主机名称(适用于集群调试)
  • 🧵 ThreadId:线程 ID(方便定位多线程日志)
  • 🌐 Environment:部署环境(如 Development、Production)

注意UseAbpSerilogEnrichers() 必须放在 UseRouting() 之后、UseAuthentication() 之前;如果您使用 ABP 脚手架模板,则无需手动调用中间件顺序,InitializeApplicationAsync() 已自动处理。

7.2 LogContext.PushProperty 自定义属性

在业务代码里,如果需要在单次请求或某个操作中,对特定实体(如 Order)添加自定义属性,可以使用 LogContext.PushProperty(...),示例如下:

using Serilog;
using Serilog.Context;
using Microsoft.Extensions.Logging;public class OrderService
{private readonly ILogger<OrderService> _logger;public OrderService(ILogger<OrderService> logger){_logger = logger;}public void ProcessOrder(Order order){// 在这个 using 块内,所有日志都会带上 OrderId 属性using (LogContext.PushProperty("OrderId", order.Id)){_logger.LogInformation("✅ Processing order {@Order}", order);// … 其它业务逻辑_logger.LogWarning("⚠️ Order {@Order} took too long to process", order);}}
}
  • 说明
    1. LogContext.PushProperty("OrderId", order.Id) 会在当前上下文中将 OrderId 写入所有后续日志。
    2. 使用 {@Order} 这种序列化写法,会把 Order 对象的所有字段写到 JSON 中,方便在 ES/Kibana/Loki 中查看结构化数据。
    3. 在控制台或日志平台中,该条日志会像:
      {"Timestamp": "2025-05-31T20:00:00.0000000Z","Level": "Information","MessageTemplate": "✅ Processing order {@Order}","Properties": {"OrderId": 12345,"Order": { "Id": 12345, "Amount": 99.99, "CustomerId": 67890 },"TraceId": "abcdef1234567890","UserId": 42,"TenantId": 1,"MachineName": "server01","ThreadId": 12,"Environment": "Production"}
      }
      

8. 对接平台:Seq & ELK & Grafana Loki 🌐

8.1 部署 Seq(推荐开发阶段)

docker run -d \-p 5341:80 \-v seq_data:/data \datalust/seq
  • 说明
    1. -p 5341:80 将容器 80 端口映射到宿主机 5341 端口;访问地址为 http://localhost:5341
    2. -v seq_data:/data 挂载一个 Docker 卷,用于持久化 Seq 数据;容器重启后数据依然保留。
    3. 启动后,可在 Seq Web 界面里创建 Dashboard,使用筛选条件(如 @l = "Error"@t >= "2025-05-01")进行日志定位。

8.2 部署 ELK(推荐生产环境)

创建一个 docker-compose.yml 文件,内容如下:

version: '3.7'volumes:es_data:kibana_data:services:elasticsearch:image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0container_name: elasticsearchenvironment:- node.name=es-node-1- discovery.type=single-node- xpack.security.enabled=false- ES_JAVA_OPTS=-Xms1g -Xmx1gvolumes:- es_data:/usr/share/elasticsearch/dataports:- 9200:9200kibana:image: docker.elastic.co/kibana/kibana:7.17.0container_name: kibanaenvironment:- ELASTICSEARCH_HOSTS=http://elasticsearch:9200volumes:- kibana_data:/usr/share/kibana/dataports:- 5601:5601depends_on:- elasticsearch

运行:

docker-compose up -d
  • 说明
    1. Elasticsearch
      • 挂载 es_data 卷用以持久化数据;
      • 设置 JVM 堆大小为 1G(ES_JAVA_OPTS=-Xms1g -Xmx1g),生产环境可根据节点内存调整;
      • 关闭 X-Pack 安全认证方便本地测试;
    2. Kibana
      • 指定 ELASTICSEARCH_HOSTS 以连接 Elasticsearch;
      • 挂载 kibana_data 用于持久化 Kibana 配置;
      • 启动后访问 http://localhost:5601 即可登录;
8.2.1 在 Kibana 中创建 Index Pattern 🔍
  1. 打开 Kibana → 左侧菜单 “Management” → “Index Patterns” → “Create index pattern”。
  2. 在 “Index pattern name” 中输入 myapp-logs-*,点击 “Next step”。
  3. 选择时间字段(如 @timestamp)后点击 “Create index pattern”。
  4. 在 “Discover” 页面就能看到所有符合 myapp-logs-2025.05.XX 格式的索引,日志字段会以 JSON 形式展示,可以按字段进行过滤、排序、聚合。

提示:为了更直观地展示 Kibana 中的日志分组和聚合效果,可以创建一个简单的 Dashboard,比如“日志级别分布图”、“每小时错误请求数统计”等。这样在生产环境排查问题时,更加快捷。

8.3 对接 Grafana Loki(可选)🔗

如果您使用 Grafana Loki 作为日志收集平台,可参考以下步骤:

  1. 部署 Loki

    • 推荐使用 Loki 官方提供的 docker-compose.yml 或者 Helm Chart。
    • 简单示例(仅做测试用):
      version: '3.7'
      services:loki:image: grafana/loki:2.7.1container_name: lokicommand: -config.file=/etc/loki/local-config.yamlports:- 3100:3100promtail:image: grafana/promtail:2.7.1container_name: promtailvolumes:- /var/log:/var/log- ./promtail-config.yaml:/etc/promtail/config.yamlcommand: -config.file=/etc/promtail/config.yaml
      
    1. promtail-config.yaml 中,配置读取应用输出到标准输出(Console Sink)的日志,并推送到 Loki。
    2. 在 Grafana 中添加 Loki 数据源,创建 Dashboard 时选择 Loki 数据源即可查询 MyAbpApp 相关日志。
  2. GrafanaLoki Sink 配置示例
    已在第四节的 appsettings.json 中给出完整配置。再次回顾重点字段:

    {"Name": "GrafanaLoki","Args": {"uri": "http://localhost:3100/loki/api/v1/push","batchPostingLimit": 50,"period": "00:00:05","labels": "{\"Application\":\"MyAbpApp\",\"Environment\":\"Production\"}"}
    }
    
    • uri:Loki 的 Push API 地址;
    • batchPostingLimitperiod:控制批量推送频率;
    • labels:为日志打上标签,便于在 Grafana 中按标签筛选。

注意:在容器化环境下,将 uri 指向 Loki Service(如 http://loki:3100/loki/api/v1/push),不要使用 localhost


9. 总结 📋

  • 🚀 性能

    • 支持 bufferedflushToDiskInterval 控制文件写入 IO,平衡延迟与吞吐;
    • Elasticsearch Sink 中可配置 batchPostingLimitperiod,避免过于频繁的小批量请求。
  • 📈 规模

    • 支持日志按天滚动(rollingInterval: Day)和限制单文件大小(fileSizeLimitBytes),通过 retainedFileCountLimit 最多保留 14 天历史,防止磁盘耗尽。
  • 🎨 可视化

    • 结构化 JSON 日志让 Seq/Kibana/Loki 能以字段形式展示,可按字段、日期、级别精准搜索和聚合统计,大幅提升故障排查效率。
  • 🔧 可配置

    • 通过 appsettings.Development.jsonappsettings.Production.json 差异化配置,可在不同环境灵活切换最小日志级别与输出通道。
    • 支持自定义 Enrichers 和 Sink,能够将任意业务上下文(如 OrderId、ProductId、TraceId 等)注入到日志中。
  • 🐳 容器化注意

    • 如果服务跑在 Docker 或 Kubernetes,推荐保留 Console Sink 输出,通过容器平台日志采集(如 Fluentd、Filebeat、堆栈驱动)统一收集。
    • 若仍需写入日志文件,请确保挂载 Volume 以避免容器磁盘耗尽。
    • 根据目标平台(Seq、Elasticsearch、Loki)是否开启安全认证,需在对应 Sink 的 Args 中添加凭证信息(用户名、密码或 API Key)。

📎 推荐阅读 📚

  • ABP Serilog 模块文档
  • Serilog 官方文档
  • Seq 可视化平台
  • Grafana Loki 文档

相关文章:

在 ABP VNext 中集成 Serilog:打造可观测、结构化日志系统

&#x1f680; 在 ABP VNext 中集成 Serilog&#xff1a;打造可观测、结构化日志系统 &#x1f4da; 目录 &#x1f680; 在 ABP VNext 中集成 Serilog&#xff1a;打造可观测、结构化日志系统1. 为什么要使用结构化日志&#xff1f; &#x1f914;2. 核心集成步骤 &#x1f6e…...

pikachu靶场通关笔记07 XSS关卡03-存储型XSS

目录 一、XSS 二、存储型XSS 三、源码分析 四、渗透实战 1、输入mooyuan试一试 2、注入Payload 3、查看数据库 4、再次进入留言板页面 本系列为通过《pikachu靶场通关笔记》的XSS关卡(共10关&#xff09;渗透集合&#xff0c;通过对XSS关卡源码的代码审计找到XSS风险的…...

GitLab CI、GitHub Actions和Jenkins进行比较

特性/工具JenkinsGitLab CIGitHub Actions架构设计哲学Master/Agent分布式架构&#xff0c;通过插件扩展功能代码与CI/CD强耦合&#xff0c;内置Git仓库&#xff0c;基于Runner注册机制事件驱动&#xff0c;与GitHub深度集成&#xff0c;基于虚拟机的Job执行单元核心运行机制支…...

strcat及其模拟实现

#define _CRT_SECURE_NO_WARNINGS strcat 追加字符串 str "string"&#xff08;字符串&#xff09; cat "concatenate"&#xff08;连接 / 追加&#xff09; char* strcat(char* destination, const char* source); strcat的应用 方法一&#xff…...

OpenCV CUDA模块直方图计算------用于在 GPU 上执行对比度受限的自适应直方图均衡类cv::cuda::CLAHE

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::CLAHE 是 OpenCV 的 CUDA 模块中提供的一个类&#xff0c;用于在 GPU 上执行对比度受限的自适应直方图均衡&#xff08;Contrast Limi…...

华为OD机试真题——矩形绘制(2025A卷:200分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 200分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…...

通义开源视觉感知多模态 RAG 推理框架 VRAG-RL:开启多模态推理新时代

通义实验室的自然语言智能团队&#xff0c;凭借深厚的技术积累与创新精神&#xff0c;成功研发并开源了视觉感知多模态 RAG 推理框架 VRAG-RL&#xff0c;为 AI 在复杂视觉信息处理领域带来了重大突破。 传统 RAG 方法的局限 传统的检索增强型生成&#xff08;RAG&#xff0…...

爬虫入门:从基础到实战全攻略

&#x1f9e0; 一、爬虫基础概念 1.1 爬虫定义 爬虫&#xff08;Web Crawler&#xff09;是模拟浏览器行为&#xff0c;自动向服务器发送请求并获取响应数据的一种程序。主要用于从网页中提取结构化数据&#xff0c;供后续分析、展示或存储使用。 1.2 爬虫特点 数据碎片化&…...

qemu安装risc-V 64

参考这篇文章https://developer.aliyun.com/article/1323996&#xff0c;其中在wsl下面安装可能会报错环境变量中有空格。 # clean_path.sh#!/bin/bash# 备份旧 PATH OLD_PATH"$PATH"# 过滤掉包含空格、制表符、换行的路径 CLEAN_PATH"" IFS: read -ra PA…...

JDBC连不上mysql:Unable to load authentication plugin ‘caching_sha2_password‘.

最近为一个spring-boot项目下了mysql-9.3.0&#xff0c;结果因为mysql版本太新一直报错连不上。 错误如下&#xff1a; 2025-06-01 16:19:43.516 ERROR 22088 --- [http-nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispat…...

AsyncIOScheduler与BackgroundScheduler的线程模型对比

1. BackgroundScheduler的线程机制‌ ‌多线程模型‌&#xff1a;BackgroundScheduler基于线程池执行任务&#xff0c;默认通过ThreadPoolExecutor创建独立线程处理任务&#xff0c;每个任务运行在单独的线程中&#xff0c;主线程不会被阻塞。‌适用场景‌&#xff1a;适合同步…...

Python+MongoDb使用手册(精简)

这里是学了下面链接的内容&#xff0c;加上一些自己学习的内容综合的&#xff0c;大家也可以去看看这篇文章&#xff0c;写的特别好 【python】在Python中操作MongoDB的详细用法教程与实战案例分享_python轻松入门&#xff0c;基础语法到高阶实战教学-CSDN专栏 1 库&#xff1…...

前端面经 协商缓存和强缓存

HHTTPTTP缓存 协商缓存和强缓存 核心区别是否向服务器发起请求验证资源过期 强缓存 浏览器直接读取本地缓存,不发请求 HTTP响应头 Cache-Control:max-age3600资源有效期 Expires优先级低 如果有效浏览器返回200(浏览器换伪造的200) 应用静态资源 协商缓存 OK如果 1强缓…...

MacOS安装Docker Desktop并汉化

1. 安装Docker Desktop 到Docker Desktop For Mac下载对应系统的Docker Desktop 安装包&#xff0c;下载后安装&#xff0c;没有账号需要注册&#xff0c;然后登陆即可。 2. 汉化 前往汉化包下载链接下载对应系统的.asar文件 然后将安装好的文件覆盖原先的文件app.asar文件…...

Centos系统搭建主备DNS服务

目录 一、主DNS服务器配置 1.安装 BIND 软件包 2.配置主配置文件 3.创建正向区域文件 4.创建区域数据文件 5.检查配置语法并重启服务 二、从DNS服务配置 1.安装 BIND 软件包 2.配置主配置文件 3.创建缓存目录 4.启动并设置开机自启 一、主DNS服务器配置 1.安装 BIN…...

VUE项目部署IIS服务器手册

IIS部署Vue项目完整手册 &#x1f4cb; 目录 基础概念准备工作Vue项目构建web.config详解IIS部署步骤不同场景配置常见问题实用配置模板 基础概念 Vue单页应用&#xff08;SPA&#xff09;工作原理 重要理解&#xff1a;Vue项目是单页应用&#xff0c;这意味着&#xff1a;…...

使用 HTML + JavaScript 实现在线考试系统

在现代的在线教育平台中&#xff0c;在线考试系统是不可或缺的一部分。本文将通过一个完整的示例&#xff0c;演示如何使用 HTML、CSS 和 JavaScript 构建一个支持多种题型的在线考试系统。 效果演示 项目概述 本项目主要包含以下核心功能&#xff1a; 支持4种常见题型&…...

谷歌工作自动化——仙盟大衍灵机——仙盟创梦IDE

下载地址 https://chromewebstore.google.com/detail/selenium-ide/mooikfkahbdckldjjndioackbalphokd https://chrome.zzzmh.cn/info/mooikfkahbdckldjjndioackbalphokd...

嵌入式(C语言篇)Day13

嵌入式Day13 一段话总结 文档主要介绍带有头指针和尾指针的单链表的实现及操作&#xff0c;涵盖创建、销毁、头插、尾插、按索引/数据增删查、遍历等核心操作&#xff0c;强调头插/尾插时间复杂度为O(1)&#xff0c;按索引/数据操作需遍历链表、时间复杂度为O(n)&#xff0c;并…...

Oracle 的V$LOCK 视图详解

Oracle 的V$LOCK 视图详解 V$LOCK 是 Oracle 数据库中最重要的动态性能视图之一&#xff0c;用于显示当前数据库中锁的持有和等待情况。 一、V$LOCK 视图结构 列名数据类型描述SIDNUMBER持有或等待锁的会话标识符TYPEVARCHAR2(2)锁类型标识符ID1NUMBER锁标识符1&#xff08;…...

秒杀系统—1.架构设计和方案简介

大纲 1.秒杀系统的方案设计要点 2.秒杀系统的数据 页面 接口的处理方案 3.秒杀系统的负载均衡方案底层相关 4.秒杀系统的限流机制和超卖问题处理 5.秒杀系统的异步下单和高可用方案 1.秒杀系统的方案设计要点 (1)秒杀促销活动的数据处理 (2)秒杀促销活动的页面处理 (…...

基于FashionMnist数据集的自监督学习(生成式自监督学习AE算法)

目录 一&#xff0c;生成式自监督学习 1.1 简介 1.2 核心思想 1.3 常见算法 1.3.1 自动编码器&#xff08;Autoencoder&#xff09; 1.3.2 生成对抗网络&#xff08;GANs&#xff09; 1.3.3 变分自编码器&#xff08;VAE&#xff09; 1.3.4 Transformer-based 模型&…...

从监控到告警:Prometheus+Grafana+Alertmanager+告警通知服务全链路落地实践

文章目录 一、引言1.1 监控告警的必要性1.2 监控告警的基本原理1.2.1 指标采集与存储1.2.2 告警规则与触发机制1.2.3 多渠道通知与闭环 二、技术选型与架构设计2.1 为什么选择 Prometheus 及其生态2.1.1 Prometheus 优势分析2.1.2 Grafana 可视化能力2.1.3 Alertmanager 灵活告…...

AUTOSAR图解==>AUTOSAR_EXP_AIADASAndVMC

AUTOSAR高级驾驶辅助系统与车辆运动控制接口详解 基于AUTOSAR R22-11标准的ADAS与VMC接口规范解析 目录 1. 引言2. 术语和概念说明 2.1 坐标系统2.2 定义 2.2.1 乘用车重心2.2.2 极坐标系统2.2.3 车辆加速度/推进力方向2.2.4 倾斜方向2.2.5 方向盘角度2.2.6 道路变量2.2.7 曲率…...

WPF【09】WPF基础入门 (三层架构与MVC架构)

9-2 【操作】WPF 基础入门 新建一项目 Create a new project - WPF Application (A project for creating a .NET Core WPF Application) - Next - .NET 5.0 (Current) - Create 项目创建完成&#xff0c;VS自动打开 GUI用户界面&#xff0c;格式是 .xaml文件&#xff0c;跟xm…...

macOS 风格番茄计时器:设计与实现详解

macOS 风格番茄计时器&#xff1a;设计与实现详解 概述 本文介绍一款采用 macOS 设计语言的网页版番茄计时器实现。该计时器完全遵循苹果的人机界面指南(HIG)&#xff0c;提供原汁原味的 macOS 使用体验&#xff0c;同时具备响应式设计和深色模式支持。 核心特性 原生 macOS…...

中文NLP with fastai - Fastai Part4

使用fastai进行自然语言处理 在之前的教程中,我们已经了解了如何利用预训练模型并对其进行微调,以执行图像分类任务(MNIST)。应用于图像的迁移学习原理同样也可以应用于NLP任务。在本教程中,我们将使用名为AWD_LSTM的预训练模型来对中文电影评论进行分类。AWD_LSTM是LSTM…...

oracle goldengate实现远程抽取postgresql 到 postgresql的实时同步【绝对无坑版,亲测流程验证】

oracle goldengate实现postgresql 到 postgresql的实时同步 源端&#xff1a;postgresql1 -> postgresql2 流复制主备同步 目标端&#xff1a;postgresql 数据库版本&#xff1a;postgresql 12.14 ogg版本&#xff1a;21.3 架构图&#xff1a; 数据库安装以及流复制主备…...

【MYSQL】索引篇(一)

1.为什么要有索引 索引的本质是一种数据结构&#xff0c;她的作用其实就是更好更快的帮我们找到数据库中存储的数据&#xff0c;就好比一本书&#xff0c;你想要找到指定的内容&#xff0c;但是如果在没有目录的情况下&#xff0c;你只能一页页的进行寻找&#xff0c;这样效率…...

ISCC-2025-web-wp

web 校赛 校赛靠着ENOCH师傅发力&#xff0c;也是一路躺进了区域赛&#xff0c;E师傅不好意思发这抽象比赛的wp(这比赛确实啥必到让人大开眼界&#xff0c;反正明年我是肯定不会打了)&#xff0c;我就顺手要过来连着区域赛的一起发了 web 150分 按照提示进入/includes/fla…...