Estou tentando medir a latência entre meu publicador Java e um corretor de mensagens Cpp (padrão do setor).
O broker registra o horário em que recebe cada mensagem e, para o publicador Java, estou usando o seguinte código para obter registros de data e hora com precisão de microssegundos (que são gravados na mensagem de saída):
private static final long NANOTIME_OFFSET;
static {
Instant instant = Instant.now(); // Get absolute time
long nanoTime = System.nanoTime(); // Get relative time
// Offset to convert from relative to absolute time
NANOTIME_OFFSET = TimeUnit.SECONDS.toNanos(instant.getEpochSecond()) + instant.getNano() - nanoTime;
}
public static long currentTimeNanos() {
return System.nanoTime() + NANOTIME_OFFSET;
}
No entanto, estou percebendo que a latência medida entre o publicador e o corretor aumenta ao longo do dia e não diminui até que eu reinicie meu publicador Java.
A latência começa em <<1 ms e, de repente, salta para 500 ms. Saltos subsequentes a aproximam da marca de 1 segundo, o que é difícil de acreditar, visto que ambos os processos residem na mesma máquina.
A criação de perfil com o VisualVM indica que não há problemas de recursos no meu processo Java, e a captura de pacotes com o Wireshark confirma que o problema está nos registros de data e hora produzidos por currentTimeNanos()
.
Então por que System.nanoTime()
perde precisão ao longo do dia?
Acho que a coisa correta a fazer é sempre usar Instant.now()
, mas é uma chamada mais pesada que System.nanoTime()
(gera um novo Instance
objeto toda vez), então adicionaria mais sobrecarga, especialmente com um alto volume de mensagens.
Editar: Eu também acrescentaria que optei por um nanoTime()
relógio baseado em -, já que Instance.now()
só produzia precisão de milissegundos na minha máquina