Есть ли способ начать мониторинг / запись JFR с пульта через код? - PullRequest
3 голосов
/ 18 апреля 2019

Я использую Jmeter, чтобы выполнить нагрузочный тест, используя плагин Ant. В настоящее время захватывает метрики JVM сервера во время теста с использованием режима графического интерфейса JFR для каждого узла. Для каждого узла неудобно начинать, а иногда его не хватает для запуска. Есть ли способ начать делать их вместе с помощью кода?

Данные клиента

Точка доступа JDK 1.8_131, Mac OS, Jmeter 4,0

Данные сервера

Точка доступа 1.8.0_152, OEL, Tomcat

В интернете я получаю опции для запуска JFR программно на серверном узле, что мне не подойдет.

1 Ответ

4 голосов
/ 19 апреля 2019

Если у вас есть терминальный доступ, вы можете создать скрипт и начать запись, используя инструмент командной строки jcmd.

$ jcmd <class/jarfile> VM.unlock_commercial_features
$ jcmd <class/jarfile> JFR.start

или

$ jcmd (to list available pids)
$ jcmd <pid> VM.unlock_commercial_features
$ jcmd <pid> JFR.start

Подробнее см. Пример 2-1. Динамическое взаимодействие с использованием jcmd

Если вы не можете получить доступ к серверу по SSH или не хотите делать это в оболочке, вы можете использовать JMX и отправлять те же команды, что и команды диагностики.

В JMC в консоли Management / JMX вы можете проверить MBean-компоненты на сервере. Там вы найдете MXBean «com.sun.management / DiagnosticCommand» и операции, против которых вы можете написать код. Имя объекта - com.sun.management:type=DiagnosticCommand, и вам нужно вызвать его с помощью jfrStart.

Вы можете настроить соединение следующим образом.

String host ="myHost";
int port = 1234;
HashMap map = new HashMap();
String[] credentials = new String[2];
credentials[0] = user;
credentials[1] = password;
map.put("jmx.remote.credentials", credentials);
String s = "/jndi/rmi://" + host + ":" + port + "/jmxrmi";
JMXServiceURL url = new JMXServiceURL("rmi", "", 0, s);
JMXConnector c= JMXConnectorFactory.newJMXConnector(url, map);
c.connect();
MBeanServerConnection conn = c.getMBeanServerConnection();

Если вы не заботитесь о безопасности, вы можете установить карту на ноль. Затем вы создаете имя объекта и вызываете операцию, которую хотите выполнить, например:

ObjectName on = new ObjectName("com.sun.management:type=DiagnosticCommand"); 
Object[] args = new Object[] {
    new String[] {
        "dumponexit=true",
        "filename=/recordings/rec.jfr",
        "duration=600s"
    }
};
String[] sig = new String[] {"[Ljava.lang.String;"};
conn.invoke(on, "jfrStart", args, sig);

В JDK 9 и более поздних версиях есть FlightRecorderMXBean , который можно использовать для удаленного доступа (включая загрузку записи), но если вы застряли в JDK 8, я бы сделал выше. В Oracle JDK 8 также есть MBean, но он не поддерживается, недокументирован, и для его работы требуется черная магия.

...