Reputation: 101
I'm running regular Spring Boot 2.6.5 java app on Cloud Run that that periodicals has problems with connecting to DB - usually after a few days
I'm using spring-cloud-gcp-starter-sql-mysql to connect to DB. MySQL has private IP - using serverless VCP to connect to it.
I was connecting the issue with maintenance window / backup window - but that problem does not go away after couple of hours - redeploying the Cloud Run is the only help - and it helps for another few days ...
The stacktrace:
java.sql.SQLNonTransientConnectionException: Could not create connection to database server.
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException ( com/mysql.cj.jdbc.exceptions/SQLError.java:110 )
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException ( com/mysql.cj.jdbc.exceptions/SQLError.java:97 )
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException ( com/mysql.cj.jdbc.exceptions/SQLError.java:89 )
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException ( com/mysql.cj.jdbc.exceptions/SQLError.java:63 )
at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly ( com/mysql.cj.jdbc/ConnectionImpl.java:1002 )
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO ( com/mysql.cj.jdbc/ConnectionImpl.java:819 )
at com.mysql.cj.jdbc.ConnectionImpl.<init> ( com/mysql.cj.jdbc/ConnectionImpl.java:449 )
at com.mysql.cj.jdbc.ConnectionImpl.getInstance ( com/mysql.cj.jdbc/ConnectionImpl.java:242 )
at com.mysql.cj.jdbc.NonRegisteringDriver.connect ( com/mysql.cj.jdbc/NonRegisteringDriver.java:198 )
at com.zaxxer.hikari.util.DriverDataSource.getConnection ( com/zaxxer.hikari.util/DriverDataSource.java:138 )
at com.zaxxer.hikari.pool.PoolBase.newConnection ( com/zaxxer.hikari.pool/PoolBase.java:364 )
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry ( com/zaxxer.hikari.pool/PoolBase.java:206 )
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry ( com/zaxxer.hikari.pool/HikariPool.java:476 )
at com.zaxxer.hikari.pool.HikariPool.access$100 ( com/zaxxer.hikari.pool/HikariPool.java:71 )
at com.zaxxer.hikari.pool.HikariPool$PoolEntryCreator.call ( com/zaxxer.hikari.pool/HikariPool.java:726 )
at com.zaxxer.hikari.pool.HikariPool$PoolEntryCreator.call ( com/zaxxer.hikari.pool/HikariPool.java:712 )
at java.util.concurrent.FutureTask.run ( java/util.concurrent/FutureTask.java:264 )
at java.util.concurrent.ThreadPoolExecutor.runWorker ( java/util.concurrent/ThreadPoolExecutor.java:1128 )
at java.util.concurrent.ThreadPoolExecutor$Worker.run ( java/util.concurrent/ThreadPoolExecutor.java:628 )
at java.lang.Thread.run ( java/lang/Thread.java:829 )
Caused by: java.lang.RuntimeException
at com.google.cloud.sql.core.CloudSqlInstance.addExceptionContext ( CloudSqlInstance.java:574 )
at com.google.cloud.sql.core.CloudSqlInstance.fetchEphemeralCertificate ( CloudSqlInstance.java:515 )
at com.google.cloud.sql.core.CloudSqlInstance.lambda$performRefresh$0 ( CloudSqlInstance.java:330 )
at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly ( TrustedListenableFutureTask.java:125 )
at com.google.common.util.concurrent.InterruptibleTask.run ( InterruptibleTask.java:69 )
at com.google.common.util.concurrent.TrustedListenableFutureTask.run ( TrustedListenableFutureTask.java:78 )
at java.util.concurrent.Executors$RunnableAdapter.call ( Executors.java:515 )
at java.util.concurrent.FutureTask.run ( FutureTask.java:264 )
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run ( ScheduledThreadPoolExecutor.java:304 )
Upvotes: 2
Views: 503
Reputation: 2065
I managed to replicate your question and encountered the same stacktrace that you provided. I used this spring-cloud-gcp
github link and fixed the stacktrace error by editing the application.properties
under spring-cloud-gcp/spring-cloud-gcp-samples/spring-cloud-gcp-sql-mysql-sample/
folder.
This is the format that I follow:
spring.cloud.gcp.sql.database-name=<database-name>
spring.cloud.gcp.sql.instance-connection-name=<project-id>:<region>:<instance-id>
# So app starts despite "table already exists" errors.
spring.datasource.continue-on-error=true
# Enforces database initialization
spring.datasource.initialization-mode=always
# Leave empty for root, uncomment and fill out if you specified a user
#spring.datasource.username=
# Uncomment if root password is specified
spring.datasource.password=<password> # Uncomment this if you add a password for
your instance-id
spring.cloud.gcp.project-id=<project-id>
#spring.cloud.gcp.credentials.location=file:/path/to/service-account.json
Please make sure to avoid using quotation marks for the values as this would lead to the same stacktrace error. Just type the values as is.
If you're not using Cloud Shell, you need to create a service account from the Google Cloud Console and download its private key. Then, uncomment the spring.cloud.gcp.sql.credentials.location
property in the application.properties
file and fill its value with the path to your service account private key on your local file system, prepended with file:
.
Please let me know if you have questions or clarifications.
Upvotes: 1