Skip to content

Neo4j JMX监控 ​

JMX(Java Management Extensions)是Java平台的标准管理和监控技术,Neo4j提供了丰富的JMX MBean(Managed Beans),用于监控数据库的各个方面。通过JMX监控,可以实时了解Neo4j的运行状态、性能指标和资源使用率。

JMX基本概念 ​

  • MBean:Managed Bean,是JMX的核心组件,代表一个可管理的资源,包含属性和操作
  • MBean Server:MBean的容器,负责管理MBean的注册和访问
  • JMX客户端:用于访问MBean Server的工具,如JConsole、VisualVM等
  • JMX代理:运行在被监控Java应用中的组件,包含MBean Server和MBean

Neo4j的JMX MBean分类 ​

Neo4j提供的JMX MBean主要分为以下几类:

MBean类别描述主要MBean
数据库核心数据库的基本信息和状态org.neo4j:instance=kernel#0,name=Database
事务管理事务相关的指标和操作org.neo4j:instance=kernel#0,name=TransactionCount
查询执行Cypher查询相关的指标org.neo4j:instance=kernel#0,name=QueryLogger
存储引擎存储相关的指标和操作org.neo4j:instance=kernel#0,name=Store
页缓存页缓存的使用情况org.neo4j:instance=kernel#0,name=PageCache
JVM资源JVM内存、CPU、GC等指标java.lang:type=Memory、java.lang:type=Threading
集群管理集群相关的指标和操作org.neo4j:instance=kernel#0,name=Cluster
网络通信网络连接和通信指标org.neo4j:instance=kernel#0,name=Network

JMX配置 ​

1. 启用JMX远程访问 ​

Neo4j默认启用了本地JMX访问,但如果需要远程访问JMX,需要进行额外配置。编辑neo4j.conf文件,添加以下配置:

txt
# 启用JMX远程访问
dbms.jmx.remote.enabled=true

# 配置JMX远程访问端口
dbms.jmx.remote.port=3637

# 配置JMX远程访问主机(0.0.0.0表示允许所有主机访问)
dbms.jmx.remote.host=0.0.0.0

# 配置JMX远程访问认证
dbms.jmx.remote.authenticate=true

# 配置JMX远程访问SSL
dbms.jmx.remote.ssl=false

# 配置JMX认证文件路径
dbms.jmx.remote.password.file=conf/jmx.password

dbms.jmx.remote.access.file=conf/jmx.access

2. 配置JMX认证 ​

Neo4j的JMX认证需要配置两个文件:

jmx.access文件 ​

用于配置JMX用户的访问权限,格式为:username access

txt
# 只读访问
monitorRole readonly

# 读写访问
controlRole readwrite

jmx.password文件 ​

用于配置JMX用户的密码,格式为:username password

txt
# 只读用户
monitorRole monitorPassword

# 读写用户
controlRole controlPassword

3. 设置文件权限 ​

确保JMX认证文件的权限设置正确,只有Neo4j进程能够读取:

bash
# Linux系统
chmod 600 conf/jmx.password conf/jmx.access
chown neo4j:neo4j conf/jmx.password conf/jmx.access

# Windows系统
# 使用文件系统的安全设置,确保只有Neo4j服务账户能够访问

4. 配置JMX监控指标 ​

可以通过以下配置调整JMX监控指标的收集:

txt
# 启用或禁用JMX监控
dbms.jmx.enabled=true

# 启用或禁用特定类型的指标
dbms.metrics.enabled{transaction}=true
dbms.metrics.enabled{cypher}=true
dbms.metrics.enabled{storage}=true

# 配置监控指标的导出频率(秒)
dbms.metrics.polling_interval=30

使用JConsole监控 ​

JConsole是JDK自带的JMX监控工具,可以用于监控Java应用程序,包括Neo4j。

1. 启动JConsole ​

bash
# Linux/Mac系统
jconsole

# Windows系统
jconsole.exe

2. 连接到Neo4j的JMX ​

  1. 启动JConsole后,选择"远程进程"选项
  2. 输入JMX服务URL:service:jmx:rmi:///jndi/rmi://neo4j-server:3637/jmxrmi
  3. 输入用户名和密码(在jmx.password文件中配置)
  4. 点击"连接"按钮
  5. 如果是首次连接,会弹出安全警告,点击"不安全的连接"继续

