利用golang_Consul代码实现Prometheus监控目标的注册以及动态发现与配置

文章目录

  • 前言
  • 一、prometheus发现方式
  • 二、监控指标注册架构图
  • 三、部分代码展示
    • 1.核心思想
    • 2.代码目录
    • 3、程序入口函数剖析
    • 4、settings配置文件
    • 5、初始化配置文件及consul
    • 6、全局变量
    • 7、配置config
    • 8、公共方法目录common
    • 9、工具目录tools
    • 10、service层展示
    • 11、命令行参数
    • 12、Makefile示例
    • 13、脚本示例
  • 四、演示效果
    • 1、上传代码,并整理xlsx文件
    • 2、脚本执行命令
      • 2.1 创建go.mod文件并下载标准库
      • 2.2 执行构建命令
      • 2.3 执行xlsx文件解析为json文件命令
      • 2.4 执行获取json文件内容并注册到命令
      • 2.5 验证
      • 2.6 扩展情况说明
  • 总结


前言

在实际产生环境中主要以prometheus监控为主,在使用该监控时,有个很大的问题时,需要手动修改Prometheus.yml文件,将监控指标手动添加进去,当监控指标少的时候,维护和添加都很方便,但是当一套环境中监控指标多大几百个,添加工作繁琐,这时你会想到写个shell脚本,对多个监控指标进行添加,但是你有没有考虑过此时的prometheus.yaml文件的可维护性以及当添加的监控指标越来越多时,prometheus主机的cpu、内存也随之增长,这时你该怎么处理呢?因此,本篇文章带你解决此类问题,准备好开始发车了!!!


一、prometheus发现方式

	prometheus主要有以下几种发现方式:1)static_configs: #静态服务发现2)file_sd_configs: #文件服务发现3)dns_sd_configs: DNS #服务发现4)kubernetes_sd_configs: #Kubernetes 服务发现5)consul_sd_configs: Consul #consul服务发现

二、监控指标注册架构图

在这里插入图片描述

三、部分代码展示

1.核心思想

 	1、本代码主要是使用golang、xlsx文件、consul三大部分将整理好的监控指标(主机监控、微服务端口监控、业务接口监控、telegraf组件监控等及部分)通过golang调用consulApi注册到consul中2、xlsx文件中的sheet页必须满足settings.yaml文件中的这部分sheet_name:- "hosts_data"- "service_data"- "serviceurl_data"或者自行定义sheet页名称,同时一定要修改settings.yaml文件中的上述部分,二者必须保持一致3、代码的主要功能就是将整理好的xlsx文件,通过`tools.ProcessExcelFiles(cmdFlags)` 函数将xlsx形式中的文件转换为以json结尾的文件,具体的转换过程看代码即可4、注册到consul时,首先通过json反序列化操作,拿到对应的json数据值,然后对注册到consul中的五大部分(主机、主机探活、业务接口、微服务端口监控、agent组件监控)分别进行相关拼接操作5、当拼接操作结束后,调用tools目录下的函数,并传参,实际tools目录下的函数都是调用了consulAPI进行的注册6、makefile定义了代码的多重操作,但是执行繁琐,因此引入了launch.sh脚本,执行launch.sh xx 即可完成xlsx文件转换、注册功能等

2.代码目录

采用Makefile和launch.sh脚本做到执行代码命令的统一管理
在这里插入图片描述

3、程序入口函数剖析

cmd/main.go文件主要是代码的执行入口处,包含配置文件的解析、命令行参数解析、consul初始化、代码的执行入口

package mainimport ("log""import_consul/core"myflags "import_consul/flag""import_consul/global""import_consul/service""import_consul/tools"
)func main() {// 解析命令行参数cmdFlags := myflags.Parse()//读取配置文件core.InitConf()// 初始化Consulif consulClient, err := core.ConsulConnect(); err != nil {log.Fatalf("consul connect failed: %v", err)return} else {// 将初始化的客户端实例赋值给global.ConsulClient,以便全局使用global.ConsulClient = consulClientlog.Println("consul connect success")}//执行execl转json文件tools.ProcessExcelFiles(cmdFlags)//其余代码不在展示~~~~
}

