Artisan di lingkungan produksi
Sekilas
Bagian berjudul “Sekilas”Di lingkungan produksi, injeksikan renderer yang sudah dikonfigurasi dan logger PHP Standards Recommendation 3 (PSR-3), gunakan ulang proses Chrome yang aktif antar-render, tetapkan tinggi eksplisit untuk dokumen multi-elemen, dan batasi jalur render dengan batas waktu di sisi hulu.
Gambaran konseptual
Bagian berjudul “Gambaran konseptual”BrowserPool mempertahankan satu proses Chrome tetap aktif (keepAlive: true) dan memulai ulang proses tersebut setiap 100 render untuk membatasi pertumbuhan memori, yaitu pola akumulasi yang dikenal pada klien Chrome DevTools Protocol (CDP) berumur panjang. Untuk worker yang merender banyak dokumen, gunakan satu renderer berumur panjang alih-alih satu renderer per permintaan, sehingga biaya startup Chrome jarang ditanggung.
Contoh kode — Produksi
Bagian berjudul “Contoh kode — Produksi”<?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(); }}Buat renderer satu kali, lalu gunakan kembali. Panggil close() saat worker dimatikan untuk melepaskan proses Chrome secara deterministik alih-alih menunggu destructor. Kedua cabang catch memisahkan kegagalan deployment (runtime tidak tersedia) dari kegagalan saat render (dapat dicoba ulang). Jangan gunakan blok catch kosong.
Daftarkan di dalam container sebagai singleton:
$container->singleton(ReportRenderer::class, fn ($c) => new ReportRenderer($c->get(Psr\Log\LoggerInterface::class)));Penanganan tinggi
Bagian berjudul “Penanganan tinggi”Saat Anda tidak menyertakan tinggi, jembatan mengukur tinggi konten di Chrome (max dari tinggi scroll dan offset body/document), mengonversinya menjadi poin, lalu menambahkan buffer keamanan sekitar 0,2 inci (~14,4 pt). Buffer ini mengompensasi selisih antara tata letak viewport Chrome dan reflow tata letak cetaknya. Tanpa buffer ini, printToPDF dapat membuat konten meluber ke halaman kedua yang akan dipotong oleh PageImporter (hanya halaman 0). Jembatan menerapkan tinggi kertas minimum sebesar 0,1 inci. Pengujian ChromeHtmlRendererTest::renderUsesAutoFitHeightByDefault, ::renderAutoFitBufferIsAddedNotSubtracted, dan ::renderAppliesMinimumHeightOf0Point1InchForTinyExplicitHeight memverifikasi perilaku ini.
Untuk dokumen dengan tata letak tetap (faktur, sertifikat), berikan tinggi eksplisit dalam satuan poin. Jika tinggi diberikan secara eksplisit, tidak ada buffer yang ditambahkan, dan keluarannya sama persis dengan ukuran kertas yang diminta (diverifikasi oleh ::renderHonorsExplicitHeightWithoutAutoBuffer).
Worker batch
Bagian berjudul “Worker batch”- Buat satu renderer per worker, lalu gunakan kembali.
BrowserPoolmenggunakan kembali peramban yang aktif dan otomatis memulai ulang saat mencapai batas 100 render. - Panggil
close()saat worker dimatikan dan di antara batch besar jika Anda menginginkan proses Chrome yang baru sebelum batas 100 render. - Destructor memanggil
close(), tetapi memanggilclose()secara eksplisit bersifat deterministik dan lebih disarankan dalam proses yang berjalan lama. - Pemberitahuan restart dicatat pada level
noticebeserta jumlah render; siapkan peringatan untuk laju restart yang meningkat, karena hal itu menandakan dokumen lebih berat daripada yang diperkirakan.
Observabilitas
Bagian berjudul “Observabilitas”Injeksikan logger PSR-3. Renderer memancarkan event dan level berikut:
| Event | Level | Konteks |
|---|---|---|
| Mulai render | debug | size, width, height |
| Render selesai | debug | pdfSize, contentHeight |
| Peluncuran peramban | info | binary |
| Restart peramban | notice | count |
| Penutupan peramban | debug | renderCount |
Tidak ada HTML, bita PDF, ataupun teks hasil ekstraksi yang dicatat. Hal ini menjaga payload tetap berada di luar log operasional dan selaras dengan panduan isi log National Institute of Standards and Technology Special Publication (NIST SP) 800-92. Buat service-level objective (SLO) latensi berdasarkan pasangan start/complete, dan siapkan peringatan laju restart dari event notice.
Pola deployment
Bagian berjudul “Pola deployment”- Sidecar Chrome: jalankan Chrome di container yang sama dengan worker PHP; sematkan
chrome_binary. Sediakan container yang mendukung sandbox; lihat /integrations/artisan/chrome-renderer-setup/. - Tanpa container / CLI: Artisan tidak menyediakan container dependency injection. Gunakan
EInvoiceServiceFactoryuntuk kontrak e-invoice Premium pada runner command-line interface (CLI); lihat /integrations/artisan/boot-and-discovery/. - Pembatasan sumber daya: pasangkan
render_timeoutdengan anggaran permintaan di sisi hulu serta cgroup/ulimit host. Lihat model ancaman di /integrations/artisan/security-and-operations/.
Kasus tepi & jebakan
Bagian berjudul “Kasus tepi & jebakan”- Renderer yang terhenti saat proses render berlangsung tetap menutup halaman Chrome (
finally), dan pool tetap dapat digunakan. - Penggunaan ulang satu renderer di seluruh threads/processes tidak didukung; satu renderer memiliki satu proses Chrome.
- Restart pada 100 render bersifat tetap; tentukan ukuran batch dengan mempertimbangkan hal ini agar lonjakan latensi tetap dapat diprediksi.
Performa
Bagian berjudul “Performa”Biaya pada kondisi stabil adalah tata letak Chrome untuk input ditambah printToPDF, bukan overhead jembatan. keepAlive menyebarkan biaya startup ke seluruh render. Perkirakan adanya lonjakan latensi pada setiap render ke-100 (restart proses); perhitungkan hal itu dalam SLO alih-alih memperlakukannya sebagai insiden.
Catatan keamanan
Bagian berjudul “Catatan keamanan”Jalur produksi menerima HTML yang tidak tepercaya. Baca ulang /integrations/artisan/security-and-operations/. Penghalang jaringan tetap berlaku apa pun konfigurasinya, tetapi no_sandbox: true menghapus isolasi proses Chrome dan meningkatkan tingkat kepercayaan yang disyaratkan terhadap input.
Konteks komersial
Bagian berjudul “Konteks komersial”Pada worker tanpa container, EInvoiceServiceFactory mengembalikan null saat Premium tidak terpasang, sehingga jalur render open-source tetap berjalan tanpa perubahan. Pasang Pro/Enterprise untuk mengaktifkan penyematan dan validasi e-invoice pada dokumen yang telah dirender.
Lihat juga
Bagian berjudul “Lihat juga”- /integrations/artisan/quickstart/
- /integrations/artisan/configuration/
- /integrations/artisan/security-and-operations/
- /integrations/artisan/chrome-renderer-setup/
- /integrations/artisan/troubleshooting/