Install
(For Java11at least version 1.5 is needed) Download Async Profiler from: https://github.com/jvm-profiling-tools/async-profiler
wget https://github.com/jvm-profiling-tools/async-profiler/releases/download/v1.7.1/async-profiler-1.7.1-linux-x64.tar.gz mkdir /opt/async-profiler tar xvzf async-profiler-*-linux-x64.tar.gz -C /opt/async-profiler
Since Kernel 4.6 the following commands must be executed as root on the system to enable profiling
echo 1 > /proc/sys/kernel/perf_event_paranoid echo 0 > /proc/sys/kernel/kptr_restrict
Usage
Find the HiveMQ process id (must be user root or user hivemq)
#Java Process ID Tool jps #or #ps with filter for only pid and only processes by user hivemq ps -u hivemq -o pid= #or #always works ps aux | grep hivemq
Run profiler.sh (-d is the duration of the recording in seconds)
/opt/async-profiler/profiler.sh -d 600 -f /(absolute path)/flamegraph.svg <hivemq process id>
You need to make sure that all async-pofiler files belong to the same user that is running the HiveMQ process and that you start the profiler.sh script as that user.
Quick command (can be run as root, only works if hivemq is the only process running for user `hivemq`)
/opt/async-profiler/profiler.sh -d 600 -f /opt/hivemq/flamegraph.svg `ps -u hivemq -o pid=`
Kubernetes / Docker
As usual, container platforms have some paranoid settings that are read-only. On the up side, we can leverage the fact that HiveMQ is always PID 1 in containers (unless shared namespaces are used in K8s):
Here's an idempotent block you can simply execute to generate a flamegraph in a container:
curl -L https://github.com/jvm-profiling-tools/async-profiler/releases/download/v1.7.1/async-profiler-1.7.1-linux-x64.tar.gz > async.tar.gz tar xfvz async.tar.gz rm -f flame.svg ./profiler.sh -d 60 -f $(pwd)/flame.svg 1 --all-user -e alloc
Then use kubectl cp or docker cp to copy the graph from the container.
systemd
Alternative: When using systemd, you can simply use
systemctl show --property MainPID hivemq | sed -e "s/MainPID=//"
Using async profiler in the systemd unit (start with HiveMQ):
sed -i -e "s|-Djava.net.preferIPv4Stack=true|-Djava.net.preferIPv4Stack=true -agentpath:/opt/async-profiler/build/libasyncProfiler.so=start,svg,file=flamegraph.svg|" /opt/hivemq/bin/run.sh