4、settings配置文件

consul:ip: "xx" #conusl主机ipport: xx		   #consul端口service_name:        #consul-web界面中的service目录名- "Host_Status"- "ICMP"- "Telegraf"- "Service_TCP"- "Service_URL"xlsx:xlsxfile_path: "/root/test.xlsx" #xlsx监控指标文件位置sheet_name:					   #xlsx文件中的sheet页名称- "hostinfo"- "serviceinfo"- "serviceurlInfo"jsonfile: 	                      #xlsx文件转为json文件后的保存位置hostjson_path: "/root/jsonfile/host.json" servicejson_path: "/root/jsonfile/service.json"serviceurljson_path: "/root/jsonfile/serviceUrl.json"

5、初始化配置文件及consul

初始化settings.yaml配置文件,主要使用golang的gopkg.in/yaml.v2 标准库,指定yaml文件位置并读取yaml文件进行反序列操作

package coreimport ("log""os""path/filepath""import_consul/config""import_consul/global""gopkg.in/yaml.v2"
)func InitConf() {// 直接构建配置文件的路径ConfigFile := filepath.Join("settings.yaml")c := &config.Config{}yamlConf, err := os.ReadFile(ConfigFile)if err != nil {log.Fatalf("get yamlconf error: %s", err)}err = yaml.Unmarshal(yamlConf, c) //yaml文件反序列化if err != nil {log.Fatalf("config init Unmarsharl: %v", err)}log.Print("config init Unmarsharl success")global.Config = c
}

初始化consul,主要使用github.com/hashicorp/consul/api consul的标准库,创建一个consul客户端对象

package coreimport ("import_consul/global""github.com/hashicorp/consul/api"
)// consul 初始化
func ConsulConnect() (*api.Client, error) {config := api.DefaultConfig()config.Address = global.Config.Consul.URL()if client, err := api.NewClient(config); err != nil {return nil, err} else {return client, nil}
}

6、全局变量

因为文件都已分层处理,为了方便程序间调用相应的文件,因此在此处将Config、consul客户端对象进行全局处理,使用时直接global.Config.xxx 或global.CounsulClient.xxx即可

package globalimport ("import_consul/config""github.com/hashicorp/consul/api"
)var (Config       *config.Config //接收读取到的config文件ConsulClient *api.Client    //consul客户端
)

7、配置config

主要是根据settings.yaml文件中定义的变量进行结构体配置,enter.go文件是config目录下结构体文件的总入口,与global中的全局变量Config遥相呼应

enter.gopackage config//配置入口初始化 采用结构体type Config struct {Consul   Consul   `yaml:"consul"`Xlsx     Xlsx     `yaml:"xlsx"`JsonFile JsonFile `yaml:"jsonfile"`}
consul.go
#consul结构体字段package configimport "fmt"//连接consul的ip、端口type Consul struct {IP          string   `yaml:"ip"`Port        int      `yaml:"port"`ServiceName []string `yaml:"service_name"`}func (c *Consul) URL() string {return fmt.Sprintf("%s:%d", c.IP, c.Port)}

其余的结构体不在展示,自行按照settings.yaml编写对应的struct结构体即可

8、公共方法目录common

此目录下的parse_xlsx_common.go文件主要是针对定义的sheet页来做相关操作,使用xlsx标准库获取到对应sheet页中的行、列数,然后循环获取每个表格中的数据,调用 writeJSONToFile()方法,将获取到的数据转换为json形式的文件并保存

