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

ABP VNext 在 Kubernetes 中的零停机蓝绿发布

ABP VNext 在 Kubernetes 中的零停机蓝绿发布 🚀


📚 目录

  • ABP VNext 在 Kubernetes 中的零停机蓝绿发布 🚀
    • 📌 一、前提准备 ℹ️
    • 🧱 二、项目结构与目标 🎯
    • 🐳 三、多阶段 Dockerfile 构建 🐋
      • .dockerignore 示例 📝
    • 📦 四、Kubernetes 核心 YAML 模板 ☸️
      • 4.1 Namespace 创建 🚀
      • 4.2 ConfigMap 与 Secret 🔧🔒
        • 4.2.1 ConfigMap(挂载 appsettings.json) 📝
        • 4.2.2 Secret(敏感信息管理) 🔐
        • 4.2.3 ConfigMap & Secret 配置流程图 📈
      • 4.3 Deployment(Blue & Green) 🔄
        • 4.3.1 Blue 版本 Deployment 🔵
        • 4.3.2 Green 版本 Deployment 🟢
      • 4.4 Service(统一入口 & 蓝绿切换) 🔀
      • 4.5 Ingress(暴露外部访问) 🌐
    • 🔧 五、ABP 应用健康检查配置 🩺
      • 5.1 Program.cs 示例(.NET 8 Minimal API 风格) 💻
      • 5.2 健康检查流程图 📈
    • 🚀 六、发布流程与回滚示例 🔄
    • 🔍 七、日志与监控扩展建议 📈
    • 🔒 八、安全与最佳实践 🛡️
    • 🔖 九、优势 🎉
    • 📚 参考资料


📌 一、前提准备 ℹ️

  1. 命名空间创建
    在开始之前,请先创建一个专用命名空间(示例名为 your-namespace):

    kubectl create namespace your-namespace
    
  2. 安装 NGINX Ingress Controller ☸️
    若尚未安装 Ingress Controller,可使用 Helm 进行安装(示例使用 ingress-nginx):

    helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
    helm install ingress-nginx ingress-nginx/ingress-nginx
    

    安装完成后,可通过以下命令确认 Controller 已就绪:

    kubectl get pods -n ingress-nginx
    
  3. 前提环境

    • Kubernetes 版本 ≥ 1.19
    • 已部署 Docker Registry(如 Docker Hub、Harbor 等)并能推送、拉取镜像 🐳
    • .NET 8.0 SDK 与 Runtime 基础镜像可用
    • 本文示例假设您将镜像推送到 your-registry/abp-app,并使用标签 bluegreen 做版本区分
    • 所有 YAML 资源都以命名空间 your-namespace 部署,若需修改,请将 namespace: your-namespace 替换为实际环境命名空间

🧱 二、项目结构与目标 🎯

  • 目标一:多阶段 Docker 镜像构建 🐋
    使用 .NET 8.0 SDK 构建并生成最小的 ASP.NET Core 运行时镜像。

  • 目标二:蓝绿发布策略 🔄
    在 Kubernetes 中使用两套 Deployment(Blue 与 Green)并通过 Service Selector 切换流量,实现零停机发布。

  • 目标三:配置管理 🔧
    使用 ConfigMap 挂载 appsettings.json,并通过 reloadOnChange: true 实现热重载;敏感信息放入 Secret,遵循最小权限原则。

  • 目标四:健康检查 🩺
    在 ABP 应用中配置健康检查端点 /healthz,并在 Deployment 中配置 ReadinessProbe 与 LivenessProbe,保障版本切换的无缝。

  • 目标五:安全与监控 🔒
    提示最小权限运行、非 root 用户、资源限额、日志采集与指标监控推荐,帮助构建生产级方案。


🐳 三、多阶段 Dockerfile 构建 🐋

在项目根目录下,创建 Dockerfile 并填写以下内容。示例假设以下目录结构:

