Pular para o conteúdo

NextPDF Gotenberg em produção

A ponte faz uma ida e volta síncrona via Hypertext Transfer Protocol (HTTP) e valida o resultado. Ela não faz novas tentativas, enfileiramento, cache nem limitação de taxa. Coloque esses comportamentos na aplicação que envolve a ponte. Esta página mostra o que pertence a cada lugar e o que a ponte garante, para que você possa construir o restante corretamente.

Trate cada conversão como uma chamada remota a um serviço que você opera, mas não controla no mesmo processo. Planeje a latência e as falhas desse serviço.

GotenbergConfig armazena o Uniform Resource Locator (URL) da application programming interface (API) e, quando a autenticação está habilitada, um bearer token. O campo do token é marcado com #[\SensitiveParameter], de modo que os stack traces o ocultem. Você continua responsável por obtê-lo com segurança.

  • Carregue o token a partir de um gerenciador de segredos ou de um valor de ambiente injetado no início do processo. Não faça commit dele e não o coloque em um arquivo de configuração incluído na imagem.
  • Construa a configuração uma vez por escopo de requisição ou uma vez por worker, não a cada conversão. A configuração é imutável e barata de manter.
  • GotenbergConfig::fromArray() aceita entrada malformada por design e a substitui silenciosamente por valores padrão. Em produção, valide o array de origem antes de chamar fromArray(). Assim, uma URL ausente aparece como erro de configuração durante o boot, e não mais tarde como uma exceção Invalid Gotenberg configuration: apiUrl is empty por conversão.

timeout (em segundos, padrão 30) é o timeout rígido de transferência aplicado pelo transporte baseado em cURL. A conversão de Office por meio do LibreOffice não é instantânea; documentos grandes ou complexos demoram mais. Defina o timeout com base na latência de conversão medida para documentos reais, com folga. Mantenha-o abaixo de qualquer timeout de gateway upstream ou do max_execution_time do runtime do PHP. Isso permite que a ponte atinja o timeout primeiro, com uma exceção tipada, em vez de um processo encerrado.

Se você usar o caminho de cliente injetado da PHP Standard Recommendation 18 (PSR-18) (sem responseFactory injetado ou com uma URL de Internet Protocol (IP) crua sem pins), a ponte não aplica o valor de timeout a esse cliente. Configure o timeout também no cliente PSR-18, para que ambos os transportes permaneçam limitados.

A ponte envia exatamente uma requisição por chamada e nunca faz novas tentativas. Adicione novas tentativas no chamador e faça isso com segurança:

  • Refaça a tentativa apenas para falhas no nível de transporte (uma GotenbergConvertException cuja causa é uma exceção de cliente PSR-18) e erros de servidor idempotentes (HTTP 502, 503, 504). Não refaça a tentativa para toda GotenbergConvertException de forma indiscriminada. Uma resposta da classe 400 geralmente significa que a entrada está incorreta; portanto, a mesma nova tentativa falhará da mesma forma.
  • Use backoff exponencial limitado com jitter. Quando um serviço de conversão sob carga retorna 503, sobrecarregá-lo piora a indisponibilidade.
  • Limite o total de tentativas e o tempo total de relógio. A conversão já é lenta; portanto, novas tentativas ilimitadas multiplicam a latência de cauda.
  • A revalidação ocorre automaticamente: cada chamada repetida reexecuta a validação da URL e a reverificação do endereço, de modo que uma nova tentativa não possa contornar acidentalmente a proteção contra server-side request forgery (SSRF).

Cada conversão mantém uma conexão e um worker do LibreOffice no lado do Gotenberg até que a requisição termine. A própria ponte é stateless e segura para uso por muitos workers ao mesmo tempo. Ainda assim, o serviço Gotenberg tem capacidade de conversão finita.

  • Limite o número de conversões em andamento no seu lado (com uma fila, um semáforo ou um pool de workers) à capacidade que o Gotenberg consegue sustentar. O dimensionamento depende da sua implantação do Gotenberg, não deste pacote; consulte /integrations/gotenberg/security-and-operations/.
  • O limite de tamanho da entrada (maxFileSize, padrão 50 MiB) é o único limite de recurso embutido da ponte. A ponte o aplica no processo antes de a requisição ser enviada, de modo que um arquivo grande demais nunca consuma capacidade do serviço. Reduza-o para corresponder ao que os documentos realmente precisam; um limite menor é um controle de negação de serviço mais barato do que um limite maior.
  • Não há cache no processo. Se você converter o mesmo documento repetidamente, faça cache do Portable Document Format (PDF) resultante na aplicação, indexado por um hash de conteúdo da entrada.