3. 监控Neo4j ​

连接成功后,JConsole会显示以下标签页:

内存标签页 ​

显示JVM内存的详细使用情况,包括堆内存和非堆内存的使用情况,以及内存池的详细信息。

线程标签页 ​

显示Neo4j的线程使用情况,包括活跃线程数、峰值线程数、守护线程数等,还可以查看每个线程的详细信息和堆栈跟踪。

类标签页 ​

显示Neo4j加载的类信息,包括已加载的类数量、已卸载的类数量等。

VM摘要标签页 ​

显示JVM的详细信息,包括JVM版本、供应商、启动参数、系统属性等。

MBeans标签页 ​

显示Neo4j的所有MBean,可以浏览和操作各个MBean的属性和方法:

  • org.neo4j: 包含Neo4j特定的MBean
    • instance=kernel#0: 包含Neo4j内核的MBean
      • name=Database: 数据库基本信息和状态
      • name=TransactionCount: 事务相关指标
      • name=QueryLogger: 查询相关指标
      • name=Store: 存储相关指标
      • name=PageCache: 页缓存使用情况
      • name=Cluster: 集群相关指标
  • java.lang: 包含JVM相关的MBean
    • type=Memory: JVM内存信息
    • type=Threading: 线程信息
    • type=GarbageCollector: GC信息
    • type=OperatingSystem: 操作系统信息

使用VisualVM监控 ​

VisualVM是一个功能强大的JVM监控和分析工具,可以用于监控Neo4j的运行状态和性能。

1. 安装VisualVM ​

VisualVM从JDK 9开始不再随JDK捆绑,需要单独下载:

  1. 访问VisualVM官网:https://visualvm.github.io/
  2. 下载最新版本的VisualVM
  3. 解压下载的文件
  4. 运行VisualVM:
bash
# Linux/Mac系统
./visualvm/bin/visualvm

# Windows系统
visualvm.exe

2. 连接到Neo4j的JMX ​

  1. 启动VisualVM
  2. 在左侧导航栏中,右键点击"远程",选择"添加远程主机"
  3. 输入Neo4j服务器的主机名或IP地址,点击"确定"
  4. 右键点击添加的远程主机,选择"添加JMX连接"
  5. 输入JMX连接URL:service:jmx:rmi:///jndi/rmi://neo4j-server:3637/jmxrmi
  6. 勾选"使用安全凭证"
  7. 输入用户名和密码,点击"确定"

3. 监控Neo4j ​

连接成功后,可以在VisualVM中查看Neo4j的各种监控信息:

监控标签页 ​

显示Neo4j的实时监控数据,包括CPU使用率、内存使用情况、堆内存大小、类加载情况和线程数。

线程标签页 ​

显示Neo4j的线程使用情况,包括线程状态分布、线程详情和线程堆栈跟踪。

抽样器标签页 ​

可以对Neo4j进行CPU和内存抽样,分析性能瓶颈:

  • CPU抽样:分析方法的CPU使用率,找出耗时最长的方法
  • 内存抽样:分析对象的内存使用情况,找出内存占用最大的对象

Profiler标签页 ​

提供更详细的性能分析功能,可以分析方法的调用次数、执行时间和内存分配情况。

MBeans标签页 ​

与JConsole类似,可以浏览和操作Neo4j的所有MBean。

常用JMX指标 ​

1. 数据库核心指标 ​

MBean属性名描述单位
DatabaseStoreId数据库存储ID字符串
DatabaseStatus数据库状态字符串
DatabaseStoreDirectory数据库存储目录字符串
DatabaseCreationDate数据库创建日期日期时间

2. 事务指标 ​

MBean属性名描述单位
TransactionCountStarted已启动的事务数计数
TransactionCountCommitted已提交的事务数计数
TransactionCountRolledBack已回滚的事务数计数
TransactionCountActive当前活跃的事务数计数

3. 查询指标 ​

MBean属性名描述单位
QueryLoggerQueries执行的查询总数计数
QueryLoggerUpdates更新查询数计数
QueryLoggerReads只读查询数计数
QueryLoggerAverageExecutionTime平均查询执行时间毫秒