.
├── MySolution.sln
└── src└── YourProjectName├── YourProjectName.csproj└── (其余源文件)
# ---------------- BUILD STAGE ----------------
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src# 复制解决方案文件及项目文件,执行 restore
COPY *.sln ./
COPY src/YourProjectName/YourProjectName.csproj ./src/YourProjectName/
RUN dotnet restore# 复制所有源代码并发布到 /app/publish
COPY . .
RUN dotnet publish src/YourProjectName/YourProjectName.csproj -c Release -o /app/publish# ---------------- RUNTIME STAGE ----------------
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app# 创建非 root 用户以提高安全性
RUN adduser --disabled-password --gecos "" appuser \&& chown -R appuser /app
USER appuser# 复制发布产物
COPY --from=build /app/publish .# 设置监听端口与环境
ENV ASPNETCORE_URLS=http://+:80
ENV DOTNET_ENVIRONMENT=ProductionEXPOSE 80ENTRYPOINT ["dotnet", "YourProjectName.dll"]

.dockerignore 示例 📝

**/bin
**/obj
**/.vs
**/*.user
**/*.suo

✅ 说明

  • .dockerignore 文件可显著加速 Docker 构建并减少镜像体积。
  • 若您的项目结构与示例不同,请相应调整 COPY 路径。
  • ENTRYPOINT 中的 YourProjectName.dll 必须与发布输出一致,若有所不同,请替换为实际可执行文件名。

📦 四、Kubernetes 核心 YAML 模板 ☸️

4.1 Namespace 创建 🚀

apiVersion: v1
kind: Namespace
metadata:name: your-namespace

4.2 ConfigMap 与 Secret 🔧🔒

4.2.1 ConfigMap(挂载 appsettings.json) 📝
apiVersion: v1
kind: ConfigMap
metadata:name: abp-confignamespace: your-namespace
data:appsettings.json: |{"App": {"Name": "ABP in K8s","HotReload": true},"Logging": {"LogLevel": {"Default": "Information","Microsoft": "Warning"}}}

挂载示例(在 Deployment 中使用):

volumeMounts:- name: config-volumemountPath: /app/appsettings.jsonsubPath: appsettings.json
volumes:- name: config-volumeconfigMap:name: abp-config
4.2.2 Secret(敏感信息管理) 🔐
apiVersion: v1
kind: Secret
metadata:name: abp-secretsnamespace: your-namespace
type: Opaque
data:# 请将真实值进行 base64 编码后填入ConnectionStrings__Default: <base64-encoded-db-connection-string>ConnectionStrings__Redis:    <base64-encoded-redis-connection-string>Jwt__Secret:                 <base64-encoded-jwt-secret>

创建命令示例(以 Linux/macOS 为例):

echo -n "Server=mssql;Database=YourDb;User Id=sa;Password=YourPassword;" | base64
# 输出类似:U2VydmVyPW1zc3FsO0RhdGFiYXNlPVlvdXJEYjtVc2VyIElkPXNhO1Bhc3N3b3JkPVlvdXJQYXNzd29yZDs=
kubectl -n your-namespace create secret generic abp-secrets \--from-literal=ConnectionStrings__Default="Server=mssql;Database=YourDb;User Id=sa;Password=YourPassword;" \--from-literal=ConnectionStrings__Redis="Server=redis;Password=YourRedisPassword;" \--from-literal=Jwt__Secret="YourJwtSecret"

🔒 安全提示

  • 生产环境切勿直接将数据库连接串等明文写入 ConfigMap。
  • 应使用 Kubernetes Secret 存储敏感信息,并结合 RBAC 限制访问权限。
  • 如需更高安全性,可使用 Vault 或 Kubernetes CSI Secrets Store 将 Secret 以加密方式挂载到 Pod。
4.2.3 ConfigMap & Secret 配置流程图 📈
ConfigMap: appsettings.json
Pod 文件系统: /app/appsettings.json
Secret: 连接串、密钥
Pod 环境变量
ABP 应用读取配置

ℹ️ 说明

  • ConfigMap 将配置文件挂载到 Pod 内特定路径,应用通过 AddJsonFile("appsettings.json", reloadOnChange: true) 热加载。
  • Secret 中的密钥通过环境变量注入到 Pod,应用可以用 builder.Configuration.GetConnectionString("Redis") 等方式读取。

4.3 Deployment(Blue & Green) 🔄

