用Go+Vue编写自己的轻量工具软件(服务端监控和reids客户端)

前言

有需要编写前后端配合的软件,轻量且跨平台,快速就能开发一个属于自己的小工具。

思路

  • Go语言负责后端,获取磁盘信息,连接数据库等前端无法胜任的活路
  • Vue负责页面编写,调用后端接口,vue3一键生成开发模版,即刻上手,使用ElementPlus,美滋滋
  • 使用Go内置技术,将前端dist包内嵌入程序中,单文件exe运行够清爽
  • 每个客户端独立保存配置,可以用前端浏览器缓存,也可以后端用sqlite,都是轻量级

使用技术

  • 前端:Vue3、Vite、ElementPlus、axios
  • 后端:go1.20、systray、go-redis

开始操作

前端

封装axios请求后端api

js 复制代码
import axios from 'axios'
import { ElNotification , ElMessageBox, ElMessage, ElLoading } from 'element-plus'

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: '/monitor-api',
  // 超时
  timeout: 40000
})

service.interceptors.response.use(res => {
  // 拦截器
})

export default service

路由添加

js 复制代码
const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    {
      path: '/',
      name: 'home',
      component: () => import('@/views/monitor/index.vue')
    },
    {
      path: '/redis',
      name: 'redis',
      component: () => import('@/views/redis/index.vue')
    },
  ]
})

export default router

页面编写, 根据业务自己写, 打包应用yarn build

后端

初始化项目

shell 复制代码
go mod init dmonitor

下载依赖

shell 复制代码
go get -u github.com/redis/go-redis/v9
...

编写代码

  1. 主函数
  • 通过go:embed 指定静态资源目录, 可以直接将前端打包的资源封装入exe中
  • http.HandleFunc 将api前缀交给函数处理, 在函数里面具体处理子路由
  • 匿名函数go func() {}(), 不会阻塞主进程
go 复制代码
//go:embed webapp
var f embed.FS

func main() {
  // 端口配置可以通过运行参数指定
	port := flag.Int("p", 40001, "server port")
	base.RunPort = *port
	flag.Parse()
	addr := fmt.Sprintf(":%d", *port)

	http.HandleFunc("/monitor-api/info", getInfoHandler)
	http.HandleFunc("/monitor-api/redis/", redis.HandleApi)

	st, _ := fs.Sub(f, "webapp")
	// 将文件服务器注册到指定路径
	http.Handle("/", http.StripPrefix("/", http.FileServer(http.FS(st))))

	fmt.Printf("***********************app run on http://localhost:%d/ *******************", *port)
	fmt.Println("")

	utils.OpenBrowser(fmt.Sprintf("http://localhost:%d/", *port))
	go func() {
		utils.GenTaskBarIcon()
	}()

	fmt.Println("start http.... ", *port)
	err := http.ListenAndServe(addr, nil)
	if err != nil {
		fmt.Println("start http error: ", err)
	}
	fmt.Println("start http success ", *port)
}
  1. HandleApi 处理子路由
go 复制代码
func HandleApi(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")             //允许访问所有域
	w.Header().Add("Access-Control-Allow-Headers", "Content-Type") //header的类型
	w.Header().Set("Content-Type", "application/json")

	path := r.URL.Path
	fmt.Println("redis HandleApi path:", path)

	switch {
	case strings.Contains(path, "/getRedisDbInfo"):
		getRedisDbInfo(w, r)
	case strings.Contains(path, "/changeRedisDb"):
		changeRedisDb(w, r)
	case strings.Contains(path, "/pingRedis"):
		pingRedis(w, r)
	case strings.Contains(path, "/initRedis"):
		initRedis(w, r)
	case strings.Contains(path, "/listKey"):
		listKey(w, r)
	case strings.Contains(path, "/getByKey"):
		getByKey(w, r)
	default:
		http.NotFound(w, r)
	}
}
  1. windows任务栏添加应用小图标和菜单
go 复制代码
func GenTaskBarIcon() {
	if runtime.GOOS == "windows" {
		systray.Run(onReady, onExit)
	}
}

