İçeriğe geç

Üretimde NextPDF Symfony kullanımı

Paketi uzun süre çalışan PHP çalışma zamanlarında kullanın. Paket, paylaşılmayan belgeler oluşturur, ısınmadan sonra yazı tipi kayıt defterini kilitler ve istekler arasında görüntü önbelleğini sıfırlar. Büyük PDF dosyalarını akış olarak iletin ve ağır işleri Messenger iş parçacıklarına devredin.

İş parçacığı açısından güvenli servis yaşam döngüsü

“İş parçacığı açısından güvenli servis yaşam döngüsü” başlıklı bölüm

Uzun süre çalışan çalışma zamanları, kapsayıcıyı istekler arasında etkin tutar; bu nedenle istek başına durumun yalıtılmış kalması gerekir. FrankenPHP, RoadRunner ve Messenger iş parçacıkları bu modeli izler. Paketin services.php dosyası, servis tanımlarıyla doğrulanmış aşağıdaki yaşam döngüsünü tanımlar:

  • Document — paylaşılmaz. nextpdf.document (ve PdfDocumentInterface / Document diğer adları) her çözümlemede yeni bir örnek olarak çözümlenir. PSR-11 (PHP Standart Önerisi 11) uyarınca bir kapsayıcı, aynı kimlik için her get() çağrısında geçerli biçimde farklı bir değer döndürebilir (PSR-11 §1.1.2). Bir belgeyi istek başına çözümleyin. İstekler arasında asla tutmayın.
  • FontRegistry — paylaşılan ve kilitli. Kayıt defteri, işlemin yaşam süresi boyunca tek bir örnek olarak kalır. warmup() sonrasında (preload_fonts boş olmadığında) derleyici geçişi lock() çağrısını yapar. Kilit, çalışma zamanında değiştirmeyi ve istekler arasında yazı tipi durumunun kirlenmesini önler.
  • ImageRegistry — paylaşılan, istek başına sıfırlanan. Sınırlandırılmış en az yakın zamanda kullanılan (LRU) görüntü önbelleği paylaşılır, ancak kernel.reset etiketiyle ve reset yöntemiyle işaretlenir; böylece Symfony, kernel.reset yöntemini destekleyen çalışma zamanlarında bu önbelleği istekler arasında temizler.
  • EInvoice sözleşmeleri — paylaşılmaz. Premium uygulamaları mevcut olduğunda embedder, validator, profil ve schematron servisleri paylaşılmayan olarak kaydedilir. Ayrıştırıcı bağlamı her çağrı kapsamında kalır ve istekler arasına asla sızmaz.

Paylaşılan, durumsuz bir yapılandırma tutucusu olan PdfFactory nesnesini enjekte edin ve her istek için create() çağrısını yapın:

public function __construct(private readonly PdfFactory $pdf) {}
public function action(): Response
{
$doc = $this->pdf->create(); // fresh, disposable
// ... build ...
return PdfResponse::inline($doc, 'document.pdf');
}

İstekler arasında tutulan paylaşılan bir servise Document veya nextpdf.document nesnesini enjekte etmeyin. Bunun yerine onu istek kapsamındaki yöntemin içinde çözümleyin.

PdfResponse::streamDownload() ve streamInline(), bir StreamedResponse döndürür. Geri çağırma, PDF gövdesini 64 KB’lık parçalar halinde üretir ve her parçanın ardından boşaltır; bu da büyük belgelerde yanıt arabelleğini sınırlandırır. Aşağıdaki davranışlar PdfResponse ile doğrulanmıştır:

  • Akış varyantları, yanıt nesnesi gövde boyutunu önceden bilmediği için kasıtlı olarak Content-Length başlığını atlar. İndirme ilerleme çubukları ve bazı proxy’ler, bilinen bir uzunlukla daha iyi çalışır. Belge bellekte tutulabilecek kadar küçük olduğunda ve bir içerik uzunluğu isteniyorsa, akışsız download() veya inline() yöntemini kullanın.
  • Akış varyantları, arabelleğe alınmış varyantlarla aynı güvenlik başlıklarını ve aynı Cache-Control: private, max-age=0, must-revalidate başlığını üretir.

Çok megabaytlık raporlar ve toplu dışa aktarmalar için akışı seçin. Küçük, gecikmeye duyarlı yanıtlar için arabelleğe alınmış varyantları seçin.

İsteklerin hızlıca yanıt vermesi gerektiğinde veya oluşturma işlemciyi yoğun kullanıyorsa, oluşturmayı Messenger’a devredin.

  1. Her belge türü için PdfBuilderInterface arabirimini uygulayın.
  2. Oluşturucuları bir container.service_locator içinde kaydedin ve bunu GeneratePdfHandler sınıfının $builderLocator bağımlılığı olarak bağlayın.
  3. Bir GeneratePdfMessage iletisini dayanıklı bir taşıma yöntemine yönlendirin.
  4. İş parçacıklarını sınırlandırılmış yaşam süreleriyle çalıştırın.

Sınırlandırılmış iş parçacığı yaşam süresi

