5

こんにちは、基本的な 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 エラーが原因でクラッシュしていることが明らかになった後、そのエラーがスローされた場合は、接続のセットアップを再試行する必要があると判断しましたが、それも役に立ちませんでした。この問題を解決するための正しい方向に私を向けることができますか?

4

1 に答える 1

3

08003 エラーが原因でクラッシュしていることが明らかになった後、そのエラーがスローされた場合は、接続のセットアップを再試行する必要があると判断しましたが、それも役に立ちませんでした。この問題を解決するための正しい方向に私を向けることができますか?

基本的に、解決する必要がある 2 つの問題があります。

  • そもそも接続が失われるのはなぜですか?
  • 再接続の試みが成功しないのはなぜですか?

最初の問題については、MySQL ログを調べて、そこに兆候があるかどうかを確認する必要があります。また、(繰り返される)「state 080003」例外の直前に SQL 例外がないかチェックします。後者は、接続が以前に切断されたことを単に伝えています。

私の推測では、問題は次のいずれかです。

  • 非アクティブのため、MySQL サーバーが接続をタイムアウトしました。これが問題である場合は、MySQL 構成で接続タイムアウトを変更できます。

  • アプリケーションで JDBC 接続が徐々にリークしている可能性があります。

2 番目の問題については、一般的なアプローチは正しいですが、コードが説明と一致しません。実際、メソッドが呼び出されるたびに、常に新しいデータベース接続を確立しようとしているようです。executeこれにより、例外ハンドラーでの再接続呼び出しが無意味になります。(OTOH、コードは、誰かがそれを機能させようとして「それを打ち負かしている」という兆候を示しています...そしてそれは問題の一部である可能性があります。)

必要なときにsetupConnection呼び出されていることを確認し、スローされる可能性のある例外を探します。さらに、死んだ接続オブジェクトを明示的に確認し、リークしないように接続管理を再考/再コーディングする必要があります。close()


記録として、「autoReconnect」と呼ばれる接続 URL パラメータがあります。これは、遠い昔、失われた接続に「対処」するために使用されていました。残念ながら、元の実装は安全ではなかったため、事実上無効にしました。詳細については、この質問を参照してください: autoReconnect=true が機能していないように見えるのはなぜですか?

于 2012-11-15T00:12:28.257 に答える