Grails如何连接多数据库

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Grails如何连接多数据库相关的知识,希望对你有一定的参考价值。

参考技术A 区分版本,2.X版本是在dataSource.groovy中,3.X版本是在application.yml中按照默认的datasource配置多个datasource即可

Grails 应用程序似乎持有对陈旧数据库连接的引用

【中文标题】Grails 应用程序似乎持有对陈旧数据库连接的引用【英文标题】:Grails app seems like it's holding a reference to a stale DB connection 【发布时间】:2012-10-15 16:48:35 【问题描述】:

更新:Rackspace 已回复我,并告诉我他们的 MySQL 云使用 wait_timeout 值为 120 秒

我一直在反对这个,所以我想我会问你们。您可能有任何想法将不胜感激

util.JDBCExceptionReporter  - SQL Error: 0, SQLState: 08S01
util.JDBCExceptionReporter  - Communications link failure
The last packet successfully received from the server was 264,736 milliseconds 
ago. The last packet sent successfully to the server was 32 milliseconds ago.

错误会间歇性发生,通常在相关服务器启动后几分钟。数据库在负载或连接方面远不及容量,我尝试了几十种不同的配置组合。

这个连接最后一次收到来自服务器的数据包是在 264 秒前这一事实表明,因为它远高于 Rackspace 设置的 120 秒超时。我还从数据库端确认,我的 30 秒限制得到遵守。

我尝试过的事情

将 DBCP 设置为在 30 秒后主动过期连接,并通过SELECT * FROM PROCESSLIST 验证 MySQL 实例反映了此行为 已将连接字符串从主机名切换到 IP 地址,因此这不是 DNS 问题 各种不同的连接设置组合 尝试在 DataSources.groovy 或 resources.groovy 中声明连接池设置,但我相当确定这些设置得到尊重,因为 DB 反映了这些设置:超过 30 秒的任何内容都会很快被终止

有什么想法吗?

现在我最好的猜测是,Grails 中的某些东西会长时间保持对陈旧连接的引用,以至于 120 秒的限制是有问题的......但这是一个令人绝望的理论,实际上我怀疑它是真的,但这留下了我没有想法。

我尝试过的最新配置:

dataSource 
    pooled = true
    driverClassName = "com.mysql.jdbc.Driver"
    dialect = 'org.hibernate.dialect.MySQL5InnoDBDialect'
    properties 
        maxActive = 50
        maxIdle = 20
        minIdle = 5 
        maxWait = 10000
        initialSize = 5
        minEvictableIdleTimeMillis = 1000 * 30
        timeBetweenEvictionRunsMillis = 1000 * 5
        numTestsPerEvictionRun = 50
        testOnBorrow = true
        testWhileIdle = true
        testOnReturn = true
        validationQuery = "SELECT 1"
    

堆栈跟踪:

2012-10-25 12:36:12,375 [http-bio-8080-exec-2] WARN  util.JDBCExceptionReporter  - SQL Error: 0, SQLState: 08S01
2012-10-25 12:36:12,375 [http-bio-8080-exec-2] ERROR util.JDBCExceptionReporter  - Communications link failure

The last packet successfully received from the server was 264,736 milliseconds ago.  The last packet sent successfully to the server was 32 milliseconds ago.
2012-10-25 12:36:12,433 [http-bio-8080-exec-2] ERROR errors.GrailsExceptionResolver  - EOFException occurred when processing request: [GET] /cart
Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.. Stacktrace follows:
org.hibernate.exception.JDBCConnectionException: could not execute query
at grails.orm.HibernateCriteriaBuilder.invokeMethod(HibernateCriteriaBuilder.java:1531)
at SsoRealm.hasRole(SsoRealm.groovy:30)
at org.apache.shiro.grails.RealmWrapper.hasRole(RealmWrapper.groovy:193)
at org.apache.shiro.authz.ModularRealmAuthorizer.hasRole(ModularRealmAuthorizer.java:374)
at org.apache.shiro.mgt.AuthorizingSecurityManager.hasRole(AuthorizingSecurityManager.java:153)
at org.apache.shiro.subject.support.DelegatingSubject.hasRole(DelegatingSubject.java:225)
at ShiroSecurityFilters$_closure1_closure4_closure6.doCall(ShiroSecurityFilters.groovy:98)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at org.apache.shiro.grails.SavedRequestFilter.doFilter(SavedRequestFilter.java:55)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:380)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 264,736 milliseconds ago.  The last packet sent successfully to the server was 32 milliseconds ago.
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3589)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3478)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4019)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2683)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2144)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2310)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
... 20 more
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3039)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3489)
... 29 more

【问题讨论】:

【参考方案1】:

想通了。 grails-elasticsearch 插件保留了陈旧的连接。这是该插件中的known issue 和fix came in via this pull request:

【讨论】:

以上是关于Grails如何连接多数据库的主要内容,如果未能解决你的问题,请参考以下文章

groovy grails构建测试数据(buildtestdata插件)如何创建多对多

如何使用 Gradle 设置多项目 Grails?

Grails:运行时改变dataSource url实现多租户数据库分离

Grails:如何在多对多映射中查询对象?

Grails 3 中一对多域的深拷贝

grails many_to_many 自定义映射表