yemeishu 5 часов назад
Родитель
Сommit
0eb0c63c69
1 измененных файлов с 57 добавлено и 32 удалено
  1. 57 32
      app/Services/ExamPdfExportService.php

+ 57 - 32
app/Services/ExamPdfExportService.php

@@ -1043,14 +1043,13 @@ class ExamPdfExportService
 
         $process = new Process([
             $chromeBinary,
-            '--headless',
+            '--headless=new', // 【优化】使用新渲染引擎
             '--disable-gpu',
             '--no-sandbox',
             '--disable-setuid-sandbox',
             '--disable-dev-shm-usage',
-            '--no-zygote',
+            '--disable-web-security',
             '--disable-features=VizDisplayCompositor',
-            '--disable-software-rasterizer',
             '--disable-extensions',
             '--disable-background-networking',
             '--disable-component-update',
@@ -1058,31 +1057,36 @@ class ExamPdfExportService
             '--disable-default-apps',
             '--disable-domain-reliability',
             '--disable-sync',
-            '--safebrowsing-disable-auto-update',
             '--no-first-run',
             '--no-default-browser-check',
             '--disable-crash-reporter',
             '--disable-print-preview',
-            '--disable-features=PrintHeaderFooter',
             '--disable-features=TranslateUI',
             '--disable-features=OptimizationHints',
             '--disable-ipc-flooding-protection',
-            '--disable-background-networking',
             '--disable-background-timer-throttling',
             '--disable-backgrounding-occluded-windows',
             '--disable-renderer-backgrounding',
             '--disable-features=AudioServiceOutOfProcess',
+            '--single-process', // 【优化】单进程模式,减少资源占用
+            '--disable-gpu-sandbox',
+            '--disable-software-rasterizer',
+            '--disable-background-mode',
+            '--disable-extensions-http-throttling',
+            '--disable-ipc-flooding-protection',
             '--user-data-dir=' . $userDataDir,
             '--print-to-pdf=' . $tmpPdf,
             '--print-to-pdf-no-header',
             '--allow-file-access-from-files',
+            '--font-render-hinting=none', // 【优化】禁用字体渲染提示
+            '--disable-font-antialiasing',
             'file://' . $htmlPath,
         ], null, [
             'HOME' => $runtimeHome,
             'XDG_RUNTIME_DIR' => $runtimeXdg,
         ]);
 
-        $process->setTimeout(120);
+        $process->setTimeout(60); // 【优化】减少超时到60秒
         $killSignal = \defined('SIGKILL') ? \SIGKILL : 9;
 
         try {
@@ -1090,33 +1094,46 @@ class ExamPdfExportService
             $process->start();
             $pdfGenerated = false;
 
-            // 轮询检测PDF是否生成
+            // 轮询检测PDF是否生成(【优化】减少超时和间隔)
             $pollStart = microtime(true);
-            $maxPollSeconds = 90;
+            $maxPollSeconds = 50; // 【优化】从90秒减少到50秒
             while ($process->isRunning() && (microtime(true) - $pollStart) < $maxPollSeconds) {
                 if (file_exists($tmpPdf) && filesize($tmpPdf) > 0) {
                     $pdfGenerated = true;
-                    $process->stop(5, $killSignal);
+                    Log::info('ExamPdfExportService: PDF生成成功,提前终止Chrome进程', [
+                        'elapsed' => round(microtime(true) - $startedAt, 2),
+                        'pdf_size' => filesize($tmpPdf),
+                    ]);
+                    $process->stop(3, $killSignal); // 【优化】减少停止等待时间
                     break;
                 }
-                usleep(200_000);
+                usleep(100_000); // 【优化】从200ms减少到100ms
             }
 
             if ($process->isRunning()) {
-                $process->stop(5, $killSignal);
+                $process->stop(3, $killSignal); // 【优化】减少停止等待时间
             }
 
-            $process->wait();
+            // 【优化】删除不必要的wait()调用,避免重复等待
+            // $process->wait();
 
         } catch (ProcessTimedOutException|ProcessSignaledException $e) {
             if ($process->isRunning()) {
-                $process->stop(5, $killSignal);
+                $process->stop(3, $killSignal); // 【优化】减少停止等待时间
             }
+            Log::warning('ExamPdfExportService: Chrome进程超时或被信号中断', [
+                'elapsed' => round((microtime(true) - $startedAt), 2),
+                'exception' => get_class($e),
+            ]);
             return $this->handleChromeProcessResult($tmpPdf, $userDataDir, $process, $startedAt);
         } catch (\Throwable $e) {
             if ($process->isRunning()) {
-                $process->stop(5, $killSignal);
+                $process->stop(3, $killSignal); // 【优化】减少停止等待时间
             }
+            Log::error('ExamPdfExportService: Chrome进程异常', [
+                'elapsed' => round((microtime(true) - $startedAt), 2),
+                'error' => $e->getMessage(),
+            ]);
             return $this->handleChromeProcessResult($tmpPdf, $userDataDir, $process, null);
         }
 
@@ -1130,28 +1147,36 @@ class ExamPdfExportService
     {
         $pdfExists = file_exists($tmpPdf);
         $pdfSize = $pdfExists ? filesize($tmpPdf) : null;
+        $elapsed = $startedAt ? round((microtime(true) - $startedAt), 2) : null;
+
+        // 【优化】即使进程未成功,只要PDF存在且大小合理就返回
+        if ($pdfExists && $pdfSize > 1000) { // 至少1KB
+            Log::info('ExamPdfExportService: PDF生成成功', [
+                'elapsed' => $elapsed,
+                'pdf_size' => $pdfSize,
+                'exit_code' => $process->getExitCode(),
+                'is_successful' => $process->isSuccessful(),
+            ]);
 
-        if (!$process->isSuccessful()) {
-            if ($pdfExists && $pdfSize > 0) {
-                Log::warning('ExamPdfExportService: Chrome进程异常但生成了PDF', [
-                    'exit_code' => $process->getExitCode(),
-                    'tmp_pdf_size' => $pdfSize,
-                ]);
-            } else {
-                Log::error('ExamPdfExportService: Chrome渲染失败', [
-                    'exit_code' => $process->getExitCode(),
-                    'error' => $process->getErrorOutput(),
-                ]);
-                @unlink($tmpPdf);
-                File::deleteDirectory($userDataDir);
-                return null;
-            }
+            $pdfBinary = file_get_contents($tmpPdf);
+            @unlink($tmpPdf);
+            File::deleteDirectory($userDataDir);
+            return $pdfBinary;
         }
 
-        $pdfBinary = $pdfExists ? file_get_contents($tmpPdf) : null;
+        // 如果PDF不存在或太小,记录错误
+        Log::error('ExamPdfExportService: Chrome渲染失败', [
+            'elapsed' => $elapsed,
+            'pdf_exists' => $pdfExists,
+            'pdf_size' => $pdfSize,
+            'exit_code' => $process->getExitCode(),
+            'error' => $process->getErrorOutput(),
+            'output' => $process->getOutput(),
+        ]);
+
         @unlink($tmpPdf);
         File::deleteDirectory($userDataDir);
-        return $pdfBinary ?: null;
+        return null;
     }
 
     /**