【问题标题】:Communication to DB error in production [duplicate]生产中与数据库的通信错误[重复]
【发布时间】:2016-10-12 02:08:18
【问题描述】:

我做了一些网络应用程序来部署到生产环境中。但是几个小时后(看起来像 8 小时),我无法与 DB 通信。

这是我的 Connect.java

package util;

import java.sql.Connection;
import java.sql.DriverManager;
import javax.xml.ws.Response;

public class Connect {
    public static Connection connection = null;

    public static Connection getConnection() {
        if (connection != null) {
            return connection;
        } else {
            String driver = "com.mysql.jdbc.Driver";
            String url = "jdbc:mysql://localhost/DBPRK?autoReconnect=true&useUnicode=true&characterEncoding=utf8";
            String username = "prk";
            String password = "prk";

            try {
                Class.forName(driver);
                connection = DriverManager.getConnection(url, username, password);
            } catch (Exception e) {
                System.out.println("ERROR");
            }
            return connection;
        }
    }
}

这是我从 tomcat 日志中得到的错误消息:

com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception: 

** BEGIN NESTED EXCEPTION ** 

java.net.SocketException
MESSAGE: Software caused connection abort: socket write error

STACKTRACE:

java.net.SocketException: Software caused connection abort: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:2616)
    at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:2547)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1512)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1622)
    at com.mysql.jdbc.Connection.execSQL(Connection.java:2370)
    at com.mysql.jdbc.Connection.execSQL(Connection.java:2297)
    at com.mysql.jdbc.Statement.executeQuery(Statement.java:1183)
    at controller.GetAllClients.processRequest(GetAllClients.java:39)
    at controller.GetAllClients.doGet(GetAllClients.java:73)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:745)


** END NESTED EXCEPTION **


    at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:2634)
    at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:2547)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1512)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1622)
    at com.mysql.jdbc.Connection.execSQL(Connection.java:2370)
    at com.mysql.jdbc.Connection.execSQL(Connection.java:2297)
    at com.mysql.jdbc.Statement.executeQuery(Statement.java:1183)
    at controller.GetAllClients.processRequest(GetAllClients.java:39)
    at controller.GetAllClients.doGet(GetAllClients.java:73)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:745)

顺便说一句,我使用没有框架的纯 jsp。 非常感谢任何帮助。

【问题讨论】:

  • 当异常发生时,您是否可以从 cmd 或任何其他客户端连接到数据库?
  • 检查到运行您的数据库服务器的机器的网络连接?

标签: java mysql jdbc


【解决方案1】:

以下情况可能会出现此问题:

  1. 当我们试图获得过多的数据库连接时。
  2. 当数据库连接长时间空闲时。

所以,在你的程序中尝试在使用后关闭连接,并获得一个新的连接。

【讨论】:

  • 是的,连接绝对空闲了很长时间。如何获得与数据库的新连接?
  • 在每种方法中使用后关闭数据库连接,并且每当您需要再次与数据库通信时调用 Connect.getConnection() 以获取新连接。
【解决方案2】:

这在您的代码中显示以下行的异常:

at controller.GetAllClients.processRequest(GetAllClients.java:39)
at controller.GetAllClients.doGet(GetAllClients.java:73)

可能导致此异常的原因可能是您在获得和使用连接后可能没有关闭连接。

在任何计算机系统中,可用于连接的套接字数量都是有限的,这在很大程度上取决于您用于连接的硬件规格和驱动程序。

与数据库的连接在资源和性能方面具有很高的成本。每次考虑连接到数据库时都必须注意这一点。

现在假设一种情况,您有 5 辆自行车和 7 名骑手,所有骑手都需要一辆自行车,因此您可以为每个骑手分配 1 辆自行车,但最多只能有 5 名骑手,那么剩下 2 辆呢?因此,现在唯一的选择是等待任何两个骑车完成并归还自行车的骑手,以便您可以将其分配给其他两个骑手...但是在您的情况下,前 5 人拿走了自行车(连接到数据库),完成他们的骑行(对数据库执行查询)但没有返回自行车(没有关闭连接)。

同样,在您的情况下,它被分配但在使用后没有被释放,这反过来又占用所有可用的套接字并且没有可用的套接字来提供连接。

我假设您在 "con" 变量中捕获了“连接”(由 getConnection() 方法返回)。

现在,

con.close();

只需要写在这里。

还有一件事,目前所有的socket都被占用了,需要重启数据库服务器(MySQL等)和项目服务器(Tomcat等)。并在数据库使用结束后随处添加以上 1 行代码。

【讨论】:

  • 如果您没有收到此信息,请告诉我。我会尝试以不同的方式提供帮助...祝您有美好的一天...
  • 您使用引用块的事实表明您是从另一个来源复制的,请添加指向该来源的链接。如果这是您自己的文本,专门针对此问题编写,则不要使用引号。
  • @MarkRotteveel 伙计,我是 StackOverflow.com 的新手,所以如果这是你所说的写作方式,我会注意下次。那些是我的文字,同时打字 Stackoverflow.com 建议这样的事情来吸引读者的注意力,以便快速阅读重点。
  • @MarkRotteveel 我不相信复制。哈哈哈...谢谢老兄..
  • @ManojShukla 我已经尝试过 conn.close()。但它会导致其他问题。当我这样做时,我收到错误消息,指出“连接关闭后不允许操作”
【解决方案3】:

哥们,在String Url的连接中添加端口号(3306)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-16
    • 2019-09-03
    相关资源
    最近更新 更多