ошибка соединения с одним узлом cassandra

Я пытаюсь использовать кассандру в качестве базы данных для приложения, над которым я работаю. Это приложение платформы Netbeans. Чтобы запустить сервер cassandra на моем локальном хосте, я выдаю Runtime.getRuntime (). Exec (command), где command - это строка для запуска сервера cassandra, а затем я подключаюсь к серверу cassandra с драйвером datastax. Однако я получаю сообщение об ошибке:

com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query   failed (tried: /127.0.0.1:9042 (com.datastax.driver.core.TransportException: [/127.0.0.1:9042]  Cannot connect))
at com.datastax.driver.core.ControlConnection.reconnectInternal(ControlConnection.java:199)
at com.datastax.driver.core.ControlConnection.connect(ControlConnection.java:80)
at com.datastax.driver.core.Cluster$Manager.init(Cluster.java:1154)
at com.datastax.driver.core.Cluster.getMetadata(Cluster.java:318)
at org.dhviz.boot.DatabaseClient.connect(DatabaseClient.java:43)
at org.dhviz.boot.Installer.restored(Installer.java:67)
....

Я понял, что серверу требуется некоторое время для запуска, поэтому я добавил строку Thread.sleep (MAX_DELAY_SERVER), которая, похоже, решает проблему.

Есть ли более элегантный способ решить эту проблему? Спасибо.

Код ниже.

public class Installer extends ModuleInstall {

private final int MAX_DELAY_SERVER = 12000;

//private static final String pathSrc = "/org/dhviz/resources";
@Override
public void restored() {

    /*
     -*-*-*-*-*DESCRIPTION*-*-*-*-*-*
     IMPLEMENT THE CASSANDRA DATABASE
     *********************************
     */
    DatabaseClient d = new DatabaseClient();
    // launch an instance of the cassandra server 
    d.loadDatabaseServer();


    /*wait for MAX_DELAY_SERVER milliseconds before launching the other instructions. 
    */
    try {
        Thread.sleep(MAX_DELAY_SERVER);
        Logger.getLogger(Installer.class.getName()).log(Level.INFO, "wait for MAX_DELAY_SERVER milliseconds before the connect database");
    } catch (InterruptedException ex) {
        Exceptions.printStackTrace(ex);
        Logger.getLogger(Installer.class.getName()).log(Level.INFO, "exeption in thread sleep");
    }

    d.connect("127.0.0.1");

}
}



public class DatabaseClient {

private Cluster cluster;
private Session session;
private ShellCommand shellCommand;
private final String defaultKeyspace = "dhviz";

final private String LOAD_CASSANDRA = "launchctl load    /usr/local/Cellar/cassandra/2.1.2/homebrew.mxcl.cassandra.plist";

final private String UNLOAD_CASSANDRA = "launchctl unload /usr/local/Cellar/cassandra/2.1.2/homebrew.mxcl.cassandra.plist";

public DatabaseClient() {
    shellCommand = new ShellCommand();

}

public void connect(String node) {
//this connect to the cassandra database

    cluster = Cluster.builder()
            .addContactPoint(node).build();
//  cluster.getConfiguration().getSocketOptions().setConnectTimeoutMillis(12000);
    Metadata metadata = cluster.getMetadata();
    System.out.printf("Connected to cluster: %s\n",
            metadata.getClusterName());
    for (Host host
            : metadata.getAllHosts()) {
        System.out.printf("Datatacenter: %s; Host: %s; Rack: %s\n",
                host.getDatacenter(), host.getAddress(), host.getRack());

    }

        session = cluster.connect();


    Logger.getLogger(DatabaseClient.class.getName()).log(Level.INFO, "connected to server");
}

public void loadDatabaseServer() {
    if (shellCommand == null) {

        shellCommand = new ShellCommand();

    }
    shellCommand.executeCommand(LOAD_CASSANDRA);
    Logger.getLogger(DatabaseClient.class.getName()).log(Level.INFO, "database cassandra loaded");
}

public void unloadDatabaseServer() {
    if (shellCommand == null) {

        shellCommand = new ShellCommand();

    }

    shellCommand.executeCommand(UNLOAD_CASSANDRA);

    Logger.getLogger(DatabaseClient.class.getName()).log(Level.INFO, "database cassandra unloaded");
}

}

