SMV—构建运维可视化管理全息视图

330 阅读4分钟

       SMV是什么?与运维有什么样的关联?我们都知道的,运维工程师面对的最大挑战是大规模集群的管理问题,如何管理好几十万台服务器上的服务,同时保障服务的高可用性,是运维工程师面临的最大挑战。如何通过SMV帮助运维人员更好的管理和完善工作?如何实现运维可视化管理?且听小编来分析讲解!


  SMV提供一种面向业务、面向场景的运维界面组装能力,让运维人员能够从应用和业务的角度出发,针对具体的使用场景,将跨界的数据和工具功能与日常管理场景融合,实现信息流的场景化呈现和推送,构建面向具体管理场景的全息视图。

  1、场景驱动的运维资源整合

  将配置、性能、告警、日志、工单、预案等不同工具的数据/信息进行封装整合,以多维度多层次的信息面板直观呈现,实现了信息流的场景化呈现和推送。针对不同的运维场景,运维人员可以快速完成各个运维数据与工具的整合,避免多个工具之间切换操作,从而更加直观、全面、高效地进行日常运维管理工作。

  2、易用透明的ChatOps平台

  针对不同的业务场景,相关运维人员通过组建讨论组进行在线协同工作。所有的工作消息都在同一个协作平台中沉淀并公开给所有相关成员,消除沟通壁垒,工作历史有迹可循。通过与智能贴心的“维秘”机器人对话即可完成与后台工具、系统的交互,无需再与众多复杂的工具直接对接,大大提升运维操作的简便性和效率。

  3、一站式的个人工作台

  通过整合日常运维中的各种工具,为运维人员定制一站式的工作处理平台,支持工作台内完成签到签退、工单、告警、邮件、巡检等日常运维工作,跨平台的信息整合,让工作一览无遗,降低信息干扰,提升工作效率。

运维工程师真心太难了,要负责如此庞大的服务器规模,小编都要替他们捏一把汗,不过呢,企业自然不会在这种情况下还让他们高负荷运作,自然会给运维工程师提供可操作的运维平台,否则服务器都要死翘翘了。后边还会为大家讲解更多可视化管理相关的东西,期待吧~

/**
* 说明:通过请求数据 动态创建柜子中的书
*/
var app = new THING.App({
url: 'https://www.thingjs.com/static/models/storehouse' // 场景地址
});
// 请求书籍数据的url
var url = 'https://www.thingjs.com/static/data/books.json';
// 书籍的物体面板
var panel;
app.on('load', function (ev) {
// 开启层级切换
app.level.change(ev.campus);
// 获取目标书柜
var cabinetSelector = app.query('cabinetB4')[0];
// 点击按钮到目标书柜
new THING.widget.Button('目标书柜', function () {
app.level.change(cabinetSelector);
});

// 进入物体层级效果
cabinetSelector.on(THING.EventType.EnterLevel, function (ev) {
// 当前进入层级的物体(书柜)
var object = ev.object;
// 上一层级的物体
var preObject = ev.previous;

// 如果当前层级物体的父亲是上一层级(即正向进入)
if (object.parent === preObject) {
console.log("从楼层进入了书柜");
object.playAnimation('OpenDoor');
// 如果书柜没有创建书籍 则请求数据 创建书籍
if (!object._isAlreadyCreateBooks) {
getBooksData(object);
}
}
}, 'customEnter');

// 设置退出层级效果
cabinetSelector.on(THING.EventType.LeaveLevel, function (ev) {
// 退出层级的物体(书柜)
var object = ev.object;
// 退出后的层级物体
var curObject = ev.current;
// 如果所退出层级物体的父亲是 退出后的层级(即正向退出)
if (object.parent === curObject) {
console.log("退出书柜进入楼层");
object.playAnimation('CloseDoor');
destroyBooks();
object._isAlreadyCreateBooks = false;
}
}, 'customLeave');
});

// 获取JSON数据
function getBooksData(obj) {
$.ajax({
type: "get",
url: url,
dataType: "json",
success: function (data) {
createBooks(data, obj);
}
});
}


function createBooks(data, parent) {
var books = data.books;
var cabinetInfo = data.cabinetInfo;
var cabinetInfoOffsetX = cabinetInfo.offsetX;
var cabinetInfoOffsetY = cabinetInfo.offsetY;

// 按书架每一层 整理数据
// 结果形如
/*
{
"1":[{"name":"C++","row":1,"column":1,"width":10},{"name":"Java","row":1,"column":2,"width":14},......],
"2":[{"name":"js","row":2,"column":1,"width":5},......],
"3":[{"name":"js","row":3,"column":1,"width":5},......]
}
*/
var booksMap = processData(books);

for (var row in booksMap) {
var arr = booksMap[row];
var offsetX = 0;
var sum = 0;

for (var i = 0; i < arr.length; i++) {
var book = arr[i];
var name = book.name;
// 行
var row = book.row;

var width = book.width / 100;
sum += width;

offsetX = sum - width / 2;
// 创建Box 模拟书籍 (书籍的父亲是书柜 并根据相对坐标创建)
var objBook = app.create({
type: 'Box',
width: width, // 宽度 (书籍厚度)
height: 0.2, // 高度
depth: 0.15, // 深度
center: 'Bottom', // 中心点
parent: parent,
localPosition: [offsetX - cabinetInfoOffsetX[row - 1], cabinetInfoOffsetY[row - 1], 0]
});

objBook.userData['书名'] = name;
objBook.userData['物体类型'] = '书';
objBook.style.color = THING.Math.randomColor();


objBook.on(THING.EventType.SingleClick, function (ev) {
// 如果单击获取的物体不在当前选择集中
if (!app.selection.has(ev.object)) {
app.selection.clear();
app.selection.select(ev.object);
}
})
objBook.on(THING.EventType.Select, function (ev) {
var book = ev.object;
// 创建物体面板
createPanel(book);
});

objBook.on(THING.EventType.Deselect, function (ev) {
// 删除物体面板
destroyPanel();
});
}
}

parent._isAlreadyCreateBooks = true;
}

function destroyBooks() {
var books = app.query('["userData/物体类型"="书"]');
books.destroy();
destroyPanel();
}

app.on(THING.EventType.SingleClick, function (ev) {
if (!ev.picked || !app.selection.has(ev.object)) {
app.selection.clear();
}
}, '单击其他清空选择集');


function createPanel(obj) {
if (panel) return;

panel = new THING.widget.Panel({
titleText: '基本信息',
hasTitle: true,
position: [5, 50]
});
panel.addString(obj.userData, "书名").caption("书名");
}

// 删除面板
function destroyPanel() {
if (panel) {
panel.destroy();
panel = null;
}
}

// 数据处理
function processData(books) {
var booksMap = {};
for (var i = 0; i < books.length; i++) {
var book = books[i];
// 按每一行 整理数据
var row = book.row;

if (!booksMap[row]) {
booksMap[row] = [];
}
booksMap[row].push(book);
}
return booksMap;
}