第十三章 部署和性能优化
13.1 生产环境配置
环境特定配置
在不同环境中使用不同的配置文件:
appsettings.json:基础配置appsettings.Development.json:开发环境配置appsettings.Production.json:生产环境配置
// appsettings.Production.json
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"DefaultConnection": "Server=prod-server;Database=TodoDB;Trusted_Connection=true;"
},
"JWT": {
"Secret": "your-super-secret-key-for-production",
"Issuer": "https://yourdomain.com",
"Audience": "https://yourdomain.com"
}
}
健康检查
// 添加健康检查
builder.Services.AddHealthChecks()
.AddDbContext<TodoContext>()
.AddCheck("Database", () =>
{
// 自定义数据库健康检查
return HealthCheckResult.Healthy();
});
// 配置健康检查端点
app.MapHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
13.2 性能优化
响应缓存
// 添加响应缓存
builder.Services.AddResponseCaching();
// 使用响应缓存中间件
app.UseResponseCaching();
// 在控制器中设置缓存
[HttpGet]
[ResponseCache(Duration = 300)] // 缓存5分钟
public async Task<ActionResult<IEnumerable<TodoItem>>> GetTodoItems()
{
return await _repository.GetAllAsync();
}
数据库优化
// 使用异步方法
public async Task<IEnumerable<TodoItem>> GetCompletedItemsAsync()
{
return await _context.TodoItems
.Where(t => t.IsComplete)
.AsNoTracking() // 只读查询时禁用跟踪
.ToListAsync();
}
// 分页查询
public async Task<PagedResult<TodoItem>> GetPagedItemsAsync(int page, int pageSize)
{
var totalCount = await _context.TodoItems.CountAsync();
var items = await _context.TodoItems
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
return new PagedResult<TodoItem>
{
Items = items,
TotalCount = totalCount,
Page = page,
PageSize = pageSize
};
}
13.3 部署到云平台
Azure App Service部署
# azure-pipelines.yml
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
variables:
buildConfiguration: 'Release'
steps:
- task: DotNetCoreCLI@2
displayName: 'Restore packages'
inputs:
command: 'restore'
projects: '**/*.csproj'
- task: DotNetCoreCLI@2
displayName: 'Build project'
inputs:
command: 'build'
projects: '**/*.csproj'
arguments: '--configuration $(buildConfiguration)'
- task: DotNetCoreCLI@2
displayName: 'Run tests'
inputs:
command: 'test'
projects: '**/*Tests.csproj'
arguments: '--configuration $(buildConfiguration)'
- task: DotNetCoreCLI@2
displayName: 'Publish application'
inputs:
command: 'publish'
publishWebProjects: true
arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
displayName: 'Publish artifacts'
inputs:
pathToPublish: '$(Build.ArtifactStagingDirectory)'
artifactName: 'drop'
Docker部署
# Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["TodoApi/TodoApi.csproj", "TodoApi/"]
RUN dotnet restore "TodoApi/TodoApi.csproj"
COPY . .
WORKDIR "/src/TodoApi"
RUN dotnet build "TodoApi.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "TodoApi.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "TodoApi.dll"]
# docker-compose.yml
version: '3.8'
services:
todoapi:
build: .
ports:
- "8080:80"
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ConnectionStrings__DefaultConnection=Server=db;Database=TodoDB;User=sa;Password=YourPassword123;
depends_on:
- db
db:
image: mcr.microsoft.com/mssql/server:2022-latest
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=YourPassword123
ports:
- "1433:1433"
volumes:
- sqldata:/var/opt/mssql
volumes:
sqldata:
13.4 监控和诊断
Application Insights集成
// 添加Application Insights
builder.Services.AddApplicationInsightsTelemetry();
// 自定义遥测
public class TodoItemsController : ControllerBase
{
private readonly TelemetryClient _telemetryClient;
public TodoItemsController(TelemetryClient telemetryClient)
{
_telemetryClient = telemetryClient;
}
[HttpPost]
public async Task<ActionResult<TodoItem>> CreateTodoItem(TodoItem item)
{
_telemetryClient.TrackEvent("TodoItemCreated",
new Dictionary<string, string> { { "ItemName", item.Name } });
// 业务逻辑...
}
}
性能计数器
// 自定义性能指标
public class MetricsService
{
private readonly IMetrics _metrics;
private readonly Counter<int> _todoItemsCreated;
public MetricsService(IMeterFactory meterFactory)
{
var meter = meterFactory.Create("TodoApi");
_todoItemsCreated = meter.CreateCounter<int>("todo_items_created");
}
public void IncrementTodoItemsCreated()
{
_todoItemsCreated.Add(1);
}
}


浙公网安备 33010602011771号