package commonimport ("bufio""encoding/json""log""os""github.com/tealeg/xlsx/v3"
)// 处理hostinfo表格
func ParseHostInfo(sheet *xlsx.Sheet, fileName string) error {hostDist := make(map[string][]string)// 从第二行开始遍历(假设第一行是标题行)for rowNumber := 1; rowNumber < sheet.MaxRow; rowNumber++ {row, _ := sheet.Row(rowNumber)ip := row.GetCell(0).String()env := row.GetCell(1).String()hostType := row.GetCell(2).String()productInfo := row.GetCell(3).String()hostDist[ip] = []string{env, hostType, productInfo}}// 将hostDist序列化为JSON并写入文件if err := writeJSONToFile(hostDist, fileName); err != nil {log.Fatalf("ParseHostInfo Failed to write JSON to file: %v", err)}log.Printf("ParseHostInfo Success to write JSON to file: %v", hostDist)return nil//其余代码不在展示~~~~
}

9、工具目录tools

这个目录下主要用于存放实现代码所需要的工具文件,例如:golang解析xlsx文件、读取json文件、创建目录文件、consul注册监控指标文件工具等,如下所示

golang解析xlsx文件
package toolsimport ("fmt""log""sync""import_consul/common"myflags "import_consul/flag""import_consul/global""github.com/tealeg/xlsx/v3"
)//定义xlsx转json所需要的结构体
type ExcelToJson struct {File  *xlsx.FileSheet *xlsx.Sheet
}
//创建工厂函数,实例化结构体
func newExcelToJson(filePath, sheetName string) (*ExcelToJson, error) {file, err := xlsx.OpenFile(filePath)if err != nil {log.Fatalf("open xlsx file failed:%v\n", err)return nil, err}log.Printf("open xlsx file success:%s\n", filePath)sheet, ok := file.Sheet[sheetName]if !ok {return nil, fmt.Errorf("sheet %s not found", sheetName)}return &ExcelToJson{File: file, Sheet: sheet}, nil
}// 调用common包中的ParseHostInfo方法 将xlsx中的hostinfo页解析并存到host.json文件中
func (e *ExcelToJson) ParseXLSXHost() error {if err := EnsureDir(global.Config.JsonFile.Hostjson_Path); err != nil {return fmt.Errorf("failed to ensure directory for host json: %w", err)}return common.ParseHostInfo(e.Sheet, global.Config.JsonFile.Hostjson_Path)
}// 处理Execl文件的逻辑函数入口,使用协程和互斥锁,提高执行效率
var mutex sync.Mutex // 声明互斥锁
func ProcessExcelFiles(cmdFlags myflags.CmdFlags) {//创建匿名切片结构体并初始化sheetActions := []struct {Flag   boolSheet  stringAction func(*ExcelToJson) error}{{cmdFlags.ParseHost, global.Config.Xlsx.SheetName[0], (*ExcelToJson).ParseXLSXHost},}var wg sync.WaitGroup//定义保存error的管道errChan := make(chan error, len(sheetActions))for _, action := range sheetActions {if action.Flag {wg.Add(1)//开启协程go func(action struct {Flag   boolSheet  stringAction func(*ExcelToJson) error}) {defer wg.Done()e, err := newExcelToJson(global.Config.Xlsx.XlsxFile_Path, action.Sheet)if err != nil {log.Fatalf("实例化ExcelToJson结构体失败,%v\n", err)errChan <- errreturn}if err := action.Action(e); err != nil {errChan <- errreturn}// 示例:安全更新共享资源mutex.Lock() // 在访问共享资源前加锁mutex.Unlock() // 完成后解锁}(action)}}wg.Wait()close(errChan)//循环打印管道中的错误并输出for err := range errChan {if err != nil {log.Fatalf("Error processing sheet: %v", err)}}
}
//其余代码不在展示~~~~

此处更重要的是数据清洗转换,设置好指标注册到consul中Tag标签都展示什么,因为这关系到prometheus采集到数据后,在grafana中怎么对图形进行处理