4. 存储指标 ​

MBean属性名描述单位
StoreNodeCount节点数量计数
StoreRelationshipCount关系数量计数
StorePropertyCount属性数量计数
StoreStoreSize存储文件大小字节

5. 页缓存指标 ​

MBean属性名描述单位
PageCacheHitRatio页缓存命中率比率
PageCacheMissRatio页缓存未命中率比率
PageCacheHitCount页缓存命中次数计数
PageCacheMissCount页缓存未命中次数计数
PageCacheFileCount缓存的文件数量计数
PageCacheMemoryUsed页缓存使用的内存字节

6. JVM指标 ​

MBean属性名描述单位
MemoryHeapMemoryUsage堆内存使用情况字节
MemoryNonHeapMemoryUsage非堆内存使用情况字节
ThreadingThreadCount线程总数计数
ThreadingDaemonThreadCount守护线程数计数
ThreadingPeakThreadCount峰值线程数计数
OperatingSystemSystemCpuLoad系统CPU负载比率
OperatingSystemProcessCpuLoad进程CPU负载比率
GarbageCollectorCollectionCountGC收集次数计数
GarbageCollectorCollectionTimeGC收集总时间毫秒

7. 集群指标 ​

MBean属性名描述单位
ClusterMembers集群成员数量计数
ClusterCoreMembers核心成员数量计数
ClusterReadReplicas只读副本数量计数
ClusterLeader当前领导者节点字符串
ClusterRaftTerm当前Raft任期计数
ClusterReplicationDelay复制延迟毫秒

JMX监控最佳实践 ​

1. 监控策略 ​

  • 全面监控:监控所有关键指标,包括数据库核心、事务、查询、存储、页缓存、JVM和集群指标
  • 分层监控:从概览到细节,分层设计监控方案
  • 告警配置:对关键指标设置告警阈值,及时发现问题
  • 历史数据分析:保存监控数据,定期分析趋势,预测潜在问题
  • 性能基准:建立性能基准,用于比较和分析性能变化

2. 告警阈值 ​

为关键指标设置合理的告警阈值,例如:

指标类型指标名告警阈值告警级别
JVM内存堆内存使用率> 80%警告
JVM内存堆内存使用率> 90%严重
CPU进程CPU负载> 80%警告
CPU进程CPU负载> 90%严重
事务活跃事务数> 100警告
事务事务平均执行时间> 1000ms警告
页缓存页缓存未命中率> 5%警告
集群复制延迟> 1000ms警告

3. 性能优化 ​

根据JMX监控数据,可以进行以下性能优化:

  • JVM内存优化:根据堆内存使用情况,调整JVM的堆内存大小
  • GC优化:根据GC收集次数和时间,调整GC参数
  • 页缓存优化:根据页缓存命中率,调整页缓存大小
  • 查询优化:根据查询执行时间,优化慢查询
  • 线程优化:根据线程使用情况,调整线程池大小
  • 存储优化:根据存储使用情况,优化数据模型和索引

4. 安全配置 ​

  • 启用JMX认证:始终启用JMX认证,避免未授权访问
  • 使用SSL加密:对于生产环境,建议启用JMX的SSL加密
  • 限制访问IP:通过防火墙或网络配置,限制JMX的访问IP
  • 定期更换密码:定期更换JMX用户的密码
  • 最小权限原则:为JMX用户分配最小必要的权限,例如只读权限

5. 监控工具集成 ​

  • 集成到监控系统:将JMX监控数据集成到Prometheus、Grafana等监控系统
  • 使用自定义监控脚本:编写自定义脚本,定期采集JMX指标并发送到监控系统
  • 使用JMX Exporter:使用Prometheus的JMX Exporter,将JMX指标导出为Prometheus格式

常见问题与解决方案 ​

1. 无法连接到JMX ​

问题现象:JConsole或VisualVM无法连接到Neo4j的JMX

解决方案:

  • 检查Neo4j的JMX配置是否正确
  • 检查JMX端口是否被防火墙或安全组阻止
  • 检查JMX认证文件的权限是否正确
  • 检查JMX用户名和密码是否正确
  • 检查Neo4j的日志文件,查看是否有JMX相关的错误信息

