昨天我们进行了开发流程中的第二步架构设计,并且创建了vite vue的项目并且引入了antd的UI组件,今天我们就进行开发流程中的比较费时间的第三部分,就是前后端功能模块的实际开发,利用程序实现自己的业务需求。
之前我们用的的elmentplus的ui组件,显示K8s的集群信息。今天我们利用antd组件显示后端信息组件也是大同小异,所以前后端交互流程也都是一样的。那么我们的功能模块包括暂时包括三个模块,一个是传统模块,一个是云原生模块,还有一个就是微服务的模块。
我们现阶段先开发传统模块,包含监控、终端等功能。
监控模块开发
那么从监控功能开始,如果想开发监控功能的话,一般有那些方式呢,个人目前理解的大方向有两个:
1、使用后端语言单独开发监控资源
2、直接调用成熟系统的api接口返回数据给前端
第一种方式优点就是可以完全自定义监控的逻辑,灵活度高,而且不依赖第三方监控系统,部署简单。缺点也是显而易见的就是自行开发和维护监控功能,工作量大。关键功能还不如成熟系统强大。
第二种方式优点显而易见,可以利用成熟的监控系统,监控功能强大,前端获取的监控数据还比较丰富。缺点就是依赖第三方监控系统,系统更换或者升级会带来影响,监控的数据结构和api需要依赖监控系统,可能不是很灵活。
所以一般我们除了需要高度定制的监控功能,一般都会选择直接调用成熟监控系统的API这是一种简单高效,能够快速获取监控数据的方案。所以说一切都是按需求定义,看客户需求是什么,两者结合都是可以的。
那么我这边平台的需求暂时没有什么高度定制的监控需求,所以我们只要部署监控系统,调用它的api,利用前端显示即可。
调用方式也有几种方式:
1、前端直接调用监控系统API,优势就是简单快速,直接展示api返回的丰富监控数据,但是缺点就是面向具体的监控系统的api进行开发,更换系统的话影响就比较大
2、后端调用
前端调用后端接口,后端再调用监控api获取数据,返回给前端,优势在于前端和具体的监控系统解耦,更换监控系统影响不大,但是需要后端进行二次开发
3、基于socket推送
监控系统直接推送实时监控数据和事件到后端,后端通过socket连接推送到前端,这个实时推送监控消息,前端实时展示,但是开发复杂度还是大
4、基于webhook
监控系统通过webhook推送到后端,后端再将数据返回给前端,和上面的方法一样,需要webhook接入的开发。
本来想我们直接调用监控系统api显示即可,但是我又想到另一种方法,直接将现有的监控面板grafana接入我的前端页面是最快速高效的办法。
所以我就着手搭建监控系统,我本来是利用helm直接一套安装的,但那成想,网络原因一直下载不下来,所以暂时不浪费时间了,明天再抽空搭建一套之后再引入。
但是,我觉得除了直接引入,自己开发单独的监控流程还是要熟悉一下。
这里我们使用go语言,简单的来监控一下远程linux机器的cpu的信息,设置每5秒来监控一下,然后返回cpu的占用率和可用率。
马上动手,新建go项目monitor,代码如下:
代码语言:javascript复制package main
import (
"encoding/json"
"flag"
"net/http"
"strconv"
"time"
"github.com/shirou/gopsutil/cpu"
"golang.org/x/crypto/ssh"
)
// CPUInfo 定义CPU信息结构体
type CPUInfo struct {
CPUPercent float64 `json:"cpu_percent"`
CPUFree float64 `json:"cpu_free"`
}
// ServerConfig 定义SSH连接配置
type ServerConfig struct {
IP string
Port int
User string
Password string
}
func main() {
// 从命令行参数读取配置
conf := getConfig()
// 建立与远程主机的SSH连接
sshClient, _ := ssh.Dial("tcp", conf.IP ":" strconv.Itoa(conf.Port), &ssh.ClientConfig{
User: conf.User,
Auth: []ssh.AuthMethod{ssh.Password(conf.Password)},
})
// 定期获取CPU信息
var cpuInfo CPUInfo
ticker := time.NewTicker(time.Second * 5)
go func() {
for range ticker.C {
getCPUStat(sshClient, &cpuInfo)
}
}()
// 提供HTTP接口
http.HandleFunc("/cpu", func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin") // 设置允许请求的域
json.NewEncoder(w).Encode(cpuInfo)
})
http.ListenAndServe("0.0.0.0:8000", nil)
}
func getConfig() *ServerConfig {
ip := flag.String("ip", "", "IP address")
port := flag.Int("port", 22, "Port")
user := flag.String("user", "", "Username")
password := flag.String("password", "", "Password")
flag.Parse()
conf := &ServerConfig{
IP: *ip,
Port: *port,
User: *user,
Password: *password,
}
return conf
}
func getCPUStat(sshClient *ssh.Client, info *CPUInfo) {
stats, _ := cpu.Percent(0, false)
info.CPUPercent = stats[0]
info.CPUFree = 100 - stats[0]
}
这里简单说下流程就是下载引入需要的模块,利用ssh连接远程机器,执行模块封装的函数,返回具体的机器信息,并用json格式,这里还要设置下跨域访问,不然前端因为浏览器安全设置无法获取后端数据。
运行看一下:
再在昨天vite创建的项目上引入页面:
上代码:
完整的前端代码如下:
代码语言:javascript复制vue
<template>
<a-card title="CPU信息"
:bordered="true">
<a-row :gutter="16">
<a-col :span="12" >
<a-card title="CPU占用率"
:bordered="true">
<a-progress :percent="cpuInfo.cpuPercent"
:format="percent => `${percent}%`" />
</a-card>
</a-col>
<a-col :span="12" >
<a-card title="CPU可用率"
:bordered="true">
<a-progress :percent="cpuInfo.cpuFree" :format="percent
=> `${percent}%`" />
</a-card>
</a-col>
</a-row>
</a-card>
</template>
<script lang="ts">
import { defineComponent, reactive,
onMounted } from 'vue'
import Axios from 'axios'
interface CPUInfo {
cpuPercent: number
cpuFree: number
}
export default defineComponent({
setup() {
const cpuInfo = reactive<CPUInfo>({
cpuPercent: 0,
cpuFree: 0
})
const getCPUInfo = async () => {
const { data } = await
Axios.get<CPUInfo>(('http://localhost:8000/cpu'))
// 格式化后端数据,限制小数点后2位
data.cpu_percent = data.cpu_percent.toFixed(2)
data.cpu_free = data.cpu_free.toFixed(2)
cpuInfo.cpuPercent = data.cpu_percent
cpuInfo.cpuFree = data.cpu_free
}
onMounted(async () => {
await getCPUInfo()
})
return { cpuInfo }
}
})
</script>
这里调整了几次样式,使用antd的卡片,我们看看效果:
我们实际看看机器信息:
当然这里的后端可用率逻辑只是简单的100-用户空间cpu占用率,没算系统占用的,还可以改善一下。
所以其他的内存硬盘等主机信息也是类似的开发流程。所以说对于特定的比较重要的监控信息可以采取单独开发。不然还是直接调用API是最好的选择。
那么好了,今天的分享就到这了,感兴趣的朋友别忘了关注点赞呀。