
O JVMM (JVM Monitor) é uma ferramenta que fornece monitoramento baseado em serviço de máquinas virtuais Java e sistemas operacionais. Possui ricos funções de aquisição de dados: OS (memória, CPU, status de disco e IO, status da placa de rede e IO, etc.), JVM (memória, threads, threads pool, pool de memória, GC, carregador de classe, etc.) e também é o que é o que é o que é o que é o que é o que é o que é o que é o que é o que é o que é o que é o que é o que é o que é o que é o que é o que é o que é o que é o que você está fazendo com exceão em geral, com o objetivo de avaliar a saúde e a quantidade de serviços de queda, o carregador de classe, o desempenho da gestão, o que é o que é necessário, como o desempenho, o que é o que é o que é um dos dados testes, etc.
Por favor, vá para lançamentos para baixar a versão mais recente do JVMM e descompactar
Dicas: Algumas funções do JVMM dependem do JDK no ambiente local. Certifique -se de instalar o JDK em vez de apenas JRE em seu ambiente. Verificação simples: execute
jps -lem seu ambiente. Se puder ser executado normalmente e emitir o resultado, significa que o ambiente está ok, caso contrário, o JVMM pode não ser capaz de ser executado.
Primeiro, execute o seguinte comando para gerar o pacote JAR de serviço
java -jar jvmm.jar -m jar -sEm seguida, inicie o servidor, preste atenção à sua versão JDK ao iniciar
# 启动server,jdk 8使用下面命令
java -jar jvmm-server.jar
# jdk 9+ 为确保成功运行建议使用下面命令
java -jar --add-opens java.base/jdk.internal.loader=ALL-UNNAMED
--add-opens jdk.zipfs/jdk.nio.zipfs=ALL-UNNAMED
--add-opens java.base/java.net=ALL-UNNAMED
--add-opens java.management/sun.management=ALL-UNNAMED
jvmm-server.jarSe o servidor JVMM for iniciado com sucesso, ele será executado na porta 5010 por padrão e você precisará configurar uma nova janela no diretório atual para executar:
java -jar jvmm.jar -m client -a 127.0.0.1:5010 Se a conexão do servidor for bem -sucedida, você entrará no modo cliente. Você pode inserir o seguinte comando para coletar dados de processo. Obviamente, você pode inserir help para visualizar o uso de todas as instruções executáveis neste modo.
info -t processAqui estão exemplos de dados coletados no modo de cliente JVMM. As funções fornecidas pelo JVMM são muito mais do que isso. Para mais funções, leia a documentação de uso do JVMM.
A função de aquisição de dados principal da JVMM está no módulo core , e a função orientada a serviço está no módulo server . De acordo com o seu cenário de uso, você pode escolher os dois métodos de uso a seguir:
core (mais funções) Primeiro de tudo, você precisa entender o que o servidor pode fazer? O servidor fornece três modos de serviço. Antes de usá -lo, qual você precisa escolher é mais adequado para você. Aqui estão os três modos de serviço:
Qualquer modo de serviço é inseparável a partir do arquivo de configuração JVMM.YML. server.type é usado para configurar qual modo ou qual modo você escolher. Eles podem correr ao mesmo tempo . As configurações específicas de cada modo correspondem ao server.jvmm , server.http e server.sentinel .
server :
type : jvmm,http,sentinel # 支持同时开启多种模式
jvmm :
# ...
http :
# ...
sentinel :
# ...Para a configuração padrão, consulte JVMM.yML e para obter informações de configuração, consulte os comentários no arquivo de configuração.
O JVMM fornece quatro maneiras de iniciar seu servidor:
-javaagent )jvmm-server.jar (decompilação e atualização de código de código não suportam)Perceber! ! !
Não importa de que maneira você inicie o servidor, se o seu ambiente de execução for JDK 9+ ou acima, é recomendável adicionar os seguintes parâmetros da JVM na inicialização para garantir uma operação bem -sucedida.
--add-opens java.base/jdk.internal.loader=ALL-UNNAMED
--add-opens jdk.zipfs/jdk.nio.zipfs=ALL-UNNAMED
--add-opens java.base/java.net=ALL-UNNAMED
--add-opens java.management/sun.management=ALL-UNNAMED
Execute JVMM.Jar e selecione Modo Anexar
java -jar jvmm.jar -m attach -c ./jvmm.ymlEm seguida, você será solicitado a selecionar o número do processo de destino. Após a seleção, o servidor será iniciado no processo de destino.
Se você já conhece o PID do processo de destino, pode especificá -lo diretamente:
java -jar jvmm.jar -m attach -c ./jvmm.yml -pid 80080
No método do agente Java, você precisa criar o pacote JAR necessário e usar o parâmetro -a para especificar o agent de geração:
# 如果你的宿主程序中包含了 SLF4J 的实现(例如 logback),需要在生成时使用 -e 参数排除掉jvmm自带的 slf4j 实现
java -jar jvmm.jar -m jar -a -e logger
# 如果你的宿主程序中没有 SLF4J 的实现,无需排除 logger
java -jar jvmm.jar -m jar -a Após a execução, o arquivo correspondente será gerado no mesmo diretório de nível: jvmm-agent.jar e, em seguida, -javaagent é adicionado ao iniciar o programa de destino (assumindo que ele seja app.jar). O formato é o seguinte:
java -javaagent:<jvmm-agent.jar路径>=config=<jvmm.yml路径> -jar your-app.jar
Por exemplo:
java -javaagent:/path/jvmm-agent.jar=config=/path/jvmm.yml -jar app.jarPara ser compatível com a funcionalidade do uso de servidores externos, o formato Javaagent completo é:
-javaagent:<jvmm-agent.jar路径>=server=<jvmm-server.jar路径>;config=<jvmm.yml路径>
Quando o seu programa começar, o JVMM começará como um agente