2. JMX连接超时 ​

问题现象:JConsole或VisualVM连接JMX时超时

解决方案:

  • 检查网络连接是否正常
  • 增加JMX连接的超时时间
  • 检查Neo4j的负载情况,是否因为负载过高导致无法响应JMX请求
  • 优化Neo4j的性能,减少负载

3. JMX监控数据不准确 ​

问题现象:JMX监控数据与实际情况不符

解决方案:

  • 检查JMX指标的收集频率是否合理
  • 检查JMX配置是否正确启用了所有需要的指标
  • 重启Neo4j服务,重新加载JMX配置
  • 更新JMX客户端到最新版本

4. JMX监控影响Neo4j性能 ​

问题现象:启用JMX监控后,Neo4j性能下降

解决方案:

  • 减少JMX指标的收集频率
  • 只监控必要的指标,减少监控数据量
  • 关闭不必要的JMX MBean
  • 增加Neo4j的资源配置,如内存、CPU等
  • 使用异步方式采集JMX指标,减少对Neo4j主线程的影响

5. JMX MBean不可用 ​

问题现象:某些JMX MBean不可用或显示为null

解决方案:

  • 检查Neo4j版本是否支持该MBean
  • 检查Neo4j的配置是否正确启用了该MBean
  • 检查Neo4j的日志文件,查看是否有相关错误信息
  • 更新Neo4j到最新版本

JMX监控工具 ​

1. 命令行工具 ​

jmxterm ​

jmxterm是一个命令行JMX客户端,可以用于访问和操作JMX MBean:

bash
# 安装jmxterm
wget https://github.com/jiaqi/jmxterm/releases/download/v1.0.4/jmxterm-1.0.4-uber.jar

# 运行jmxterm
java -jar jmxterm-1.0.4-uber.jar

# 连接到Neo4j的JMX
> open service:jmx:rmi:///jndi/rmi://localhost:3637/jmxrmi -u monitorRole -p monitorPassword

# 列出所有MBean
> domains

# 查看特定MBean的属性
> bean org.neo4j:instance=kernel#0,name=TransactionCount
> get Started Committed RolledBack Active

# 退出jmxterm
> exit

jvisualvm命令行 ​

可以使用VisualVM的命令行工具jvisualvm,批量导出JMX指标:

bash
# 导出JMX指标到文件
jvisualvm --openjmx service:jmx:rmi:///jndi/rmi://localhost:3637/jmxrmi --format csv --output neo4j-jmx.csv

2. 自定义监控脚本 ​

可以使用Java或Python编写自定义监控脚本,采集JMX指标:

Java脚本示例 ​

java
import javax.management.*;
import javax.management.remote.*;
import java.util.Set;

public class Neo4jJmxMonitor {
    public static void main(String[] args) throws Exception {
        // JMX连接URL
        String jmxUrl = "service:jmx:rmi:///jndi/rmi://localhost:3637/jmxrmi";
        String username = "monitorRole";
        String password = "monitorPassword";

        // 创建JMX连接
        JMXServiceURL url = new JMXServiceURL(jmxUrl);
        JMXConnector connector = JMXConnectorFactory.connect(url, 
            new javax.security.auth.Subject().getPrincipals().isEmpty() ? null : 
            new java.util.HashMap<String, Object>() {
                { put(JMXConnector.CREDENTIALS, new String[] { username, password }); }
            }
        );
        connector.connect();

        // 获取MBeanServer连接
        MBeanServerConnection connection = connector.getMBeanServerConnection();

        // 获取TransactionCount MBean
        ObjectName txCountName = new ObjectName("org.neo4j:instance=kernel#0,name=TransactionCount");
        Set<ObjectName> txCountBeans = connection.queryNames(txCountName, null);
        if (!txCountBeans.isEmpty()) {
            ObjectName txCountBean = txCountBeans.iterator().next();
            // 获取属性值
            long started = (long) connection.getAttribute(txCountBean, "Started");
            long committed = (long) connection.getAttribute(txCountBean, "Committed");
            long rolledBack = (long) connection.getAttribute(txCountBean, "RolledBack");
            long active = (long) connection.getAttribute(txCountBean, "Active");

            System.out.println("Transaction Count:");
            System.out.println("Started: " + started);
            System.out.println("Committed: " + committed);
            System.out.println("RolledBack: " + rolledBack);
            System.out.println("Active: " + active);
        }

        // 关闭连接
        connector.close();
    }
}