4.3.1 Blue 版本 Deployment 🔵
apiVersion: apps/v1
kind: Deployment
metadata:name: abp-app-bluenamespace: your-namespacelabels:app: abpversion: blue
spec:replicas: 2selector:matchLabels:app: abpversion: bluestrategy:type: RollingUpdaterollingUpdate:maxUnavailable: 0maxSurge: 1template:metadata:labels:app: abpversion: bluespec:containers:- name: abp-containerimage: your-registry/abp-app:blueimagePullPolicy: IfNotPresentports:- containerPort: 80envFrom:- configMapRef:name: abp-config- secretRef:name: abp-secretsreadinessProbe:httpGet:path: /healthzport: 80initialDelaySeconds: 10periodSeconds: 10timeoutSeconds: 5successThreshold: 1failureThreshold: 3livenessProbe:httpGet:path: /healthzport: 80initialDelaySeconds: 20periodSeconds: 20timeoutSeconds: 5successThreshold: 1failureThreshold: 3resources:requests:cpu: "250m"memory: "512Mi"limits:cpu: "1"memory: "1Gi"volumeMounts:- name: config-volumemountPath: /app/appsettings.jsonsubPath: appsettings.jsonvolumes:- name: config-volumeconfigMap:name: abp-config
4.3.2 Green 版本 Deployment 🟢
apiVersion: apps/v1
kind: Deployment
metadata:name: abp-app-greennamespace: your-namespacelabels:app: abpversion: green
spec:replicas: 2selector:matchLabels:app: abpversion: greenstrategy:type: RollingUpdaterollingUpdate:maxUnavailable: 0maxSurge: 1template:metadata:labels:app: abpversion: greenspec:containers:- name: abp-containerimage: your-registry/abp-app:greenimagePullPolicy: IfNotPresentports:- containerPort: 80envFrom:- configMapRef:name: abp-config- secretRef:name: abp-secretsreadinessProbe:httpGet:path: /healthzport: 80initialDelaySeconds: 10periodSeconds: 10timeoutSeconds: 5successThreshold: 1failureThreshold: 3livenessProbe:httpGet:path: /healthzport: 80initialDelaySeconds: 20periodSeconds: 20timeoutSeconds: 5successThreshold: 1failureThreshold: 3resources:requests:cpu: "250m"memory: "512Mi"limits:cpu: "1"memory: "1Gi"volumeMounts:- name: config-volumemountPath: /app/appsettings.jsonsubPath: appsettings.jsonvolumes:- name: config-volumeconfigMap:name: abp-config

✅ 说明

  • 初始部署时,仅需创建 Blue Deployment;如需先验证 Blue 无误,再创建 Green Deployment,保持 Service 指向 Blue。
  • rollingUpdate 策略可保证滚动更新时 Pod 始终保持可用,并且按需扩容。若只需纯粹蓝绿切换,可将 strategy.type 改为 Recreate
  • 确保项目的工作目录与挂载路径保持一致,例如本示例假设可执行文件与配置文件位于容器内部 /app 下。

4.4 Service(统一入口 & 蓝绿切换) 🔀

apiVersion: v1
kind: Service
metadata:name: abp-servicenamespace: your-namespace
spec:type: ClusterIPselector:app: abpversion: blue       # 初始指向 Blue 版本ports:- port: 80targetPort: 80

🔄 蓝绿切换命令

  • 将流量切换到 Green:
    kubectl -n your-namespace patch svc abp-service \-p '{"spec":{"selector":{"app":"abp","version":"green"}}}'
    
  • 回滚至 Blue:
    kubectl -n your-namespace patch svc abp-service \-p '{"spec":{"selector":{"app":"abp","version":"blue"}}}'
    
  • ⚠️ 注意:同时运行 Blue/Green 会占用双倍资源,请确保集群容量充足;切换稳定后可删除不再使用的一侧 Deployment。

4.5 Ingress(暴露外部访问) 🌐

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: abp-ingressnamespace: your-namespaceannotations:nginx.ingress.kubernetes.io/rewrite-target: /
spec:ingressClassName: nginxtls:- hosts:- abp.yourdomain.comsecretName: abp-tlsrules:- host: abp.yourdomain.comhttp:paths:- path: /pathType: Prefixbackend:service:name: abp-serviceport:number: 80

🔐 TLS Secret 创建示例

kubectl -n your-namespace create secret tls abp-tls \--cert=/path/to/tls.crt \--key=/path/to/tls.key

ℹ️ 说明

  • ingressClassName: nginx 假定已安装并就绪 NGINX Ingress Controller,且 IngressClass 名称为 nginx
  • rewrite-target: / 会将所有外部路径重写到 /,适合后端全路径托管场景。若需保留原始路径,可移除该注解,或使用正则重写。
  • 如需精确匹配根路径,可将 pathType: Prefix 改为 Exact