Se você não deseja ser anexado a nenhum programa host, pode optar por iniciar um servidor JVMM separadamente, como no cenário de monitorar uma máquina física.
Primeiro, você precisa gerar a dependência do jar inicial e usar o parâmetro -s para especificar o server de geração:
java -jar jvmm.jar -s Após a conclusão da execução, um jvmm-server.jar será gerado no mesmo diretório e o servidor será iniciado. Por favor, preste atenção à sua versão JDK ao iniciar.
# 启动server,jdk 8使用下面命令
java -jar jvmm-server.jar
# jdk 9+ 为确保成功运行建议使用下面命令
java -jar --add-opens java.base/jdk.internal.loader=ALL-UNNAMED
--add-opens jdk.zipfs/jdk.nio.zipfs=ALL-UNNAMED
--add-opens java.base/java.net=ALL-UNNAMED
--add-opens java.management/sun.management=ALL-UNNAMED
jvmm-server.jarSe você deseja usar o servidor em seu projeto, você precisa primeiro introduzir dependências mavenes
< dependencies >
< dependency >
< groupId >io.github.tzfun.jvmm</ groupId >
< artifactId >jvmm-server</ artifactId >
< version >${jvmm-version}</ version >
</ dependency >
<!-- jvmm日志依赖,如果你的项目中有 SLF4J、Log4J2、Log4J中任意一个依赖,可以去掉此依赖 -->
< dependency >
< groupId >io.github.tzfun.jvmm</ groupId >
< artifactId >jvmm-logger</ artifactId >
< version >${jvmm-version}</ version >
</ dependency >
</ dependencies >Inicie o servidor com uma linha de código
import org . beifengtz . jvmm . server . ServerBootstrap ;
public class Jvmm {
public static void main ( String [] args ) {
ServerBootstrap . getInstance (). start ();
}
} Obviamente, o método de inicialização acima usará a configuração padrão e geralmente requer configuração personalizada. getInstance pode passar para um objeto org.beifengtz.jvmm.server.entity.conf.Configuration . A configuração personalizada pode ser implementada pela construção da configuração.
Connect jvmm server serverconveydemo.java usando jvmmconnector
Quando o servidor é iniciado no modo jvmm ou http , você pode chamar remotamente a interface embutida.

