go之基于rabbitmq的火山云服务器弹性伸缩管理程序

news2024/12/24 11:26:58
Author: wencoo
Blog:https://wencoo.blog.csdn.net/
Date: 18/04/2023
Details:

文章目录

  • 项目背景
  • 项目功能
  • 模块实现
    • configMq.json
    • configECS.json
    • configDB.json
  • 完整代码
  • 打赏

项目背景

项目服务器不够用了,需要弹性伸缩服务器,准备使用火山的弹性伸缩功能,但是在配置的过程中发现,弹性伸缩的指标都是针对于本机的负载等等进行监控,从而实现弹性伸缩。我的项目是使用的GPU服务器,在程序启动的时候,相关GPU资源都已经申请好了,达到了最大值,即使没有任务,也是资源占用掉了,任务的来源是中间件rabbitmq,所以在本机上监控,并不合理。

项目功能

因为使用的rabbitmq,任务都存储在队列中,先获取队列任务数量,根据队列任务数量,按照策略,决定是否创建弹性伸缩的服务器,创建之后,待任务消费减少,再删除之前创建好的弹性伸缩的服务器。

模块实现

创建配置mq的相关信息的配置文件configMq.json,创建配置服务器的相关信息的配置文件configECS.json,创建配置数据库的相关信息的配置文件configDB.json,这里内容很简单,也没必要整个数据库啦,所以直接使用配置文件解决

configMq.json

{
	"port": 5672,
	"hostName": "106.15.0.159",
	"passwd": "xxx",
	"userName": "admin",
	"maxCounts": 3000,
	"interval": 3000
}

configECS.json

{
	"ImageId":            "image-ycct00qocb4qwlkufab4",
	"InstanceName":       "instance-test",
	"InstanceTypeId":     "ecs.g1tl.4xlarge",
	"Password":           "xxx",	
	"ZoneId":             "cn-beijing-b"
}

configDB.json

{
	"min":2,
	"max":3,
	"base":[
		"i-yc9mljz3vo2ud9z787ky",
		"i-ycbpj0u2pz8rx7cc8n06"
	],
	"elasticity": [
	],
	"rule":1
}

读取相关配置信息

//读取configDB.json
	jsonFile, err := os.Open("configDB.json")
	if err != nil {
		fmt.Println("error opening json file")
		return
	}
	defer jsonFile.Close()

	jsonData, err := ioutil.ReadAll(jsonFile)
	if err != nil {
		fmt.Println("error reading json file")
		return
	}
	var dbS DbConfStruct
	json.Unmarshal(jsonData, &dbS)
	fmt.Println(dbS.Max)

	//读取configECS.json
	jsonFile, err = os.Open("configECS.json")
	if err != nil {
		fmt.Println("error opening json file")
		return
	}
	defer jsonFile.Close()

	jsonData, err = ioutil.ReadAll(jsonFile)
	if err != nil {
		fmt.Println("error reading json file")
		return
	}
	var ecsS EcsConfStruct
	json.Unmarshal(jsonData, &ecsS)
	fmt.Println(ecsS.ImageId)

	//读取configMq.json
	jsonFile, err = os.Open("configMq.json")
	if err != nil {
		fmt.Println("error opening json file")
		return
	}
	defer jsonFile.Close()

	jsonData, err = ioutil.ReadAll(jsonFile)
	if err != nil {
		fmt.Println("error reading json file")
		return
	}
	var mqS MqConfStruct
	json.Unmarshal(jsonData, &mqS)
	fmt.Println(mqS.Port)

获取mq队列里面的任务数量

//获取mq队列任务数量
		msgCounts := getQueueMsgCounts("material.analysis.new", "material.exchange",
			"material.analysis.new", mqS.HostName, mqS.UserName, mqS.Passwd, mqS.Port)

创建弹性伸缩的机器的规则,并创建新的服务器

