Magento 2 e New Relic: achando requests lentos em produção
Quando uma loja Magento 2 está lenta em produção, chutar sai caro. O New Relic APM mostra quais transações estão lentas, em quais queries SQL e chamadas externas elas gastam tempo e se um deploy mudou alguma coisa. Este artigo cobre como configurar o New Relic para o Magento Open Source e o Adobe Commerce 2.4.8, o que o módulo de reporting nativo faz e o que não faz, e como ler os dados para achar problemas reais.
Duas peças separadas
As pessoas costumam misturar duas coisas que levam o nome New Relic no Magento:
- O agent PHP do New Relic. Uma extensão PHP mais um daemon instalados em cada servidor. É ele que coleta tempos de transação, traces, SQL e chamadas externas. Ele conhece o Magento 2 como framework e nomeia as transações pelo controller ou pela rota que as atendeu.
- O módulo Magento_NewRelicReporting. Um módulo do core que, quando habilitado, envia ao New Relic eventos extras do Magento, como deploys, atividade do admin e contagens baseadas em cron, e pode definir o nome da aplicação por área. É um complemento. Ele não faz o profiling.
Você tira a maior parte do valor só com o agent. O módulo é útil, mas opcional.
Instalando o agent
Instale o agent pelo repositório de pacotes do New Relic para a sua distribuição e rode o instalador, que pede a license key e grava um arquivo ini para cada versão de PHP que encontrar. Depois confira as configurações no newrelic.ini gerado:
extension = "newrelic.so"
newrelic.enabled = true
newrelic.license = "YOUR_LICENSE_KEY"
newrelic.appname = "Shop Production"
newrelic.framework = "magento2"
newrelic.transaction_tracer.enabled = true
newrelic.transaction_tracer.detail = 1
newrelic.transaction_tracer.record_sql = "obfuscated"
newrelic.transaction_tracer.slow_sql = true
newrelic.distributed_tracing_enabled = true
A detecção do framework costuma ser automática, mas definir explicitamente evita surpresas. O record_sql = "obfuscated" troca os valores literais das queries por placeholders, então e-mails e endereços de clientes não vão parar na sua conta do APM. Mantenha assim.
Dê reload no PHP-FPM depois de instalar. O agent conversa com o newrelic-daemon local, que encaminha os dados ao New Relic, então confira se o daemon está rodando.
Um nome de app por ambiente
Use nomes de app diferentes para produção e staging. Misturar os dois gera médias que não descrevem nenhum. Você também pode definir o nome do app por pool do FPM com php_value[newrelic.appname] na config do pool, o que ajuda quando admin e storefront rodam em pools separados.
Habilitando o módulo de reporting
As configurações do módulo ficam em Stores, Configuration, General, New Relic Reporting. Você precisa de uma API key e dos dados da conta no New Relic. Habilitado, ele pode:
- Registrar deployment markers para você ver cada deploy nos gráficos.
- Reportar a aplicação com nomes diferentes para frontend e admin, quando você escolhe enviá-los como apps separados.
- Enviar contagens periódicas por um cron, por exemplo de dados de catálogo e de clientes.
Os deployment markers são a parte que acho mais útil. Um marker de deploy no gráfico de tempo de resposta transforma "o site ficou mais lento na semana passada" em "o site ficou mais lento logo depois do release de terça". O módulo também traz um comando de CLI para isso, o bin/magento newrelic:create:deploy-marker, que você pode chamar do script de deploy. Rode bin/magento newrelic:create:deploy-marker --help na sua versão para ver os argumentos exatos que ele aceita.
Lendo a lista de transações
No APM, abra a visão de transações e ordene por most time consuming, não pela maior média. Uma transação com média alta mas pouquíssimas chamadas é só uma curiosidade. A que consome mais tempo total é para onde vai a capacidade do seu servidor.
No Magento, as entradas do topo costumam ser:
- Controllers de categoria e de produto, quando não são servidos em cache pelo Varnish.
- Carregamentos de customer data sections, a rota
customer/section/load, que nunca entram no full page cache. - Rotas de carrinho e checkout, incluindo as chamadas REST que o checkout faz para estimar frete e totais.
- GraphQL, se você roda um storefront headless.
- Rotas do admin e chamadas à API REST vindas de integrações.
Se páginas de categoria aparecem no alto da lista e você roda Varnish, a primeira pergunta é por que tantas delas chegam ao PHP. Isso é problema de taxa de cache hit, não de PHP.
Transaction traces
É nos traces que está o detalhe. O trace de um request lento mostra uma árvore do tempo gasto: quais segmentos do request levaram quanto tempo, qual SQL rodou, quais chamadas HTTP saíram. Com transaction_tracer.detail = 1, o agent grava mais segmentos no nível de função. Procure:
- Uma query repetida muitas vezes. Uma product collection carregada dentro de um loop, ou um
getByIdde repository dentro de um foreach. O trace mostra o mesmo SQL com uma contagem alta de chamadas. É o clássico problema N+1. - Chamadas externas. Um block que chama uma API de frete, um serviço de imposto ou um motor de recomendação durante o render da página. Se esse serviço está lento, sua página está lenta. Essas chamadas devem ser cacheadas ou tiradas do render da página.
- Tempo no Redis ou na sessão. Esperas longas na leitura da sessão geralmente significam session locking com requests paralelos do mesmo navegador.
- Muito tempo não instrumentado. Tempo que não é SQL nem externo, só PHP. Aí um profiler como o Blackfire dá mais detalhe.
Instrumentação customizada
O agent expõe funções PHP que você pode chamar do seu próprio código. Proteja sempre com extension_loaded('newrelic'), porque ambientes locais e de CI não têm a extensão.
<?php
declare(strict_types=1);
namespace Vendor\ErpSync\Model;
class OrderExporter
{
public function export(int $orderId): void
{
if (extension_loaded('newrelic')) {
newrelic_add_custom_parameter('order_id', $orderId);
}
// export logic
}
}
Parâmetros customizados aparecem nos traces e nas queries, então você consegue achar a exportação lenta de um pedido específico. Não adicione dados pessoais como parâmetros.
As funções úteis para trabalho com Magento são newrelic_add_custom_parameter, newrelic_name_transaction para dar um nome com sentido ao que o agent nomeia mal, newrelic_background_job para marcar trabalho de CLI como não web, e newrelic_notice_error para reportar uma exceção tratada que você ainda quer ver.
Cron e consumers de queue
Jobs de cron e consumers de message queue rodam pelo PHP CLI. Se o agent os reporta depende de a extensão estar carregada e habilitada no CLI. Eles aparecem como transações não web. Essa visão costuma ser mais reveladora que o lado web, porque um indexer lento ou um consumer que reconecta ao banco a cada mensagem pode sobrecarregar o servidor de banco e atrasar todos os requests web junto.
Consumers de longa duração são um caso especial. Um processo pode rodar por horas, e o agent trata a execução inteira como uma única transação, a menos que você a divida. Se precisar de tempos por mensagem em um consumer customizado, marque você mesmo os limites da transação com newrelic_end_transaction e newrelic_start_transaction. O guia de consumers do RabbitMQ explica como os consumers rodam.
Alertas que valem a pena
Algumas condições de alerta pegam a maioria dos incidentes cedo:
- Apdex ou tempo de resposta nas transações de checkout e carrinho, não só na média geral.
- Taxa de erro acima de um limite.
- Throughput caindo para perto de zero, o que muitas vezes significa que o site caiu ou que uma camada de cache está servindo erros.
- Tempo de banco por request subindo, o que muitas vezes vem antes de uma queda total.
O que o New Relic não mostra
O APM mostra o comportamento em produção com tráfego real, e essa é sua força. Mas ele trabalha por amostragem, e os traces não mostram toda chamada de função. Para um call graph detalhado de um request lento, use um profiler. Falo disso no guia de profiling com Blackfire. Para o lado de banco dos problemas que você encontrar, veja ajuste de MySQL para o Magento.
FAQ
Preciso do módulo New Relic do Magento para usar o New Relic APM?
Não. O agent PHP coleta transações, traces e SQL sozinho. O módulo do Magento adiciona deploy markers, nomes de app por área e alguns relatórios extras.
Como vejo os deploys do Magento no New Relic?
Habilite o New Relic Reporting na config do Magento e chame bin/magento newrelic:create:deploy-marker do seu script de deploy, ou crie o marker direto pela API do New Relic.
O New Relic grava dados de clientes das queries SQL?
Com transaction_tracer.record_sql em obfuscated, os valores literais são trocados por placeholders. Mantenha essa configuração e não adicione dados pessoais como parâmetros customizados.
Quanto overhead o agent do New Relic adiciona?
Ele adiciona algum overhead a cada request, e o tracing detalhado adiciona mais. A maioria das lojas roda em produção sem problema, mas meça no seu setup se estiver perto da capacidade.
Atendo como freelancer em Magento e Adobe Commerce, incluindo investigações de performance. Se precisar de ajuda com isso, fale comigo.
Artigos relacionados
Magento 2: tipos de cache, clean, flush e cache type próprio
O que cada cache type do Magento 2 guarda, a diferença real entre cache:clean e cache:flush, caches invalidados e como criar seu próprio cache type.
Core Web Vitals no Magento 2: como corrigir LCP, INP e CLS
Onde lojas Magento 2 com Luma perdem nos Core Web Vitals e como corrigir LCP, INP e CLS: resposta do servidor, CSS, fontes, imagens, galeria e scripts de terceiros.
Ajuste do PHP-FPM no Magento 2: workers, OPcache, php.ini
Dimensione os pools do PHP-FPM para o Magento 2, escolha o process manager certo, configure o OPcache para um codebase grande e evite os erros de php.ini que deixam a loja lenta.
Atributos de produto no Magento 2: boas práticas para um catálogo limpo
Como projetar atributos de produto no Magento 2: input types, scope, flags de busca e filtro, attribute sets, data patches e limpeza de atributos sem uso.