Docker 容器化
.NET 9 支持直接通过 MSBuild 发布为 Docker 镜像,无需手写 Dockerfile(当然也可以手写以获得更多控制)。
多阶段 Dockerfile(推荐)
# 阶段一:构建
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /src
# 先复制项目文件(利用 Docker 层缓存)
COPY ["src/Api/Api.csproj", "src/Api/"]
COPY ["src/Core/Core.csproj", "src/Core/"]
RUN dotnet restore "src/Api/Api.csproj"
# 复制源码并发布
COPY . .
RUN dotnet publish "src/Api/Api.csproj" \
-c Release \
-o /app/publish \
--no-restore
# 阶段二:运行时(更小的镜像)
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS final
WORKDIR /app
# 非 root 用户运行(安全最佳实践)
USER app
COPY --from=build /app/publish .
EXPOSE 8080
ENTRYPOINT ["dotnet", "Api.dll"]
MSBuild 直接发布为容器镜像
# 发布为本地 Docker 镜像(无需 Dockerfile)
dotnet publish /t:PublishContainer \
-p ContainerImageName=myapp \
-p ContainerImageTag=1.0.0
# 推送到 Docker Hub
dotnet publish /t:PublishContainer \
-p ContainerRegistry=docker.io \
-p ContainerImageName=username/myapp \
-p ContainerImageTag=latest
<!-- .csproj 中配置容器属性 -->
<PropertyGroup>
<ContainerBaseImage>mcr.microsoft.com/dotnet/aspnet:9.0-alpine</ContainerBaseImage>
<ContainerImageName>my-api</ContainerImageName>
<ContainerPort>8080</ContainerPort>
</PropertyGroup>
Native AOT:启动时间 <5ms
Native AOT(Ahead-of-Time)将整个应用编译为平台原生可执行文件,无需 .NET 运行时。适合 CLI 工具、云函数(冷启动要求严苛)、边缘计算等场景。
Native AOT 优势
- 启动时间:<5ms(vs JIT 的 100-500ms)
- 内存占用:减少 50-70%
- 无需安装 .NET 运行时
- 更小的攻击面
- 适合容器/云函数
Native AOT 限制
- 不支持运行时反射(需用 Source Generator)
- 不支持动态代码加载
- 编译时间较长
- 部分 NuGet 包不兼容
- EF Core 需额外配置
<!-- 启用 Native AOT 发布 -->
<PropertyGroup>
<PublishAot>true</PublishAot>
<InvariantGlobalization>true</InvariantGlobalization> <!-- 减小体积 -->
</PropertyGroup>
# AOT 发布(需要相同 OS 的构建环境)
dotnet publish -r linux-x64 -c Release
# 结果:单个自包含可执行文件
ls -lh ./bin/Release/net9.0/linux-x64/publish/
# -rwxr-xr-x 1 user group 12M Apr 9 10:00 myapp
// Minimal API + Native AOT 完整示例
using System.Text.Json.Serialization;
var builder = WebApplication.CreateSlimBuilder(args); // Slim = AOT 优化版
// AOT 下 JSON 序列化需要 Source Generator
builder.Services.ConfigureHttpJsonOptions(options =>
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default));
var app = builder.Build();
app.MapGet("/users", () => new[] { new User(1, "Alice") });
app.Run();
record User(int Id, string Name);
[JsonSerializable(typeof(User[]))]
partial class AppJsonSerializerContext : JsonSerializerContext { }
.NET Aspire:分布式应用框架
.NET Aspire 是 .NET 8 引入(1.0 于 2024 年 5 月正式发布)的分布式应用开发框架,解决了微服务开发中最痛苦的问题:服务编排、服务发现、配置注入、可观测性。
AppHost 项目
定义分布式应用的组合方式——哪些服务、哪些基础设施(Redis、PostgreSQL、RabbitMQ 等)、它们之间的依赖关系。开发时 Aspire 自动用 Docker 启动基础设施,服务发现和连接字符串自动注入,无需手写。
Dashboard
Aspire 内置的可观测性仪表盘,集成 OpenTelemetry,实时展示所有服务的日志、追踪、指标,以及服务间调用关系图。开发阶段无需配置 Jaeger/Grafana 等额外工具。
// AppHost/Program.cs(Aspire 编排)
var builder = DistributedApplication.CreateBuilder(args);
// 声明基础设施
var postgres = builder.AddPostgres("postgres")
.WithDataVolume() // 数据持久化
.AddDatabase("appdb");
var redis = builder.AddRedis("cache");
// 声明服务,注入依赖
var api = builder.AddProject<Projects.Api>("api")
.WithReference(postgres) // 自动注入连接字符串
.WithReference(redis)
.WaitFor(postgres); // 等待 postgres 就绪再启动
builder.AddProject<Projects.Worker>("worker")
.WithReference(api)
.WithReference(postgres);
await builder.Build().RunAsync();
健康检查
builder.Services.AddHealthChecks()
.AddNpgSql(connStr, name: "postgres")
.AddRedis(redisConn, name: "redis")
.AddUrlGroup(new Uri("https://api.payments.com/health"), name: "payment-api")
.AddCheck<CustomHealthCheck>("custom");
// 端点映射
app.MapHealthChecks("/health/live", new HealthCheckOptions { Predicate = _ => false });
app.MapHealthChecks("/health/ready", new HealthCheckOptions
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
OpenTelemetry:可观测性三支柱
// 安装: dotnet add package OpenTelemetry.Extensions.Hosting
// dotnet add package OpenTelemetry.Instrumentation.AspNetCore
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
tracing
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddEntityFrameworkCoreInstrumentation()
.AddOtlpExporter(); // 导出到 Jaeger/Grafana Tempo
})
.WithMetrics(metrics =>
{
metrics
.AddAspNetCoreInstrumentation()
.AddRuntimeInstrumentation()
.AddPrometheusExporter(); // /metrics 端点
})
.WithLogging(logging =>
{
logging.AddOtlpExporter();
});
// 自定义 Activity(手动追踪)
private static readonly ActivitySource _activitySource =
new("MyApp.OrderService");
public async Task<Order> ProcessOrderAsync(Order order)
{
using var activity = _activitySource.StartActivity("ProcessOrder");
activity?.SetTag("order.id", order.Id);
activity?.SetTag("order.total", order.Total);
try
{
var result = await DoProcessAsync(order);
activity?.SetStatus(ActivityStatusCode.Ok);
return result;
}
catch (Exception ex)
{
activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
activity?.RecordException(ex);
throw;
}
}
Microsoft Semantic Kernel:构建 .NET AI Agent
Semantic Kernel 是微软开源的 AI 编排框架,让 .NET 开发者能方便地将 AI 能力(OpenAI、Azure OpenAI、本地 LLM)集成到应用中,并构建 AI Agent。
// 安装: dotnet add package Microsoft.SemanticKernel
var kernel = Kernel.CreateBuilder()
.AddAzureOpenAIChatCompletion(
deploymentName: "gpt-4o",
endpoint: builder.Configuration["AzureOpenAI:Endpoint"]!,
apiKey: builder.Configuration["AzureOpenAI:ApiKey"]!)
.Build();
// 定义 Plugin(工具函数)
public class OrderPlugin(IOrderService orderService)
{
[KernelFunction, Description("查询用户的订单列表")]
public async Task<string> GetOrders(
[Description("用户ID")] string userId)
{
var orders = await orderService.GetByUserIdAsync(userId);
return JsonSerializer.Serialize(orders);
}
[KernelFunction, Description("取消指定订单")]
public async Task<string> CancelOrder(
[Description("订单ID")] string orderId)
{
await orderService.CancelAsync(Guid.Parse(orderId));
return $"订单 {orderId} 已取消";
}
}
// 注册 Plugin 并启用自动函数调用(Function Calling)
kernel.Plugins.AddFromObject(new OrderPlugin(orderService));
var settings = new OpenAIPromptExecutionSettings
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() // 自动选择工具
};
var history = new ChatHistory();
history.AddSystemMessage("你是一个客服助手,可以帮用户查询和管理订单。");
history.AddUserMessage("帮我查一下 user123 的所有订单");
var chatService = kernel.GetRequiredService<IChatCompletionService>();
var response = await chatService.GetChatMessageContentAsync(
history, settings, kernel);
Console.WriteLine(response.Content);
云部署选项
| 平台 | 特点 | 适用场景 |
|---|---|---|
| Azure Container Apps | 微软原生,Aspire 深度集成,自动缩放 | .NET 应用首选云平台 |
| Azure App Service | PaaS,部署最简单,支持部署槽 | 中小型 Web 应用 |
| AWS App Runner | 全托管容器运行,自动缩放 | 已在 AWS 生态的团队 |
| Fly.io | 全球边缘节点,CLI 部署简单,费用低 | 个人项目/初创公司 |
| Kubernetes (AKS/EKS) | 最大控制权,适合复杂微服务 | 大型企业级应用 |
本章小结 · 课程总结
Docker 多阶段构建让 .NET 镜像小巧安全,MSBuild 直接发布镜像更便捷。Native AOT 是 Serverless/Edge 场景的杀手锏——5ms 冷启动、无运行时依赖。.NET Aspire 彻底改变了微服务本地开发体验,服务发现、配置、可观测性全部自动化。OpenTelemetry 标准让追踪/指标/日志一体化。Semantic Kernel 让 .NET 开发者轻松站上 AI 浪潮。至此,你已掌握从 C# 13 语法到企业级云原生 .NET 9 开发的完整技能树。