O serviço JVMM fornece as seguintes interfaces da API:
| Tipo | Dados | Descrição |
|---|---|---|
| Jvmm_collect_sys_info | / | Colete informações do sistema operacional |
| Jvmm_collect_sys_memory_info | / | Colete dados de memória do sistema operacional |
| Jvmm_collect_sys_file_info | / | Colete dados de uso de partição de disco do sistema operacional |
| Jvmm_collect_process_info | / | Colete dados de processo atuais |
| Jvmm_collect_disk_info | / | Colete dados de disco da máquina física |
| Jvmm_collect_disk_io_info | / | Colete o disco IO e dados de rendimento da máquina física |
| Jvmm_collect_cpu_info | / | Colete dados de carregamento da CPU da máquina física |
| Jvmm_collect_network_info | / | Colete informações físicas para cartão de rede e dados de IO |
| JVMM_COLLECT_PORT_STATUS | JsonArray, cujo elemento é o número da porta | Colete o uso da porta da máquina física |
| Jvmm_collect_jvm_classloading_info | / | Colete informações de carregamento da classe JVM |
| Jvmm_collect_jvm_classloader_info | / | Colete informações do carregador de classe JVM |
| Jvmm_collect_jvm_compilation_info | / | Colete informações de compilação da JVM |
| JVMM_COLLECT_JVM_GC_INFO | / | Colete informações de coletor de lixo JVM |
| Jvmm_collect_jvm_memory_manager_info | / | Reúna informações do gerenciador de memória JVM |
| Jvmm_collect_jvm_memory_pool_info | / | Colete informações do pool de memória JVM |
| Jvmm_collect_jvm_memory_info | / | Colete o uso da memória da JVM |
| Jvmm_collect_jvm_thread_info | / | Colete estatísticas de threads JVM |
| Jvmm_collect_jvm_thread_stack | Veja ThreadInfodto | Colete os dados especificados da pilha de threads jvm |
| Jvmm_collect_jvm_thread_detail | JsonArray, cujo elemento é ID do thread | Colete detalhes do thread JVM (tempo da CPU, tempo de bloco, bloqueios, etc.) |
| Jvmm_collect_jvm_thread_pool | JsonObject, suas propriedades são: ClassloaderHash (String), Clazz (String), ExtantyField (String), Field (String) | Colete informações do pool de threads JVM |
| Jvmm_collect_jvm_thread_ordered_cpu_time | JsonObject, suas propriedades são: tipo (string, pilha | info), durações e segundos (int) | Aquisição de uso da CPU em threads de JVM dentro de um determinado momento |
| Jvmm_collect_jvm_dump_thread | / | despejar todos os dados da pilha de threads |
| Jvmm_collect_batch | Coleção | Coleta de dados em lotes com base em opções |
| JVMM_EXECUTE_GC | / | Executar gc |
| JVMM_EXECUTE_JAVA_PROCESS | / | Liste todos os processos Java |
| JVMM_EXECUTE_JVM_TOOL | Corda | Execute o comando da ferramenta JVM |
| JVMM_EXECUTE_JAD | JsonObject, suas propriedades são: ClassName (String), MethodName (String) | Decompilação de código (somente agentes são suportados) |
| Jvmm_execute_load_patch | JsonArray, cujo elemento é patchdto | Código Atualizações Hot. Ao especificar o hash de classe de classe, são apenas atualizações quentes para alterar a classe carregada pelo Classloader. |
| Jvmm_execute_switches_get | / | Obtenha as informações da chave de aquisição |
| Jvmm_execute_switches_set | JsonObject, suas propriedades são: nomes (switches []), aberto (booleano) | Configure o interruptor de aquisição |
| Jvmm_profiler_sample | Veja ProfilersMpledTo | Gerar mapa de chama |
| JVMM_PROFILER_EXECUTE | Corda | Execute o comando Profiler, veja async-Profiler |
| Jvmm_profiler_start | Veja ProfilersMpledTo, onde apenas eventcounterinteval é válido | Executar o comando de amostragem para iniciar o Profiler |
| JVMM_PROFILER_STOP | String, Format Field em ProfilersMpledTo, o valor opcional é htmltxtjfr | Execute o Profiler para encerrar o comando de amostragem e exportação do arquivo |
| Jvmm_profiler_status | / | Obtenha o status atual do Profiler |
| Jvmm_profiler_list_events | / | Obtenha os eventos do Profiler apoiados pelo ambiente atual |
| JVMM_SERVER_SHUTDOWN | Corda | Fechar o serviço, os dados são do tipo de serviço |

