- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在 Eclipse Juno 中开发 Java EE Web 应用程序。我已将 Tomcat 配置为使用 JDBC 连接池 (org.apache.tomcat.jdbc.pool) 和 PostgreSQL 数据库。以下是我项目的 META-INF/context.xml 中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!-- Configuration for the Tomcat JDBC Connection Pool -->
<Resource name="jdbc/someDB"
type="javax.sql.DataSource"
auth="Container"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/somedb"
username="postgres"
password="12345"
maxActive="100"
minIdle="10"
initialSize="10"
validationQuery="SELECT 1"
validationInterval="30000"
removeAbandoned="true"
removeAbandonedTimeout="60"
abandonWhenPercentageFull="50" />
</Context>
我的应用程序使用 Eclipse 部署到 Tomcat,并且在 Tomcat 的 context.xml 中,属性 reloadable 设置为“true”,以便在检测到更改时自动重新加载 Web 应用程序:
<Context reloadable="true">
我注意到,每次发生上述自动重新加载时,都会保留 10 多个与 PostgreSQL 数据库的连接(因为在 webapp 的 context.xml 中 initialSize="10")。所以在 10 次更改后会抛出 PSQLException:
org.postgresql.util.PSQLException: FATAL: sorry, too many clients already
...
如果我手动重启 Tomcat - 一切都很好,只保留了 10 个连接。
是否有人知道解决此问题的方法,因此可以将 reloadable 设置为“true”进行开发,并且每次重新加载上下文时不会导致池化更多连接?
不胜感激。
附: Apache Tomcat 版本 7.0.32
最佳答案
为了解决这个问题,添加一个属性 closeMethod
(记录在 here)到 Resource 的值为“close” context.xml 文件中的元素。
这是我的/META-INF/context.xml 文件的正确内容:
<Context>
<!-- Configuration for the Tomcat JDBC Connection Pool -->
<Resource name="jdbc/someDB"
type="javax.sql.DataSource"
auth="Container"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/somedb"
username="postgres"
password="12345"
maxActive="100"
minIdle="10"
initialSize="10"
validationQuery="SELECT 1"
validationInterval="30000"
removeAbandoned="true"
removeAbandonedTimeout="60"
abandonWhenPercentageFull="50"
closeMethod="close" />
</Context>
注意属性closeMethod。我对其进行了测试,现在连接数严格按照 context.xml 文件中的定义进行保存!
注意
有一个时刻(与 JNDI 相关)需要处理。有关完整说明,请参阅更新 3。
好的,感谢 Apache Tomcat 提交者 Konstantin Kolinko,我找到了上述解决方案.我举报了this issue作为 ASF Bugzilla 上的一个 Apache Tomcat 错误,
结果证明这不是错误
(参见更新 1)。
好吧,它仍然是一个错误。 Mark Thomas ,Apache Tomcat 7 发布管理器,confirmed那(引用):
"This is a memory leak bug in jdbc-pool. PoolCleaner instances areretaining references to the ConnectionPool preventing it from beingGC'd.
...
This has been fixed in trunk and 7.0.x and will be included in7.0.34 onwards."
所以如果你的Tomcat版本较旧(低于7.0.34),请使用上述解决方案,否则,
从Apache Tomcat 7.0.34版本开始,应该不会出现我描述的问题。
(见更新 2)
这似乎是 my bug report 中最初描述的问题即使对于当前最新的 Apache Tomcat 版本 7.0.50 仍然存在,我还使用 Tomcat 7.0.47 复制了它(感谢 Miklos Krivan 指出)。虽然现在 Tomcat 有时会在重新加载后设法关闭额外的连接,有时重新加载后连接数会增加然后保持稳定,但最终这种行为仍然不可靠。
我仍然可以重现最初描述的问题(虽然也不是那么容易:它可能与连续重新加载的频率有关)。似乎这只是时间问题,即如果 Tomcat 在重新加载后有足够的时间,它会或多或少地管理连接池。正如马克·托马斯在他的 comment 中提到的那样(引用):“根据 closeMethod 的文档,该方法的存在仅仅是为了加速释放资源,否则这些资源会被 GC 释放。” (引用结束),看起来速度是决定性因素。
当使用 Konstantin Kolinko 提出的解决方案(使用 closeMethod="close"
)时,一切正常,并且保留的连接数严格按照 context.xml 文件中的定义保持。因此,使用 closeMethod="close"
似乎是(目前)避免在上下文重新加载后耗尽连接的唯一正确方法。
UPDATE 2 中描述的行为背后的谜团已解开。在我收到 reply 后,现在已经清除了更多详细信息来自 Mark Thomas(Tomcat 发布经理)。我希望这是最后一次更新。因此,正如更新 1 中提到的那样,该错误确实已修复。我将 Mark 回复中的重要部分作为引用发布在这里(强调我的):
The actual memory leak found while investigating this bug has beenfixed in 7.0.34 onwards as per comments #4 to #6.
The issue of the connections not being closed on reload is a result ofthe J2EE specification for JNDI resources and this part of the bugreport is therefore invalid. I am restoring the state of this bug tofixed to reflect that the memory leak that did exist has been fixed.
To expand on why the failure to immediately close connection afterreload is invalid, the J2EE specification provides no mechanism for thecontainer to tell the resource it is no longer required. Therefore allthe container can do is clear references to the resource and wait forgarbage collection (which will trigger the closure of the pool and theassociated connections). Garbage collection occurs at times determinedby the JVM so this is why it takes an indeterminate amount of time forconnections to be closed after a context reload as a garbagecollection may not occur for some time.
Tomcat has added the Tomcat specific JNDI attribute closeMethod whichcan be used to trigger the explicit close of a JNDI resource when acontext is stopped. If waiting for GC to clean up resources is notacceptable then simply use this parameter. Tomcat does not use thisby default as it may have unexpected and unwanted side-effects forsome JNDI resources.
If you'd like to see a standard mechanism provided for telling JNDIresources that they are no longer required then you need to lobby theJ2EE expert group.
只需使用本文开头介绍的解决方案(但以防万一,请记住使用它理论上可能会出现的 JNDI 相关问题)。
Michael Osipov建议使用他的CloseableResourceListener ,这可以防止在取消部署 Web 应用程序期间由未打开的资源导致的内存泄漏。所以你也可以试试看。
免责声明
UPDATES 的别名受到 Star Wars 的启发。电影系列。所有权利归其各自所有者所有。
关于java - 在 Tomcat 中启用 Context reload ="true"时,JDBC 连接池连接不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13595794/
请帮助修复算法并防止点击提交后重新加载:我的网站必须检查,用户是否曾经输入过昵称。如果他有,那么网站必须显示他的名字,如果没有,则要求输入。如果用户决定更改它,他将单击“重置用户名”。 点击“重置”后
我最近在 Chrome 中发现了这个新功能: 我可以找出选项 1 和选项 3 之间的区别,选项 2 可能介于两者之间,但我在任何地方都找不到更精确的信息。 有人知道这 3 个选项的确切行为吗? 最佳答
当我在模拟器上开发时一切都很好,但现在我正处于我的应用程序几乎完成但必须在真实设备上更改一些视觉小东西的阶段。出于这个原因,我希望有与在模拟器上测试时相同的选项:实时重载或热重载。 这是我摇动设备时的
所以,我在我的项目中使用了 gulp。 我使用 gulp-compass 来编译我的 Assets 。 而且,我的任务之一是监视开发人员的任务。像这样: gulp.task('live', funct
在 lein REPL 中有一个奇怪且非常烦人的行为,更不用说经常耗时了。 即,如果我将 :reload-all 与命名空间一起使用,并且它所需的命名空间有错误,则 repl 不会告诉我任何相关信息。
我需要使用 JavaScript 刷新页面。我尝试了 window.location.reload() 和 location.reload()。两者都在工作并重新加载页面。我应该使用哪一个? 最佳答案
我知道这很愚蠢,但我真的想了解 Location.reload() 和 window.location.reload() 之间的区别; 如果我使用 location.reload() 会发生什么?如果
In this plunk你有两个 ui-router 状态,一个父状态和一个子状态。当通过单击链接调用子级时,由于它具有选项 reload: true,因此它始终会重新加载。这很好,但问题是父状态也
当我用 expo 打开开发者菜单时,它显示: 实时重新加载不可用 和 热重载不可用 我已根据需要登录,我也尝试过使用二维码加载应用程序,但没有帮助。 .expo/settings.json: {
为什么 Live Reload、Hot Reload 和 Remote Debugger 都不可用?我试过了 重新加载 JS 包 重启模拟器 重新启动打包器 重新启动打包程序并清除缓存 重置模拟器 重
我在 Controller 中有这个: $scope.foo = function(){ return RolesService.remove({ data: rol
Angular.js 中的 $window.location.reload() 和 $route.reload() 有什么区别? 我已经使用了这两个东西,但它们的工作进度相同。 谁能解释一下区别? 最
只是一个简短的问题。我想知道是否有一个选项或开关可以启用重新加载按钮下的“硬重新加载”和“清空缓存和硬重新加载”选项而无需打开devtools,以便它们始终弹出,即使devtools没有开放。 我知道
我已经使用 flutter_web 有一段时间了,从来没有真正质疑过它在按下“热重载”时总是重新启动整个应用程序,但自从现在 flutter_web 被合并到主要的 flutter channel 我
例如,我希望导航中的此更改能够重新加载状态: #/detail/1 #/detail/2 但是我不希望这个导航重新加载状态: #/detail/1?search=blah #/detail/1?sea
遵循 uvicorn-gunicorn-fastapi-docker 中的文档我应该通过运行来运行我的图像: docker run -d -p 80:80 -v $(pwd):/app myimage
我看过很多关于 的帖子和出版物实时重载 , 热重载 , 和 热模块更换 ,指的是在 Web 客户端/FE 层工作时,在浏览器中立即反射(reflect)代码更改的不同做法。 我对这些术语指的是什么有一
我有一个脚本可以检查两个或多个选项是否相似。如果它们相似,我会阻止提交该页面。它有效,但仅当我在显示警报消息后刷新页面时才有效。如果我选择了一个合适的选项,除非刷新页面,否则错误警报仍保留在内存中。
我有一个脚本,可以动态地将一些参数写入配置文件,我需要根据更新的参数从链接模块调用一些函数。但是,当我在配置文件上调用 reload() 时,有时我看不到任何变化。 以下代码片段将解释该场景: imp
我已连接到远程 mysql 服务器,但在几次连接不良(由于自动化)后,我被服务器阻止。我正在尝试解锁自己。 提示建议我执行mysqladinlush-hosts # This was done loc
我是一名优秀的程序员,十分优秀!