利用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 main

import (
	"log"
	"import_consul/core"
	myflags "import_consul/flag"
	"import_consul/global"
	"import_consul/service"
	"import_consul/tools"
)

func main() {
	// 解析命令行参数
	cmdFlags := myflags.Parse()

	//读取配置文件
	core.InitConf()

	// 初始化Consul
	if consulClient, err := core.ConsulConnect(); err != nil {
		log.Fatalf("consul connect failed: %v", err)
		return
	} else {
		// 将初始化的客户端实例赋值给global.ConsulClient,以便全局使用
		global.ConsulClient = consulClient
		log.Println("consul connect success")
	}

	//执行execl转json文件
	tools.ProcessExcelFiles(cmdFlags)

	//其余代码不在展示~~~~
}

4、settings配置文件

consul:
  ip: "xx" #conusl主机ip
  port: 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 core

import (
	"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 core

import (
	"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 global

import (
	"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.go
	package config

	//配置入口初始化 采用结构体
	
	type Config struct {
		Consul   Consul   `yaml:"consul"`
		Xlsx     Xlsx     `yaml:"xlsx"`
		JsonFile JsonFile `yaml:"jsonfile"`
	}
consul.go
#consul结构体字段
	package config
	
	import "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 common

import (
	"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 tools

import (
	"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.File
	Sheet *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   bool
		Sheet  string
		Action 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   bool
				Sheet  string
				Action 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 <- err
					return
				}
				if err := action.Action(e); err != nil {
					errChan <- err
					return
				}

				// 示例:安全更新共享资源
				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 tools

import (
	"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, // 唯一服务ID
		Name:    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 service

import (
	"log"
	"import_consul/global"
	"import_consul/tools"
)

// HostInfo 用于映射YAML文件结构
type HostInfo map[string][]string

// Host 读取并解析host.yaml,然后添加每个主机
func Host() {

	var results HostInfo
	err := 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 flag

import (
	"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=true


run-execToAllJson:
	$(CMD) 	-parseHost=true -parseService=true -parseServiceURL=true

run-host:
	$(CMD) -registerHost=true

//其余的不展示~~~

13、脚本示例

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

#!/bin/bash

# 检查是否传递了参数
if [ "$#" -lt 1 ]; then
    echo "Usage: $0 {build|clean|run|deps|run-execlTohostJson|...|run-all} [BINARY_NAME]"
    exit 1
fi

ACTION=$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" ]; then
    touch "$NOHUP_FILE"
fi

# 如果提供了 BINARY_NAME,则将其保存到文件中
if [ -n "$BINARY_NAME" ]; then
    echo "$BINARY_NAME" > "$BINARY_NAME_FILE"
elif [ -f "$BINARY_NAME_FILE" ]; then
    # 如果没有提供 BINARY_NAME 但文件存在,则从文件中读取
    BINARY_NAME=$(cat "$BINARY_NAME_FILE")
fi

# 根据参数执行相应的 make 命令
case "$ACTION" in
    build)
        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_NAME
        if [ -n "$BINARY_NAME" ]; then
            echo "===== 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"
        else
            echo "No BINARY_NAME specified or found. Please provide a binary name or run a build first."
            exit 1
        fi
        ;;
    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标签处理部分也仅适用于我司,如果要想看源码.见本博客下载即可。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

双指针算法——部分OJ题详解

目录 关于双指针算法&#xff1a; 1&#xff0c;对撞指针 2&#xff0c;快慢指针 部分OJ题详解 283.移动零 1089.复写零 202.快乐数 11.盛水最多的容器 611.有效三角形的个数 剑指offer 57.和为s的两个数字 15.三数之和 18.四数之和 关于双指针算法&#xff1a; …

6月20日(周四)A股行情总结:A股险守3000点,恒生科技指数跌1.6%

A股三大股指走弱&#xff0c;科创板逆势上扬&#xff0c;半导体板块走强&#xff0c;多股20CM涨停。中芯国际港股涨超1%。恒生科技指数跌超1%。离岸人民币对美元汇率小幅走低&#xff0c;20日盘中最低跌至7.2874&#xff0c;创下2023年11月中旬以来的新低&#xff0c;随后收复部…

免费一年SSL证书申请——建议收藏

免费一年SSL证书申请——建议收藏 获取免费一年期SSL证书其实挺简单的 准备你的网站&#xff1a; 确保你的网站已经有了域名&#xff0c;而且这个域名已经指向你的服务器。还要检查你的服务器支持HTTPS&#xff0c;也就是443端口要打开&#xff0c;这是HTTPS默认用的。 验证域…

nlp基础-文本预处理及循环神经网络

1 认识文本预处理 1 文本预处理及其作用 定义&#xff1a;文本送给模型之前&#xff0c;提前要做的工作 作用&#xff1a;指导模型超参数的选择 、提升模型的评估指标 举个例子&#xff1a; 思路常识&#xff0c;打造成 X Y关于Y&#xff1a;10分类标签是否均衡关于X&#xf…

cesium 添加 Echarts 饼图

cesium 添加 Echarts 饼图 1、实现思路 1、首先创建echarts饼图,拿到创建好的canvas 2、用echarts里面生成的canvas添加到cesium billboard中 2、示例代码 <!DOCTYPE html> <html lang="en"><head><

实验四:复合对象的基本应用

如果文章有写的不准确或需要改进的地方&#xff0c;还请各位大佬不吝赐教&#x1f49e;&#x1f49e;&#x1f49e;。朱七在此先感谢大家了。&#x1f618;&#x1f618;&#x1f618; &#x1f3e0;个人主页&#xff1a;语雀个人知识库 &#x1f9d1;个人简介&#xff1a;大家…

QT事件处理系统之五:自定义事件的发送案例 sendEvent和postEvent接口

1、案例 双击窗口,会发送 自定义事件,然后在事件过滤中心进行拦截处理自定义事件。 2、核心代码 /*解释:双击窗口时,将产生双击事件,然后该事件被包裹成一个对象,随后将会被发往event事件中心,然后进行事件的处理(Widget对象);因为m_lineEdit开启了事件过滤机制,所…

2025秋招NLP算法面试真题(二)-史上最全Transformer面试题:灵魂20问帮你彻底搞定Transformer

简单介绍 之前的20个问题的文章在这里&#xff1a; https://zhuanlan.zhihu.com/p/148656446 其实这20个问题不是让大家背答案&#xff0c;而是为了帮助大家梳理 transformer的相关知识点&#xff0c;所以你注意看会发现我的问题也是有某种顺序的。 本文涉及到的代码可以在…

2024全网最全面及最新且最为详细的网络安全技巧四 之 lsql注入以及mysql绕过技巧 (1)———— 作者:LJS

目录 4. SQL注入基础之联合查询 什么是SQL注入漏洞 SQL注入原理 SQL注入带来的危害 注入按照注入技术&#xff08;执行效果&#xff09;分类 简单联合查询注入语句 4.1 [网鼎杯 2018]Comment二次注入 正好总结一下绕过addslashes的方式 4.2 ciscn2019web5CyberPunk 复现平台 解…

四川汇聚荣科技有限公司怎么样?

在探讨一家科技公司的综合实力时&#xff0c;我们往往从多个维度进行考量&#xff0c;包括但不限于公司的发展历程、产品与服务的质量、市场表现、技术创新能力以及企业文化。四川汇聚荣科技有限公司作为一家位于中国西部的科技企业&#xff0c;其表现和影响力自然也受到业界和…

卧槽,6。套死你猴子,Tomcat访问html页面显示源码?

卧槽&#xff0c;6。Tomcat访问html页面显示源码&#xff1f; 元凶text/explain //踩坑&#xff01;&#xff01;&#xff01;不能用 servletResponse.setContentType("text/explain&#xff0c;否则访问html会看到源码&#xff0c;而不是渲染页面; charsetUTF-8"…

接口提示信息国际化, 调用LibreTranslate 离线翻译, 国际化支持

文章目录 背景实现方式步骤下载并部署离线翻译服务;前端接入 背景 将接口返回内容进行翻译, 以适配多语言需求; 实现方式 前端拦截接口返回内容, 调用离线翻译服务进行翻译, 翻译之后再进行相应的提示 参考资料: 离线翻译服务: https://github.com/LibreTranslate/LibreTra…

ADD属性驱动架构设计(一)

目录 一、架构设计过程 1.1、架构设计过程 1.1.1、设计目的 1.1.2、质量属性&#xff08;非功能需求&#xff09; 1.1.3、核心功能&#xff08;功能需求&#xff09; 1.1.4、架构关注 1.1.5、约束条件 1.2、基于设计过程 二、什么是ADD? 三、为什么选择ADD? 四、作…

力扣SQL50 超过5名学生的课

Problem: 596. 超过5名学生的课 Code select class from courses group by class having count(distinct student) > 5;

【转型指南】从软件测试到技术多面手

★ 导言 小艺是一位毕业于985的计算机硕士&#xff0c;工作多年&#xff0c;现在某大厂从事软件测试方面的管理工作。目前在工作中游刃有余&#xff0c;但面对技术的飞速变化和职业发展的不确定性&#xff0c;还是难免焦虑&#xff0c;正在积极思考如何进一步提升自己&#xff…

【图文解说】BP神经网络与深度学习CNN的关系

本文来自《老饼讲解-BP神经网络》https://www.bbbdata.com/ 目录 一、BP神经网络网络是什么二、BP神经网络用于图象识别问题1.1.BP神经网络解决图象识别问题1.2.BP神经网络解决图象识别问题的困难 三、从BP到CNN深度学习模型 BP神经网络是一个经典、有效的算法&#xff0c;即使…

【Java】已解决java.lang.FileNotFoundException异常

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决java.lang.FileNotFoundException异常 在Java编程中&#xff0c;java.lang.FileNotFoundException是一个常见的异常&#xff0c;它通常表示程序试图打开一个不存在的文件、文…

LabVIEW与3D相机开发高精度表面检测系统

使用LabVIEW与3D相机开发一个高精度表面检测系统。该系统能够实时获取三维图像&#xff0c;进行精细的表面分析&#xff0c;广泛应用于工业质量控制、自动化检测和科学研究等领域。通过真实案例&#xff0c;展示开发过程中的关键步骤、挑战及解决方案&#xff0c;确保系统的高性…

python - 变量和字符串

一.变量 变量名就像我们现实社会的名字&#xff0c;把一个值赋值给一个名字时&#xff0c;Ta会存储在内存中&#xff0c;称之为变量&#xff08;variable&#xff09;&#xff0c;在大多数语言中&#xff0c;都把这种行为称为“给变量赋值”或“把值存储在变量中”。 •不过P…

重复文件清理软件怎么用?分享3个删除重复文件的方法!

删除重复文件能够为电脑腾出很大的存储空间&#xff0c;不信&#xff1f;可以试试看哦&#xff01; 电脑使用久了&#xff0c;都会积累大量的文件&#xff0c;这其中难免会出现重复的文件&#xff0c;这些重复文件没有任何作用&#xff0c;而且会占用着电脑的空间&#xff0c;…