私は今、Mongo in Java はこの点で特に弱いと考えています。エラーコードを解釈するあなたの戦略がうまくスケーリングされたり、ドライバーの進化に耐えられたりするとは思いません。もちろん、これは意見です。
良いニュースは、Mongo ドライバーが ReplicaSet のステータスを取得する方法を提供することです: http://api.mongodb.org/java/2.11.1/com/mongodb/ReplicaSetStatus.html。これを直接使用して、アプリケーションに表示されるマスターがあるかどうかを確認できます。これだけ知りたい場合は、http://api.mongodb.org/java/2.11.1/com/mongodb/Mongo.html#getReplicaSetStatus()で十分です。その子供をつかんで、null でないマスターをチェックしてください。
ReplicaSetStatus rss = mongo.getReplicaSetStatus();
boolean driverInFailover = rss.getMaster() == null;
ReplSet が死んでいるか、読み取り専用か、読み書き可能かを判断することが本当に必要な場合、これはさらに困難になります。これは、私にとってはうまくいくコードです。私はそれが嫌いです。
@Override
public ReplSetStatus getReplSetStatus() {
ReplSetStatus rss = ReplSetStatus.DOWN;
MongoClient freshClient = null;
try {
if ( mongo != null ) {
ReplicaSetStatus replicaSetStatus = mongo.getReplicaSetStatus();
if ( replicaSetStatus != null ) {
if ( replicaSetStatus.getMaster() != null ) {
rss = ReplSetStatus.ReadWrite;
} else {
/*
* When mongo.getReplicaSetStatus().getMaster() returns null, it takes a a
* fresh client to assert whether the ReplSet is read-only or completely
* down. I freaking hate this, but take it up with 10gen.
*/
freshClient = new MongoClient( mongo.getAllAddress(), mongo.getMongoClientOptions() );
replicaSetStatus = freshClient.getReplicaSetStatus();
if ( replicaSetStatus != null ) {
rss = replicaSetStatus.getMaster() != null ? ReplSetStatus.ReadWrite : ReplSetStatus.ReadOnly;
} else {
log.warn( "freshClient.getReplicaSetStatus() is null" );
}
}
} else {
log.warn( "mongo.getReplicaSetStatus() returned null" );
}
} else {
throw new IllegalStateException( "mongo is null?!?" );
}
} catch ( Throwable t ) {
log.error( "Ingore unexpected error", t );
} finally {
if ( freshClient != null ) {
freshClient.close();
}
}
log.debug( "getReplSetStatus(): {}", rss );
return rss;
}
アプリケーションのMongo Java Driver規則に従わないため、単一のMongoのみが必要であり、このシングルトンを介して残りのMongoデータ構造(DB、コレクションなど)に接続するため、嫌いです。「ReplSet-DOWN」と「読み取り専用」を区別するために ReplicaSetStatus null チェックに依存できるように、チェック中に 2 番目の Mongo を新しくすることによってのみ、この動作を観察できました。
このドライバーで本当に必要なのは、Mongo に直接質問して、現時点で ReplSet が WriteConcerns または ReadPreferences のそれぞれをサポートできるかどうかを確認する方法です。何かのようなもの...
/**
* @return true if current state of Client can support readPreference, false otherwise
*/
boolean mongo.canDoRead( ReadPreference readPreference )
/**
* @return true if current state of Client can support writeConcern; false otherwise
*/
boolean mongo.canDoWrite( WriteConcern writeConcern )
これは、Mongo が作成されたときに ReplSet が優れていた可能性があるという事実を認めているため、私には理にかなっていますが、現在の条件は、条件の変化により特定のタイプの読み取りまたは書き込み操作が失敗する可能性があることを意味します。
いずれにせよ、おそらくhttp://api.mongodb.org/java/2.11.1/com/mongodb/ReplicaSetStatus.htmlで必要なものが得られます。