当前位置: 首页 > news >正文

【无标题】jenkins消息模板(飞书)

这里写目录标题

    • Jenkins 安装的插件
  • 发送消息到飞书
    • 预览 1 (单Job)
    • 预览 2 (多Job,概览)

Jenkins 安装的插件

插件名称作用
Rebuilder
  1. Rebuilder。
    官方地址:https://plugins.jenkins.io/rebuild
    安装方式:在Jenkins插件当中直接搜索即可安装。
    功能说明:此插件可以直接重复上次构建,也可以用于查看一些参数比较复杂的构建时,上次构建所选的参数是什么。非常nice的一个插件。

  2. AnsiColor。
    官方地址:https://plugins.jenkins.io/ansicolor
    安装方式:在Jenkins插件当中直接搜索即可安装。
    功能说明:扩展支持我们在shell当中定义的echo -e指令,从而给一定的输出上颜色。
    使用方式:点此跳转到使用介绍。(opens new window)

  3. Maven Release Plug-in。
    maven风格插件。
    安装方式:在Jenkins插件当中直接搜索即可安装。

  4. user build vars。
    官方地址:https://wiki.jenkins.io/display/JENKINS/Build+User+Vars+Plugin
    安装方式:在Jenkins插件当中直接搜索即可安装。
    功能说明:通过此插件,让整个Jenkins系统中的用户参数成为一个可调用的变量。
    使用方式:在构建环境中选中Set Jenkins user build variables。

  5. Post build task
    功能说明:此功能允许您关联 shell 或批处理脚本,这些脚本根据构建日志输出在 Hudson
    上执行某些任务。如果日志文本与构建日志文件中的某处匹配,脚本将执行。例如:如果在日志文本中指定了“IOException”,并且构建日志文件包含字符串“IOException”,则脚本将执行。
    允许使用 Java 正则表达式,并且可以将组用作脚本参数。如果文本是“Last Build : #(\d+)”并且脚本是“script.sh”,那么如果日志包含一行“Last
    Build : #4”,脚本“script.sh 4”将被调用.

  6. MultiJob Phase
    功能说明:上下游执行

发送消息到飞书

预览 1 (单Job)

在这里插入图片描述

  • 对应shell
