第十三章 部署和性能优化

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);
    }
}

wechat_2025-07-31_105805_938


posted @ 2025-08-07 09:11  高宏顺  阅读(248)  评论(0)    收藏  举报