2012-11-14 40 views
5

大家好我有一个基本的Storm应用程序设置,它接收推文流并将它们存储在MySQL数据库中。该应用程序在第一〜23小时左右运行良好,然后开始给出以下错误:风暴23小时后崩溃

SQL Exception 
SQL State: 08003 

之后,它几次死亡。我使用标准的JBDC连接器从Java连接到数据库。是用于存储和建立数据库连接功能的代码如下:

private String _db=""; 
private Connection conn = null; 
private PreparedStatement pst = null; 

public ArchiveBolt(String db){ 
    _db = db; 
} 

private void setupConnection() { 
    //Connect to the database 
    try { 
     Class.forName("com.mysql.jdbc.Driver"); 
     conn = DriverManager.getConnection("jdbc:mysql://localhost:8889/twitter_recording", "root", "root"); 
    } catch (Exception e){ 
     e.printStackTrace(); 
    } 
} 

public void execute(Tuple tuple, BasicOutputCollector collector) { 

    Status s = (Status) tuple.getValue(0); 

    //setup the connection on the first run through or if the connection got closed down 
    try { 
     setupConnection(); 
    } catch (Exception e) { 
     // TODO: handle exception 
     System.out.println(e.toString()); 
    } 


    try { 

     pst = conn.prepareStatement("INSERT INTO " + _db + " (tweet)" + 
            "VALUES (?);"); 

     pst.setString(1, s.toString()); 

     //execute the SQL 
     pst.executeUpdate(); 

    } catch (SQLException ex) { 
     // handle any errors 
     System.out.println("SQLException: " + ex.getMessage()); 
     System.out.println("SQLState: " + ex.getSQLState()); 
     System.out.println("VendorError: " + ex.getErrorCode()); 

     if(ex.getSQLState().equals("08003")){ 
      setupConnection(); 
     } 

    } finally { 
     try { 
      conn.close(); 
     } catch (SQLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

后很明显,这是因为一个08003的错误,我决定,如果它抛出这个错误应该重试集的崩溃但是这并没有帮助。任何人都可以指出我解决这个问题的正确方向吗?

+0

[08003 \t连接不存在](http://dev.mysql.com/doc/refman/5。0/en/connector-odbc-reference-errorcodes.html) –

+0

连接是否在一天中的同一时间断开?如果是这样,也许连接被某个预定的事件中断(例如,DB每天重新启动)。 –

+0

是的,我知道这一点。这就是为什么我在遇到这个错误的情况下再次进行连接设置。如上所示'catch(SQLException ex){//处理任何错误 System.out.println(“SQLException:”+ ex.getMessage()); System.out.println(“SQLState:”+ ex.getSQLState()); System.out.println(“VendorError:”+ ex.getErrorCode()); (ex.getSQLState()。equals(“08003”)){ setupConnection(); } }' –

回答

3

After it became apparent that it was crashing because of a 08003 error I decided that if it threw that error it should retry the set up of the connection, however that didn't help either. Could anyone point me in the right direction for solving this issue?

基本上有这里有两个问题需要解决:

  • 为什么连接迷路摆在首位?
  • 为什么不尝试重新连接成功?

对于第一个问题,你应该看看MySQL日志,看看有没有迹象。此外,还要在(重复)“状态080003”异常之前检查SQL异常。后者只是告诉你,连接已经死亡。

我的猜测是,这个问题是下列之一:

  • MySQL服务器超时由于不活动的连接。如果这是问题,您可以在MySQL配置中更改连接超时。

  • 您的应用程序可能正在缓慢泄漏JDBC连接。

对于第二个问题,一般方法是正确的,但是您的代码与描述不匹配。实际上,它看起来像是总是每次调用execute方法时都试图建立一个新的数据库连接。这会使异常处理程序中的重新连接调用毫无意义。 (OTOH,代码显示有人一直在“殴打”以尝试使其工作......这可能是问题的一部分)。

我会检查setupConnection正在调用当它需要为时,并查找可能抛出的任何异常。另外,你应该确保你明确地知道close()死连接对象...并重新思考/重新编码你的连接管理,以便它不泄漏。


为了记录,有一个名为“autoReconnect”的连接URL参数,它在遥远的过去用于“处理”丢失的连接。不幸的是,最初的实施是不安全的,所以他们实际上已经禁用了它;看到这个问题的详细信息:Why does autoReconnect=true not seem to work?