O serviço HTTP fornece as seguintes interfaces da API:
| Uri | método | parâmetro | Corpo | descrever |
|---|---|---|---|---|
| /colecionar/processo | PEGAR | / | / | Coletar informações do processo |
| /colecionar/disco | PEGAR | / | / | Colete dados de disco da máquina física |
| /colecione/disk_io | PEGAR | / | / | Colete o disco IO e dados de rendimento da máquina física |
| /Coletar/CPU | PEGAR | / | / | Colete dados de carregamento da CPU da máquina física |
| /colecionar/rede | PEGAR | / | / | Colete informações físicas para cartão de rede e dados de IO |
| /colecionar/sys | PEGAR | / | / | Colete informações do sistema operacional |
| /colecionar/sys/memória | PEGAR | / | / | Colete dados de memória do sistema operacional |
| /colecione/sys/arquivo | PEGAR | / | / | Colete dados de uso de partição de disco do sistema operacional |
| /colecionar/porta | PEGAR | portas (int []) | / | Aquisição de ocupação do porto do sistema operacional |
| /colecionar/jvm/classe de carga | PEGAR | / | / | Colete informações de carregamento da classe JVM |
| /colecionar/jvm/classelloader | PEGAR | / | / | Colete informações do carregador de classe JVM |
| /colecionar/jvm/compilação | PEGAR | / | / | Colete informações de compilação da JVM |
| /colecionar/jvm/gc | PEGAR | / | / | Colete informações de coletor de lixo JVM |
| /colecionar/jvm/memória_manager | PEGAR | / | / | Reúna informações do gerenciador de memória JVM |
| /colecionar/jvm/memória_pool | PEGAR | / | / | Colete informações do pool de memória JVM |
| /colecionar/jvm/memória | PEGAR | / | / | Colete o uso da memória da JVM |
| /colecionar/jvm/thread | PEGAR | / | / | Colete estatísticas de threads JVM |
| /colecionar/jvm/thread_stack | PUBLICAR | / | Veja ThreadInfodto | Colete os dados especificados da pilha de threads jvm |
| /colecionar/jvm/dump_thread | PEGAR | / | / | despejar todos os dados da pilha de threads |
| /colecionar/jvm/thread_ordered_cpu_time | PEGAR | TIPO (String, Stack | Info), DurationSeconds (int) | / | Aquisição de uso da CPU em threads de JVM dentro de um determinado momento |
| /colecionar/jvm/thread_detail | PEGAR | id (long []) | / | Colete detalhes do thread JVM (tempo da CPU, tempo de bloco, bloqueios, etc.) |
| /colecionar/jvm/thread_pool | PEGAR | ClassloadReHash (String), Clazz (String), InstanceField (String), Campo (String) | / | Colete informações do pool de threads JVM |
| /colecione/by_options | PEGAR | Opções (Coleção Type []) | Coleta de dados em lotes com base em opções | |
| /execute/gc | PEGAR | / | / | Executar gc |
| /execute/jps | PEGAR | / | / | Liste todos os processos Java |
| /execute/jvm_tool | PUBLICAR | / | comando (string) | Execute o comando da ferramenta JVM |
| /execute/jad | PEGAR | ClassName (String), MethodName (String) | / | Decompilação de código (somente agentes são suportados) |
| /execute/load_patch | PUBLICAR | / | JsonArray, cujo elemento é patchdto | Código Atualizações Hot. Ao especificar o hash de classe de classe, são apenas atualizações quentes para alterar a classe carregada pelo Classloader. |
| /execute/get_switches | PEGAR | / | / | Obtenha as informações da chave de aquisição |
| /execute/set_switches | PEGAR | Nomes (switches []), aberto (booleano) | / | Configure o interruptor de aquisição |
| /Profiler/flame_graph | PUBLICAR | / | Veja ProfilersMpledTo | Gerar mapa de chama |
| /Profiler/Iniciar | PUBLICAR | / | Veja ProfilersMpledTo, onde apenas eventcounterinteval é válido | Executar o comando de amostragem para iniciar o Profiler |
| /Profiler/Stop | PUBLICAR | / | String, Format Field em ProfilersMpledTo, o valor opcional é htmltxtjfr | Execute o Profiler para encerrar o comando de amostragem e exportação do arquivo |
| /Profiler/status | PEGAR | / | / | Obtenha o status atual do Profiler |
| /Profiler/list_events | PEGAR | / | / | Obtenha os eventos do Profiler apoiados pelo ambiente atual |
| /Profiler/Execute | PUBLICAR | / | comando (string) | Execute o comando Profiler, veja async-Profiler |
| /servidor/desligamento | PEGAR | Target (string) | / | Fechar o serviço, os dados são do tipo de serviço |