Python脚本示例 ​

使用PyJMX库访问JMX:

python
from jmxquery import JMXQuery, JMXConnection

# JMX连接配置
jmx_url = "service:jmx:rmi:///jndi/rmi://localhost:3637/jmxrmi"
username = "monitorRole"
password = "monitorPassword"

# 创建JMX连接
jmx_connection = JMXConnection(jmx_url, username=username, password=password)

# 定义JMX查询
jmx_queries = [
    # 事务指标
    JMXQuery("org.neo4j:instance=kernel#0,name=TransactionCount:Started"),
    JMXQuery("org.neo4j:instance=kernel#0,name=TransactionCount:Committed"),
    JMXQuery("org.neo4j:instance=kernel#0,name=TransactionCount:RolledBack"),
    JMXQuery("org.neo4j:instance=kernel#0,name=TransactionCount:Active"),
    # JVM内存指标
    JMXQuery("java.lang:type=Memory:HeapMemoryUsage"),
    JMXQuery("java.lang:type=Memory:NonHeapMemoryUsage"),
    # 页缓存指标
    JMXQuery("org.neo4j:instance=kernel#0,name=PageCache:HitRatio"),
    JMXQuery("org.neo4j:instance=kernel#0,name=PageCache:MissRatio")
]

# 执行JMX查询
jmx_results = jmx_connection.query(jmx_queries)

# 打印查询结果
for result in jmx_results:
    print(f"{result.mbean_attribute}: {result.value}")

常见问题(FAQ) ​

Q1: Neo4j默认启用JMX吗? ​

A1: 是的,Neo4j默认启用了本地JMX访问,但如果需要远程访问JMX,需要进行额外配置。

Q2: JMX监控会影响Neo4j的性能吗? ​

A2: JMX监控会有一定的性能开销,但如果合理配置,开销可以控制在可接受范围内。建议只监控必要的指标,调整合适的监控频率。

Q3: 如何在Kubernetes环境中监控Neo4j的JMX? ​

A3: 在Kubernetes环境中,可以使用以下方式监控Neo4j的JMX:

  • 使用JMX Exporter将JMX指标导出为Prometheus格式
  • 使用ServiceMonitor或PodMonitor资源,配置Prometheus自动发现
  • 使用Neo4j的Helm chart,自动配置JMX监控

Q4: 如何备份JMX配置? ​

A4: 可以通过以下方式备份JMX配置:

  • 备份neo4j.conf文件中的JMX相关配置
  • 备份jmx.access和jmx.password文件
  • 使用配置管理工具(如Ansible、Puppet等)管理JMX配置

Q5: 如何升级JMX客户端? ​

A5: JConsole和VisualVM是随JDK分发的,升级JDK即可升级这些工具。对于第三方JMX客户端,建议定期检查并升级到最新版本。

Q6: 如何监控多个Neo4j实例的JMX? ​

A6: 可以使用以下方式监控多个Neo4j实例的JMX:

  • 使用VisualVM的"添加JMX连接"功能,为每个实例添加一个JMX连接
  • 使用JConsole的"连接"菜单,连接到不同的实例
  • 将JMX指标集成到统一的监控系统,如Prometheus、Grafana等

Q7: 如何自定义JMX指标? ​

A7: Neo4j的JMX指标是内置的,无法直接自定义,但可以通过以下方式扩展监控:

  • 使用Neo4j的监控API,编写自定义监控脚本
  • 使用Neo4j的扩展机制,开发自定义MBean
  • 使用第三方监控工具,采集更多指标

Q8: 如何排查JMX监控问题? ​

A8: 可以通过以下方式排查JMX监控问题:

  • 检查Neo4j的日志文件,查看是否有JMX相关的错误信息
  • 检查JMX配置是否正确
  • 使用telnet或nc命令测试JMX端口是否可访问
  • 检查JMX认证文件的权限和内容是否正确
  • 使用不同的JMX客户端进行测试,排除客户端问题