Konfigurieren Sie den GlassFish-JDBC-Verbindungspool für Amazon RDS Multi-AZ-Failover
Ich habe eine Java EE-Anwendung, die in GlassFish auf EC2 mit einer MySQL-Datenbank auf Amazon RDS ausgeführt wird. Ich versuche, den JDBC-Verbindungspool so zu konfigurieren, dass Ausfallzeiten bei einem Datenbank-Failover minimiert werden.
Meine aktuelle Konfiguration funktioniert während eines Multi-AZ-Failovers nicht ordnungsgemäß, da die Standby-Datenbankinstanz (laut AWS-Konsole) in ein paar Minuten verfügbar zu sein scheint, während meine GlassFish-Instanz für eine lange Zeit (ca. 15 Minuten) nicht funktioniert ) vor der Wiederaufnahme der Arbeit.
Der Verbindungspool ist folgendermaßen konfiguriert:
asadmin create-jdbc-connection-pool --restype javax.sql.ConnectionPoolDataSource \
--datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource \
--isconnectvalidatereq=true --validateatmostonceperiod=60 --validationmethod=auto-commit \
--property user=$DBUSER:password=$DBPASS:databaseName=$DBNAME:serverName=$DBHOST:port=$DBPORT \
MyPool
Wenn ich a benutzeSingle-AZ db.m1.small instance undneustarten In der Datenbank der Konsole macht GlassFish die unterbrochenen Verbindungen ungültig, löst einige Ausnahmen aus und stellt die Verbindung wieder her, sobald die Datenbank verfügbar ist. In dieser Konfiguration habe ich weniger als 1 Minute Ausfallzeit.
Wenn ich a benutzeMulti-AZ db.m1.small instance undNeustart mit Failover Von der AWS-Konsole sehe ich überhaupt keine Ausnahme. Der Server wird vollständig angehalten, und alle eingehenden Anforderungen laufen aus. Nach 15 Minuten bekomme ich endlich folgendes:
Communication failure detected when attempting to perform read query outside of a transaction. Attempting to retry query. Error was: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 940,715 milliseconds ago. The last packet sent successfully to the server was 935,598 milliseconds ago.
Es sieht so aus, als ob jeder HTTP-Thread für eine ungültige Verbindung blockiert wird, ohne eine Ausnahme zu erhalten, sodass keine Möglichkeit besteht, eine Verbindungsüberprüfung durchzuführen.
Die Ausfallzeit im Multi-AZ-Fall liegt immer zwischen 15 und 16 Minuten. Es sieht also nach einer Art Zeitüberschreitung aus, die ich jedoch nicht ändern konnte.
Dinge, die ich erfolglos versucht habe:
Verbindungsleck-Zeitüberschreitung / WiederherstellungAnweisungsleckzeitüberschreitung / -rückforderungAnweisungs-Timeoutunter Verwendung einer anderen ValidierungsmethodemitMysqlDataSource
Anstatt vonMysqlConnectionPoolDataSource
Wie kann ich eine Zeitüberschreitung für feststeckende Abfragen festlegen, damit Verbindungen im Pool wiederverwendet, überprüft und ersetzt werden? Oder wie kann ich GlassFish ein Datenbank-Failover erkennen lassen?