baseCounts := len(dbS.Base)
		elasticityCounts := len(dbS.Elasticity)
		nextMaxCounts := mqS.MaxCounts + (elasticityCounts+1)*mqS.Interval

		if (baseCounts + elasticityCounts) >= dbS.Max {
			logger.Println("启动服务器数量已达到最大值...不再继续启动新服务器")
			goto Sleep
		}

		if msgCounts >= mqS.MaxCounts && msgCounts < nextMaxCounts {
			//资源申请
			serverIdList, err := RunInstances()
			var serverId *string
			if err == nil {
				if len(serverIdList) >= 1 {
					serverId = serverIdList[0]
					logger.Println("创建伸缩服务器成功,serverId:", serverId)
					fmt.Println("create server id:", serverId)
				}
			} else {
				logger.Println("创建伸缩服务器失败,err:", err.Error())
				goto Sleep
			}
			...

删除服务器资源

//资源释放
			elasticityCount := len(dbS.Elasticity)
			if 0 == elasticityCount {
				fmt.Println("没有伸缩资源,继续休眠")
				goto Sleep
			} else {
				eServerId := dbS.Elasticity[len(dbS.Elasticity)-1].EServerId
				DeleteInstance(eServerId)
				fmt.Println("删除伸缩资源:", eServerId)
			}

完整代码

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"time"
)

var logger *log.Logger