监控指标向consul注册
package toolsimport ("log""import_consul/global""github.com/hashicorp/consul/api"
)func Add_host(ip, env, HostType, businesscode string) {// 构造服务注册的配置registration := &api.AgentServiceRegistration{ID:      global.Config.Consul.ServiceName[0] + ip, // 唯一服务IDName:    global.Config.Consul.ServiceName[0],      // 服务名称Address: ip,Tags:    []string{global.Config.Consul.ServiceName[0]},Meta: map[string]string{"ip":            ip,"env":           env,"type":          HostType,"business_code": businesscode,},}// 调用Consul客户端及consul的注册服务函数Agent().ServiceRegister(registration)if err := global.ConsulClient.Agent().ServiceRegister(registration); err != nil {log.Fatalf("Error registering host with Consul:%v\n", err)return}log.Printf("Host %s registered successfully\n", ip)
}
//其余代码不在展示~~~~

当用上述代码对注册到consul中的相关标签进行清洗转换后,就如下图所示
处理好后注册到consul的截图

10、service层展示

通过自定义类型HostInfo,调用tools目录中json文件处理函数ReadJSONFile(),对json文件进行处理,处理完成后,调用tools目录下的Add_host()函数,实现监控指标的注册

package serviceimport ("log""import_consul/global""import_consul/tools"
)// HostInfo 用于映射YAML文件结构
type HostInfo map[string][]string// Host 读取并解析host.yaml,然后添加每个主机
func Host() {var results HostInfoerr := tools.ReadJSONFile(global.Config.JsonFile.Hostjson_Path, &results)if err != nil {log.Fatalf("Error reading adn parsing JSON file: %s,error: %v\n", global.Config.JsonFile.Hostjson_Path, err)}log.Printf("Success reading and parsing JSON file: %s\n", global.Config.JsonFile.Hostjson_Path)for hostIP, info := range results {if len(info) >= 3 {tools.Add_host(hostIP, info[0], info[1], info[2])}}
}
//其余代码不在展示~~~~

11、命令行参数

因为有xlsx文件转换json文件的代码、各监控指标注册consul的代码,每次执行并不需要全部执行,因为引入命令行参数的标准库,想要执行哪些代码,直接编译程序代码,然后./xxx -parseHost=true即可执行对应的代码

package flagimport ("flag"
)// CmdFlags 用于保存命令行参数
type CmdFlags struct {ParseHost         bool
}// Parse 解析命令行参数
func Parse() CmdFlags {var cmdFlags CmdFlags//只有parseHost=true时才会执行flag.BoolVar(&cmdFlags.ParseHost, "parseHost", false, "Parse hosts from XLSX and convert to YAML")flag.Parse()return cmdFlags
}

12、Makefile示例

# 定义变量
BINARY_NAME ?= default_app_name #如果BINARY_NAME没有在命令行中指定,则使用default_app_name为默认值GOBUILD=go build -o $(BINARY_NAME) ./cmd
GOCLEAN=go clean
GORUN=go run ./cmd/...
GOGET=go get
CMD=./$(BINARY_NAME)# 默认目标
all: build# 构建二进制文件
build:$(GOBUILD)# 清理构建文件
clean:$(GOCLEAN)rm -f $(BINARY_NAME)# 依赖获取,如果有外部依赖可以使用
#./...: 这是go get命令的参数,指示go get搜索当前目录(以及所有子目录)中的所有Go文件,并分析它们的导入声明
deps:$(GOGET) ./...# 根据需要执行的特定服务,可以添加更多的运行目标
run-execlTohostJson:$(CMD) -parseHost=truerun-execToAllJson:$(CMD) 	-parseHost=true -parseService=true -parseServiceURL=truerun-host:$(CMD) -registerHost=true//其余的不展示~~~

13、脚本示例

主要将makefile中的指令集中到脚本中,执行方便,不容易出错.前提是服务器必须提前安装好make gcc等基础命令

