У меня есть экземпляр MySQL, развернутый на сервере Amazon EC2 вместе с файлом Java .Jar, который подключается к локальной базе данных для архивирования метаданных, полученных из API. У меня Java-файл автоматически запускается 4 раза в день через задачу Linux Crontab.
Мой код всегда будет запускаться и сначала нормально подключаться к MySQL, но затем он будет испытывать сбой канала связи JDBC через минуту после запуска (однако время, в течение которого это происходит, может варьироваться). Это следующее сообщение об ошибке, которое отображается на терминале:
com.mysql.cj.jdbc.exceptions.CommunicationsException: сбой линии связи
Последний пакет, успешно полученный от сервера, был 4 278 миллисекунд назад.
Перед отображением вышеуказанного сообщения об ошибке моя программа зависла. Замораживание моей программы очевидно, потому что она перестает выводить: «Точка метаданных была заархивирована». У меня есть вывод моей программы, что каждый раз точка метаданных из API архивируется соответственно в таблицы моей базы данных.
Я пытался найти много решений, чтобы решить эту проблему, и я совершенно не понимаю, что ее вызывает. Я добавил несколько параметров в мою строку URL:
JDBC: MySQL: // локальный / MYDBNAME serverTimezone = EST5EDT & UseSSL = ложь и autoReconnect = истина & maxReconnects = 10 & failOverReadOnly = ложь и allowPublicKeyRetrieval = истина и useUnicode = верно и tcpKeepAlive = верно и interactiveClient = верно?
Параметр autoReconnect иногда позволяет моей программе повторно подключаться к базе данных после сбоя канала связи и выполнять заново, но иногда это не помогает вообще.
Я гарантировал, что моя программа не закрывает соединение JDBC до завершения программы.
Я гарантировал, что все мои подготовленные состояния и наборы результатов закрываются в блоке finally после выполнения или получения значений из них.
Я гарантировал, что версия MySQL коннектора java driver.jar, которую использует моя программа, совпадает с версией установленной базы данных MySQL.
Я пытался увеличить встроенные переменные тайм-аута MySQL.
Ниже приведен метод, который я использую для инициализации глобальной переменной подключения, которая используется исключительно для запросов в этом классе для запросов.
private void setUpConnectionToDatabase() {
try {
connection = DriverManager.getConnection(
url, username, password); // connects to server using url, username, password.
} catch (Exception e) {
System.out.println(e);
connection=null;
}
}
Ниже приведен один из моих методов, который запрашивает базу данных. Дайте мне знать, если увидите какие-либо ошибки. Другие методы в классе, по сути, следуют тому же формату. Обратите внимание, что сама переменная соединения не закрывается в методе.
public Coordinates getCoordsFromArchivedLocationData(String bioLocation) {
Coordinates coords= new Coordinates();
double lat=0;
double longit=0;
String queryStatement= "SELECT latitude, longitude FROM archived_location_data WHERE LocationName=?;";
PreparedStatement query=null;
ResultSet result=null;
try {
query = connection.prepareStatement(queryStatement);
query.setString(1, bioLocation);
result = query.executeQuery();
if(result.next()) {
lat= result.getDouble(1);
longit= result.getDouble(2);
}
coords.setLatitude(lat);
coords.setLongitude(longit);
}
catch(Exception e) {
System.out.println(e);
return coords;
}
finally {
try {
if(query != null) {
query.close();
}
if(result != null) {
result.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return coords;
}