Spring Boot JPA连接MariaDB如何获取连接详情及Galera节点信息
Spring Boot整合JPA访问MariaDB问题解答
现有基础配置参考
application.properties配置
spring.jpa.hibernate.ddl-auto = update spring.jpa.database-platform = org.hibernate.dialect.MariaDBDialect spring.jpa.show-sql = false spring.datasource.url = jdbc:mysql://localhost:3306/abc?serverTimezone=Europe/Paris spring.datasource.username = myuser spring.datasource.password = mysecret
Repository层定义
@Transactional public interface MyRepo extends CrudRepository <MyRec, Long> { }
业务组件示例
@Component public class MyComp { @Autowired MyRepo mr; public void foo () { MyRec rec = new MyRec (); rec.setName ("Sam"); this.mr.save (rec); } }
问题1:获取数据库连接相关详细信息
可以通过三种方式获取不同维度的连接信息:
- 代码读取JDBC元数据:注入Spring管理的
DataSource对象,从连接池获取连接后读取JDBC标准元数据,可拿到连接URL、用户名、数据库版本、驱动版本等基础信息。注意使用完连接必须归还连接池,推荐用try-with-resources语法自动释放资源。
@Autowired private DataSource dataSource; public void getConnBaseInfo() throws SQLException { try (Connection conn = dataSource.getConnection()) { DatabaseMetaData metaData = conn.getMetaData(); System.out.println("连接URL:" + metaData.getURL()); System.out.println("登录用户名:" + metaData.getUserName()); System.out.println("数据库版本:" + metaData.getDatabaseProductVersion()); System.out.println("JDBC驱动版本:" + metaData.getDriverVersion()); } }
- 读取连接池运行指标:Spring Boot 2.x后默认使用HikariCP连接池,直接注入
HikariDataSource实例即可拿到连接池运行时数据,包括活跃连接数、空闲连接数、等待连接的线程数等。
@Autowired private HikariDataSource hikariDataSource; public void getPoolRuntimeStats() { HikariPoolMXBean poolBean = hikariDataSource.getHikariPoolMXBean(); System.out.println("活跃连接数:" + poolBean.getActiveConnections()); System.out.println("空闲连接数:" + poolBean.getIdleConnections()); System.out.println("总连接数:" + poolBean.getTotalConnections()); System.out.println("等待连接的线程数:" + poolBean.getThreadsAwaitingConnection()); }
- 端点查询:如果项目引入了
spring-boot-starter-actuator依赖,开启datasource端点后,可直接访问/actuator/datasource端点拿到连接配置、健康检查结果,无需自定义代码。
问题2:Galera双节点集群下识别当前实际连接的节点
不要通过JDBC配置的主机列表判断连接节点——MariaDB驱动会根据配置的负载均衡策略、节点健康状态自动切换连接,配置的地址列表不代表实际连接位置。最通用可靠的方式是在获取连接后,直接查询数据库内置系统变量,从服务端返回当前节点的真实信息:
@Autowired private DataSource dataSource; public String getCurrentGaleraNode() throws SQLException { try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT @@hostname AS host, @@wsrep_node_name AS node_name, @@wsrep_node_address AS node_addr")) { if (rs.next()) { String host = rs.getString("host"); String nodeName = rs.getString("node_name"); String nodeAddr = rs.getString("node_addr"); return String.format("当前连接节点:主机名=%s, Galera节点名=%s, 节点地址=%s", host, nodeName, nodeAddr); } } throw new RuntimeException("查询Galera节点信息失败"); }
注意事项
- 查询返回的三个字段中,
@@hostname是节点服务器的主机名,@@wsrep_node_name是Galera配置中定义的节点名称,@@wsrep_node_address是节点集群通信的IP和端口,三者组合可以唯一确定连接的节点。 - 受连接池回收、故障转移机制影响,不同请求拿到的连接可能落在不同节点上,节点信息不要做本地缓存,需要识别时实时查询即可。
- 该方法不依赖特定驱动版本、连接池实现,兼容MariaDB驱动和MySQL驱动,单节点、主从、Galera集群场景都可使用。
内容的提问来源于stack exchange,提问作者chris01
相关产品推荐
相关产品推荐