person user3498704    schedule 15.01.2015    source источник
comment
Почему вы не использовали драйвер cassandra? github.com/datastax/java-driver Что происходит при подключении через терминал?   -  person Lompa    schedule 16.01.2015
comment
Похоже, здесь используется java-драйвер на основе предоставленной трассировки стека.   -  person Andy Tolbert    schedule 16.01.2015


Ответы (2)


Если вы вызываете cassandra без каких-либо параметров в Runtime.getRuntime().exec(command), вероятно, это порождает cassandra в качестве фонового процесса и возвращается до того, как узел cassandra полностью запустился и прослушивает.

Я не уверен, почему вы пытаетесь встроить кассандру в свое приложение, но вы можете найти использование cassandra-unit полезен для обеспечения механизма встраивания кассандры в ваше приложение. Он в основном используется для запуска тестов, для которых требуется экземпляр cassandra, но он также может соответствовать вашему варианту использования.

Вики предоставляет полезный пример того, как запустить встроенный экземпляр cassandra с помощью cassandra-unit:

EmbeddedCassandraServerHelper.startEmbeddedCassandra();

По моему опыту, cassandra-unit будет ждать, пока сервер заработает, и слушает, прежде чем вернуться. Вы также можете написать метод, ожидающий использования сокета, используя логику, противоположную этому ответу.

person Andy Tolbert    schedule 15.01.2015
comment
Привет, Энди. Спасибо за вашу помощь. просто уточнение. Я новичок в программировании и очень зеленый в базах данных. У меня есть приложение, которое будет создавать ежегодные временные ряды для многих объектов, поэтому я подумал, что сохраню это в Кассандре, вместо того, чтобы хранить их все в памяти. На мой взгляд, Кассандра будет работать как сервер на машине, на которой запущено приложение. Проблема именно в том, что вы сказали. Сервер еще не прослушивает, пока не будет выдана команда подключения. Однако я не уверен, как использовать приведенный вами пример. Не могли бы вы дать еще несколько указателей? Спасибо. - person user3498704; 16.01.2015
comment
В приведенном мной примере вы имеете в виду EmbeddedCassandraHelper или ссылку на опубликованный мною ответ, в котором показано, как проверить, слушают ли сокеты? EmbeddedCassandraHelper просто запускает встроенный экземпляр cassandra в вашей JVM, что может быть не тем, что вам нужно, поскольку он разделяет ресурсы со всем остальным, что делает ваше приложение. Ответ, который я привел, может быть не лучшим примером сейчас, когда я думаю об этом. Лучше попробовать открыть сокет на localhost: 9042 вместо использования ServerSocket. Если вы не можете установить соединение с localhost: 9042, кассандра не слушает. - person Andy Tolbert; 16.01.2015
comment
Спасибо, Энди. Мне не удалось заставить код порта работать, но я черпал вдохновение в нем и изменил несколько строк в своем коде. Спасибо за вашу помощь ! - person user3498704; 30.01.2015

Я изменил код на следующий, вдохновленный приведенными ниже ответами. Спасибо за вашу помощь!

cluster = Cluster.builder()
            .addContactPoint(node).build();

    cluster.getConfiguration().getSocketOptions().setConnectTimeoutMillis(50000);

    boolean serverConnected = false;
    while (serverConnected == false) {
        try {
            try {
                Thread.sleep(MAX_DELAY_SERVER);

            } catch (InterruptedException ex) {
                Exceptions.printStackTrace(ex);
            }
            cluster = Cluster.builder()
                    .addContactPoint(node).build();

            cluster.getConfiguration().getSocketOptions().setConnectTimeoutMillis(50000);
            session = cluster.connect();
            serverConnected = true;

        } catch (NoHostAvailableException ex) {
            Logger.getLogger(DatabaseClient.class.getName()).log(Level.INFO, "trying connection to cassandra server...");
            serverConnected = false;
        }

    }                                                   
person user3498704    schedule 30.01.2015