🔧 五、ABP 应用健康检查配置 🩺

为了让 Kubernetes 的探针(Probe)与 ABP 应用的健康检查端点对齐,需要在应用内部添加健康检查服务。

5.1 Program.cs 示例(.NET 8 Minimal API 风格) 💻

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;var builder = WebApplication.CreateBuilder(args);// 配置 appsettings.json 并开启热重载
builder.Host.ConfigureAppConfiguration((context, config) =>
{config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true).AddEnvironmentVariables(prefix: "ASPNETCORE_");
});// 注册健康检查服务
builder.Services.AddHealthChecks().AddCheck("Self", () => HealthCheckResult.Healthy());
// 可根据需要添加更多检查项,例如:
// .AddSqlServer(builder.Configuration.GetConnectionString("Default"), name: "SQL Server", failureStatus: HealthStatus.Unhealthy)
// .AddRedis(builder.Configuration.GetConnectionString("Redis"), name: "Redis", failureStatus: HealthStatus.Degraded);builder.Services.AddControllers();  // 注册控制器var app = builder.Build();app.UseRouting();// 映射健康检查端点
app.MapHealthChecks("/healthz");// 映射 API 控制器
app.MapControllers();app.Run();

✅ 说明

  • .AddHealthChecks() 默认会注册一个自检项,使 /healthz 始终返回 200。
  • 若要做更细粒度检查,可启用 .AddSqlServer().AddRedis() 等扩展方法,此时需引用对应 NuGet 包。
  • reloadOnChange: true 可在 ConfigMap 更新后自动加载新的配置值,无需重启应用。

5.2 健康检查流程图 📈

200 OK
非 200
应用启动
注册 HealthChecks
映射 /healthz
Probe 请求
继续运行
Pod 重启

ℹ️ 说明

  • 应用启动后,注册健康检查并映射路由。
  • Kubernetes 发起 ReadinessProbe 和 LivenessProbe 请求到 /healthz,判断 Pod 是否就绪或存活。
  • 当探针返回 200 OK 时,Pod 被认为健康;否则 K8s 会执行重启或不就绪操作。

详情参考:健康检查:在 .NET 微服务模板中优雅配置 Health Checks


🚀 六、发布流程与回滚示例 🔄

以下流程展示在 Kubernetes 中从 Blue 到 Green 的切换细节,并提供回滚步骤。

正常
失败
部署 Blue 版本
验证 Blue 健康
部署 Green 版本
验证 Green 健康
切换 Service 至 Green
监控 Green 稳定性
删除 Blue 版本
回滚至 Blue
监控 Blue 稳定
  1. 部署 Blue 版本 🔵

    • 确保命名空间已创建:
      kubectl apply -f namespace.yaml
      
    • 部署 ConfigMap 与 Secret:
      kubectl -n your-namespace apply -f configmap.yaml
      kubectl -n your-namespace apply -f secret.yaml
      
    • 构建并推送 Blue 镜像:
      docker build -t your-registry/abp-app:blue .
      docker push your-registry/abp-app:blue
      
    • 应用 Blue Deployment 与 Service:
      kubectl -n your-namespace apply -f deployment-blue.yaml
      kubectl -n your-namespace apply -f service.yaml
      
    • 验证 Blue Pod 健康:
      kubectl -n your-namespace get pods -l version=blue
      kubectl -n your-namespace exec -it <blue-pod> -- curl -f http://localhost/healthz
      
  2. 部署 Green 版本(保留 Blue) 🟢

    • 构建并推送 Green 镜像:
      docker build -t your-registry/abp-app:green .
      docker push your-registry/abp-app:green
      
    • 应用 Green Deployment(Service 仍指向 Blue):
      kubectl -n your-namespace apply -f deployment-green.yaml
      
    • 验证 Green Pod 健康:
      kubectl -n your-namespace get pods -l version=green
      kubectl -n your-namespace exec -it <green-pod> -- curl -f http://localhost/healthz
      
  3. 切换 Service Selector 至 Green 🎯

    kubectl -n your-namespace patch svc abp-service \-p '{"spec":{"selector":{"app":"abp","version":"green"}}}'
    
    • 此时所有外部流量会瞬时切换到 Green 副本,而 Blue 副本依旧保留,只是不再接收流量。
  4. 监控 Green 稳定性 📊

    • 观察一段时间(建议 5–10 分钟),通过以下方式检查:
      kubectl -n your-namespace get pods -l version=green
      kubectl -n your-namespace logs -l version=green --tail=50
      
    • 使用日志采集与指标监控(如 Prometheus + Grafana)查看 CPU、内存、请求时延、错误率等关键指标。
  5. 回滚至 Blue(如有必要) ⚠️
    如果在监控过程中发现 Green 不稳定,可立即执行:

    kubectl -n your-namespace patch svc abp-service \-p '{"spec":{"selector":{"app":"abp","version":"blue"}}}'
    
    • 此时流量将自动回切到 Blue 副本。确认系统恢复正常后,再做进一步排查。
  6. 删除 Blue 版本 🗑️
    当 Green 完全稳定后,可按以下命令删除 Blue Deployment 及其关联资源:

    kubectl -n your-namespace delete deployment abp-app-blue
    
    • Kubernetes 会自动删除与该 Deployment 关联的 ReplicaSet。若发现残留可额外检查并删除:
      kubectl -n your-namespace get rs -l version=blue
      kubectl -n your-namespace delete rs -l version=blue
      

