无法读取服务器的响应

问题描述 投票:0回答:4

我编写了一个Java程序,该程序连接到我服务器上的数据库,以查找记录、写入记录、更新和删除。由于某种原因,查找记录有效,但大多数时候,当我尝试保存或写入记录时,它会给出错误消息:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 9,787 milliseconds ago.       The last packet sent successfully to the server was 8,183 milliseconds ago.

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:2552)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3002)
... 46 more

谁能解释为什么会发生这种情况? 通常,当我让软件运行超过半分钟后,尝试添加记录时,这会给我错误消息。好像连接松了或者什么的。当我运行程序并快速写入新记录时,它起作用了

java mysql jdbc
4个回答
4
投票

我也遇到了同样的问题。我引用了很多帖子和评论,但对我有用的是更改

my.cnf
文件的一些参数。希望它也能帮助你......

my.cnf [mysqld] 部分

设置以下参数
interactive_timeout=180 # "No.of sec. a server waits for activity on interactive connection before closing it"

wait_timeout=180 # "No. of sec. a server waits for an activity on a connection before closing it"

max_connect_errors=9999 # "More than this number of interrupted connections from a host this host will be blocked from further connections"

skip-name-resolve # "Don't resolved host names. All host names are IP's"

2
投票

有时此问题是由于系统 RAM 的大小引起的。可能是您通过 RAM 使用缓冲区插入数据。为了摆脱这个问题。

  1. 在插入数据之前设置自动提交禁用。
  2. 插入一些适合您的系统 RAM 的数据(而不是 整个)。
  3. 提交查询。
  4. 重复步骤2和3,直到整个插入不再 完成了。

你可以通过下面的代码来理解这一点。

public static void main(string args[]) 
{
  Connection con = null;
  Statement stm = null;
  int i;
  float ratio;
  ratio=1.0f;
  try
  {
    Class.forName("com.mysql.jdbc.Driver");
    // Connecting to the database
    con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/demo",
                                      "ashish", "impetus");
    File f = new File("filler"); // taking the random text data from the file
                                 // filler.txt and inserting that string
                                 // in filler field of the relations
    RandomAccessFile r = new RandomAccessFile(f,"r");
    Random randomGenerator = new Random();
    String strLine=new String();
    int r1,flag=0;
    stm = con.createStatement();
    con.setAutoCommit(false) ;

    int k=0;
    i=0;                

    long sum2=0;
    while(k%50000==0)
    {
      final long start = currentTimeMillis();
      final StringBuilder builder =
        new StringBuilder("INSERT INTO accounts 
                           (aid, bid,abalance,filler) VALUES ");
      while(i!=naccounts*ratio*scale )
        {
        int j=i+1;
        for(int l=0;l<40;l++)
        {
          strLine+=((char)r.read());
          r.skipBytes(0);
        }
        r1=randomGenerator.nextInt(1500);
        if(strLine.equals(""))
        {
          flag=1;
        }
        if(flag!=1)
        {   
          strLine=strLine.replaceAll("\\s","");
          strLine=strLine.replaceAll("\\t","");
        }                   
        flag=0;
        if (i%50000!=0) 
        {
          builder.append(",");
        }
        builder.append(format("(%s, %s, %s, '%s')", j, 
                       i/naccounts+1, 0, strLine));
        strLine="";
        r.seek(r1);
        i++;
        if(i%50000==0||i>=naccounts*ratio*scale)
        {   
          final String query = builder.toString();
          final PreparedStatement statement1 = con.prepareStatement(query);
          statement1.execute();
          con.commit();
          final long stop= currentTimeMillis();
          sum2=sum2+(stop-start);
          statement1.close();
        }
        if(i%50000==0||i>=naccounts*ratio*scale)
        {
          break;
        }
      }
      k=k+50000;
      if(k>naccounts*ratio*scale)
      {
        break;
      }
    }
    System.out.println(i+" rows inserted accounts table ");
    System.out.println("time taken = "+sum2+" milliseconds");
  }
  catch (SQLException e)
  {
    System.out.println("Connection Failed! Check output console");
    e.printStackTrace();
    return;
  }
  catch (Exception e) 
  {
    e.printStackTrace();
  }
}

0
投票

您遵循/阅读本教程了吗:

与 MYSQL 连接

您的例外情况有一部分对您有用。

我将引用一些有关您的特定例外情况的内容,请尝试一下:

如果收到 SQLException:连接被拒绝或连接超时 或 MySQL 特定的 CommunicationsException: Communications link 失败,则意味着数据库根本无法访问。这个可以 有以下一种或多种原因:

JDBC URL 中的 IP 地址或主机名错误。 JDBC URL 中的主机名是 本地 DNS 服务器无法识别。端口号缺失或错误 JDBC 网址。数据库服务器已关闭。数据库服务器不接受 TCP/IP 连接。数据库服务器已耗尽连接。东西在 Java 和 DB 之间的连接是阻塞的,例如防火墙或代理。

要解决其中一个问题,请遵循以下建议:

使用 ping 验证并测试它们。刷新 DNS 或在 JDBC 中使用 IP 地址 改为网址。根据MySQL DB的my.cnf进行验证。启动数据库。 验证 mysqld 是否在没有 --skip-networking 选项的情况下启动。 重新启动数据库并相应地修复您的代码以使其关闭 连接终于进来了。禁用防火墙和/或配置 防火墙/代理来允许/转发端口。


0
投票

对于我来说,我使用 TiDb 作为数据库,tidb 服务器内存是 16GB,我升级到 32GB,问题暂时解决了。

© www.soinside.com 2019 - 2024. All rights reserved.