我有一个Amazon EC2服务器上部署的MySQL实例以及一个Java .Jar文件,该文件连接到本地数据库以存档从API检索的元数据。我通过Linux Crontab任务每天自动执行4次Java文件。
我的代码最初总是可以正常运行并连接到MySQL,但随后它将在执行的大约一分钟内遇到JDBC Communications链接故障(但是,发生的时间范围可能会有所不同)。这是以下错误消息显示在终端上:
com.mysql.cj.jdbc.exceptions.CommunicationsException:通信链接失败
成功从服务器接收到的最后一个数据包是4278毫秒前。
在显示上述错误消息之前,我的程序似乎冻结了。我的程序被冻结很明显,因为它将停止输出:“元数据点已存档”。我得到程序输出,每次来自API的元数据点都相应地存储到数据库表中。
为了解决这个问题,我尝试了许多解决方案,而造成问题的原因我完全不知所措。我在网址字符串中添加了多个参数: jdbc:mysql:// localhost / MYDBNAME?serverTimezone = EST5EDT&useSSL = false&autoReconnect = true&maxReconnects = 10&failOverReadOnly = false&allowPublicKeyRetrieval = true&useUnicode = true&tcpKeepAlive = true&interactiveClient = true autoReconnect参数有时会允许我的程序在通信链接失败后重新连接到数据库并重新执行,但有时根本无济于事。
我已经确保程序完成后才关闭JDBC连接。 在执行或从中获取值之后,我已经确保所有我的PreparedStatement和结果集都将在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;
}