🔍 七、日志与监控扩展建议 📈

  1. 日志采集 📝

    • 使用 Fluentd、Fluent Bit 或 Filebeat 将容器日志收集至 Elasticsearch/Kibana,实现集中化日志管理。
    • 在 ABP 应用中,可配置 Serilog 等日志库,将日志输出到控制台或文件,再由 Sidecar 集成到日志系统。
  2. 指标监控 📊

    • 在应用中集成 Prometheus .NET Client,暴露 /metrics 端点。
    • 部署 Prometheus Operator,自动发现带有注解 prometheus.io/scrape: "true" 的 Pod 并采集指标。
    • 在 Grafana 中创建 Dashboard,监控请求量、错误率、CPU/内存使用等关键 KPIs。
  3. 告警与自动扩缩容 🔔

    • 配置 Prometheus Alertmanager,当指标异常时发送邮件或推送到 Slack、DingTalk 等。
    • 使用 Kubernetes Horizontal Pod Autoscaler (HPA),根据 CPU 使用率或自定义指标自动扩缩容,保障系统在流量高峰时平稳运行。

🔒 八、安全与最佳实践 🛡️

  1. 最小权限原则

    • 为每个 Deployment 创建独立 ServiceAccount,结合 RBAC 限制 ConfigMap/Secret/其他资源的访问权限。
    • Pod 不要使用默认 ServiceAccount。
  2. 镜像安全

    • 定期使用 Trivy 等漏洞扫描工具扫描镜像,及时修复漏洞。
    • 拉取官方或镜像加固后的基础镜像,避免使用不可信来源。
  3. 网络策略 🌐

    • 使用 Kubernetes NetworkPolicy 控制 Pod 间的网络访问,只开放必要端口和 IP 范围。
    • Ingress Controller 上可配置限流、WAF、安全组等高级策略,防御恶意流量。
  4. 审计与日志保留 📜

    • 启用 Kubernetes 审计日志功能,记录对 Deployment、Service、Secret 等关键资源的操作,以便事后追踪与稽核。
    • 配置日志轮转与归档策略,避免日志文件无限增长导致磁盘耗尽。
  5. 数据库兼容性

    • 蓝绿发布过程中,如果涉及数据库模式变更,请务必采用向后兼容迁移:
      1. 在 Green 部署前,先在数据库中新增非破坏性变更(如添加 nullable 列)。
      2. 确保 Blue 与 Green 均能兼容读取旧表结构。
      3. 切换到 Green 后,再清理废弃列或表。

🔖 九、优势 🎉

  • 零停机发布

    • 多阶段镜像构建 + Kubernetes RollingUpdate + 蓝绿切换,确保业务在发布期间始终可用。
  • 配置热重载 🔄

    • ConfigMap 挂载 appsettings.json 并启用 reloadOnChange: true,无需重启容器即可动态更新配置。
  • 安全可控 🔐

    • 使用 Secret 管理敏感信息,采用非 root 用户运行,结合 NetworkPolicy 和 RBAC,确保最小权限与安全隔离。
  • 高可用高性能

    • Kubernetes 原生自动伸缩、自愈能力,结合资源 Requests/Limits 和健康探针,实现稳定可靠的服务。
  • 可观测体系 📈

    • 建议集成 Prometheus/Grafana、Fluentd/EFK 等,实现全链路日志与指标收集、可视化与告警。

