数据库中间件Mycat源码解析(四):Mycat的心跳管理

MyCat的服务端在启动时会执行node.startHeartbeat()去设置每个node的heartbeat的状态为DBHeartbeat.OK_STATUS,然后针对每个node节点启动一个线程去对对应的node发送heartbeat sql(比如select user())进行心跳检测。

private Runnable dataNodeHeartbeat() {
		return new Runnable() {
			@Override
			public void run() {
				timerExecutor.execute(new Runnable() {
					@Override
					public void run() {
						Map<String, PhysicalDBPool> nodes = config
								.getDataHosts();
						for (PhysicalDBPool node : nodes.values()) {
							node.doHeartbeat();
						}
					}
				});
			}
		};
	}

heatbeat类会调用heartbeat方法。

public void heartbeat() {
		final ReentrantLock lock = this.lock;
		lock.lock();
		try {
			//改变状态
			if (isChecking.compareAndSet(false, true)) {
				MySQLDetector detector = this.detector;
				if (detector == null || detector.isQuit()) {
					try {
						detector = new MySQLDetector(this);
						detector.heartbeat();
					} catch (Exception e) {
						LOGGER.warn(source.getConfig().toString(), e);
						setResult(ERROR_STATUS, detector, null);
						return;
					}
					this.detector = detector;
				} else {
					detector.heartbeat();
				}
			} else {
				MySQLDetector detector = this.detector;
				if (detector != null) {
					if (detector.isQuit()) {
						isChecking.compareAndSet(true, false);
					} else if (detector.isHeartbeatTimeout()) {
						setResult(TIMEOUT_STATUS, detector, null);
					}
				}
			}
		} finally {
			lock.unlock();
		}
	}
它会调用detector属性的heartbeat方法。

public void heartbeat() {
		lastSendQryTime = System.currentTimeMillis();
		MySQLDataSource ds = heartbeat.getSource();
		String databaseName = ds.getDbPool().getSchemas()[0];
		String[] fetchColms={};
		if (heartbeat.getSource().getHostConfig().isShowSlaveSql() ) {
			fetchColms=MYSQL_SLAVE_STAUTS_COLMS;
		}
		if (heartbeat.getSource().getHostConfig().isShowClusterSql() ) {
			fetchColms=MYSQL_CLUSTER_STAUTS_COLMS;
		}
		OneRawSQLQueryResultHandler resultHandler = new OneRawSQLQueryResultHandler( fetchColms, this);
		sqlJob = new SQLJob(heartbeat.getHeartbeatSQL(), databaseName, resultHandler, ds);
		sqlJob.run();
	}
它会获取数据源和数据库名,然后创建并注册一个OneRawSQLQueryResultHandler到sqlJob,再由这个job发送sql到数据库将结果取回交给注册的handler处理。

public boolean onRowData(String dataNode, byte[] rowData) {
		RowDataPacket rowDataPkg = new RowDataPacket(fieldCount);
		rowDataPkg.read(rowData);
		String variableName = "";
		String variableValue = "";
		//fieldcount为2可能是select x也可能是show create table命令
		if(fieldCount==2 && (fetchColPosMap.get("Variable_name")!=null || fetchColPosMap.get("Value")!=null)){
			Integer ind = fetchColPosMap.get("Variable_name");
			if (ind != null) {
				byte[] columnData = rowDataPkg.fieldValues.get(ind);
                String columnVal = columnData!=null?new String(columnData):null;
                variableName = columnVal;
            }
			ind = fetchColPosMap.get("Value");
			if (ind != null) {
				byte[] columnData = rowDataPkg.fieldValues.get(ind);
                String columnVal = columnData!=null?new String(columnData):null;
                variableValue = columnVal;
            }
            result.put(variableName, variableValue);
		}else{
			for (String fetchCol : fetchCols) {
				Integer ind = fetchColPosMap.get(fetchCol);
				if (ind != null) {
					byte[] columnData = rowDataPkg.fieldValues.get(ind);
	                String columnVal = columnData!=null?new String(columnData):null;
	                result.put(fetchCol, columnVal);
				} else {
					LOGGER.warn("cant't find column in sql query result " + fetchCol);
				}
			}
		}
		return false;
	}
如果客户端发送reload指令或stop指令到服务端就会修改hearbeat的状态为stop,停止进行心跳检测。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值