git
This commit is contained in:
parent
578d84cb08
commit
a919e23494
|
|
@ -8,6 +8,8 @@ COPY HtmlToPdfService.Api/HtmlToPdfService.Api.csproj HtmlToPdfService.Api/
|
||||||
COPY HtmlToPdfService.Core/HtmlToPdfService.Core.csproj HtmlToPdfService.Core/
|
COPY HtmlToPdfService.Core/HtmlToPdfService.Core.csproj HtmlToPdfService.Core/
|
||||||
COPY HtmlToPdfService.Queue/HtmlToPdfService.Queue.csproj HtmlToPdfService.Queue/
|
COPY HtmlToPdfService.Queue/HtmlToPdfService.Queue.csproj HtmlToPdfService.Queue/
|
||||||
COPY HtmlToPdfService.Infrastructure/HtmlToPdfService.Infrastructure.csproj HtmlToPdfService.Infrastructure/
|
COPY HtmlToPdfService.Infrastructure/HtmlToPdfService.Infrastructure.csproj HtmlToPdfService.Infrastructure/
|
||||||
|
COPY HtmlToPdfService.Client/HtmlToPdfService.Client.csproj HtmlToPdfService.Client/
|
||||||
|
COPY HtmlToPdfService.Tests/HtmlToPdfService.Tests.csproj HtmlToPdfService.Tests/
|
||||||
|
|
||||||
# 还原 NuGet 包
|
# 还原 NuGet 包
|
||||||
RUN dotnet restore HtmlToPdfService.sln
|
RUN dotnet restore HtmlToPdfService.sln
|
||||||
|
|
@ -67,13 +69,14 @@ WORKDIR /app
|
||||||
COPY --from=build /app/publish .
|
COPY --from=build /app/publish .
|
||||||
|
|
||||||
# 创建存储目录
|
# 创建存储目录
|
||||||
RUN mkdir -p /app/files /app/logs && chmod -R 777 /app/files /app/logs
|
RUN mkdir -p /app/files /app/logs /app/config /app/chromium && chmod -R 777 /app/files /app/logs /app/config /app/chromium
|
||||||
|
|
||||||
# 设置环境变量
|
# 设置环境变量
|
||||||
ENV ASPNETCORE_URLS=http://+:5000
|
ENV ASPNETCORE_URLS=http://+:5000
|
||||||
ENV ASPNETCORE_ENVIRONMENT=Production
|
ENV ASPNETCORE_ENVIRONMENT=Production
|
||||||
ENV DOTNET_RUNNING_IN_CONTAINER=true
|
ENV DOTNET_RUNNING_IN_CONTAINER=true
|
||||||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=false
|
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=false
|
||||||
|
ENV PUPPETEER_CACHE_DIR=/app/chromium
|
||||||
|
|
||||||
# 暴露端口
|
# 暴露端口
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
|
|
|
||||||
|
|
@ -276,27 +276,20 @@ var logger = app.Services.GetRequiredService<ILogger<Program>>();
|
||||||
// 仅当已初始化时才预热浏览器池
|
// 仅当已初始化时才预热浏览器池
|
||||||
if (isInitialized)
|
if (isInitialized)
|
||||||
{
|
{
|
||||||
try
|
var browserPool = app.Services.GetRequiredService<IBrowserPool>();
|
||||||
{
|
|
||||||
var browserPool = app.Services.GetRequiredService<IBrowserPool>();
|
logger.LogInformation("步骤 1/2: 准备 Chromium 浏览器引擎...");
|
||||||
|
var chromiumPath = await browserPool.EnsureChromiumReadyAsync(
|
||||||
logger.LogInformation("步骤 1/2: 准备 Chromium 浏览器引擎...");
|
progress => logger.LogInformation(" {Progress}", progress));
|
||||||
var chromiumPath = await browserPool.EnsureChromiumReadyAsync(
|
|
||||||
progress => logger.LogInformation(" {Progress}", progress));
|
logger.LogInformation("步骤 2/2: 预热浏览器池...");
|
||||||
|
await browserPool.WarmUpAsync();
|
||||||
logger.LogInformation("步骤 2/2: 预热浏览器池...");
|
logger.LogInformation("浏览器池预热完成");
|
||||||
await browserPool.WarmUpAsync();
|
|
||||||
logger.LogInformation("浏览器池预热完成");
|
logger.LogInformation("========================================");
|
||||||
|
logger.LogInformation("服务准备就绪!");
|
||||||
logger.LogInformation("========================================");
|
logger.LogInformation("Swagger UI: http://localhost:5000/swagger");
|
||||||
logger.LogInformation("服务准备就绪!");
|
logger.LogInformation("========================================");
|
||||||
logger.LogInformation("Swagger UI: http://localhost:5000/swagger");
|
|
||||||
logger.LogInformation("========================================");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
logger.LogError(ex, "启动准备失败,服务可能无法正常工作");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -488,7 +488,37 @@ public class BrowserPool : IBrowserPool
|
||||||
_logger.LogInformation(message);
|
_logger.LogInformation(message);
|
||||||
progress?.Invoke(message);
|
progress?.Invoke(message);
|
||||||
|
|
||||||
var browserFetcher = new BrowserFetcher();
|
// 使用固定缓存目录,方便 Docker volume 映射持久化
|
||||||
|
var cacheDir = Environment.GetEnvironmentVariable("PUPPETEER_CACHE_DIR")
|
||||||
|
?? Path.Combine(AppContext.BaseDirectory, "chromium");
|
||||||
|
Directory.CreateDirectory(cacheDir);
|
||||||
|
|
||||||
|
var fetcherOptions = new BrowserFetcherOptions { Path = cacheDir };
|
||||||
|
|
||||||
|
// 支持通过环境变量配置 Chromium 下载代理
|
||||||
|
var proxyUrl = Environment.GetEnvironmentVariable("CHROMIUM_DOWNLOAD_PROXY");
|
||||||
|
if (!string.IsNullOrWhiteSpace(proxyUrl))
|
||||||
|
{
|
||||||
|
_logger.LogInformation("使用代理下载 Chromium: {Proxy}", proxyUrl);
|
||||||
|
fetcherOptions.CustomFileDownload = async (url, destinationPath) =>
|
||||||
|
{
|
||||||
|
var handler = new System.Net.Http.HttpClientHandler
|
||||||
|
{
|
||||||
|
Proxy = new System.Net.WebProxy(proxyUrl),
|
||||||
|
UseProxy = true
|
||||||
|
};
|
||||||
|
using var httpClient = new System.Net.Http.HttpClient(handler);
|
||||||
|
httpClient.Timeout = TimeSpan.FromMinutes(10);
|
||||||
|
|
||||||
|
using var response = await httpClient.GetAsync(url);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
|
using var fileStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||||
|
await response.Content.CopyToAsync(fileStream);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var browserFetcher = new BrowserFetcher(fetcherOptions);
|
||||||
var installedBrowsers = browserFetcher.GetInstalledBrowsers();
|
var installedBrowsers = browserFetcher.GetInstalledBrowsers();
|
||||||
|
|
||||||
if (installedBrowsers.Any())
|
if (installedBrowsers.Any())
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ using System.Diagnostics;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using PuppeteerSharp;
|
using PuppeteerSharp;
|
||||||
|
using HtmlToPdfService.Core.Configuration;
|
||||||
using HtmlToPdfService.Core.Models;
|
using HtmlToPdfService.Core.Models;
|
||||||
using HtmlToPdfService.Core.Options;
|
using HtmlToPdfService.Core.Options;
|
||||||
using HtmlToPdfService.Core.Pool;
|
using HtmlToPdfService.Core.Pool;
|
||||||
|
|
@ -13,18 +14,44 @@ namespace HtmlToPdfService.Core.Services;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PuppeteerImageService : IImageService
|
public class PuppeteerImageService : IImageService
|
||||||
{
|
{
|
||||||
private readonly PdfServiceOptions _options;
|
private readonly IOptions<PdfServiceOptions> _staticOptions;
|
||||||
|
private readonly IConfigurationManager? _configManager;
|
||||||
private readonly ILogger<PuppeteerImageService> _logger;
|
private readonly ILogger<PuppeteerImageService> _logger;
|
||||||
private readonly IBrowserPool _browserPool;
|
private readonly IBrowserPool _browserPool;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前有效配置(优先使用动态配置)
|
||||||
|
/// </summary>
|
||||||
|
private PdfServiceOptions _options
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_configManager?.IsInitialized == true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var userConfig = _configManager.GetConfigurationAsync().GetAwaiter().GetResult();
|
||||||
|
return userConfig.ToPdfServiceOptions();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 动态配置读取失败时回退到静态配置
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _staticOptions.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public PuppeteerImageService(
|
public PuppeteerImageService(
|
||||||
IOptions<PdfServiceOptions> options,
|
IOptions<PdfServiceOptions> options,
|
||||||
ILogger<PuppeteerImageService> logger,
|
ILogger<PuppeteerImageService> logger,
|
||||||
IBrowserPool browserPool)
|
IBrowserPool browserPool,
|
||||||
|
IConfigurationManager? configManager = null)
|
||||||
{
|
{
|
||||||
_options = options.Value;
|
_staticOptions = options;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_browserPool = browserPool;
|
_browserPool = browserPool;
|
||||||
|
_configManager = configManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using PuppeteerSharp;
|
using PuppeteerSharp;
|
||||||
using PuppeteerSharp.Media;
|
using PuppeteerSharp.Media;
|
||||||
|
using HtmlToPdfService.Core.Configuration;
|
||||||
using HtmlToPdfService.Core.Models;
|
using HtmlToPdfService.Core.Models;
|
||||||
using HtmlToPdfService.Core.Options;
|
using HtmlToPdfService.Core.Options;
|
||||||
using HtmlToPdfService.Core.Pool;
|
using HtmlToPdfService.Core.Pool;
|
||||||
|
|
@ -14,18 +15,44 @@ namespace HtmlToPdfService.Core.Services;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PuppeteerPdfService : IPdfService
|
public class PuppeteerPdfService : IPdfService
|
||||||
{
|
{
|
||||||
private readonly PdfServiceOptions _options;
|
private readonly IOptions<PdfServiceOptions> _staticOptions;
|
||||||
|
private readonly IConfigurationManager? _configManager;
|
||||||
private readonly ILogger<PuppeteerPdfService> _logger;
|
private readonly ILogger<PuppeteerPdfService> _logger;
|
||||||
private readonly IBrowserPool _browserPool;
|
private readonly IBrowserPool _browserPool;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前有效配置(优先使用动态配置)
|
||||||
|
/// </summary>
|
||||||
|
private PdfServiceOptions _options
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_configManager?.IsInitialized == true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var userConfig = _configManager.GetConfigurationAsync().GetAwaiter().GetResult();
|
||||||
|
return userConfig.ToPdfServiceOptions();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 动态配置读取失败时回退到静态配置
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _staticOptions.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public PuppeteerPdfService(
|
public PuppeteerPdfService(
|
||||||
IOptions<PdfServiceOptions> options,
|
IOptions<PdfServiceOptions> options,
|
||||||
ILogger<PuppeteerPdfService> logger,
|
ILogger<PuppeteerPdfService> logger,
|
||||||
IBrowserPool browserPool)
|
IBrowserPool browserPool,
|
||||||
|
IConfigurationManager? configManager = null)
|
||||||
{
|
{
|
||||||
_options = options.Value;
|
_staticOptions = options;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_browserPool = browserPool;
|
_browserPool = browserPool;
|
||||||
|
_configManager = configManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user