使用JDBC Ping MySQL服务器

17
这似乎相当简单(不对我来说)...
如何使用JDBC ping一个mysql服务器?我已经成功地使用JDBC和MySQL执行了select和insert查询,但如何ping?
谢谢。

如果你不知道如何做,怎么会觉得它很简单呢? - Bombe
3个回答

35

MySQL JDBC驱动程序(Connector/J)提供了一种ping机制。

如果您执行以/* ping */开头的SQL查询,例如:

"/* ping */ SELECT 1"

这将导致驱动程序向服务器发送一个ping并返回一个虚假、轻量级的结果集。

(您可以在Connector/J文档中深入查找“ping”;请仔细阅读:这个机制对使用的语法非常敏感。与大多数SQL不同,“ping”标记的“解析”发生在客户端JDBC驱动程序本身中。)


1
+1。了解与简单的SELECT 1相比,这个“轻量级”的特点是什么会很有帮助。我在那个页面上找不到任何记录ping比较“轻”的程度的文档。 - user330315
1
需要使用SELECT 1吗?文档:http://docs.oracle.com/cd/E17952_01/connector-j-en/connector-j-usagenotes-tomcat.html提到“请注意,Connector/J 5.1.3引入了一种方法,可以使用validationQuery的值为/* ping */,而不是使用SELECT 1的validationQuery值。” - pm_labs
是的,上述文档与其他有关该主题的文档相矛盾,指出它必须“精确地”为/* ping */,而不仅仅是以此开头:“请注意,必须精确指定/* ping */。”这是怎么回事? - Jon
为了对我的问题进行猜测,这个页面(http://dev.mysql.com/doc/connector-j/en/connector-j-usagenotes-j2ee-concepts-connection-pooling.html#idm47534937957872)似乎提供了Connector/J源代码的片段,如果是这样的话,它将意味着“以...开始”,而不是“完全匹配”的要求。如果是这种情况,在我之前的评论中Tomcat的文档规范中的“完全匹配”将在技术上是不正确的。但是最好不要在这里使用猜测。 - Jon
1
与 SELECT 1 相比,使 ping 更有效的原因是服务器端处理(解析语句、创建和发送结果集元数据,即使是 SELECT 1 也会这样做)。最便宜的 SQL 命令不是 SELECT 1。它是 "DO 1" - 它可以节省一些时间,因为它不发送结果集。您需要使用 statement.executeUpdate("DO 1")。 - Vladislav Vaintroub
显示剩余2条评论

2
我认为 JDBC API 中没有这方面的内容。但是你可以简单地使用 InetAddress 和 isReachable() 方法来检查服务器是否存在(这本质上就是 ping 的功能)。

http://download.oracle.com/javase/6/docs/api/java/net/InetAddress.html#isReachable%28int%29

编辑:
如果你想要检查MySQL是否正在运行,而不是ping服务器,你可以尝试在MySQL默认端口上打开一个套接字来连接服务器。
类似这样:
InetAddress addr = InetAddress.getByName("your.server.com");
int port = 3306;
SocketAddress sockaddr = new InetSocketAddress(addr, port);
Socket sock = new Socket();
sock.connect(sockaddr, 2000); // 使用2秒超时打开连接
如果connect()没有抛出异常,则表示端口3306上有进程在运行。
如果你想确保该端口上运行的是MySQL服务器,唯一的方法是建立一个JDBC连接(但你需要一个有效的用户名/密码),并运行一个语句,例如Brian提到的PING语句。

这不会检查主机上的数据库存在。 - Piotr Findeisen
@Piotr Findeisen:你说你想要ping服务器,所以我假定你想要确保服务器本身是可达的。 - user330315
我不知道提问者想要什么 :) - Piotr Findeisen

1

我不知道如何在JDBC中实现这一点,但是您可以使用连接池来验证您的连接,就像这样(这是Tomcat的context.xml(在应用程序的META-INF目录中找到)):

<Resource name="jdbc/My_DS" auth="Container" type="javax.sql.DataSource"
            maxActive="100" maxIdle="30" maxWait="10000"
            username="USERNAME" password="PASSWORD" driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/MYDB?autoReconnect=true" 
            removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"
            testOnBorrow="true" validationQuery="SELECT 1" />

validationQuery 用于验证连接是否成功。


1
也许validationQuery="/* ping */ SELECT 1"会更好? - Suma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接