Artisan في الإنتاج
نظرة سريعة
قسم بعنوان «نظرة سريعة»في بيئة الإنتاج، احقن مُصيِّرًا مُهيَّأً ومُسجِّلًا متوافقًا مع توصية معايير PHP رقم 3 (PSR-3)، وأعد استخدام عملية Chrome الحية بين عمليات التصيير، وحدِّد ارتفاعات صريحة للمستندات متعددة العناصر، وقيِّد مسار التصيير بمهلة زمنية يفرضها المصدر الأعلى.
نظرة عامة مفاهيمية
قسم بعنوان «نظرة عامة مفاهيمية»يُبقي BrowserPool عملية Chrome واحدة حية (keepAlive: true) ويعيد تشغيلها كل 100 عملية تصيير للحد من نمو استهلاك الذاكرة، وهو نمط تراكم معروف في عملاء بروتوكول أدوات مطوري Chrome (CDP) طويلة العمر. في عامل المعالجة الذي يُصيِّر مستندات كثيرة، استخدم مُصيِّرًا واحدًا طويل العمر بدلًا من مُصيِّر لكل طلب، حتى لا تتحمّل تكلفة بدء تشغيل Chrome إلا نادرًا.
نموذج برمجي — بيئة الإنتاج
قسم بعنوان «نموذج برمجي — بيئة الإنتاج»<?php
declare(strict_types=1);
use NextPDF\Artisan\ChromeHtmlRenderer;use NextPDF\Artisan\ChromeRendererConfig;use NextPDF\Artisan\Exception\ChromeNotAvailableException;use NextPDF\Artisan\Exception\ChromeRenderException;use Psr\Log\LoggerInterface;
final class ReportRenderer{ private ChromeHtmlRenderer $renderer;
public function __construct(LoggerInterface $logger) { $config = ChromeRendererConfig::fromArray([ 'chrome_binary' => getenv('CHROME_BINARY') ?: null, 'render_timeout' => 45, 'max_html_size' => 2_000_000, 'no_sandbox' => (bool) getenv('CHROME_NO_SANDBOX'), ]);
$this->renderer = new ChromeHtmlRenderer($config, $logger); }
public function render(string $html, float $widthPt, float $heightPt = 0.0): string { try { return $this->renderer->render($html, $widthPt, $heightPt)->getPdfData(); } catch (ChromeNotAvailableException $e) { // Deployment fault: Chrome runtime missing. Page the on-call owner. throw $e; } catch (ChromeRenderException $e) { // Render-time fault: timeout, crash, empty output. Retryable once. throw $e; } }
public function shutdown(): void { $this->renderer->close(); }}أنشئ المُصيِّر مرة واحدة، ثم أعد استخدامه. استدعِ close() عند إيقاف عامل المعالجة لتحرير عملية Chrome على نحو حتمي بدلًا من انتظار المُدمِّر. يميّز فرعا الالتقاط بين عطل في النشر (بيئة تشغيل مفقودة) وعطل في وقت التصيير (قابل لإعادة المحاولة). لا تستخدم كتل catch فارغة.
اربطه في الحاوية كنسخة وحيدة (singleton):
$container->singleton(ReportRenderer::class, fn ($c) => new ReportRenderer($c->get(Psr\Log\LoggerInterface::class)));معالجة الارتفاع
قسم بعنوان «معالجة الارتفاع»عند حذف الارتفاع، يقيس الجسر ارتفاع المحتوى في Chrome (max لارتفاعات التمرير والإزاحة لـ body/document)، ويحوِّله إلى نقاط، ويضيف هامش أمان يقارب 0.2 بوصة (نحو 14.4 نقطة). يغطي هذا الهامش الفجوة بين تخطيط منفذ العرض في Chrome وإعادة تدفق تخطيط الطباعة فيه. ومن دونه، قد يدفع printToPDF المحتوى إلى صفحة ثانية يقصها PageImporter (الصفحة 0 فقط). يفرض الجسر حدًا أدنى لارتفاع الورقة يبلغ 0.1 بوصة. تؤكد الاختبارات ChromeHtmlRendererTest::renderUsesAutoFitHeightByDefault، و::renderAutoFitBufferIsAddedNotSubtracted، و::renderAppliesMinimumHeightOf0Point1InchForTinyExplicitHeight هذا السلوك.
بالنسبة إلى المستندات ذات التخطيط الثابت (مثل الفواتير والشهادات)، مرِّر ارتفاعًا صريحًا بالنقاط. عندما يكون الارتفاع صريحًا، لا يُضاف أي هامش، ويطابق الخرج حجم الورقة المطلوب تمامًا (وهو ما يؤكده ::renderHonorsExplicitHeightWithoutAutoBuffer).
عمال معالجة الدُفعات
قسم بعنوان «عمال معالجة الدُفعات»- أنشئ مُصيِّرًا واحدًا لكل عامل معالجة، وأعد استخدامه. يعيد
BrowserPoolاستخدام المتصفح الحي ويعيد التشغيل تلقائيًا عند حد الـ 100 عملية تصيير. - استدعِ
close()عند إيقاف عامل المعالجة وبين الدُفعات الكبيرة عندما تريد عملية Chrome جديدة قبل بلوغ حد الـ 100 عملية تصيير. - يستدعي المُدمِّر
close()، لكن استدعاءclose()الصريح حتمي ومُفضَّل في العمليات طويلة التشغيل. - تُسجَّل إشعارات إعادة التشغيل عند مستوى
noticeمع عدد عمليات التصيير؛ أطلق تنبيهًا عند ارتفاع معدل إعادة التشغيل لأنه قد يشير إلى مستندات أثقل من المتوقع.
قابلية المراقبة
قسم بعنوان «قابلية المراقبة»احقن مُسجِّلًا متوافقًا مع PSR-3. يُصدر المُصيِّر الأحداث والمستويات الآتية:
| الحدث | المستوى | السياق |
|---|---|---|
| بدء التصيير | debug | size، width، height |
| اكتمال التصيير | debug | pdfSize، contentHeight |
| تشغيل المتصفح | info | binary |
| إعادة تشغيل المتصفح | notice | count |
| إغلاق المتصفح | debug | renderCount |
لا تُسجَّل أي بايتات HTML أو PDF أو نص مُستخرَج. يُبقي ذلك الحمولات خارج سجلات التشغيل، ويتوافق مع إرشادات محتوى السجلات في المنشور الخاص للمعهد الوطني للمعايير والتقنية (NIST SP) 800-92. أنشئ أهداف مستوى الخدمة (SLOs) لزمن الاستجابة من زوج start/complete، وأنشئ تنبيهًا لمعدل إعادة التشغيل من أحداث notice.
أنماط النشر
قسم بعنوان «أنماط النشر»- Sidecar Chrome: شغِّل Chrome في الحاوية نفسها التي يعمل فيها عامل المعالجة PHP؛ ثبِّت
chrome_binary. جهِّز حاوية قادرة على تشغيل بيئة معزولة (sandbox)؛ راجع /integrations/artisan/chrome-renderer-setup/. - بدون حاوية / CLI: لا تتوفر لدى Artisan حاوية لحقن التبعيات. استخدم
EInvoiceServiceFactoryلعقود الفوترة الإلكترونية في إصدار Premium ضمن مشغِّلات واجهة سطر الأوامر (CLI)؛ راجع /integrations/artisan/boot-and-discovery/. - تقييد الموارد: اقرن
render_timeoutبميزانية طلب من المصدر الأعلى وبأداة على المضيف من نوع cgroup/ulimit. راجع نموذج التهديد في /integrations/artisan/security-and-operations/.
الحالات الحدّية والمزالق
قسم بعنوان «الحالات الحدّية والمزالق»- المُصيِّر الذي يُقاطَع في منتصف التصيير يغلق صفحة Chrome مع ذلك (
finally)، ويظلّ المجمع قابلًا للاستخدام. - إعادة استخدام مُصيِّر واحد عبر threads/processes غير مدعومة؛ فكل مُصيِّر يملك عملية Chrome واحدة.
- إعادة التشغيل عند الـ 100 عملية تصيير ثابتة؛ فحدِّد أحجام الدُفعات مع وضع ذلك في الاعتبار حتى تبقى ارتفاعات زمن الاستجابة قابلة للتنبؤ.
الأداء
قسم بعنوان «الأداء»التكلفة في الحالة المستقرة هي تخطيط Chrome للمدخل إضافةً إلى printToPDF، وليست عبء الجسر. يوزِّع keepAlive تكلفة بدء التشغيل على عمليات التصيير. توقَّع ارتفاعًا في زمن الاستجابة عند كل عملية تصيير رقم 100 (إعادة تشغيل العملية)؛ فأبرِزه في أهداف مستوى الخدمة (SLOs) بدلًا من التعامل معه كحادث تشغيلي.
ملاحظات أمنية
قسم بعنوان «ملاحظات أمنية»تستقبل مسارات الإنتاج محتوى HTML غير موثوق. أعد قراءة /integrations/artisan/security-and-operations/. تظل حواجز الشبكة فعّالة بغض النظر عن التهيئة، لكن no_sandbox: true يزيل عزل عملية Chrome ويرفع متطلب الثقة المفروض على المدخل.
السياق التجاري
قسم بعنوان «السياق التجاري»في عمال المعالجة بدون حاوية، يُرجِع EInvoiceServiceFactory القيمة null عند عدم تثبيت إصدار Premium، فيستمر مسار التصيير مفتوح المصدر دون تغيير. ثبِّت Pro/Enterprise لتفعيل تضمين الفاتورة الإلكترونية والتحقق منها داخل المستند المُصيَّر.
انظر أيضًا
قسم بعنوان «انظر أيضًا»- /integrations/artisan/quickstart/
- /integrations/artisan/configuration/
- /integrations/artisan/security-and-operations/
- /integrations/artisan/chrome-renderer-setup/
- /integrations/artisan/troubleshooting/