Parzavil
Parzavil

Reputation: 388

Decreasing timeout for JDBC MySQL connection attempts

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

Answers (1)

scae2201
scae2201

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

Related Questions