让我们来聊聊在实际工作中经常遇到的部署问题。很多团队在使用DotNetCore进行项目部署时,经常会遇到一些"默认配置"带来的坑,今天我就把这些常见问题梳理一下,并给出解决方案。

一、部署后无法访问的常见原因

最常见的就是部署完成后,打开浏览器访问却显示无法连接。这种情况多半是因为Kestrel服务器的默认配置导致的。DotNetCore默认使用Kestrel作为内置web服务器,但它默认只监听localhost。

// Program.cs中的典型配置
public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
            // 默认情况下没有指定URL,会使用localhost
        });

解决方案很简单,我们需要显式指定监听地址:

webBuilder.UseUrls("http://*:5000");  // *表示监听所有网络接口

或者在appsettings.json中配置:

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://*:5000"
      }
    }
  }
}

二、静态文件无法加载的问题

部署后页面能打开,但是CSS、JS等静态资源全部404?这是因为DotNetCore默认不会自动提供静态文件,需要手动配置中间件。

// Startup.cs中的Configure方法
public void Configure(IApplicationBuilder app)
{
    // 必须添加静态文件中间件
    app.UseStaticFiles();
    
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

如果你想使用自定义的静态文件目录:

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
    RequestPath = "/StaticFiles"
});

三、数据库连接失败问题

部署到服务器后数据库连不上?这通常是因为开发环境和生产环境配置不同导致的。最佳实践是使用环境变量来管理连接字符串。

// 在appsettings.Production.json中配置
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=prod-db-server;Database=myapp;User Id=produser;Password=strongpassword;"
  }
}

或者在Program.cs中使用环境变量:

var connectionString = Environment.GetEnvironmentVariable("DB_CONNECTION_STRING");
services.AddDbContext<AppDbContext>(options => 
    options.UseSqlServer(connectionString));

四、性能突然下降问题

有时候部署后应用响应变得特别慢,这可能是由于以下原因:

  1. 未启用响应压缩
  2. 未配置适当的缓存策略
  3. 未使用生产环境配置

解决方案:

// 启用响应压缩
services.AddResponseCompression(options =>
{
    options.Providers.Add<GzipCompressionProvider>();
    options.EnableForHttps = true;
});

// 配置缓存
app.UseResponseCaching();

生产环境配置:

// Program.cs
if (env.IsProduction())
{
    services.AddHttpsRedirection(options =>
    {
        options.HttpsPort = 443;
    });
}

五、日志记录不工作问题

生产环境最怕的就是出问题没日志。DotNetCore默认的日志配置可能不适合生产环境。

// Program.cs中配置日志
Host.CreateDefaultBuilder(args)
    .ConfigureLogging((hostingContext, logging) =>
    {
        logging.ClearProviders();
        logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
        logging.AddConsole();
        logging.AddDebug();
        logging.AddFile("Logs/myapp-{Date}.txt", LogLevel.Warning);
    })

对应的appsettings.json配置:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    },
    "File": {
      "Path": "Logs/log.txt",
      "Append": true,
      "MinLevel": "Warning",
      "FileSizeLimitBytes": 10485760,
      "MaxRollingFiles": 3
    }
  }
}

六、跨域问题(CORS)

前端调用API时遇到跨域问题?这是因为默认情况下DotNetCore不允许跨域请求。

解决方案:

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy("AllowMyOrigin",
            builder => builder.WithOrigins("https://myfrontend.com")
                            .AllowAnyMethod()
                            .AllowAnyHeader());
    });
}

public void Configure(IApplicationBuilder app)
{
    app.UseCors("AllowMyOrigin");
    // 其他中间件...
}

七、健康检查配置

生产环境应该配置健康检查端点,方便监控系统状态。

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddHealthChecks()
        .AddSqlServer(Configuration.GetConnectionString("DefaultConnection"))
        .AddDbContextCheck<AppDbContext>();
}

public void Configure(IApplicationBuilder app)
{
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHealthChecks("/health");
        // 其他端点...
    });
}

八、HTTPS重定向问题

生产环境应该强制使用HTTPS,但默认配置可能需要调整。

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpsRedirection(options =>
    {
        options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
        options.HttpsPort = 443;
    });
}

九、总结与最佳实践

通过以上问题的分析,我们可以总结出一些DotNetCore部署的最佳实践:

  1. 始终区分开发和生产环境配置
  2. 使用环境变量管理敏感信息
  3. 配置适当的日志记录策略
  4. 显式配置Kestrel监听地址
  5. 启用必要的中间件(静态文件、CORS等)
  6. 配置健康检查端点
  7. 生产环境强制使用HTTPS
  8. 启用响应压缩和缓存

记住,默认配置是为了开发方便,生产环境需要根据实际情况进行调整。希望这些解决方案能帮你少踩一些坑!