Injete um logger da PHP Standard Recommendation 3 (PSR-3) para obter uma entrada debug para cada requisição de conversão. A entrada contém a URL da requisição, o nome do arquivo, o formato detectado e o tamanho do conteúdo da requisição. Ela não contém o conteúdo do arquivo nem o bearer token.

  • Transforme esse sinal em uma métrica: conte conversões por formato e resultado, e registre o tempo de relógio em torno de cada chamada convertFile() / convertString() como histograma de latência. A ponte não emite métricas por conta própria.
  • O objeto de resultado expõe um campo renderTimeMs. Ele é 0.0 a menos que a integração o meça e o defina; a ponte não o preenche a partir da resposta do Gotenberg. Cronometre a chamada você mesmo se precisar do valor.
  • Registre exceções com o tipo delas. O tipo da exceção é o sinal principal do que falhou; consulte /integrations/gotenberg/troubleshooting/ para o catálogo.
  • Sonde isAvailable() a partir do seu endpoint de readiness ou de health, não em cada conversão. Ela envia um HEAD para /health. Executá-la antes de cada conversão dobra a taxa de requisições ao serviço sem nenhum benefício.

A ponte expõe falhas como exceções tipadas e nunca retorna resultado parcial ou não validado. Ela garante o seguinte:

  • Um status diferente de 200, um Content-Type sem application/pdf ou um corpo que não começa com %PDF levanta uma GotenbergConvertException. A ponte retorna um objeto de resultado somente quando todas as três verificações passam.
  • Uma falha de cliente PSR-18 (incluindo uma falha de rede ou timeout) é encapsulada como uma GotenbergConvertException, com a exceção original como causa e o código do cliente como código da exceção.
  • Falhas de validação (URL não HTTPS, endereço private/reserved, entrada grande demais, nome de arquivo inseguro) levantam RuntimeException antes de qualquer tráfego de rede.
  • Uma extensão de arquivo não reconhecida levanta ValueError antes de qualquer tráfego de rede.

Capture os tipos específicos. O programa de exemplo em examples/convert-office-to-pdf.php mostra a ordem exaustiva de captura. /integrations/gotenberg/troubleshooting/ explica cada gatilho.

A ponte produz um PDF e para aí. Um pipeline de produção comum é:

  1. Converta o documento Office com esta ponte.
  2. Carregue os bytes resultantes em um documento NextPDF.
  3. Aplique o pós-processamento: montagem de páginas, marca d’água, conversão para Portable Document Format/Archive (PDF/A) e assinaturas digitais.

O passo 3 pertence ao NextPDF, não à ponte. nextpdf/premium fornece assinatura, perfis PDF/A e marca d’água. Mantenha a conversão e o pós-processamento como estágios separados, para poder diagnosticar uma falha de conversão independentemente de uma falha de assinatura.

O suporte da edição Pro a PDF Advanced Electronic Signatures (PAdES) é apenas o baseline B-B. Ela não fornece B-T, B-LT ou B-LTA, e esses perfis não são implicados por converter um documento através desta ponte. A capacidade de validação de longo prazo é uma questão de edição separada e está fora do escopo deste pacote.

  • /integrations/gotenberg/configuration/ - regras de seleção de transporte e modelo de pins.
  • /integrations/gotenberg/security-and-operations/ - implantação e hardening da dependência Gotenberg.
  • /integrations/gotenberg/troubleshooting/ - o catálogo de exceções.
  • /integrations/gotenberg/integration/ - conexão do PDF convertido a um pipeline NextPDF.