func init() {
	//指定路径的文件,无则创建
	logFile, err := os.OpenFile("./log.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND|os.O_TRUNC, 0666)
	if err != nil {
		panic(err)
	}
	logger = log.New(logFile, "", log.Lshortfile|log.Lmicroseconds)
}

func main() {
	logger.Println("application start ...")

	//读取configDB.json
	jsonFile, err := os.Open("configDB.json")
	if err != nil {
		fmt.Println("error opening json file")
		return
	}
	defer jsonFile.Close()

	jsonData, err := ioutil.ReadAll(jsonFile)
	if err != nil {
		fmt.Println("error reading json file")
		return
	}
	var dbS DbConfStruct
	json.Unmarshal(jsonData, &dbS)
	fmt.Println(dbS.Max)

	//读取configECS.json
	jsonFile, err = os.Open("configECS.json")
	if err != nil {
		fmt.Println("error opening json file")
		return
	}
	defer jsonFile.Close()

	jsonData, err = ioutil.ReadAll(jsonFile)
	if err != nil {
		fmt.Println("error reading json file")
		return
	}
	var ecsS EcsConfStruct
	json.Unmarshal(jsonData, &ecsS)
	fmt.Println(ecsS.ImageId)

	//读取configMq.json
	jsonFile, err = os.Open("configMq.json")
	if err != nil {
		fmt.Println("error opening json file")
		return
	}
	defer jsonFile.Close()

	jsonData, err = ioutil.ReadAll(jsonFile)
	if err != nil {
		fmt.Println("error reading json file")
		return
	}
	var mqS MqConfStruct
	json.Unmarshal(jsonData, &mqS)
	fmt.Println(mqS.Port)

	for {
		//获取mq队列任务数量
		msgCounts := getQueueMsgCounts("material.analysis.new", "material.exchange",
			"material.analysis.new", mqS.HostName, mqS.UserName, mqS.Passwd, mqS.Port)

		fmt.Println("get queue counts is: ", msgCounts)

		baseCounts := len(dbS.Base)
		elasticityCounts := len(dbS.Elasticity)
		nextMaxCounts := mqS.MaxCounts + (elasticityCounts+1)*mqS.Interval

		if (baseCounts + elasticityCounts) >= dbS.Max {
			logger.Println("启动服务器数量已达到最大值...不再继续启动新服务器")
			goto Sleep
		}

		if msgCounts >= mqS.MaxCounts && msgCounts < nextMaxCounts {
			//资源申请
			serverIdList, err := RunInstances()
			var serverId *string
			if err == nil {
				if len(serverIdList) >= 1 {
					serverId = serverIdList[0]
					logger.Println("创建伸缩服务器成功,serverId:", serverId)
					fmt.Println("create server id:", serverId)
				}
			} else {
				logger.Println("创建伸缩服务器失败,err:", err.Error())
				goto Sleep
			}
			//写入json
			var eesId ElasticityMachine
			eesId.EServerId = *serverId
			dbS.Elasticity = append(dbS.Elasticity, eesId)

			jsonFile, err = os.Open("configDB.json")
			if err != nil {
				fmt.Println("error opening json file")
				return
			}
			defer jsonFile.Close()

			data, err := json.MarshalIndent(dbS, "", "	") // 第二个表示每行的前缀,这里不用,第三个是缩进符号,这里用tab
			if err != nil {
				panic(err)
			}

			err = ioutil.WriteFile("configDB.json", data, 0777)
			if err != nil {
				panic(err)
			}

		} else {
			fmt.Println("队列任务较少,尝试释放资源")
			//查询弹性设备创建时间,不用查,直接删除任意一个,反正值伸缩出来的服务
			// for _, serverId := range dbS.Elasticity {
			// 	sid := serverId.EServerId

			// }
			//资源释放
			elasticityCount := len(dbS.Elasticity)
			if 0 == elasticityCount {
				fmt.Println("没有伸缩资源,继续休眠")
				goto Sleep
			} else {
				eServerId := dbS.Elasticity[len(dbS.Elasticity)-1].EServerId
				DeleteInstance(eServerId)
				fmt.Println("删除伸缩资源:", eServerId)
			}
			//删除数据写入json
			dbS.Elasticity = dbS.Elasticity[:len(dbS.Elasticity)-1]
			jsonFile, err = os.Open("configDB.json")
			if err != nil {
				fmt.Println("error opening json file")
				return
			}
			defer jsonFile.Close()

			data, err := json.MarshalIndent(dbS, "", "   ") // 第二个表示每行的前缀,这里不用,第三个是缩进符号,这里用tab
			if err != nil {
				panic(err)
			}

			err = ioutil.WriteFile("configDB.json", data, 0777)
			if err != nil {
				panic(err)
			}
		}
	Sleep:
		time.Sleep(time.Second * 300)
	}

}

项目代码已上传至gitee,传送门 volcano_ecs_manage

打赏

如果该文章对您有帮助,可以小小的打上一下哈,您的支持,是对原创的最大支持。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/431504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法套路十——回溯法之子集型回溯

算法套路十——回溯法之子集型回溯 算法实例一&#xff1a;LeetCode17. 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不…

【Spring Boot】spring boot 项目的创建

目录 一.本地创建 二.官网创建 一&#xff1a;本地创建 1. 2. 3. 4. 5. 6. 选择相应的版本&#xff0c;并点击next 7. 8. 9. 二.官网创建 1. 点击链接进入官网 2. 3. 5. 6.

【进阶C语言】动态内存管理

前言 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于C语言进阶系列&#xff0c;本专栏主要内容为数据的存储、指针的进阶、字符串和内存函数…

win10 专业版登录Microsoft账户提示:0x800704cf 错误代码——问题解决记录

win10 专业版登录Microsoft账户提示&#xff1a;0x800704cf 错误代码——问题解决记录 系统版本 版本 Windows 10 专业版 版本号 21H2 安装日期 ‎2021/‎5/‎7 操作系统内部版本 19044.2846 体验 Windows Feature Experience Pack 120.2212.4190.0 问题描述 曾经手动修改过…

《程序员面试金典(第6版)》面试题 10.11. 峰与谷(双指针,贪心思想)

题目描述 在一个整数数组中&#xff0c;“峰”是大于或等于相邻整数的元素&#xff0c;相应地&#xff0c;“谷”是小于或等于相邻整数的元素。例如&#xff0c;在数组{5, 8, 4, 2, 3, 4, 6}中&#xff0c;{8, 6}是峰&#xff0c; {5, 2}是谷。现在给定一个整数数组&#xff0c…

网络原理IP协议

hi,大家好,小魏又来了,我们已经认识了UDP,TCP,现在来认识一下位于网络层的协议,IP 认识IP地址 1.地址管理 2.路由选择 在之前的讲解中我们已经认识到了网络层的IP协议,负责寻路操作 IP地址&#xff08;Internet Protocol Address&#xff09;是指互联网协议地址&#xff0…

【Java版oj】day35年会抽奖、抄送列表

目录 一、年会抽奖 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代码 二、抄送列表 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代码 一、年会抽奖 …

C++ 命名空间 输入输出 缺省参数 引用 函数重载

在学习C之前&#xff0c;我们要先知道C和C是向上兼容的&#xff0c;也就是说&#xff0c;在cpp文件中既可以写入C的代码&#xff0c;也可以写C的代码&#xff0c;在日常编写代码中&#xff0c;经常会出现C和C混编的情况。 此博客都是在 C 的缺陷的基础之上 整理 C 中对其的优化…

PyTorch 之 强大的 hub 模块和搭建神经网络进行气温预测

文章目录一、强大的 hub 模块1. hub 模块的使用2. hub 模块的代码演示二、搭建神经网络进行气温预测1. 数据信息处理2. 数据图画绘制3. 构建网络模型4. 更简单的构建网络模型本文参加新星计划人工智能(Pytorch)赛道&#xff1a;https://bbs.csdn.net/topics/613989052 一、强…

机器学习——回归与聚类算法

线性回归 广义的线性模型 不仅是自变量是一次方的是线性模型&#xff0c;参数是一次方的也是线性模型&#xff0c;比如&#xff1a; 总结&#xff1a;线性关系的一定是线性模型&#xff0c;线性模型的不一定是线性关系。 损失函数 优化损失 求解模型中的w&#xff0c;使得…

SeNet论文解读/总结

此文章为深度学习在计算机视觉领域的图片分类经典论文SeNet&#xff08;Squeeze-and-Excitation Networks&#xff09;论文总结。 此系列文章是非常适合深度学习领域的小白观看的图像分类经典论文。系列文章如下&#xff1a; AlexNet&#xff1a;AlexNet论文解读/总结_alexnet…

uniapp-搜索配置

自定义搜索组件 1.定义组件的 UI 结构: <template><!-- 通过属性绑定的形式&#xff0c;为 .my-search-container 盒子和 .my-search-box 盒子动态绑定 style 属性 --><view class"my-search-container" :style"{background-color: bgcolor}&q…

《花雕学AI》23:中文调教ChatGPT的秘诀:体验测试与通用案例,解锁无限有趣玩法!

引言&#xff1a; 你有没有想过和一台智能机器人聊天&#xff1f;你有没有想过让一台智能机器人为你创作诗歌、故事或歌曲&#xff1f;你有没有想过让一台智能机器人陪你玩游戏、学习或社交&#xff1f;如果你的答案是肯定的&#xff0c;那么你一定会对ChatGPT感兴趣。 ChatG…

Hystrix详解

前言 Hystrix基于Feign&#xff0c;想熟悉Hystrix&#xff0c;必须先熟悉Feign。 Feign&#xff08;简介和使用&#xff09;&#xff1a; Feign&#xff08;简介和使用&#xff09;_长头发的程序猿的博客-CSDN博客 Hystrix简介 hystrix对应的中文名字是“豪猪”&#xff0c…

Android开发 Camera2获取输出SurfaceTexture

目录 一、Camera2概述 1 Pipeline 2 CameraManager 3 CameraDevice 4 CameraCharacteristics 5 CameraCaptureSession 6 CaptureRequest 7 Surface 8 CaptureResult 三、Camera2的特性 1 Camera2 才支持的高级特性 2 Camera1 迁移到 Camera2 二、示例源码 一、Came…

Honggfuzz Linux arch_clone 源码阅读 (setjmp, clone)

Honggfuzz Linux arch_clone 源码阅读 &#xff08;setjmp, clone&#xff09; 阅读 Honggfuzz 系统架构相关源码&#xff0c;在创建子进程部分遇到了几个问题&#xff0c;经过研究得以解决&#xff0c;在此记录。 Source Code 代码节选自linux/arch.c&#xff0c;已添加注释&…

RabbitMq 消息可靠性问题(一) --- publisher发送时丢失

前言 消息从生产者发送到exchange, 再到 queue, 再到消费者。这个过程中有哪些有消息丢失的可能性呢&#xff1f; 发送时丢失&#xff1a; 生产者发送的消息未送达 exchange消息到达 exchange 后未到达 queue MQ 宕机&#xff0c;queue将消息丢失consumer 接收到消息后未消费…

聊聊如何运用JAVA注解处理器(APT)

什么是APT APT&#xff08;Annotation Processing Tool&#xff09;它是Java编译期注解处理器&#xff0c;它可以让开发人员在编译期对注解进行处理&#xff0c;通过APT可以获取到注解和被注解对象的相关信息&#xff0c;并根据这些信息在编译期按我们的需求生成java代码模板或…

基于DistFlow的含分布式电源配电网优化模型【IEEE39节点】(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

SpringBoot【基础篇】---- SSMP整合综合案例

SpringBoot【基础篇】---- SSMP整合综合案例1. 模块创建2. 实体类开发3. 数据层开发----基于CRUD查看MP运行日志查看 MP 的运行日志4. 数据层开发----分页功能制作5. 数据层开发----条件查询功能制作6. 业务层开发业务层快速开发7. 表现层开发8. 表现层消息一致性处理9. 前后端…