我正在使用JDBC连接到与我的应用程序位于同一网络上的MySQL数据库。服务器定期关闭和打开,并且没有静态IP,这意味着每次打开应用程序时,我都会向网络上的每个IP发送一个虚拟SQL命令。有没有办法减少请求的超时以加快处理速度?我已经在使用线程并发尝试多个IP。我已包括当前班级以供参考。
import java.sql.*;
public class PortSniffer {
// Stores number of connections to test per thread
int threadIPcount = 3;
// Stores list of IP's
String[] ip = new String[threadIPcount];
//Stores active threads
Sniffer[] sniff = new Sniffer[1 + (255 / threadIPcount)];
public PortSniffer() {
InetAddress localHost = null;
try {
localHost = Inet4Address.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
NetworkInterface networkInterface = null;
try {
networkInterface = NetworkInterface.getByInetAddress(localHost);
} catch (SocketException e) {
e.printStackTrace();
}
// Gets current mask
String[] host = networkInterface.getInterfaceAddresses().get(0).getAddress().toString().split("\\.");
String mask = host[0].replace("/", "") + "." + host[1] + "." + host[2];
Log.logLine(this.getClass(), "Searching for server");
int counter = 0;
int threadCount = 0;
for (int i = 0;i < 255;i++) {
if (counter == threadIPcount) {
counter = 0;
sniff[threadCount] = new Sniffer(ip.clone());
sniff[threadCount].start();
Log.logLine(this.getClass(), "Running thread count " + threadCount);
threadCount++;
}
ip[counter] = "jdbc:mysql://" + mask + "." + i + "/apdb";
counter++;
}
// Runs remainder threads (10/3 would result in 1 excess thread)
sniff[threadCount] = new Sniffer(ip.clone());
sniff[threadCount].start();
}
private class Sniffer extends Thread {
String openIP;
String[] ip;
public Sniffer(String[] ip) {
this.ip = ip;
Log.log(this.getClass(), "Thread " + this.getId() + " checking IP ", ip);
}
public void run() {
for (String i:
ip) {
if(poke(i)){
openIP = i;
break;
}
}
}
private boolean poke(String ip) {// Returns true/false depending on if server is available
try {
Connection dbConnection = DriverManager.getConnection(ip, "user", "password");
Statement statement = dbConnection.createStatement();
ResultSet result = statement.executeQuery("SELECT 1 AS A");
result.next();
if (result.getInt("A") != 1) throw new SQLException();
Log.logLine(this.getClass(), "IP check on " + ip + " success");
return true;
} catch (SQLException e) {
Log.logLine(this.getClass(), "IP check on " + ip + " fail");
return false;
}
}
}
}
您可以在DriverManager中设置超时:
DriverManager.setLoginTimeout(10);
Connection c = DriverManager.getConnection(url, username, password);
但是,在您的情况下,您需要检查一组IP,可以尝试在连接前使用'ping'来减少尝试次数。使用IP作为地址,数据库服务器端口和超时来调用此函数。因此,您只需要检查网络中运行数据库服务器的计算机即可。
private static boolean crunchifyAddressReachable(String address, int port, int timeout) {
try {
try (Socket crunchifySocket = new Socket()) {
// Connects this socket to the server with a specified timeout value.
crunchifySocket.connect(new InetSocketAddress(address, port), timeout);
}
// Return true if connection successful
return true;
} catch (IOException exception) {
exception.printStackTrace();
// Return false if connection fails
return false;
}
}