2

レプリケーション ドライバーを使用しcom.mysql.jdbc.ReplicationDriverており、jdbc を使用して接続を構成しています

jdbc.de.url=jdbc:mysql:replication://master:3306,slave:3306/lieferando_de?zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8&tcpKeepAlive=true

c3p0 は、プールされた接続を 30 秒ごとにテストするように構成されています。

<bean id="basisDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" abstract="true">
        <property name="driverClass" value="${jdbc.driverClassName}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="minPoolSize" value="5" />
        <property name="maxPoolSize" value="30" />
        <property name="maxIdleTime" value="14400" />
        <property name="maxConnectionAge" value="14400" />
        <property name="testConnectionOnCheckout" value="false" />
        <property name="idleConnectionTestPeriod" value="30" />
        <property name="preferredTestQuery" value="SELECT 1" />
    </bean>

しかし、テストされているのはマスターだけです

[DEBUG] 25.06.2013 13:29:30 com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0 Testing PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@6b6a16ae] on IDLE CHECK.
[DEBUG] 25.06.2013 13:29:30 com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1 Testing PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@5c219c51] on IDLE CHECK.
[DEBUG] 25.06.2013 13:29:30 com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2 Testing PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@7e350225] on IDLE CHECK.
[DEBUG] 25.06.2013 13:29:30 com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1 Test of PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@5c219c51] on IDLE CHECK has SUCCEEDED.
[DEBUG] 25.06.2013 13:29:30 com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1 Testing PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@602f892f] on IDLE CHECK.
[DEBUG] 25.06.2013 13:29:30 com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0 Test of PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@6b6a16ae] on IDLE CHECK has SUCCEEDED.
[DEBUG] 25.06.2013 13:29:30 com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0 Testing PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@7deb41d6] on IDLE CHECK.
[DEBUG] 25.06.2013 13:29:30 com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2 Test of PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@7e350225] on IDLE CHECK has SUCCEEDED.
[DEBUG] 25.06.2013 13:29:30 com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1 Test of PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@602f892f] on IDLE CHECK has SUCCEEDED.
[DEBUG] 25.06.2013 13:29:30 com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0 Test of PooledConnection [com.mchange.v2.c3p0.impl.NewPooledConnection@7deb41d6] on IDLE CHECK has SUCCEEDED.

最初はマスターとスレーブへの接続が開いており、カウントは 5 です。

macbookpro-533f:~ mlaug$ netstat -nat | grep 3306
tcp4       0      0  10.10.14.181.57215     slave.3306     ESTABLISHED
tcp4       0      0  10.10.14.181.57214     slave.3306     ESTABLISHED
tcp4       0      0  10.10.14.181.57213     master.3306     ESTABLISHED
tcp4       0      0  10.10.14.181.57212     master.3306     ESTABLISHED
tcp4       0      0  10.10.14.181.57211     slave.3306     ESTABLISHED
tcp4       0      0  10.10.14.181.57209     slave.3306     ESTABLISHED
tcp4       0      0  10.10.14.181.57210     slave.3306     ESTABLISHED
tcp4       0      0  10.10.14.181.57208     master.3306     ESTABLISHED
tcp4       0      0  10.10.14.181.57207     master.3306     ESTABLISHED
tcp4       0      0  10.10.14.181.57206     master.3306     ESTABLISHED

しかし、スレーブ接続はちょうど 5 分後に消え、アプリケーションはBroken Pipe Exception.

c3p0スレーブ接続もテストするように構成するにはどうすればよいですか?

4

1 に答える 1

0

私にとって問題を解決したのはDefaultConnectionTester、c3p0の独自の実装と構成でした

<property name="connectionTesterClassName" value="x.y.z.QueryReplicationConnectionTester" />

次の実装を使用します

public class QueryReplicationConnectionTester extends DefaultConnectionTester{

    private static final long serialVersionUID = -3450145378350470297L;

    /**
     * during testing we need to make sure, that not only master
     * but also the slave connection is used. Therefore we need to set
     * the connection to "readonly" to make sure, that the slave 
     * connection is used.
     * 
     * CAUTION: this will only work for ONE SLAVE ENVIRONMENT, since
     * this does not make sure all slaves are checked.
     */
    @Override
    public int activeCheckConnection(Connection connection, String arg1, Throwable[] arg2) {

        // Initially set to ok
        int status = CONNECTION_IS_OKAY;

        try {

                    // remember state and 
            boolean autoCommit = connection.getAutoCommit();
                    boolean readOnly = connection.isReadOnly();

            // switch to slave and check slave
            connection.setReadOnly(true);
            connection.setAutoCommit(false);
            status = super.activeCheckConnection(connection, arg1, arg2);

            // if slave is fine, lets check the master
            if ( status == CONNECTION_IS_OKAY ){
                connection.setReadOnly(false);
                connection.setAutoCommit(autoCommit);
                status = super.activeCheckConnection(connection, arg1, arg2);
            }

            connection.setAutoCommit(autoCommit);
            connection.setReadOnly(readOnly);

        } catch (SQLException e) {
            status = CONNECTION_IS_INVALID;
        }

        // return final state
        return status;
    }

}
于 2013-10-05T02:38:46.923 に答える