- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我遇到一个问题,在我通过 tomcat 网络应用程序应用户请求重置我的 MySQL 数据库后,我遇到了 tomcat 异常。到目前为止,我已尝试将其分解为设置、问题和我的分析,以帮助任何试图阅读本文的人。
重置基本上包括从 java 代码调用 bash 脚本以:
这是一个用户启动的过程,通常将数据库恢复到以前的状态,但它也可用于从另一个系统导入数据库。一切都完成后,用户将尝试访问 Web 应用程序的不同部分(即使用相同的 session 而不注销/重新登录),这会执行数据库查询以获取一些数据。
一旦tomcat应用查询DB,出现异常:
Dec 29, 2014 3:49:50 PM ERROR BasicSecurityRealm:216 -
ERROR: ----- SQLException -----
Dec 29, 2014 3:49:50 PM INFO BasicSecurityRealm:218 - Exceptioncom.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 234,810 milliseconds ago. The last packet sent successfully to the server was 12 milliseconds ago.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
...
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:2540)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2990)
即使用户注销并重新登录,我也会看到这个异常。如果我刷新页面四次,页面每次都会加载更多一些,但会出现一些不同的异常(上述所有变体 - 由“EOFException:无法从服务器读取响应”引起的 CommunicationsException)。最后一次,一切似乎都在正常运行。
要避免这些异常,我唯一能做的就是重新启动 tomcat。我想避免这种情况,因为这意味着当前登录的用户将失去他们的 session ,并且必须等待 tomcat 重新启动才能重新登录。强制他们注销/重新登录可能是一个可以接受的妥协,但这并不能解决问题。
据我所知,我认为问题与 JDBC 连接池有关。我正在使用 JNDI 数据源访问我的数据库,如下所示:
服务器.xml:
<GlobalNamingResources>
<Resource name="jdbc/mydb"
auth="Container"
type="javax.sql.DataSource"
maxActive="30" maxIdle="30" maxWait="2147483647"
username="x" password="x"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mydb?autoReconnect=true"/>
web.xml:
<!-- Data source definitions -->
<resource-ref>
<res-ref-name>jdbc/mydb</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
Java:
// Get connection to specified database
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
DataSource ds = (DataSource) envCtx.lookup("jdbc/mydb");
con = ds.getConnection();
stmt = con.createStatement();
rs = stmt.executeQuery("...");
我认为连接池中包含过时/失效的连接。每当我与 ds.getConnection
建立连接时,它就会获得这些旧连接之一。第一次尝试使用它会失败,连接会重置(请注意我正在使用 autoReconnect=true
,所以第二次应该(并且确实)有效)。但是,该池包含许多(在我的例子中,经验上有 4 或 5 个)失效连接,因此需要一段时间才能将它们全部正确重置。重置连接后,一切都会正常运行。
因为我使用了 autoReconnect=true
,所以我可以重新构建我的代码,这样如果我在尝试查询时遇到异常,我可以重试一次查询。如果再失败,我就知道真的有问题了。如果通过,则连接已成功重新建立。
问题在于代码中到处都有查询。重构它们将花费大量时间和测试,如果有必要我会这样做,但我想避免。此外,如果查询由于其他原因失败,则在报告之前会尝试两次。对于长查询,这可能会导致严重的用户体验延迟,但仅限于错误情况。
另一种解决方案是强制重置/重新连接连接池中的所有连接。我可以通过编程方式(即在 bash 脚本调用完成时从我的 java 代码)或从 bash 脚本(例如使用某种类型的命令行实用程序)来执行此操作。问题是,我不知道该怎么做,或者是否可能。
我找到了一些关于拦截器的文档,但我不确定这是否适用于重置连接。我会继续调查。
感谢大家的时间和帮助!
最佳答案
您可以在从池中获取之前测试连接
默认 Tomcat <7 使用 commond-dbcp对于 Tomcat >= 7,它是 jdbc-pool
在这两种情况下,将下一个属性添加到连接池配置中:
validationQuery=<TEST SQL>
testOnBorrow=true
关于java - 如何重置 JDBC 连接池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27693147/
最近,我们将专用 SQL 池部署到生产中的 Synapse 工作区。在开发中,我们可以访问无服务器 SQL 池和专用 SQL 池。但是,在生产中,我们可以访问无服务器 SQL 池,但无法访问专用 SQ
假设您从一个项目公开 WCF 服务,并使用“添加服务引用”(在本例中为 Framework 3.5 WPF 应用程序)在另一个项目中使用它。 当您重新实例化 ClientBase 派生代理时,Clie
我有一个函数,它使用 multiprocessing.Pool 并行处理一个数据集中的所有数据。 from multiprocessing import Pool ... def func():
我正在尝试使用进程对象在 python 中使用工作池。每个 worker (一个进程)进行一些初始化(花费大量时间),传递一系列作业(理想情况下使用 map()),并返回一些东西。除此之外,不需要任何
我是软件工程师,最近我构建了我的 Linux 机器,想探索更多系统管理员类型的任务。我已经探索并阅读了很多关于 ZFS 的内容,但我越来越困惑,因为每篇文章对它的描述都不一样。 Everything
我有 zfs 池: $ sudo zpool status lxd pool: lxd state: ONLINE scan: none requested config: NAME
我有一个基于 Actor 的项目,对于其中的一部分,我必须使用一些接收消息的 Actor ,然后一个 Actor 分别分配给每个请求,每个 Actor 负责执行其消息请求,所以我需要类似线程的东西我的
我已经使用 QEMU 模拟器成功地将 FreeBSD 安装到原始图像文件中。我已经使用 ZFS 文件系统 (ZFS POOL) 格式化了图像文件。 使用下面的命令我已经成功地挂载了准备好由 zpool
我正在使用 multiprocessor.Pool并行处理一些文件。该代码等待接收文件,然后使用 Pool.apply_async 将该文件发送给工作人员。 ,然后处理文件。 这段代码应该一直在运行,
我正在使用带有光滑的 Bonecp 数据源。并发现池包含关闭的连接所以我总是遇到这个异常 java.sql.SQLException: Connection is closed! at com
我有apartment gem的 Multi-Tenancy Rails应用程序,我可以使用apartment-sidekiq在每个工作程序中成功切换数据库租户。但是,sidekiq worker 正
ZFS 池可能由数据集(文件系统、快照等)或卷组成。 ZFS 卷就像 block 设备,但我不明白池和文件系统之间的区别。当我通过 zpool create pool1 sda sdb sdc 创建
我在 docker 容器上运行了 airflow。我正在使用 airflow 2.0.2 版。 我知道我实际上可以通过 UI 创建池。但我正在寻找一种通过 pools.json 文件在 docker
我在tomcat中有一个jdbc池,用于建立数据库连接。我在使用后没有显式关闭连接对象。我的“maxActive”参数设置为100。应用程序运行了一段时间,但随后失败进行数据库查询。它会等待无限时间来
阅读 PostgreSQL 文档 here我读了以下内容: As well, connections requested for users other than the default config
我在 docker 容器上运行了 airflow。我正在使用 airflow 2.0.2 版。 我知道我实际上可以通过 UI 创建池。但我正在寻找一种通过 pools.json 文件在 docker
我正在读取一个大的 URL 文件并向服务发出请求。该请求由返回 ListenableFuture 的客户端执行。现在我想保留一个 ListenableFuture 池,例如最多同时执行 N 个 Fut
我想使用队列来保存结果,因为我希望消费者(串行而不是并行)在工作人员产生结果时处理工作人员的结果。 现在,我想知道为什么以下程序挂起。 import multiprocessing as mp imp
我正在开发一个单页应用程序,目前正在构建一个 JQuery、ajax 函数,以便我的所有调用都能通过。 对于一个典型的页面,我可能有 3 个 ajax 调用。我的想法是,如果用户互联网出去将这些 aj
我有一个单位类及其一些子类(弓箭手、剑客等)。我怎样才能创建一个回收所有单元类型子类的池? 最佳答案 这是不可能的,因为池只能包含一种特定类型的对象。否则你可能会遇到这样的情况: Pool unitP
我是一名优秀的程序员,十分优秀!