#!/bin/bash# 检查是否传递了参数
if [ "$#" -lt 1 ]; thenecho "Usage: $0 {build|clean|run|deps|run-execlTohostJson|...|run-all} [BINARY_NAME]"exit 1
fiACTION=$1
BINARY_NAME=${2:-} # 如果提供了第二个参数,使用它作为BINARY_NAME# 获取脚本所在的目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"# 推断 Makefile 所在的目录(假设 Makefile 在脚本目录的上一级)
MAKEFILE_DIR="$(dirname "$SCRIPT_DIR")"# nohup.out 文件路径
NOHUP_FILE="$SCRIPT_DIR/nohup.out"# binary_name 文件路径,用于存储和读取 BINARY_NAME
BINARY_NAME_FILE="$SCRIPT_DIR/.binary_name"# 检查 nohup.out 文件是否存在,如果不存在则创建
if [ ! -f "$NOHUP_FILE" ]; thentouch "$NOHUP_FILE"
fi# 如果提供了 BINARY_NAME,则将其保存到文件中
if [ -n "$BINARY_NAME" ]; thenecho "$BINARY_NAME" > "$BINARY_NAME_FILE"
elif [ -f "$BINARY_NAME_FILE" ]; then# 如果没有提供 BINARY_NAME 但文件存在,则从文件中读取BINARY_NAME=$(cat "$BINARY_NAME_FILE")
fi# 根据参数执行相应的 make 命令
case "$ACTION" inbuild)echo "===== Starting $ACTION with BINARY_NAME=$BINARY_NAME at $(date) =====" >> "$NOHUP_FILE"BINARY_NAME=$BINARY_NAME make -C "$MAKEFILE_DIR" $ACTION &>> "$NOHUP_FILE";;clean)# 清理时,需要确保使用之前存储的 BINARY_NAMEif [ -n "$BINARY_NAME" ]; thenecho "===== Cleaning with BINARY_NAME=$BINARY_NAME at $(date) =====" >> "$NOHUP_FILE"BINARY_NAME=$BINARY_NAME make -C "$MAKEFILE_DIR" $ACTION &>> "$NOHUP_FILE"# 清理操作完成后,删除 BINARY_NAME 文件rm -f "$BINARY_NAME_FILE"elseecho "No BINARY_NAME specified or found. Please provide a binary name or run a build first."exit 1fi;;run|deps|run-execlTohostJson|run-registerServices|run-all)echo "===== Starting $ACTION with BINARY_NAME=$BINARY_NAME at $(date) =====" >> "$NOHUP_FILE"BINARY_NAME=$BINARY_NAME make -C "$MAKEFILE_DIR" $ACTION &>> "$NOHUP_FILE";;*)echo "Invalid option: $ACTION"echo "Usage: $0 {build|clean|run|deps|run-execlTohostJson|...|run-all} [BINARY_NAME]"exit 1;;
esac

四、演示效果

1、上传代码,并整理xlsx文件

	1、上传代码至prometheus或与pormetheus机器相同的机器2、机器必须已安装golang环境 go>=1.18版本3、整理xlsx文件,xlsx模板如下截图所示

host截图
在这里插入图片描述
在这里插入图片描述

2、脚本执行命令

上传完代码后,cd /xxx/xxx/xxx/ 目录下

2.1 创建go.mod文件并下载标准库

[root@python2 import_consul]# go mod init import_consul
[root@python2 import_consul]# go mod tidy  #下载依赖

2.2 执行构建命令

[root@python2 root]#     cd scripts
[root@python2 scripts]# ./launch.sh build service_register_consul

2.3 执行xlsx文件解析为json文件命令

第一种: 只解析某一个sheet页[root@python2 scripts]# ./launch.sh run-execlTohostJson
第二种: 解析全部sheet页[root@python2 scripts]# ./launch.sh run-execlToALLJson

2.4 执行获取json文件内容并注册到命令

第一种: 只注册某个监控指标[root@python2 scripts]# ./launch.sh run-host
第二种: 注册全部指标[root@python2 scripts]# ./launch.sh run-registerServices

2.5 验证

	1、查看scripts/nphup.out文件中命令执行是否有报错2、查看consul中是否已注册到指标

nohup.out
在这里插入图片描述

