服務(wù)器管理系統(tǒng)可視化監(jiān)控有很多成熟的框架可以選擇悉罕,我們用過(guò) zabbix , 功能是很多的,但是我們有一些項(xiàng)目只需要很簡(jiǎn)單的性能監(jiān)控碍岔,用這種成熟框架就有點(diǎn)大材小用了痴施,筆者這里嘗試一個(gè)簡(jiǎn)化的方式擎厢。
一. 基本結(jié)構(gòu)
image.png
- 服務(wù)端有一個(gè) agent 應(yīng)用,不斷的輪詢(xún)發(fā)送實(shí)時(shí)的系統(tǒng)數(shù)據(jù)晾剖,比如 cpu锉矢、memory等。以 mqtt 的方式推送到 MQTT Broker.
- 這個(gè) borker 可以用Apache Apollo或EMQ X.
- 網(wǎng)頁(yè)端就是訂閱 mqtt 的消息齿尽,然后實(shí)時(shí)繪制折線圖
二. 服務(wù)端實(shí)現(xiàn)
這里主要使用 sigar 來(lái)獲取系統(tǒng)相關(guān)信息沽损,sigar 在不同的操作系統(tǒng)下需要拷貝對(duì)應(yīng)的 dll 或 so 文件,所以我們封裝了一個(gè)d1.framework.osinfo庫(kù)來(lái)簡(jiǎn)化操作循头,拷貝這些文件都是自動(dòng)的,相關(guān)代碼參考Git绵估。連接 mqtt borker 并發(fā)布消息調(diào)用的是自封裝的 d1.framework.mqttclient 庫(kù),代碼參考 Git 卡骂。所以最后的主要代碼非常少:
@Scheduled(cron = "0/10 * * * * ?") //10秒一次
public void task() {
//do something
try {
OsInfo info = osInfo.getOsInfo();
mqttService.publish("cpu", info.getFreeCpu());
mqttService.publish("memory", info.getFreeMemory());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("又過(guò)了10秒了......");
}
三. 網(wǎng)頁(yè)端
網(wǎng)頁(yè)端只是用 IBM 提供的 paho-mqtt js庫(kù)來(lái)訂閱 mqtt 消息国裳,然后使用 echarts 來(lái)畫(huà)動(dòng)態(tài)曲線圖,代碼也很簡(jiǎn)單全跨。
function initChart(chart, name, xDatas, yDatas) {
// 指定圖表的配置項(xiàng)和數(shù)據(jù)
var option = {
title: {
text: name+"空閑%"
},
tooltip: {},
legend: {
data: [name]
},
xAxis: {
data: xDatas
},
yAxis: {},
series: [{
name: '空閑',
type: 'line',
data: yDatas
}]
};
chart.setOption(option)
return option;
}
//
function initMQTT() {
// Create a client instance
var client = new Paho.Client("這里填broker的地址", 8083, "/mqtt", getRandomString());
// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
// connect the client
client.connect({
userName: "user2",
password: "password2",
onSuccess: onConnect,
onFailure: onFailure
});
// called when the client failed to connect
function onFailure(error) {
console.log("onFailure:" + JSON.stringify(error));
}
// called when the client connects
function onConnect() {
// Once a connection has been made, make a subscription and send a message.
console.log("onConnect");
client.subscribe("cpu");
client.subscribe("memory");
}
// called when the client loses its connection
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:" + responseObject.errorMessage);
}
}
// called when a message arrives
function onMessageArrived(message) {
console.log("onMessageArrived:" + JSON.stringify(message));
if (message.payloadString) {
var temp = message.payloadString;
if ("cpu" == message.topic) {
if(yDatasCPU.length>100)//不能無(wú)限增長(zhǎng)缝左,只保留最新100條
yDatasCPU.shift();
yDatasCPU.push(Number.parseFloat(temp.substring(0, temp.length - 1)));
if(xDatasCPU.length>100)
xDatasCPU.shift();
xDatasCPU.push(getNow());
cpuChart.setOption(cpuOption);
} else if ("memory" == message.topic) {
if(xDatasMemory.length>100)
xDatasMemory.shift();
xDatasMemory.push(getNow());
if(yDatasMemory.length>100)
yDatasMemory.shift();
yDatasMemory.push(Number.parseFloat(temp.substring(0, temp.length - 1)));
memoryChart.setOption(memoryOption);
}
}
}
}
只是一個(gè)示例,所以最后的效果圖比較簡(jiǎn)陋,每10秒會(huì)接受到推送過(guò)來(lái)的 cpu 和 memory 空閑率渺杉,動(dòng)態(tài)顯示出來(lái)蛇数,最多顯示最近100條數(shù)據(jù)。
image.png
所有源碼參考 Git