📚 参考资料

  • Microsoft Docs

    • Kubernetes Deployment
    • Kubernetes Service
    • Kubernetes Ingress
    • ConfigMap
    • Secret
    • Liveness and Readiness Probes
  • Docker Docs

    • Multi-stage builds
    • Dockerfile reference
  • Prometheus & Grafana

    • Prometheus .NET Client
    • Prometheus Operator
    • Grafana Official
  • Trivy

    • Aqua Security Trivy

相关文章:

ABP VNext 在 Kubernetes 中的零停机蓝绿发布

ABP VNext 在 Kubernetes 中的零停机蓝绿发布 &#x1f680; &#x1f4da; 目录 ABP VNext 在 Kubernetes 中的零停机蓝绿发布 &#x1f680;&#x1f4cc; 一、前提准备 ℹ️&#x1f9f1; 二、项目结构与目标 &#x1f3af;&#x1f433; 三、多阶段 Dockerfile 构建 &#…...

linux 故障处置通用流程-36计-14-27

014&#xff1a;查看系统主要日志 查看以下日志&#xff1a; 主要查以下关键字 error/NIC/fs /"link down"/Oout of memory" /var/log/messages /var/log/dmesg 015&#xff1a;主机通讯是否延迟 执行命令&#xff1a; #ping 网关_IP #ping 关联主机_IP ​​​​…...

https和http有什么区别-http各个版本有什么区别

http和 https的区别 HTTP&#xff08;超文本传输协议&#xff09;和 HTTPS&#xff08;安全超文本传输协议&#xff09;是两种用于在网络上传输数据的协议&#xff0c;它们的主要区别在于安全性&#xff1a; HTTP&#xff08;Hypertext Transfer Protocol&#xff09;&#x…...

基于回归算法的心理健康预测(EDA + 预测)

心理健康涵盖情感、心理与社会福祉&#xff0c;影响认知、情绪和行为模式&#xff0c;决定压力应对、人际交往及健康决策&#xff0c;且在生命各阶段&#xff08;从童年至成年&#xff09;均至关重要。心理健康与身体健康同为整体健康的核心要素&#xff1a;抑郁会增加糖尿病、…...

React Native开发鸿蒙运动健康类应用的项目实践记录

​​项目名称​​&#xff1a;HarmonyFitness - 基于React Native的鸿蒙运动健康应用 ​​技术栈​​&#xff1a;React Native 0.72.5 TypeScript HarmonyOS API ArkTS原生模块 一、环境搭建与项目初始化 ​​双环境配置​​ ​​React Native环境​​&#xff1a; npx re…...

【新品解读】一板多能,AXRF49 定义新一代 RFSoC FPGA 开发平台

“硬件系统庞杂、调试周期长” “高频模拟前端不稳定&#xff0c;影响采样精度” “接收和发射链路难以同步&#xff0c;难以扩展更多通道” “数据流量大&#xff0c;处理与存储跟不上” 这些是大部分客户在构建多通道、高频宽的射频采样链路时&#xff0c;面临的主要问题。…...

贪心算法应用:线性规划贪心舍入问题详解

贪心算法应用&#xff1a;线性规划贪心舍入问题详解 贪心算法是一种在每一步选择中都采取当前状态下最优的选择&#xff0c;从而希望导致结果是全局最优的算法策略。在线性规划问题中&#xff0c;贪心算法特别是贪心舍入技术有着广泛的应用。下面我将全面详细地讲解这一主题。…...

YOLO在C#中的完整训练、验证与部署方案

YOLO在C#中的完整训练、验证与部署方案 C# 在 YOLO 部署上优势明显&#xff08;高性能、易集成&#xff09;&#xff0c;但训练能力较弱&#xff0c;通常需结合 Python 实现。若项目对开发效率要求高且不依赖 C# 生态&#xff0c;建议全程使用 Python&#xff1b;若需深度集成…...

洛谷题目:P2761 软件补丁问题 (本题简单)

个人介绍: 题目传送门: P2761 软件补丁问题 - 洛谷 (luogu.com.cn) 前言: 这道题是一个典型的状态搜索问题,核心目标就是利用给定d额多个补丁程序,将包含若干错误的软件修复成没有错误的状态,并且要使得修复过程当中的总耗时最少。下面是小亦为大家阐述滴思路: 1、状态…...

