风暴在23小时后崩溃

时间:2012-11-14 22:18:21

标签: java mysql jdbc apache-storm

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

SQL Exception
SQL State: 08003

这样做了几次就死了。我正在使用标准JBDC连接器从Java连接到数据库。存储和设置DB连接的功能代码如下:

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错误而显然它崩溃后我决定如果它抛出该错误它应该重试连接的设置,但是这也没有帮助。有人能指出我正确的方向来解决这个问题吗?

1 个答案:

答案 0 :(得分:3)

  

由于08003错误而显然它崩溃后我决定如果它抛出该错误它应该重试连接的设置,但是这也没有帮助。有人能指出我正确的方向来解决这个问题吗?

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

  • 为什么连接首先会丢失?
  • 为什么不尝试重新连接成功?

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

我的猜测是问题是以下之一:

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

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

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

我会在需要时检查setupConnection是否被称为,并查找可能引发的任何异常。此外,您应该确保明确close()死连接对象...并重新考虑/重新编码您的连接管理,以便它不会泄漏。


对于记录,有一个名为“autoReconnect”的连接URL参数,它在过去曾用于“处理”丢失的连接。不幸的是,最初的实施是不安全的,所以他们有效地禁用了它;有关详细信息,请参阅此问题:Why does autoReconnect=true not seem to work?