2.6 扩展情况说明

	如下截图所示,显示服务健康检查失败,这是因为我在指标注册到consul的代码中配置了健康检查机制checks,又因为本地开发环境与预发环境的网段不通,所有才会导致健康检查失败,并不是代码是失败的。
	指标注册到consul的代码的健康检查 部分代码示例:Check: &api.AgentServiceCheck{TTL:                            "10s", //心跳检测时间DeregisterCriticalServiceAfter: "5m", // 如果服务1分钟内处于critical状态,则自动注销},

在这里插入图片描述
至此,整个代码的演示也就完成了


总结

写这个代码的原因有两个,其一就是我刚开始所说的维护prometheus.yml文件的成本越来越高,且服务器资源日益不足;其二刚才最近在学习golang,也借此机会提高一下golang的基础语法知识以及标准库的使用方法。因此才有此代码的诞生.主要给大家一个思路,像代码中的consul标签处理部分也仅适用于我司,如果要想看源码.见本博客下载即可。

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

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

相关文章

Android笔记-安装Termux开启ssh,安装vim、android-tool、python等

背景 家里面有个老手机&#xff0c;想将此手机做成一个家庭服务器。控制各种家电。目前准备先控制电视机 流程 用电脑usb连接手机&#xff0c;下载好Termux&#xff0c;在安卓手机上安装好。这里就不记录笔记了&#xff0c;各个手机不一样。 安装好进入手机后&#xff1a; …

mfc140.dll是什么文件?mfc140.dll文件下载安装办法

一、mfc140.dll文件功能与作用 mfc140.dll作为Microsoft Foundation Classes库的一部分&#xff0c;提供了一系列的基础功能&#xff0c;这些功能对于开发Windows桌面应用程序至关重要。 2.1 应用程序框架 mfc140.dll封装了应用程序的生命周期管理&#xff0c;包括初始化、运…

赶论文不用愁:如何利用ChatGPT在3小时内完成论文

在这份指南里&#xff0c;我将详细介绍如何运用ChatGPT 4.0的高级功能来辅助学术研究与文章写作。从挖掘研究课题的初步想法开始&#xff0c;到撰写一篇内容深刻、结构完整的学术论文&#xff0c;我将逐步演示如何在研究的各个阶段中充分利用ChatGPT。值得一提的是&#xff0c;…

编程精粹—— Microsoft 编写优质无错 C 程序秘诀 07:编码中的假象

这是一本老书&#xff0c;作者 Steve Maguire 在微软工作期间写了这本书&#xff0c;英文版于 1993 年发布。2013 年推出了 20 周年纪念第二版。我们看到的标题是中译版名字&#xff0c;英文版的名字是《Writing Clean Code ─── Microsoft’s Techniques for Developing》&a…

二进制炸弹的fp是什么?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

【算法】优先级队列-基础与应用

优先级队列&#xff08;Priority Queue&#xff09;是一种特殊的队列类型&#xff0c;它允许在其元素中分配优先级。与传统的先进先出&#xff08;FIFO&#xff09;队列不同&#xff0c;优先级队列中元素的出队顺序取决于它们的优先级。优先级较高的元素会被优先处理&#xff0…

【Qt笔记①】帮助文档、窗口、按钮、信号和槽、lambda表达式

学习第一天&#xff1a;2024-3-9 文章目录 Qt creator 快捷键帮助文档默认生成的main.cpp逐行解释核心类帮助文档的查阅方法-①代码创建按钮第一个第二个对窗口的其他设置 对象树窗口坐标系信号和槽&#xff08;优点&#xff1a;松散耦合&#xff09;帮助文档的查阅方法-②找信…

轨迹规划系列之S型速度曲线绝对值定位功能块(Codesys源代码)

1、轨迹规划的作用 轨迹规划的作用(前馈速度+位置插补)-CSDN博客文章浏览阅读13次。轨迹规划可以产生运动控制系统位置闭环控制所需要的前馈速度和插补位置值。前馈速度+PID位置闭环控制典型应用可以参考下面文章链接:1、S7-1200PLC和V90伺服通过工艺对象实现定位控制S7-1200…

表驱动法 -优化逻辑分支

表驱动法 -优化逻辑分支 定义 表驱动法&#xff08;Table-Driven Approach&#xff09;是一种编程模式&#xff0c;可以将输入变量作为直接或间接索引在表里查找所需的结果或处理函数&#xff0c;而不使用逻辑语句&#xff08;if-else 和 switch-case&#xff09;。索引表可以…

VMware与windows的共享文件夹没找到怎么办?

如果这样子添加&#xff0c;在ubuntu中还是没能找到。开机后有的时候仍然未发现共享文件夹。 二、解决办法 使用如下指令&#xff1a; sudo mount -t fuse.vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other /mnt/hgfs/ 是挂载点&#xff0c;也可以指定其它挂载点 -o allow_other…

DHCP原理1-单个局域网出现多个DHCP服务器会发生什么

1. 背景 DHCP全称是Dynamic Host Configuration Protocol。其协议标准是RFC1541&#xff08;已被RFC2131取代&#xff09;&#xff0c;主要实现服务器向客户端动态分配IP地址&#xff08;如IP地址、子网掩码、网关、DNS&#xff09;和配置信息。其系统架构是标准的C/S架构。RFC…

自学SAP是学习ECC版本还是S4版本?

很多人想学SAP&#xff0c;问我应该学ECC版本还是S4版本&#xff0c;我的建议如果你是自学的话&#xff0c;我个人建议使用ECC版本就行&#xff0c;因为这两个版本前台业务和后台配置的操作差异并不大&#xff0c;主要差异在于数据库的差异&#xff0c;前台业务操作和后台系统配…

OS复习笔记ch12-1

文件系统 概述 文件是大多数应用程序的核心要素&#xff0c;文件系统是操作系统对用户来说最重要的部分之一。 本章的主要内容见下图&#xff1a; 文件&#xff0c;大家耳熟能详的就是的docx、pdf、jpg、MP4等各种后缀文件&#xff0c;根据任务需要文件又分成了文本、图片、…

超越YOLOv8,飞桨推出精度最高的实时检测器RT-DETR!

众所周知&#xff0c;实时目标检测( Real-Time Object Detection )一直由 YOLO 系列模型主导。 飞桨在去年 3 月份推出了高精度通用目标检测模型 PP-YOLOE &#xff0c;同年在 PP-YOLOE 的基础上提出了 PP-YOLOE 。后者在训练收敛速度、下游任务泛化能力以及高性能部署能力方面…

我国目前常用的卫星影像星座有哪些(高分二号、高分七号、吉林一号、高景一号······)

​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 点击学习——>遥感影像综合处理4大遥感软件ArcGISENVIErdaseCognition 中国目前的遥感卫星在数量、种类和应用领域上都取得了显著进展&#xff0c;覆盖了陆地、气象、海…

ViT:5 Knowledge Distillation

实时了解业内动态&#xff0c;论文是最好的桥梁&#xff0c;专栏精选论文重点解读热点论文&#xff0c;围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;…

Java17 --- SpringSecurity之前后端分离处理

目录 一、实现前后端分离 1.1、导入pom依赖 1.2、认证成功处理 1.3、认证失败处理 1.4、用户注销处理 1.5、请求未认证处理 1.6、跨域处理 1.7、用户认证信息处理 1.8、会话并发处理 一、实现前后端分离 1.1、导入pom依赖 <dependency><groupId>co…

【python】python股票量化交易策略分析可视化(源码+数据集+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

【fastapi+mongodb】使用motor操作mongodb(三)

本篇文章介绍mongodb的删和改&#xff0c;下面是前两篇文章的链接&#xff1a; 【fastapimongodb】使用motor操作mongodb 【fastapimongodb】使用motor操作mongodb&#xff08;二&#xff09; delete delete 的用法基本和查找一致&#xff0c;包括delete_one&#xff08;删除…

借助AI快速提高英语听力:如何获得适合自己的听力材料?

英语听力是英语学习中的一个重要组成部分&#xff0c;它对于提高语言理解和交流能力至关重要。可理解性学习&#xff08;comprehensible input&#xff09;是语言习得理论中的一个概念&#xff0c;由语言学家Stephen Krashen提出&#xff0c;指的是学习者在理解语言输入的同时&…