#!/usr/bin/env bash
url1="https://open.feishu.cn/open-apis/bot/v2/hook/" 
url2="https://open.feishu.cn/open-apis/bot/v2/hook/" #  1. 消息 接收地址
webhook_list=($url1 $url2)# ========================
#  2. 消息 参数预处理
if [ ! "$GIT_BRANCH" ]; thenecho "----------------- GIT_BRANCH 为空"GIT_BRANCH="''"
fi
echo -e "GIT_BRANCH -> ${GIT_BRANCH}"
# ========================
#  3. 消息 执行发送
run_send_msg() {echo -e "\n 复制发送消息脚本 $HOME -> ${WORKSPACE}" && cp "$HOME"/send_msg_to_feishu.py "${WORKSPACE}"for ((i = 0; i < ${#webhook_list[@]}; i++)); dowebhook=${webhook_list[$i]}echo -e "发送中 --> $webhook"python3 send_msg_to_feishu.py "${webhook}" -job_name "${JOB_NAME}" -job_url "${JOB_URL}" -build_name "${BUILD_ID}" -branch "${GIT_BRANCH}"doneecho -e "发送完成 \n\n"
}run_send_msg
  • 对应python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import json
import timeimport requestsparser = argparse.ArgumentParser(description='Jenkins 发送消息到飞书',epilog="执行示例>>> python ${webhook} -job_name ${JOB_NAME} -job_url ${JOB_URL} -branch ${GIT_BRANCH} -build_name ${BUILD_NUMBER}  ")
parser.add_argument('webhook', help='机器人webhookURL')  # 必填
parser.add_argument('-job_name', '--JOB_NAME', help='作业Name', )  # 选填
parser.add_argument('-job_url', '--JOB_URL', help='作业URL', required=True, )  # 必填
parser.add_argument('-branch', '--GIT_BRANCH', help='git分支', default='')  # 选填
parser.add_argument('-build_name', '--BUILD_DISPLAY_NAME', help='编译Name')  # 选填
# parser.add_argument('-build_url', '--BUILD_URL', help='编译URL', required=True, )  # 必填webhook = parser.parse_args().webhook
JOB_NAME = parser.parse_args().JOB_NAME
JOB_URL = parser.parse_args().JOB_URL
GIT_BRANCH = parser.parse_args().GIT_BRANCH
BUILD_DISPLAY_NAME = parser.parse_args().BUILD_DISPLAY_NAME
# BUILD_URL = parser.parse_args().BUILD_URLBUILD_URL = JOB_URL + '/lastBuild'def set_msg():# ============ 数据获取 ============result = requests.get(f'{BUILD_URL}/api/json', auth=jenkins_auth).json()# print(BUILD_STATUS.request.url)try:shortDescription = result['actions'][0]['causes'][0]['shortDescription']  # 启动者except KeyError:  # 安装 `Multijob plugin` 后位置变更shortDescription = result['actions'][1]['causes'][0]['shortDescription']  # 启动者print(result['timestamp'])timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(result['timestamp'] / 1000))  # 编译开始时间print(timestamp)BUILD_STATUS = result['result']  # 编译状态print('build_status --> ', BUILD_STATUS)duration = result['duration']  # 编译持续时间build_duration = int(duration) // 1000  # 毫秒到秒minutes, seconds = divmod(build_duration, 60)hours, minutes = divmod(minutes, 60)print(f'build duration --> {hours}H:{minutes}M:{seconds}S')# ============ 设置样式 ============if "SUCCESS" in BUILD_STATUS:  # 成功template_color = "green"elif "FAILURE" in BUILD_STATUS:  # 失败template_color = "red"elif "ABORTED" in BUILD_STATUS:  # 终止template_color = "yellow"else:template_color = "grey"# ============ 卡片模板 ============card = json.dumps({"config": {"wide_screen_mode": True},"elements": [{"tag": "markdown","content": f"触发时间:{timestamp}\n"f"分支名称:{GIT_BRANCH}\n"f"构建编号:{BUILD_DISPLAY_NAME}\n"f"构建状态:<font color={template_color}>{BUILD_STATUS}</font>\n"},{"tag": "note","elements": [{"tag": "img","img_key": f"{img_icon}","alt": {"tag": "plain_text","content": f"{JOB_URL}"}},{"tag": "plain_text","content": f"{shortDescription}"}]},{"tag": "hr"},{"tag": "action","actions": [{"tag": "button","text": {"tag": "plain_text","content": "报告链接"},"type": "primary","multi_url": {"url": f"{BUILD_URL}/allure","pc_url": "","android_url": "","ios_url": ""}}],"layout": "bisected"}],"header": {"template": f"{template_color}","title": {"content": f"作业名称: {JOB_NAME}","tag": "plain_text"}}})body = json.dumps({"msg_type": "interactive", "card": card})headers = {"Content-Type": "application/json"}res = requests.post(url=webhook, data=body, headers=headers)print(res.text)if __name__ == '__main__':img_icon = 'img_v2_098e80ae-e583-4148-b822-xxxxxx'  # img_key_id jenkinsIconjenkins_auth = ('report', 'report')  # jenkins User:Pwdset_msg()

预览 2 (多Job,概览)

Jenkins 需安装Multijob插件
Multijob https://plugins.jenkins.io/jenkins-multijob-plugin/

在这里插入图片描述

  • 对应shell
#!/usr/bin/env bashecho -e "\n\n 消息处理"
# ========================
#  消息发送
# ========================#  1. 消息 接收地址
# -----------------------
group='https://open.feishu.cn/open-apis/bot/v2/hook/'webhook_list=($group)
py_send='SendMsgFeishu.py'# ========================
#  2. 文件处理
# -----------------------
echo -e "\n 复制发送消息脚本 $HOME -> ${WORKSPACE}" && cp "$HOME"/$py_send "${WORKSPACE}"# ========================
#  3. 消息 执行发送
# -----------------------
run_send_msg() {for ((i = 0; i < ${#webhook_list[@]}; i++)); dowebhook=${webhook_list[$i]}echo -e "发送中 --> $webhook"python3 $py_send "${webhook}" -job_url "${JOB_URL}"doneecho -e "发送完成 \n\n"
}run_send_msg
  • 对应python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import datetime
import json
import subprocess
import time
from json import JSONDecodeErrorimport requestsparser = argparse.ArgumentParser(description='Jenkins 发送消息到飞书',epilog="执行示例>>> python ${webhook} -job_url ${JOB_URL}")
parser.add_argument('webhook', help='机器人webhookURL')  # 必填
parser.add_argument('-job_url', '--JOB_URL', help='作业URL', required=True, )  # 必填webhook = parser.parse_args().webhook
JOB_URL = parser.parse_args().JOB_URL
BUILD_URL = JOB_URL + '/lastBuild'job_name = []  # 运行名称
job_duration = []  # 运行时长
job_status = []  # 运行状态
job_url = []  # 运行结果
pass_rate = []  # 百分比显示print('修改时间:2023-07-04 10:02:43')def get_base_info():device_id = subprocess.getoutput('cat /etc/ding_issue')version_os = subprocess.getoutput('cat /etc/issue')version_browser = subprocess.getoutput('dingdao-dingtao-stable -version')device_sn = subprocess.getoutput('hostname').split('-')[-1]# print(deviceid,os_version,browser_version, sn)return device_id, version_os, version_browser, device_sndef sending_alarms(text=None):local_network_info = subprocess.getoutput("networkctl status")if text is None:text = f"网络异常: 无法访问\n{BUILD_URL}\n{local_network_info}"payload_message = {"msg_type": "text", "content": {"text": text}}headers = {"Content-Type": "application/json"}res = requests.post(url=webhook, data=json.dumps(payload_message), headers=headers)print(f"告警信息发送状态:{res.text}")def set_msg():get_result = requests.get(f'{BUILD_URL}/api/json', auth=jenkins_auth)# ------------------# ------ 数据获取 ------# ------------------JENKINS_URL = BUILD_URL.split('job')[0]  # JENKINS_URL# ------ begin 登陆异常 ------try:print(f"查询地址:{get_result.url}")result = get_result.json()# except JSONDecodeError:  # json解析失败 未登陆#     text = "Error 401 Unauthorized"#     sending_alarms(text)#     quit(text)# except RecursionError:  # BUG: https://github.com/jenkinsci/tikal-multijob-plugin/issues/255#     quit('递归错误:从 unicode 字符串解码 JSON 对象时超出最大递归深度')except OSError:  # 异常列表: 网络text = "No route to host"sending_alarms()quit(text)except Exception as e:  # 通用异常处理text = f"发生异常: {type(e).__name__} --> {str(e)}\n检查:{get_result.url}"sending_alarms(text)quit(text)# res = requests.get(f'{BUILD_URL}/api/json', auth=jenkins_auth)# if res.status_code == 401:#     quit('Error 401 Unauthorized')# else:#     result = res.json()# # ------ end 登陆异常 ------shortDescription = result['actions'][0]['causes'][0]['shortDescription']  # 启动者timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(result['timestamp'] / 1000))  # 编译开始时间# ------ begin 获取持续时间 ------if result['duration'] != 0:  # 获取字段duration = int(result['duration']) // 1000  # 编译持续时间minutes, seconds = divmod(duration, 60)hours, minutes = divmod(minutes, 60)build_duration = f'{hours}h {minutes}m {seconds}s'print(f"--> 通过响应值换算{build_duration}\n")else:  # 通过当前时间计算build_duration = datetime.datetime.now() - datetime.datetime.fromtimestamp(result['timestamp'] / 1000)build_duration = str(build_duration).split('.')[0]print(f"--> 通过当前时间计算耗时{build_duration}\n")# ------ end 获取持续时间 ------total_count = len(result['subBuilds'])  # 数量总计print(f'======= 项目概览 ======= \n'f'shortDescription:{shortDescription}\nbuild duration:{build_duration}\ntotal_count:{total_count}\ntimestamp:{timestamp}\n')print('提示: 没有allure就报错 无法运行 JSONDecodeError')for index in result['subBuilds']:  # 提取数据# print(index)# print(index['result'])# 数据预处理allure_summary = requests.get(f"{JENKINS_URL}{index['url']}/allure/widgets/summary.json").json()['statistic']allure_history_trend = requests.get(f"{JENKINS_URL}{index['url']}/allure/widgets/history-trend.json")# print(allure_history_trend.request.url)try:  # 获取历史数据allure_history_trend = allure_history_trend.json()[1]except IndexError:print('没有历史数据')allure_history_trend = allure_history_trend.json()[0]# 计算百分比if allure_summary['total'] != 0:  # 除数不能为0allure_pass_rate = allure_summary['passed'] / allure_summary['total']else:allure_pass_rate = 0  # 除数不能为0if allure_history_trend['data']['total'] != 0:allure_history = allure_history_trend['data']['passed'] / allure_history_trend['data']['total']else:allure_history = 0# ------------------# ------ 设置样式 ------# ------------------if "SUCCESS" == index['result']:  # 成功color = "green"elif "FAILURE" == index['result']:  # 失败color = "red"elif "ABORTED" == index['result']:  # 中止color = "yellow"else:  # 其他color = "grey"# 通过率对比allure_change = allure_pass_rate - allure_historyprint(f"{index['jobName']} --> 本次比上次通过率 {allure_change}")if allure_pass_rate > allure_history:allure_pass_rate = f'<font color=green>↑{allure_pass_rate:.2%}</font>'elif allure_pass_rate < allure_history or allure_pass_rate == 0:allure_pass_rate = f'<font color=red>↓{allure_pass_rate:.2%}</font>'else:allure_pass_rate = f' {allure_pass_rate:.2%}'# ------------------# ------ 载入数据 ------# ------------------job_name.append({"tag": "markdown", "content": f"{index['jobName']}", "text_align": "center"})job_duration.append({"tag": "markdown", "content": f"{index['duration']}", "text_align": "center"})job_status.append({"tag": "markdown", "content": f"<font color={color}>{index['result']}</font>", "text_align": "center"})job_url.append({"tag": "markdown", "content": f"[查看]({JENKINS_URL}{index['url']}/allure)", "text_align": "center"})pass_rate.append({"tag": "markdown","content": f"{allure_summary['passed']}/{allure_summary['total']}{allure_pass_rate} ","text_align": "center"})print(f'======= 项目详情 ======= \n{job_name}\n{job_duration}\n{job_status}\n{pass_rate}\n{job_url}\n')def set_msg_a(total_count=None, build_duration=None, timestamp=None, shortDescription=None):"""# ------------------# ------ 卡片模板 ------# ------------------total_count: 总数量build_duration: 持续时间timestamp: 开始时间shortDescription: 启动者"""card = json.dumps({"elements": [{"tag": "markdown","content": "**项目总览**\n"},{"tag": "column_set","flex_mode": "bisect","background_style": "grey","horizontal_spacing": "default","columns": [{"tag": "column","width": "weighted","weight": 1,"elements": [{"tag": "markdown","text_align": "center","content": f"项目数量\n**{total_count}**\n"}]},{"tag": "column","width": "weighted","weight": 1,"elements": [{"tag": "markdown","text_align": "center","content": f"运行耗时\n**{build_duration}**"}]},{"tag": "column","width": "weighted","weight": 1,"elements": [{"tag": "markdown","text_align": "center","content": f"执行时间\n**{timestamp}**\n"}]}]},{"tag": "markdown","content": "**项目信息**"},{"tag": "column_set","flex_mode": "none","background_style": "grey","columns": [{"tag": "column","width": "weighted","weight": 2,"vertical_align": "top","elements": [{"tag": "markdown","content": "**项目名**","text_align": "center"}]},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": [{"tag": "markdown","content": "**运行时长**","text_align": "center"}]},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": [{"tag": "markdown","content": "**运行状态**","text_align": "center"}]},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": [{"tag": "markdown","content": "**passed/total/通过率**","text_align": "center"}]},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": [{"tag": "markdown","content": "**Report**","text_align": "center"}]}]},{"tag": "column_set","flex_mode": "none","background_style": "default","columns": [{"tag": "column","width": "weighted","weight": 2,"vertical_align": "top","elements": job_name},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "center","elements": job_duration},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": job_status},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": pass_rate},{"tag": "column","width": "weighted","weight": 1,"vertical_align": "top","elements": job_url}]},{"tag": "hr"},{"tag": "note","elements": [{"tag": "img","img_key": f"{img_icon}","alt": {"tag": "plain_text","content": ""}},{"tag": "plain_text","content": f"{shortDescription}\n颜色代表对比上次执行,绿色上升,红色下降"}]}]})card_id = json.dumps({"type": "template","data": {"template_id": "ctp_AA6DZMfkJekh",  # 卡片id,参数必填。可在搭建工具中通过“复制卡片ID”获取"template_variable":  # 卡片中绑定的变量的取值。如没有绑定变量,可不填此字段。{"total_count": "29","group_table": [{"jobName": "test001","duration": "小于1小时","build_url": "baidu.com","build_status": "SUCCESS","tmp_color": "green"},{"jobName": "test002","duration": "2小时","build_url": "baidu.com","build_status": "FAILURE","tmp_color": "red"},{"jobName": "test003","duration": "3小时","build_url": "baidu.com","build_status": "ABORTED","tmp_color": "yellow"},{"jobName": "test004","duration": "3小时","build_url": "baidu.com","build_status": "UNSTABLE","tmp_color": "grey"}],"duration": "15080","shortDescription": "Started by user admin","timestamp": "1686645721264","jobName": "","tmp_color": ""}}})body = json.dumps({"msg_type": "interactive", "card": card})  # 使用 当前模板# body = json.dumps({"msg_type": "interactive", "card": card_id})  # 使用 预置模板headers = {"Content-Type": "application/json"}res = requests.post(url=webhook, data=body, headers=headers)print(f'消息发送响应 -->\n\t {res.text}')if __name__ == '__main__':img_icon = 'img_v2_098e80ae-e583-4148-b822-f42a05298d3g'  # img_key_id jenkinsIconjenkins_auth = ('result', 'result')  # jenkins User:Pwd# get_base_info()set_msg()deviceid, os_version, browser_version, sn = get_base_info()print(deviceid, os_version, browser_version, sn)

相关文章:

【无标题】jenkins消息模板(飞书)

这里写目录标题 Jenkins 安装的插件 发送消息到飞书预览 1 &#xff08;单Job&#xff09;预览 2 &#xff08;多Job&#xff0c;概览&#xff09; Jenkins 安装的插件 插件名称作用Rebuilder Rebuilder。 官方地址&#xff1a;https://plugins.jenkins.io/rebuild 安装方式&a…...

2023年国赛 高教社杯数学建模思路 - 案例:随机森林

文章目录 1 什么是随机森林&#xff1f;2 随机深林构造流程3 随机森林的优缺点3.1 优点3.2 缺点 4 随机深林算法实现 建模资料 ## 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 什么是随机森林&#xff…...

element Collapse 折叠面板 绑定事件

1. 点击面板触发事件 change <el-collapse accordion v-model"activeNames" change"handleChange"><el-collapse-item title"一致性 Consistency"><div>与现实生活一致&#xff1a;与现实生活的流程、逻辑保持一致&#xff0c…...

CSS :mix-blend-mode、aspect-ratio

mix-blend-mode 元素的内容应该与元素的直系父元素的内容和元素的背景如何混合。 mix-blend-mode: normal; // 正常mix-blend-mode: multiply; // 正片叠底mix-blend-mode: screen; // 滤色mix-blend-mode: overlay; // 叠加mix-blend-mode: darken; // 变暗mix-blend-mode: …...

Module not found: Error: Can‘t resolve ‘less-loader‘解决办法

前言&#xff1a; 主要是在自我提升方面&#xff0c;感觉自己做后端还是需要继续努力&#xff0c;争取炮筒前后端&#xff0c;作为一个全栈软阿金开发人员&#xff0c;所以还是需要努力下&#xff0c;找个方面&#xff0c;目前是计划学会Vue&#xff0c;这样后端有java和pytho…...

量化QAT QLoRA GPTQ

模型量化的思路可以分为PTQ&#xff08;Post-Training Quantization&#xff0c;训练后量化&#xff09;和QAT&#xff08;Quantization Aware Training&#xff0c;在量化过程中进行梯度反传更新权重&#xff0c;例如QLoRA&#xff09;&#xff0c;GPTQ是一种PTQ的思路。 QAT…...

CentOS下查看 ssd 寿命

SSD写入量达到设计极限&#xff0c;颗粒擦写寿命耗尽后会导致磁盘写入速度非常缓慢&#xff0c;读取正常。 使用smartctl及raid卡管理软件查看硬盘smart信息可以发现Media_Wearout_Indicator值降为1&#xff0c;表明寿命完全耗尽。 涉及范围 所有SSD处理方案 查看SSD smart信…...

Node基础--npm相关内容

下面,我们一起来看看Node中的至关重要的一个知识点-----npm 1.npm概述 npm(Node Package Manager),CommonJS包规范是理论,npm是其中一种实践。 对于Node而言,NPM帮助其完成了第三方模块的发布、安装和依赖等。借助npm,Node与第三方模块之间形成了很好的一个 生态系统。(类…...

Python图片爬虫工具

不废话了&#xff0c;直接上代码&#xff1a; import re import os import requests import tqdmheader{User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36}def getImg(url,idx,path):imgre…...

制造执行系统(MES)在汽车行业中的应用

汽车行业在不断发展中仍然面临一些挑战和痛点。以下是一些当前汽车行业可能面临的问题&#xff1a; 1.电动化和可持续性转型&#xff1a;汽车行业正逐渐向电动化和可持续性转型&#xff0c;但这需要投入大量资金和资源&#xff0c;包括电池技术、充电基础设施等&#xff0c;同时…...

Spring与Mybatis集成且Aop整合

目录 一、集成 1.1 集成的概述 1.2 集成的优点 1.3 代码示例 二、整合 2.1 整合概述 2.2 整合进行分页 一、集成 1.1 集成的概述 集成是指将不同的组件、部分或系统组合在一起&#xff0c;以形成一个整体功能完整的解决方案。它是通过连接、交互和协调组件之间的关系来实…...

【nonebot-plugin-mystool】快速安装使用nonebot-plugin-mystool

快速安装使用nonebot-plugin-mystool&#xff0c;以qq为主 前期准备&#xff1a;注册一个QQ号&#xff0c;python3.9以上的版本安装&#xff0c;go-cqhttp下载 用管理员模式打开powershell&#xff0c;并输入以下命令 #先排查是否有安装过的nonebot,若有则删除 pip uninstal…...

js实现数据关联查找更新。数据求和验证

为了实现这个功能我们和后端定义了数据结构 data:{id&#xff1a;‘’&#xff0c;formInfo:,formInfo2:,formInfo3:,formInfo4:, ......deailData:[ // 明细数据 // saleData 查询带出的对应明细序列号数据{ id:, ocopyId:, copyId:, odoId:, ......, saleData:[ { id:, oc…...

区块链上地址与银行账户有什么区别?

在区块链世界中&#xff0c;除了交易还有另一个基础要素&#xff1a;地址。在日前推出的Onchain AML合规技术方案&#xff0c;也有一个与区块链地址密切相关的概念&#xff1a;KYA(Know Your Address&#xff0c;了解你的地址)。 那问题来了&#xff0c;区块链地址究竟有什么用…...

CF 148 D Bag of mice(概率dp求概率)

CF 148 D. Bag of mice(概率dp求概率) Problem - 148D - Codeforces 大意&#xff1a;袋子里有 w 只白鼠和 b 只黑鼠 &#xff0c;A和B轮流从袋子里抓&#xff0c;谁先抓到白色谁就赢。A每次随机抓一只&#xff0c;B每次随机抓完一只之后会有另一只随机老鼠跑出来。如果两个人…...

引入本地 jar 包教程

将本地 jar 包&#xff0c;放到 resource 目录下&#xff0c;在 pom.xml 文件中加入如下依赖&#xff1a; <dependency><groupId>com.hk</groupId><artifactId>examples</artifactId><version>1.0</version><scope>system<…...

优维产品最佳实践第5期:什么是持续集成?

谈到到DevOps&#xff0c;持续交付流水线是绕不开的一个话题&#xff0c;相对于其他实践&#xff0c;通过流水线来实现快速高质量的交付价值是相对能快速见效的&#xff0c;特别对于开发测试人员&#xff0c;能够获得实实在在的收益。 本期EasyOps产品使用最佳实践&#xff0c…...

空时自适应处理用于机载雷达——元素空间空时自适应处理(Matla代码实现)

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

聚观早报 | 青瓷游戏上半年营收3.34亿元;如祺出行冲击IPO

【聚观365】8月26日消息 青瓷游戏上半年营收3.34亿元 如祺出行冲击IPO 索尼互动娱乐将收购Audeze 昆仑万维上半年净利润3.6亿元 T-Mobile计划在未来五周内裁员5000人 青瓷游戏上半年营收3.34亿元 青瓷游戏发布截至2023年6月30日止的中期业绩&#xff0c;财报显示&#xf…...

硅谷的魔法:如何塑造了全球技术的未来

硅谷的创新文化简介 硅谷&#xff0c;位于美国加利福尼亚州的圣克拉拉谷&#xff0c;已经从一个半导体产业的中心发展成为全球技术创新的代名词。这里集结了全球最顶尖的技术公司、创业者和投资者&#xff0c;共同创造了一个技术创新的奇迹。 起源与发展 硅谷的起源与斯坦福大…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量&#xff1a;setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...