日期:2014-05-16 浏览次数:20612 次
// 获取 master 服务器地址
ServerAddress getMaster(){
// 获取 master 服务器节点
Node n = getMasterNode();
if ( n == null )
return null;
// 返回节点地址
return n._addr;
}
// 获取 mater 服务器节点
Node getMasterNode(){
// 检查数据连是否已经关闭接
_checkClosed();
// 遍历所有节点,找到 master 服务器节点
for ( int i=0; i<_all.size(); i++ ){
Node n = _all.get(i);
if ( n.master() )
return n;
}
return null;
}
// 获取一个最佳的 secondary 服务器地址
ServerAddress getASecondary(){
// 检查数据连是否已经关闭接
_checkClosed();
Node best = null;
double badBeforeBest = 0;
// 随机选取起点
int start = _random.nextInt( _all.size() );
double mybad = 0;
for ( int i=0; i<_all.size(); i++ ){
Node n = _all.get( ( start + i ) % _all.size() );
// 不是 secondary 节点,跳过
if ( ! n.secondary() ){
mybad++;
continue;
}
// 找到第一个 secondary 节点
// 设置 best,继续查找
if ( best == null )
best = n;
badBeforeBest = mybad;
mybad = 0;
continue;
}
// 第 n 个 secondary 节点
// 与之前找到的节点比较,选用最好的
// 比较 ping 值
long diff = best._pingTime - n._pingTime;
if ( diff > slaveAcceptableLatencyMS ||
// 一种保证随机分布的算法
( ( badBeforeBest - mybad ) / ( _all.size() - 1 ) ) > _random.nextDouble() )
{
best = n;
badBeforeBest = mybad;
mybad = 0;
}
}
if ( best == null )
return null;
// 返回 best 的地址
return best._addr;
}
final ServerAddress _addr; // 地址 final Set<String> _names = Collections.synchronizedSet( new HashSet<String>() ); // 节点名称 DBPort _port; // 数据库端口 boolean _ok = false; // 状态是否正常 long _lastCheck = 0; // 上次检查时间 long _pingTime = 0; // ping 延时 boolean _isMaster = false; // 是否为 master 节点 boolean _isSecondary = false; // 是否为 secondary 节点 double _priority = 0; // 优先级
// 更新节点状态
synchronized void update(Set<Node> seenNodes){
try {
// 发送 admin 请求,检查状态
long start = System.currentTimeMillis();
CommandResult res = _port.runCommand( _mongo.getDB("admin") , _isMasterCmd );
_lastCheck = System.currentTimeMillis();
_pingTime = _lastCheck - start;
// 状态异常
if ( res == null ){
_ok = false;
return;
}
// 状态正常
_ok = true;
// 是 mater 节点
_isMaster = res.getBoolean( "ismaster" , false );
// 是 secondary 节点
_isSecondary = res.getBoolean( "secondary" , false );
// 是 primary 节点
_lastPrimarySignal = res.getString( "primary" );
// 获取 hosts 信息
if ( res.containsField( "hosts" ) ){
for ( Object x : (List)res.get("hosts") ){
String host = x.toString();