Começar pelo intervalo e pela identidade
Num portal fictício de operações, a latência aumenta durante uma importação. Antes de recolher mais dados, regista o período do impacto, os membros afetados e o tipo de pedido. Liga cada ficheiro ao host, perfil, PID e instância do processo. Dois dumps com o mesmo nome de servidor não têm necessariamente a mesma origem; um reinício pode reutilizar nomes de threads e até identificadores. Mantém tempos e fusos coerentes e assinala amostras que não são simultâneas. A primeira pergunta é se os dados podem ser comparados. Só depois calcula diferenças. Esta disciplina evita uma explicação convincente baseada em contadores que pertencem a vidas diferentes do processo.
Usar diferenças, não totais antigos
A CPU acumulada descreve trabalho desde o início do contador. Para uma thread contínua, subtrai o valor inicial ao final e divide pelo tempo decorrido. No exemplo, 14,4 menos 12,0 dá 2,4 segundos de CPU; numa janela de quatro segundos, isso representa 60% de um core lógico. Declara essa normalização, pois não equivale a 60% da máquina inteira. Um processo com várias threads pode consumir oito segundos de CPU em cinco segundos de relógio, usando cores em paralelo. Se a soma das threads observadas não coincide com o processo, verifica cobertura e alinhamento. Não atribuas automaticamente o resto a uma fuga, a GC ou a uma thread que não foi identificada.
Uma stack localiza trabalho, não prova a causa
Três snapshots mostram parseDocument na mesma thread, com incremento elevado de CPU. Isso justifica investigar esse caminho, mas não prova um loop infinito: um documento grande pode exigir trabalho legítimo durante todo o intervalo. Procura progresso do pedido, dimensão da entrada, tempo esperado e outras evidências que distingam hipóteses. O estado Runnable também não mede por si só o consumo real nem o avanço funcional. No sentido oposto, pouca CPU não significa serviço saudável: threads podem estar à espera de base de dados, rede ou outro recurso. Uma leitura JDBC deve ser correlacionada com sessões e tempos do backend. Se a base confirma um lock comum, essa observação orienta a investigação conjunta.
Recolher para responder a uma hipótese
Antes de pedir nova recolha, escreve a hipótese e o resultado que a enfraqueceria. Para CPU, uma série comparável pode mostrar se o mesmo trabalho continua ativo. Para espera JDBC, a equipa da base pode confirmar duração, bloqueador ou conclusão da consulta. Para uma falha reproduzível, trace dirigido numa janela curta pode ligar o pedido ao componente, com limites de volume e desativação definida. Não existe overhead universal: a instrumentação pode perturbar o sistema que se está a medir. Identifica o runtime e o nível de manutenção antes de escolher comandos ou opções. Esta aula usa tabelas sintéticas; não executa comandos WebSphere, não recolhe dumps e não demonstra uma janela segura no teu ambiente.
Laboratório com dados sintéticos
Lê a tabela abaixo sem procurar primeiro uma solução. A thread import-A tem o maior incremento nesta janela; report-B tem o maior total histórico. Calcula 60% e 2,5% de um core, respetivamente. Depois imagina que a instância do processo muda entre t0 e t1: nenhum desses cálculos mantém validade apenas porque o nome da thread coincide. Altera também o contador final para um valor inferior ao inicial e marca descontinuidade, em vez de aplicar valor absoluto ou substituir por zero. O laboratório verifica aritmética e interpretação de evidência. Não é um parser de javacore, não mede um processo real e não identifica qual rotina de negócio causou o incidente.
Comunicar mitigação e validar recuperação
Retirar um membro lento pode baixar a latência global enquanto o problema desse membro continua intacto. Comunica o que foi observado: impacto reduzido, capacidade restante validada para a carga atual e causa por investigar. Compara volume, erros e latência por membro e por classe de pedido em janelas equivalentes. Um agregado melhor pode refletir apenas a mudança de população. Define critérios de reentrada com quem opera o serviço: verificação funcional, dependências, capacidade, acompanhamento e limites de recuo. O estado started da JVM não basta. Fecha o diagnóstico apenas quando a evidência sustentar a conclusão e conserva a distinção entre hipótese, mitigação, correção e validação no registo do incidente.
SYNTHETIC EVIDENCE; not output from a WebSphere instance
process_instance: node-A/server1/start-2026-10-01T09:00Z
elapsed_seconds: 4
thread_identity | cpu_seconds_t0 | cpu_seconds_t1
import-A | 12.0 | 14.4
report-B | 500.0 | 500.1
one_core_percent = (cpu_seconds_t1 - cpu_seconds_t0) / elapsed_seconds * 100
Um contador histórico de 500 segundos parece alarmante, mas acrescenta só 0,1 segundos. A thread com total menor é a que consome mais CPU agora.
Armadilhas comuns
Ordenar apenas por CPU acumulada, subtrair contadores de processos diferentes, confundir frame repetida com loop e declarar recuperação só pelo indicador agregado.
Tópicos relacionados: JDBC, pools e resultados transacionais · JVM, logs e diagnóstico temporal · Manutenção, recuperação e passagem a RUN
Uma boa linha temporal liga identidade, diferença de contadores e progresso funcional; as conclusões não devem ultrapassar a evidência observada.
Referência: J9 javacore and memory diagnosis · DR WebSphere traditional ND 9.0.5; maintenance baseline 9.0.5.29 (2026-09-08); documentation reviewed 2026-09-30