A lógica operacional do modo Sentinel é coletar regularmente itens de dados especificados e empurrá -los aos assinantes . Você precisa fornecer um serviço de assinatura (interface HTTP) que possa receber dados. Se o acesso à interface exigir autenticação de identidade, a interface HTTP do assinante atualmente suporta apenas autenticação básica .
Configuração do modo Sentinel
server :
type : sentinel
sentinel :
- subscribers :
# publish jvmm data to custom http server
- type : http
url : http://127.0.0.1:9999/monitor/subscriber
auth :
enable : true
username : 123456
password : 123456
# publish jvmm data to prometheus
- type : prometheus
url : http://127.0.0.1:9090/api/v1/write
auth :
enable : true
username : 123456
password : 123456
interval : 15
tasks :
- process
- disk
- disk_io
- cpu
- port
...Um total dos seguintes itens de coleção é suportado:
[
" process " ,
" disk " ,
" disk_io " ,
" cpu " ,
" network " ,
" sys " ,
" sys_memory " ,
" sys_file " ,
" port " ,
" jvm_classloading " ,
" jvm_classloader " ,
" jvm_compilation " ,
" jvm_gc " ,
" jvm_memory " ,
" jvm_memory_manager " ,
" jvm_memory_pool " ,
" jvm_thread " ,
" jvm_thread_stack " ,
" jvm_thread_detail " ,
" jvmm_thread_pool "
]Atualmente, apenas os seguintes itens de coleção suportam a Prometheus
[
" process " ,
" disk_io " ,
" cpu " ,
" network " ,
" sys " ,
" sys_memory " ,
" sys_file " ,
" jvm_classloading " ,
" jvm_compilation " ,
" jvm_gc " ,
" jvm_memory " ,
" jvm_memory_pool " ,
" jvm_thread "
]O JVMM fornece dois painéis de modelo Grafana, a saber: nó e JVM
O modelo do nó é uma coleção de itens de monitoramento relacionados ao sistema, que podem ajudá-lo a se concentrar mais no monitoramento de dados de máquinas físicas ou hosts em nuvem.


Método de importação: Importar ID do painel 20430 ou importar painel-node.json
Para cooperar com este modelo, as seguintes tarefas precisam ser configuradas:
[
" process " ,
" disk_io " ,
" cpu " ,
" network " ,
" sys " ,
" sys_memory " ,
" sys_file "
]O JVM Modelo é uma coleção de itens de monitoramento relacionados à JVM, o que pode ajudá-lo a se concentrar mais nos dados de monitoramento do processo.


