Reputation: 388
I am using the JDBC to connect to a MySQL database on the same network as my application. The server is regularly switched off and on and does not have a static IP meaning each time I open the application I send a dummy SQL command to each IP on the network. Is there a way to decrease the timeout of a request to speed the process up? I am already using threading to try multiple IP concurrently. I have included my current class for reference.
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;
}
}
}
}
Upvotes: 0
Views: 199
Reputation: 196
You can set a timeout in DriverManager:
DriverManager.setLoginTimeout(10);
Connection c = DriverManager.getConnection(url, username, password);
But, in your case, you have a set of IPs to check, you can try to decrease the number of attemps by using a 'ping' before connection. Call this function with IP as address, the Database server port and a timeout. So, you only will have to check the machines with a database server running in the net.
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;
}
}
Upvotes: 1