智慧园区数字孪生全链交付方案:降本增效30%,多案例实践驱动全周期交付

在智慧园区建设浪潮中&#xff0c;数字孪生技术正成为破解传统园区管理难题的核心引擎。通过构建与物理园区1:1映射的数字模型&#xff0c;实现数据集成、状态同步与智能决策&#xff0c;智慧园区数字孪生全链交付方案已在多个项目中验证其降本增效价值——某物流园区通过该方案…...

【OpenGL学习】(四)统一着色和插值着色

文章目录 【OpenGL学习】&#xff08;四&#xff09;统一着色和插值着色统一着色&#xff08;Flat/Uniform Shading&#xff09;插值着色&#xff08;Interpolated Shading&#xff09; 【OpenGL学习】&#xff08;四&#xff09;统一着色和插值着色 着色器介绍&#xff1a; h…...

42、响应处理-【源码分析】-浏览器与PostMan内容协商完全适配

42、响应处理源码分析浏览器与PostMan内容协商完全适配 要实现浏览器与PostMan在内容协商上的完全适配&#xff0c;需要在Spring Boot应用中自定义内容协商策略&#xff0c;确保服务器能根据浏览器和PostMan的请求头正确返回合适格式的数据。以下是详细的步骤&#xff1a; ### …...

在 CentOS 上安装 Docker 和 Docker Compose 并配置使用国内镜像源

在 CentOS 上安装 Docker 和 Docker Compose 并配置使用国内镜像源&#xff0c;可以加速镜像下载速度。以下是详细的步骤&#xff1a; 一、安装 Docker 移除旧版本的 Docker&#xff08;如果有&#xff09;&#xff1a; sudo yum remove docker \docker-client \docker-client…...

Java Lambda表达式深度解析:从入门到实战

简介 Lambda表达式是Java 8引入的最重要特性之一,它极大地简化了Java代码的编写方式,使函数式编程风格在Java中成为可能。本文将全面介绍Lambda表达式的概念、语法、应用场景以及与相关特性的配合使用,帮助开发者掌握这一强大的编程工具。 一、Lambda表达式基础 1.1 什么…...

Docker慢慢学

1、Docker DeskTop 2、N8N下载 docker run -p 8888:5678 n8nio/n8n 3、Kafka kafka依赖zookeeper,先启动zookeeper docker pull zookeeper docker run -d --name zookeeper -p 2181:2181 -e ALLOW_ANONYMOUS_LOGINyes zookeeper 启动kafka docker pull confluentinc/cp…...

cursor-free-vip使用

一、项目简介 Cursor-Free-VIP 是一个开源项目&#xff0c;旨在帮助用户免费使用 Cursor AI 的高级功能。它通过自动注册 Cursor 账号、重置机器 ID 和完成 Auth 验证等操作&#xff0c;解决 Cursor AI 中常见的限制提示。 二、系统准备 1…cursor需要更新到最新的版本 三、…...

使用SSH tunnel访问内网的MySQL

文章目录 环境背景方法参考 注&#xff1a;本文是使用SSH tunnel做端口转发的一个示例。有关SSH端口转发&#xff0c;可参考我的几篇文档 https://blog.csdn.net/duke_ding2/article/details/106878081https://blog.csdn.net/duke_ding2/article/details/135627263https://blo…...

Redis持久化模式RDB与AOF

RDB持久化 RDB也被叫做Redis数据快照。简单来说就是把内存中的所有数据记录到磁盘中。当Redis实例故障重启后重磁盘中读取快照文件进行数据恢复(快照文件默认保存在当前运行目录)&#xff1b; 演示Redis正常停机自动执行一次RDB操作 配置Redis触发RDB机制 RDB其它配置也可在red…...

【JS进阶】ES5 实现继承的几种方式

ES5 实现继承的几种方式 1. 原型链继承&#xff08;Prototype Chaining&#xff09; function Parent(name) {this.name name || Parent;this.colors [red, blue]; }Parent.prototype.sayName function() {console.log(this.name); };function Child() {}// 关键&#xff…...

【数据结构】树形结构--二叉树(二)