Método de importação: Importar ID do painel 20429 ou importar painel-jvm.json
Para cooperar com este modelo, as seguintes tarefas precisam ser configuradas:
[
" process " ,
" jvm_classloading " ,
" jvm_compilation " ,
" jvm_gc " ,
" jvm_memory " ,
" jvm_memory_pool " ,
" jvm_thread "
]Se você deseja desenvolver secundário com base no JVMM, você só precisa introduzir dependências principais
< dependency >
< groupId >io.github.tzfun.jvmm</ groupId >
< artifactId >jvmm-core</ artifactId >
< version >${jvmm-version}</ version >
</ dependency > Todas as interfaces funcionais de aquisição de dados fornecidas pelo servidor anterior e outras interfaces funcionais que não fornecem interfaces de chamada remota podem ser obtidas por meio de uma classe de fábrica: org.beifengtz.jvmm.core.JvmmFactory
public class Jvmm {
public static void main ( String [] args ) {
// 提供所有的数据采集接口
JvmmCollector collector = JvmmFactory . getCollector ();
// 提供所有的执行接口
JvmmExecutor executor = JvmmFactory . getExecutor ();
// 提供火焰图生成器
JvmmProfiler profiler = JvmmFactory . getProfiler ();
}
}A ferramenta de cliente JVMM fornece uma maneira simples e rápida de chamar remotamente o JVMM. Obviamente, também assume funções importantes, como anexar servidor e geração de frascos de dependência.
A ferramenta Client fornece uma função de execução de comando Bootstrap e será executada, mesmo que você não faça parâmetros. Para uso específico, use o seguinte comando para visualizar o documento de ajuda:
java -jar jvmm.jar -hExemplo de aquisição de dados por ferramenta do cliente
Gerar exemplo de diagrama de chama

Exemplo de chamada de código
Exemplo de aplicativo de painel personalizado

Alguns componentes dentro do projeto podem ser usados sem o projeto, leve e fácil de usar
O motivo é que seu ambiente não possui ferramentas JDK ou variáveis de ambiente não estão configuradas. Certifique -se de que seu ambiente esteja instalado com JDK em vez de apenas JRE. Verificação simples: execute jps -l em seu ambiente e, se ele puder ser executado normalmente e produzir o resultado, significa que o ambiente está ok.
Solução: Configure o diretório JDK bin local como uma variável de ambiente
Se você iniciar o JVMM-Server.jar, o motivo é que você está usando o JDK 9 e acima, o Java proíbe o acesso reflexivo a algumas classes que começam com o JDK 9+.
java.lang.reflect.InaccessibleObjectException: Unable to make field final jdk.internal.loader.URLClassPath jdk.internal.loader.ClassLoaders$AppClassLoader.ucp accessible: module java.base does not "opens jdk.internal.loader" to unnamed module @2d127a61
Solução: Adicione os seguintes parâmetros da máquina virtual
# JDK 9+ 为确保成功运行建议设置以下几个虚拟机参数
# --add-opens java.base/jdk.internal.loader=ALL-UNNAMED
# --add-opens jdk.zipfs/jdk.nio.zipfs=ALL-UNNAMED
# --add-opens java.base/java.net=ALL-UNNAMED
# --add-opens java.management/sun.management=ALL-UNNAMED
java -jar --add-opens java.base/jdk.internal.loader=ALL-UNNAMED
--add-opens jdk.zipfs/jdk.nio.zipfs=ALL-UNNAMED
--add-opens java.base/java.net=ALL-UNNAMED
--add-opens java.management/sun.management=ALL-UNNAMED
jvmm-server.jar ./jvmm.yml Se você solicitar No access to perf events. Try --fdtransfer or --all-user option or 'sysctl kernel.perf_event_paranoid=1' , o motivo é que o kernel do sistema proíbe a detecção do desempenho do sistema por padrão e você precisa ativar esta opção.
sudo systcl -w kernel.perf_event_paranoid=1Ou modifique o arquivo sysctl
sudo sh -c ' echo "kernel.perf_event_paranoid=1" >> /etc/sysctl.conf '
sudo sysctl -pEssa ferramenta é completamente de código aberto e gratuita, e não é fácil de criar. Se você acha que é bom, pode doar para apoiar este projeto.
Lista de doações:
Se você encontrar algum problema durante o uso ou tiver informações ou sugestões únicas sobre este projeto, envie um problema ou envie uma mensagem privada para mim
E -mail: [email protected]
WeChat: Beifeng-tz (observe JVMM se você adicionar)