Java-приложение, подключающееся ко многим узлам SQL

#java #sql #multithreading #performance

#java #sql #многопоточность #Производительность

Вопрос:

У меня есть Java-приложение, работающее на tomcat. Я хочу подключить его к моему кластеру MySQL.

В кластере у меня есть три узла SQL. Я хочу попытаться подключиться ко всем трем узлам, а затем использовать соединение, которое возвращается ко мне быстрее всего!

Как я могу это сделать? Производительность действительно важна для меня.

Вот что у меня есть на данный момент:

Класс соединителя

     public class Connecter extends Thread {

    String dbURL;
    String dbDriver = "com.mysql.jdbc.Driver";
    Connection dbCon = null;

    public Connecter(String dbURL) {
        this.dbURL = dbURL;
    }

    @Override
    public void run() {
        try {
            Class.forName(dbDriver);
            try {
                dbCon = DriverManager.getConnection(dbURL, "root", "");
            } catch (SQLException ex) {
            }
        } catch (ClassNotFoundException ex) {
        }
    }

}
 

Более близкий класс

 public void run() {
        try {
            dbCon.close();
        } catch (SQLException ex) {
            ex.printStackTrace();
        } catch (NullPointerException e) {}
    }
 

И DbBean пытается подключиться с помощью этого метода:

 String dbURL1 = "jdbc:mysql://192.168.0.3/bank";
String dbURL2 = "jdbc:mysql://192.168.0.4/bank";
String dbURL3 = "jdbc:mysql://192.168.0.5/bank";
String dbDriver = "com.mysql.jdbc.Driver";
private Connection dbCon;

public boolean connect() throws ClassNotFoundException, SQLException, InterruptedException {
    Class.forName(dbDriver);

    Connecter one = new Connecter(dbURL1);
    Connecter two = new Connecter(dbURL2);
    Connecter three = new Connecter(dbURL3);

    Closer a = new Closer (one.dbCon);
    Closer b = new Closer (two.dbCon);
    Closer c = new Closer (three.dbCon);

    one.start();
    two.start();
    three.start();

    while(one.isAlive() amp;amp; two.isAlive() amp;amp; three.isAlive()){
        Thread.sleep(10);
    }

    if(one.dbCon != null) {
        this.dbCon = one.dbCon;
        two.interrupt();
        b.start();
        three.interrupt();
        c.start();
        return true;
    } else {
        one.interrupt();
        a.start();
    }
    if(two.dbCon != null) {
        this.dbCon = two.dbCon;
        one.interrupt();
        a.start();
        three.interrupt();
        c.start();
        return true;
    } else {
        two.interrupt();
        b.start();
    }
    if(three.dbCon != null) {
        this.dbCon = three.dbCon;
        one.interrupt();
        a.start();
        two.interrupt();
        b.start();
        return true;
    } else {
        three.interrupt();
        c.start();
    }

    return false;
}
 

Комментарии:

1. Разве ваш драйвер JDBC (или источник данных J2EE) не должен позаботиться об этом за вас?

2. Вам не нужно делать это вручную, и затраты на накладные расходы / сложность не принесут никакой пользы. Пока вы не определили, что это реальное узкое место (что на первый взгляд кажется маловероятным), я не думаю, что буду заниматься этим. Кроме того, было бы более важно попытаться заставить машину быстрее обслуживать ваш запрос, что не то же самое, что тот, который может быстрее всего установить соединение.

3. @VictorSorokin Привет, я действительно не знаю, как я могу реализовать это с помощью готовых функций драйвера. Есть ли у вас какие-либо примеры конфигурации, которая заставляет меня пытаться подключиться к нескольким узлам SQL? Ссылка подойдет! Спасибо!

4. @DaveNewton Спасибо за совет, но как я могу автоматически это сделать?

Ответ №1:

Просто используйте базу данных, которая поддерживает объединение пулов соединений (любая современная СУБД поддерживает это), и используйте готовое решение, такое как DataSource or c3p0.

Смотрите, например, официальный учебник по JDBC .

Одна вещь, в которой я не уверен, заключается в том, нужен ли вам пул соединений или более продвинутая кластеризация. Но, в любом случае, я сомневаюсь, что MySQL может обеспечить стабильную кластеризацию, и, насколько я знаю, Oracle поддерживает прозрачную кластеризацию с помощью своего драйвера JDBC.

Комментарии:

1. Спасибо за это, но после вчерашнего просмотра в течение нескольких часов это решает мою проблему: jdbc:mysql:loadbalance://192.168.0.3,192.168.0.4,192.168.0.5/bank Мне просто нужно подключиться к этому URL. Для этого можно выполнить другие оптимизации. Видишь dev.mysql.com/doc/refman/5.1/en /…

2. @Nikunj странно, что балансировка нагрузки настроена на стороне приложения. Главный узел (балансировщик) должен принимать каждый запрос, а затем направлять его на оптимальный узел — разрешенный с помощью некоторой стратегии балансировки.

3. @Victor Я думаю, что объединение пулов соединений не имеет никакого отношения к СУБД. Сама СУБД не знает, что ее соединения объединяются в пул — это функция на стороне приложения (сервера приложений).