func onReady() {
	systray.SetIcon(iconData)
	systray.SetTitle("D-Monitor")
	systray.SetTooltip("D-Monitor 右键点击打开菜单!")
	menuOpen := systray.AddMenuItem("打开网页", "打开系统网页")
	systray.AddSeparator()
	menuQuit := systray.AddMenuItem("退出", "退出程序")

	go func() {
		for {
			select {
			case <-menuOpen.ClickedCh:
				OpenBrowser(fmt.Sprintf("http://localhost:%d/", base.RunPort))
			case <-menuQuit.ClickedCh:
				systray.Quit()
				os.Exit(0)
			}
		}
	}()

}

func onExit() {}
  1. 针对linux和windows写不同的工具函数, 因为不同平台用的函数可能不一样, 会造成编译失败, go只能针对文件级别来区别平台编译, 所以在文件开头加入注释//go:build [platform]
go 复制代码
// utils/linux.go

//go:build linux
package utils

func OpenBrowser(url string) error {
	return nil
}
go 复制代码
// utils/windows.go

//go:build windows
package utils

func OpenBrowser(url string) error {
	var cmd string
	var args []string

	switch runtime.GOOS {
	case "windows":
		cmd = "cmd"
		args = []string{"/c", "start"}
	default: // Linux 等其他 Unix-like 系统
		cmd = ""
	}
	if cmd == "" {
		return nil
	}

	args = append(args, url)
	ec := exec.Command(cmd, args...)
	if runtime.GOOS == "windows" {
		ec.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
	}
	return ec.Start()
}
  1. 打包脚本 build.sh
shell 复制代码
#!/bin/bash

set -eu

VERSION=$(git describe --abbrev=0 --tags)
REVCNT=$(git rev-list --count HEAD)
DEVCNT=$(git rev-list --count $VERSION)
if test $REVCNT != $DEVCNT
then
	VERSION="$VERSION.dev$(expr $REVCNT - $DEVCNT)"
fi
echo "VER: $VERSION"

GITCOMMIT=$(git rev-parse HEAD)
BUILDTIME=$(date -u +%Y/%m/%d-%H:%M:%S)

LDFLAGS="-X main.VERSION=$VERSION -X main.BUILDTIME=$BUILDTIME -X main.GITCOMMIT=$GITCOMMIT"
if [[ -n "${EX_LDFLAGS:-""}" ]]
then
	LDFLAGS="$LDFLAGS $EX_LDFLAGS"
fi

build() {
	echo "$1 $2  $3... $LDFLAGS"
  LDFLAGS1="$LDFLAGS"
  if [ "$1" = "windows" ]; then
    LDFLAGS1="$LDFLAGS -H=windowsgui"
  fi
  echo "LDFLAGS1... $LDFLAGS1"
	GOOS=$1 GOARCH=$2 go build \
		-ldflags "-s -w $LDFLAGS1" \
		-o dist/dmonitor-${3:-""}
}

build linux arm linux-arm
# build darwin amd64 mac-amd64
build linux amd64 linux-amd64
build linux 386 linux-386
build windows arm64 win-arm64.exe
build windows amd64 win-amd64.exe

后言

至此就能开发一个自己的轻量小工具,目前通过go+vue开发了一个服务端监控软件, 可以实时监控服务器的CPU、内存、磁盘、进程等使用情况,也集成了简易的redis客户端,可以连接到redis并查看键值, upx压缩后也就2M左右,够轻便了

源码地址

相关推荐
蒙娜丽宁2 天前
Go语言错误处理详解
ios·golang·go·xcode·go1.19
qq_172805593 天前
GO Govaluate
开发语言·后端·golang·go
littleschemer4 天前
Go缓存系统
缓存·go·cache·bigcache
程序者王大川5 天前
【GO开发】MacOS上搭建GO的基础环境-Hello World
开发语言·后端·macos·golang·go
Grassto5 天前
Gitlab 中几种不同的认证机制(Access Tokens,SSH Keys,Deploy Tokens,Deploy Keys)
go·ssh·gitlab·ci
高兴的才哥5 天前
kubevpn 教程
kubernetes·go·开发工具·telepresence·bridge to k8s
少林码僧6 天前
sqlx1.3.4版本的问题
go
蒙娜丽宁6 天前
Go语言结构体和元组全面解析
开发语言·后端·golang·go
蒙娜丽宁7 天前
深入解析Go语言的类型方法、接口与反射
java·开发语言·golang·go
三里清风_7 天前
Docker概述
运维·docker·容器·go