1

JBoss の起動時に、JDBC 接続 (DefaultDS) に依存する Persistence Manager があります。JDBC 接続は、実際にデータベースに接続できるかどうかに関係なく正常に開始されるため、Persistence Manager の開始時に接続があると認識されます。その後、データベースに接続できず、起動しないため、爆発します。これにより、DestinationManager が起動しなくなり、あらゆる種類の頭痛の種になります。

JDBC 接続が実際にデータベースに接続できない限り、JDBC 接続に依存する MBean を開始しないようにする方法はありますか? 別の方法として、JDBC 接続を、データベースに接続できるときにのみアクティブな MBean に依存させる方法はありますか?

tl;dr; 必要なのは、MBeans/DestinationManager が起動前にデータベース (DefaultDS) が使用可能になるまで待機することだけです。

環境についてさらに情報が必要な場合は、コメントしてください。

  • JBoss バージョン 4.2.3

  • データベース: MSQL

4

2 に答える 2

2

私が問題を正しく理解している場合、問題が発生しています。DefaultDSデータ ソースが開始したことを報告しても、接続を取得していないため、接続が確立されていることを必ずしも認識していないためです。

残念ながら、事前入力オプションを有効にしても、データソース サービスは接続できなくても正常に開始されます。

最善の策は、開始を報告する前にデータソースからの実際の接続をチェックするServiceMBeanを実装することです。この例では、これをorg.bob.ConnCheckerと呼び、ObjectName org.bob:service=ConnCheckerを使用してデプロイします。

デプロイメント記述子は次のようになります。

  <mbean code="org.bob.ConnChecker" name="jboss.mq:service=DestinationManager">
    <depends optional-attribute-name="DataSource">jboss.jca:name=DefaultDS,service=ManagedConnectionPool</depends>
  </mbean>

したがって、データ ソースが開始されるまで、サービスは開始されません。接続できない限り、サービスは開始されません。次に、DestinationManager の依存関係としてorg.bob:service=ConnCheckerを追加する必要があります。

jboss.mq:service=MessageCache jboss.mq:service=PersistenceManager jboss.mq:service=StateManager jboss.mq:service=ThreadPool jboss:service=ネーミング org.bob:service=ConnChecker

ConnCheckerのコードは次のようになります。

....
import org.jboss.system.ServiceMBeanSupport;
....
public class ConnChecker extends ServiceMBeanSupport implements ConnCheckerMBean {
    /** The ObjectName of the data source */
    protected ObjectName dataSourceObjectName = null;
    /** The Datasource reference */
    protected DataSource dataSource = null;
    /**
     * Called by JBoss when the dataSource has started
     * @throws Exception This will happen if the dataSource cannot provide a connection
     * @see org.jboss.system.ServiceMBeanSupport#startService()
     */
    public void startService() throws Exception {
        Connection conn = null;
        try {
            // Get the JNDI name from the DataSource Pool MBean
            String jndiName = (String)server.getAttribute(dataSourceObjectName, "PoolJndiName");
            // Get a ref to the DataSource from JNDI
            lookupDataSource(jndiName);
            // Try getting a connection
            conn = dataSource.getConnection();
            // If we get here, we successfully got a connection and this service will report being Started
        } finally {
            if(conn!=null) try { conn.close(); } catch (Exception e) {}
        }
    }
    /**
     * Configures the service's DataSource ObjectName
     * @param dataSourceObjectName The ObjectName of the connection pool
     */
    public void setDataSource(ObjectName dataSourceObjectName) {
        this.dataSourceObjectName = dataSourceObjectName;
    }
    /**
     * Acquires a reference to the data source from JNDI
     * @param jndiName The JNDI binding name of the data source
     * @throws NamingException
     */
    protected void lookupDataSource(String jndiName) throws NamingException {
        dataSource = (DataSource)new InitialContext().lookup(jndiName);
    }
}

ConnCheckerMBeanのコードは次のようになります。

....
import org.jboss.system.ServiceMBeanSupport;
....
public interface ConnCheckerMBean extends ServiceMBean {
    public void setDataSource(ObjectName dataSourceObjectName);
}

そのため、データベースに接続できない場合でもエラーが発生しますが、DestinationManager は起動しません。うまくいけば、現在の頭痛よりはましになるでしょう。

于 2011-07-20T19:40:54.297 に答える
2

では、大量の Bean を「待機」させ、Jboss を完全に起動させる方法はありませんか?

標準的な方法ではありません。JBoss ブート サイクルが最後まで実行されるか、依存関係の障害が報告されます。プロセスはシーケンシャルでシングルスレッドです (JBoss 7 まで)。

あなたができること(そして私はこれを簡単にテストしただけです)は次のとおりです。

  • ConnCheckerを再実装して、別のスレッドで接続テストを実行します。そのスレッドが生成されるとすぐに開始されたと見なされます。
  • ConnCheckerに依存するサービスのすべての XML 構成ファイル(これはすべて JMS デプロイメント XML になると思います) ファイルをdeployの外側の別のディレクトリ(たとえば /jboss/server/bob/late-deployなど) に引き出します。
  • 遅延サービス ファイルはURLDeploymentScannerのパス リストに含まれていないため、デフォルトのデプロイ プロセスの一部としてデプロイされません。

レイト サービス ファイルを展開するための秘訣は、新しいConnCheckerが喜んでスピンし、接続を取得するのを待機することです (タイムアウトしてその場で停止する可能性があります) が、接続が正常に取得されると、次のようなコードを実行します。このような:

import javax.management.*;
.....
// The JBoss URL Deployment Scanner MBean ObjectName
ObjectName on = new ObjectName("jboss.deployment:flavor=URL,type=DeploymentScanner");
// server is the JBossMBean server. ServiceMBeans automatically have this reference.
server.invoke(on, "addURL", new Object[]{new URL("file:/jboss/server/bob/late-deploy")}, new String[]{String.class.getName});

したがって、これが行うことは、展開スキャナーに「このディレクトリも検索し始める」ように指示することであり、数秒後に遅延サービスが展開され、エラーが発生しないことを願っています。さらに、実行時に遅延サービスを追加したため (したがって非永続的に)、サーバーが再起動すると、デプロイ スキャナーは元の構成に戻り、ConnCheckerが新しい URL を追加するのを待ちます。

デプロイヤがScanEnabledを true に設定していること、およびScanPeriodが十分に低く、JDBC 接続が確立された後に遅延サービスをデプロイするために必要な応答時間が得られることを確認してください。その MBean 構成は

<jboss-home>/server/<server-name>/conf/jboss-service.xml

これを探します:

   <mbean code="org.jboss.deployment.scanner.URLDeploymentScanner"
      name="jboss.deployment:type=DeploymentScanner,flavor=URL">
....
      <!-- Frequency in milliseconds to rescan the URLs for changes -->
      <attribute name="ScanPeriod">5000</attribute>
      <!-- A flag to disable the scans -->
      <attribute name="ScanEnabled">true</attribute>
....
   </mbean>
于 2011-07-22T14:05:23.910 に答える