“Sınırlandırılmış iş parçacığı yaşam süresi” başlıklı bölüm

Üçüncü taraf bir bağımlılıktaki sızan bellek tahsisinin sınırsızca büyümesini önlemek için iş parçacıklarını geri dönüştürün:

Terminal window
php bin/console messenger:consume async \
--limit=200 \
--memory-limit=256M \
--time-limit=3600

Paketin messenger.timeout ve messenger.retries yapılandırma anahtarları, ileti başına amaçlanan zaman aşımını ve yeniden deneme bütçesini kaydeder. Aynı davranışı Symfony’nin yeniden deneme stratejisi ve iş parçacığı bayrakları aracılığıyla zorunlu kılın.

GeneratePdfMessage, çıktı yolunu nesne oluşturulurken doğrular. GeneratePdfHandler, çalıştırma sırasında diske yazmadan önce bu yolu yeniden doğrular. Bu iki aşamalı denetim, eşzamansız işler için önemlidir. Bir ileti, gönderim ile tüketim arasında kuyrukta bekleyebilir; bu nedenle işleyici, kuyruğa alınmış yola körü körüne güvenmez. Derinlemesine savunma olarak iş parçacığı dosya sistemi izinlerini amaçlanan çıktı dizinine kısıtlayın.

Paketin FontRegistry ve ImageRegistry servisleri, isteğe bağlı bir Psr\Log\LoggerInterface kabul eder (nullOnInvalid() ile bağlanmış). Uygulama bir günlükleyici sağladığında, kayıt defterleri tanılama bilgilerini bunun üzerinden yazabilir. Günlükleyici, PSR-3 günlükleyici sözleşmesi (PSR-3) kapsamında isteğe bağlı, değiştirilebilir bir iş birlikçisidir. İstek düzeyinde görünürlük için uygulama kodunuzda PdfFactory::create() çevresinde ve Messenger işleyicisinde günlük kaydı yapın. Olay triyajı sırasında messenger:consume -vv komutunu kullanın.

  • Tek bir nextpdf/core ana sürümünü uygulamanın composer.json dosyasında sabitleyin (paket ^3.0 || ^5.2 sürümlerini kabul eder).
  • Dağıtılan PHP imajında ext-mbstring ve ext-zlib uzantılarının etkin olduğundan emin olun (aksi takdirde paket önyükleme sırasında hızlıca başarısız olur).
  • Kayıt defterinin ilk istek yerine önyükleme sırasında ısınıp kilitlenmesi için preload_fonts ayarını belgelerinizin kullandığı yazı tipleriyle önceden doldurun.
  • Dağıtımlar boyunca önbelleğe alınmış yapıtlara güveniyorsanız cache_path ayarını yazılabilir, kalıcı bir konuma yönlendirin. Aksi takdirde, %kernel.cache_dir% varsayılanı uygundur.
  • Derlenmiş kapsayıcının (isteğe bağlı uzantı yoklamaları dahil) trafik almadan önce oluşturulması için dağıtım sırasında php bin/console cache:warmup komutunu çalıştırın.
  • Üretim eşzamansız işleri için dayanıklı bir Messenger taşıma yöntemi (sync değil) kullanın ve iş parçacıklarını --limit / --memory-limit / --time-limit ile geri dönüştürün.
  • Arabelleğe alan bir proxy’nin arkasındaki akış yanıtları — Gövdenin tamamını arabelleğe alan bir proxy, bellek avantajını ortadan kaldırır. Proxy’yi PDF yanıtlarını akış olarak iletecek şekilde yapılandırın veya o katmanda arabelleğe alınmış yanıtları kullanın.
  • kernel.reset desteklenmiyorkernel.reset çağrısı yapmayan bir çalışma zamanında görüntü önbelleği image_cache_mb ile sınırlandırılır, ancak istekler arasında temizlenmez; üst sınırı buna göre boyutlandırın.
  • Bir belgeyi istekler arasında tutmak — Önceki bir istekten yakalanan bir Document, eski durumu taşır. Her zaman PdfFactory aracılığıyla istek başına çözümleyin.

Her satır, bu sayfadaki normatif bir iddiaya karşılık gelir ve kısıtlı standart geliştirme kuruluşu (SDO) derlemesinden gelen tam 64 onaltılık karakterli bir reference_id değerine sabitlenmiştir. Derleme bildirimi ve alım taşıma yöntemine ilişkin köken bilgisi _sidecars/rag-citations.yaml dosyasında yer alır.

BelirtimMaddereference_idİddia
PSR-11psr_11_container#1.1.2.p3.bPaylaşılmayan servis: her çözümlemede farklı bir değer
PSR-3psr_3_logger#x3.p17İsteğe bağlı günlükleyici iş birlikçisi
  • /integrations/symfony/configuration/ — servis yaşam döngüsü ve parametreler.
  • /integrations/symfony/security-and-operations/ — yanıt başlıkları, yol doğrulama, anahtar işleme.
  • /integrations/symfony/troubleshooting/ — önyükleme ve çalışma zamanı tanılaması.
  • /integrations/symfony/quickstart/ — en küçük eşzamansız kurulum.