Свойство nanoThreadSleep в JMeter — как его использовать?

Я настраиваю решение для нагрузочного тестирования, и, прочитав документацию JMeter, я вижу, что вы можете установить множество свойств для планов тестирования. У меня есть тесты, которые уже работают нормально и дают результаты, графики и т. д., но когда я пытался получить более глубокое понимание JMeter и точности результатов и т. д., я наткнулся на аннотацию ниже.

Из документации JMeter я прочитал следующее:

# Whether to use System.nanoTime() - otherwise only use System.currentTimeMillis()
sampleresult.useNanoTime=true

# Use a background thread to calculate the nanoTime offset
# Set this to <= 0 to disable the background thread
sampleresult.nanoThreadSleep=5000

Теперь я понимаю, что nanotime будет основано на фиксированном, но произвольном исходном времени, тогда как currenttimeinmillis основано на системном времени (т. е. на настенных часах). И я знаю, что nanotime будет более точным, поэтому я заинтересован в его использовании: я провожу нагрузочное тестирование и мне нужно, чтобы измерения времени отклика были максимально точными и точными.

Но проблема, с которой я столкнулся, заключается в том, чтобы понять, как использовать nanoThreadSleep. Что такое нановременное смещение? Почему я хочу или не хочу, чтобы фоновый поток вычислял смещение нановремени? Что произойдет, если я включу JMeter для работы с использованием nanotime, но не использую параметр nanoThreadSleep явно?

Я искал в StackOverflow и Google какое-то объяснение, но я не могу найти ничего, кроме того, что говорится об этом в документации JMeter в крошечной аннотации, которую я вставил сюда. Могут ли другие помочь мне понять это и как я могу использовать это правильно и эффективно?


person liltitus27    schedule 05.03.2015    source источник


Ответы (1)


Глядя на код JMeter, я обнаружил, что раздел ниже представляет интерес. Таким образом, фоновый поток спит в течение NANOTHREAD_SLEEP миллисекунды, а затем, когда он просыпается, он спрашивает время.

Это значение должно оставаться как можно более высоким, чтобы не увеличивать нагрузку на выборку, но должно оставаться как можно более низким, чтобы обеспечить достаточную точность.

Если вы не используете нанопоток, то все время вычисляется с помощью System.nanoTime(), и это может дать или не дать дополнительную точность. Как правило, на высокоточные счетчики очень сильно влияют изменения частоты (например, из-за режимов энергосбережения). Я считаю, что вам не нужно беспокоиться об использовании System.nanoTime(), потому что вы не сможете обеспечить воспроизводимость теста с точностью на уровне наносекунд. Даже миллисекунда кажется очень коротким интервалом для этого.

Зачем использовать фоновый поток для вычисления времени? Я думаю, это потому, что если поток измеряет только время, вы можете запросить у него текущее время в любое время во время выполнения. Если вы не используете фоновый поток, я думаю, что время обновляется только в точке выборки. Я думаю, что с включенным потоком время обновляется чаще (при условии, что NANOTHREAD_SLEEP хорошо продумано). Я не писал JMeter, но думаю, что это философия потока времени.

Полезно ли это? Вероятно, это может повысить точность. Однако JMeter используется для тестирования производительности веб-приложений, где воспроизводимость плохая из-за сетевых задержек, использования ресурсов и т. д.. Даже если вы измеряете наносекунды, людей больше будут интересовать секунды и миллисекунды, а также возможность повторения теста.

КОД:

private static class NanoOffset extends Thread {

    private static volatile long nanoOffset; 

    static long getNanoOffset() {
        return nanoOffset;
    }

    @Override
    public void run() {
        // Wait longer than a clock pulse (generally 10-15ms)
        getOffset(30L); // Catch an early clock pulse to reduce slop.
        while(true) {
            getOffset(NANOTHREAD_SLEEP); // Can now afford to wait a bit longer between checks
        }
    }

    private void getOffset(long wait) {
        try {
            TimeUnit.MILLISECONDS.sleep(wait);
            long clock = System.currentTimeMillis();
            long nano = SampleResult.sampleNsClockInMs();
            nanoOffset = clock - nano;
        } catch (InterruptedException ignore) {
            // ignored
        }
    }        
}
person VAndrei    schedule 22.03.2015
comment
отличный ответ. спасибо, что покопались в коде и ответили на каждый из моих вопросов. я иногда пропускаю лес из-за деревьев, и я думаю, что сделал это здесь, беспокоясь о точности до наносекундного уровня, когда, как вы сказали, мы больше смотрим на секунды, чем даже на миллисекунды, и тест должна быть воспроизводимой и точной, более чем точной на этом уровне. Еще раз спасибо! - person liltitus27; 23.03.2015