【数据结构】树形结构--二叉树&#xff08;二&#xff09; 一.二叉树的实现1.求二叉树结点的个数2.求二叉树叶子结点的个数3.求二叉树第k层结点的个数4.求二叉树的深度&#xff08;高度&#xff09;5.在二叉树中查找值为x的结点6.判断二叉树是否为完全二叉树7.二叉树的销毁 一.…...

JavaScript性能优化实战:深入探讨JavaScript性能瓶颈与优化技巧

引言:为什么JavaScript性能至关重要 在现代Web开发中,JavaScript已成为构建交互式应用程序的核心技术。随着单页应用(SPA)和复杂前端架构的普及,JavaScript代码的性能直接影响用户体验、转化率甚至搜索引擎排名。研究表明,页面加载时间每增加1秒,转化率可能下降7%,而性能…...

在 CentOS 上将 Ansible 项目推送到 GitHub 的完整指南

1. 安装 Git 在 CentOS 中使用 yum 安装 Git&#xff0c;Git 是管理代码版本控制的工具&#xff1a; sudo yum install git -y 2. 配置 Git 用户信息 设置你的 Git 用户名和邮箱&#xff0c;这些信息会出现在你每次提交的记录中&#xff1a; git config --global user.nam…...

深度学习题目1

梯度下降法的正确步骤是什么&#xff1f; a.计算预测值和真实值之间的误差 b.重复迭代&#xff0c;直至得到网络权重的最佳值 c.把输入传入网络&#xff0c;得到输出值 d.用随机值初始化权重和偏差 e.对每一个产生误差的神经元&#xff0c;调整相应的&#xff08;权重&#xff…...

Spring @Scheduled vs XXL-JOB vs DolphinScheduler vs Airflow:任务调度框架全景对比

引言 从单机定时任务到分布式工作流调度&#xff0c;不同场景需要选择匹配的调度框架。 本文对比 Spring Scheduled、XXL-JOB、DolphinScheduler &#xff08;海豚调度器&#xff09;和 Apache Airflow 的核心差异&#xff0c;助你避免过度设计或功能不足。 一、核心定位与适用…...

【Oracle】锁

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 锁基础概述1.1 锁的概念与作用1.2 锁的工作原理1.3 Oracle锁的分类 2. 行级锁 (Row-Level Locks)2.1 行级锁的基本概念2.1.1 TX锁&#xff08;事务锁&#xff09;2.1.2 行级锁的工作机制 2.2 行级锁的类型2.…...

共识算法Raft系列(1)——什么是Raft?

Raft 算法是一种分布式一致性算法&#xff0c;由 Diego Ongaro 和 John Ousterhout 在 2014 年提出&#xff0c;旨在解决 Paxos 算法复杂且难以理解的问题。Raft 设计目标是易于理解和实现&#xff0c;同时提供强一致性&#xff08;CAP 中的 CP 系统&#xff09;&#xff0c;广…...

JS逆向爬虫教程与实战技巧

想要一个关于爬虫JS逆向的详细教程。这是一个很专业的技术需求&#xff0c;最近有个可能是正在学习爬虫技术的开发者或者数据分析师&#xff0c;遇到了需要破解JavaScript加密的反爬机制的问题&#xff0c;想让我出一期实战教程&#xff0c;话不多说&#xff0c;开干。 以下是我…...

Neovim - LSP 底层原理,难点配置(二)

Neovim LSP 的工作原理 基本概念 LSP(Language Server Protocol)可以理解成是一个"语言助手"。每种编程语言都有自己的"语言助手"(比如 TypeScript 的 tsserver),这些助手能告诉你: 哪写错了(语法错误)哪能跳转(方法定义,引用)哪可以补全(自…...

【Redis】Redis 的常见客户端汇总

目录 一、命令行客户端 二、图形界面的客户端 三、Java 客户端 3.1 SpringDataRedis 3.2 Jedis 3.2.1 连接池的配置 3.3 Lettuce 3.3.1 RedisTemplate 工具类实现 3.3.2 自定义序列化器 3.3.3 StringRedisTemplate 3.3.4 集群配置 3.3.4.1 刷新节点集群拓扑动态感应…...

关于akka官方quickstart示例程序(scala)的记录

参考资料 https://doc.akka.io/libraries/akka-core/current/typed/actors.html#first-example 关于scala语法的注意事项 extends App是个语法糖&#xff0c;等同于直接在伴生对象中编写main 方法对象是通过apply方法创建的&#xff0c;也可以通过对象的名称单独创建&#x…...