com.alibaba.otter.manager.biz.autokeeper.impl.AutoKeeperCollector Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2010-2101 Alibaba Group Holding Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.otter.manager.biz.autokeeper.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import com.alibaba.otter.manager.biz.common.exceptions.ManagerException;
import com.alibaba.otter.manager.biz.config.autokeeper.AutoKeeperClusterService;
import com.alibaba.otter.manager.biz.utils.RegexUtils;
import com.alibaba.otter.shared.common.model.autokeeper.AutoKeeperCluster;
import com.alibaba.otter.shared.common.model.autokeeper.AutoKeeperConnectionStat;
import com.alibaba.otter.shared.common.model.autokeeper.AutoKeeperEphemeralStat;
import com.alibaba.otter.shared.common.model.autokeeper.AutoKeeperQuorumType;
import com.alibaba.otter.shared.common.model.autokeeper.AutoKeeperServerStat;
import com.alibaba.otter.shared.common.model.autokeeper.AutoKeeperWatchStat;
import com.alibaba.otter.shared.common.utils.cmd.Exec;
import com.alibaba.otter.shared.common.utils.cmd.Exec.Result;
import com.alibaba.otter.shared.common.utils.thread.NamedThreadFactory;
/**
* 对应的数据采集器
*
* @author jianghang 2012-9-21 下午03:05:28
* @version 4.1.0
*/
public class AutoKeeperCollector implements InitializingBean {
@Resource(name = "autoKeeperClusterService")
private AutoKeeperClusterService autoKeeperClusterService;
private static final String MODE_FOLLOWER = "Mode: follower";
private static final String MODE_LEADERER = "Mode: leader";
private static final String MODE_OBSERVER = "Mode: observer";
private static final String MODE_STANDALONE = "Mode: standalone";
private static final String NODE_COUNT = "Node count:";
private static final String STRING_LATENCY = "Latency min/avg/max:";
private static final String STRING_SENT = "Sent:";
private static final String STRING_RECEIVED = "Received:";
private static final String STRING_OUTSTANDING = "Outstanding:";
private static final String COMMA = ",";
private static final String BRACKETS = ")";
private static final String COLON = ":";
private static final String WRAP = "\n";
private static final String CMD_STAT = "echo stat | nc %s %s";
private static final String CMD_CONS = "echo cons | nc %s %s";
private static final String CMD_DUMP = "echo dump | nc %s %s";
private static final String CMD_WCHC = "echo wchc | nc %s %s";
private static final long DEFAULT_COLLECT_INTERVAL = 300;
private long delay = 1;
private int singleSize = 1;
private long collectInterval = DEFAULT_COLLECT_INTERVAL;
private AutoKeeperData autoKeeperData;
private ScheduledExecutorService collectorExecutor;
public void collectorConnectionStat(String address) {
List netAddress = splitAddress(address);
if (netAddress.isEmpty()) {
return;
}
String ip = netAddress.get(0);
String port = netAddress.get(1);
String[] cmd = { "/bin/bash", "-c", String.format(CMD_CONS, ip, port) };
String cmdresult = collector(cmd);
String[] result = cmdresult.split(WRAP);
List summary = new ArrayList();
for (String line : result) {
if (StringUtils.isBlank(line)) {
continue;
}
String[] lineArray = line.split(":");
if (2 != lineArray.length) {
continue;
}
AutoKeeperConnectionStat autoKeeperConnectionStat = new AutoKeeperConnectionStat();
autoKeeperConnectionStat.setOriginalContent(line);
String clientIp = StringUtils.trimToEmpty(line.split(":")[0].replace("/", ""));
String sessionId = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "sid=(?s).*?[,)]")).replace("sid=",
StringUtils.EMPTY).replace(COMMA,
StringUtils.EMPTY).replace(BRACKETS,
StringUtils.EMPTY);
String queued = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "queued=(?s).*?[,)]")).replace("queued=",
StringUtils.EMPTY).replace(COMMA,
StringUtils.EMPTY).replace(BRACKETS,
StringUtils.EMPTY);
String receive = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "recved=(?s).*?[,)]")).replace("recved=",
StringUtils.EMPTY).replace(COMMA,
StringUtils.EMPTY).replace(BRACKETS,
StringUtils.EMPTY);
String sent = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "sent=(?s).*?[,)]")).replace("sent=",
StringUtils.EMPTY).replace(COMMA,
StringUtils.EMPTY).replace(BRACKETS,
StringUtils.EMPTY);
String minlat = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "minlat=(?s).*?[,)]")).replace("minlat=",
StringUtils.EMPTY).replace(COMMA,
StringUtils.EMPTY).replace(BRACKETS,
StringUtils.EMPTY);
String avglat = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "avglat=(?s).*?[,)]")).replace("avglat=",
StringUtils.EMPTY).replace(COMMA,
StringUtils.EMPTY).replace(BRACKETS,
StringUtils.EMPTY);
String maxlat = StringUtils.trimToEmpty(RegexUtils.findFirst(line.split(":")[1], "maxlat=(?s).*?[,)]")).replace("maxlat=",
StringUtils.EMPTY).replace(COMMA,
StringUtils.EMPTY).replace(BRACKETS,
StringUtils.EMPTY);
autoKeeperConnectionStat.setServerAddress(ip);
autoKeeperConnectionStat.setClientAddress(clientIp);
autoKeeperConnectionStat.setSessionId(sessionId);
if (StringUtils.isNotEmpty(queued)) {
autoKeeperConnectionStat.setQueued(Long.parseLong(queued));
}
if (StringUtils.isNotEmpty(receive)) {
autoKeeperConnectionStat.setRecved(Long.parseLong(receive));
}
if (StringUtils.isNotEmpty(sent)) {
autoKeeperConnectionStat.setSent(Long.parseLong(sent));
}
if (StringUtils.isNotEmpty(minlat)) {
autoKeeperConnectionStat.setMinLatency(Long.parseLong(minlat));
}
if (StringUtils.isNotEmpty(avglat)) {
autoKeeperConnectionStat.setAvgLatency(Long.parseLong(avglat));
}
if (StringUtils.isNotEmpty(maxlat)) {
autoKeeperConnectionStat.setMaxLatency(Long.parseLong(maxlat));
}
summary.add(autoKeeperConnectionStat);
}
autoKeeperData.joinConnection(address, summary);
}
public void collectorServerStat(String address) {
List netAddress = splitAddress(address);
if (netAddress.isEmpty()) {
return;
}
String ip = netAddress.get(0);
String port = netAddress.get(1);
String[] cmd = { "/bin/bash", "-c", String.format(CMD_STAT, ip, port) };
String cmdresult = collector(cmd);
String[] result = cmdresult.split(WRAP);
AutoKeeperServerStat summary = new AutoKeeperServerStat();
summary.setOriginalContent(cmdresult);
for (String line : result) {
if (line.contains(MODE_FOLLOWER)) {
summary.setQuorumType(AutoKeeperQuorumType.FOLLOWER);
} else if (line.contains(MODE_LEADERER)) {
summary.setQuorumType(AutoKeeperQuorumType.LEADER);
} else if (line.contains(MODE_STANDALONE)) {
summary.setQuorumType(AutoKeeperQuorumType.STANDALONE);
} else if (line.contains(MODE_OBSERVER)) {
summary.setQuorumType(AutoKeeperQuorumType.OBSERVER);
} else if (line.contains(STRING_LATENCY)) {
List latency = Arrays.asList(StringUtils.trimToEmpty(line.replace(STRING_LATENCY,
StringUtils.EMPTY)).split("/"));
summary.setMinLatency(Long.parseLong(latency.get(0)));
summary.setAvgLatency(Long.parseLong(latency.get(1)));
summary.setMaxLatency(Long.parseLong(latency.get(2)));
} else if (line.contains(STRING_OUTSTANDING)) {
summary.setQueued(Long.parseLong(StringUtils.trimToEmpty(line.replace(STRING_OUTSTANDING,
StringUtils.EMPTY))));
} else if (line.contains(NODE_COUNT)) {
summary.setNodeCount(Long.parseLong(StringUtils.trimToEmpty(line.replace(NODE_COUNT, StringUtils.EMPTY))));
} else if (line.contains(STRING_SENT)) {
summary.setSent(Long.parseLong(StringUtils.trimToEmpty(line.replace(STRING_SENT, StringUtils.EMPTY))));
} else if (line.contains(STRING_RECEIVED)) {
summary.setRecved(Long.parseLong(StringUtils.trimToEmpty(line.replace(STRING_RECEIVED,
StringUtils.EMPTY))));
}
}
autoKeeperData.joinServer(address, summary);
}
public void collectorEphemeralStat(String address) {
List netAddress = splitAddress(address);
if (netAddress.isEmpty()) {
return;
}
String ip = netAddress.get(0);
String port = netAddress.get(1);
String[] cmd = { "/bin/bash", "-c", String.format(CMD_DUMP, ip, port) };
String cmdresult = collector(cmd);
Map> pathMap = groupSessionPath(cmdresult);
List autoKeeperEphemeralStats = new ArrayList();
for (Map.Entry> entry : pathMap.entrySet()) {
AutoKeeperEphemeralStat autoKeeperEphemeralStat = new AutoKeeperEphemeralStat();
autoKeeperEphemeralStat.setSessionId(entry.getKey());
autoKeeperEphemeralStat.setPaths(entry.getValue());
autoKeeperEphemeralStats.add(autoKeeperEphemeralStat);
}
autoKeeperData.joinEphemeral(address, autoKeeperEphemeralStats);
}
public void collectorWatchStat(String address) {
List netAddress = splitAddress(address);
if (netAddress.isEmpty()) {
return;
}
String ip = netAddress.get(0);
String port = netAddress.get(1);
String[] cmd = { "/bin/bash", "-c", String.format(CMD_WCHC, ip, port) };
String cmdresult = collector(cmd);
Map> pathMap = groupSessionPath(cmdresult);
List autoKeeperWatchStats = new ArrayList();
for (Map.Entry> entry : pathMap.entrySet()) {
AutoKeeperWatchStat autoKeeperWatchStat = new AutoKeeperWatchStat();
autoKeeperWatchStat.setSessionId(entry.getKey());
autoKeeperWatchStat.setPaths(entry.getValue());
autoKeeperWatchStats.add(autoKeeperWatchStat);
}
autoKeeperData.joinWatch(address, autoKeeperWatchStats);
}
public static String collector(String[] command) {
Result result = null;
try {
result = Exec.execute(command);
if (result.getExitCode() == 0) {
return result.getStdout();
} else {
return result.getStderr();
}
} catch (Exception e) {
throw new ManagerException(e);
}
}
private List splitAddress(String address) {
List ipPort = Arrays.asList(address.split(":"));
if (ipPort.size() != 2) {
return new ArrayList();
}
return ipPort;
}
/**
*
* key=sessionId
* value=pathList
*
*/
private Map> groupSessionPath(String cmdresult) {
String[] result = cmdresult.split(WRAP);
Map> pathMap = new HashMap>();
String sessionId = StringUtils.EMPTY;
for (String line : result) {
line = StringUtils.trimToEmpty(line);
if (StringUtils.isBlank(line)) {
continue;
}
if (line.startsWith("0x")) {
sessionId = line.replace(COLON, StringUtils.EMPTY);
pathMap.put(sessionId, new ArrayList());
} else if (line.startsWith("/")) {
List paths = pathMap.get(sessionId);
paths.add(line);
}
}
return pathMap;
}
@Override
public void afterPropertiesSet() throws Exception {
collectorExecutor = Executors.newScheduledThreadPool(singleSize, new NamedThreadFactory("collector-thread",
true));
startCollect();
}
private void startCollect() {
// 启动定时工作任务
collectorExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
List autoKeeperClusters = autoKeeperClusterService.listAutoKeeperClusters();
if (!autoKeeperClusters.isEmpty()) {
autoKeeperData.persist();
for (AutoKeeperCluster autoKeeperCluster : autoKeeperClusters) {
List servers = autoKeeperCluster.getServerList();
for (String address : servers) {
collectorServerStat(address);
collectorConnectionStat(address);
collectorWatchStat(address);
collectorEphemeralStat(address);
}
}
}
}
}, delay, collectInterval, TimeUnit.SECONDS);
}
public void setAutoKeeperClusterService(AutoKeeperClusterService autoKeeperClusterService) {
this.autoKeeperClusterService = autoKeeperClusterService;
}
public void setAutoKeeperData(AutoKeeperData autoKeeperData) {
this.autoKeeperData = autoKeeperData;
}
public void setCollectInterval(long collectInterval) {
this.collectInterval = collectInterval;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy