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

基于Python脚本实现Flink on YARN任务批量触发Savepoint的实践指南

基于Python脚本实现Flink on YARN任务批量触发Savepoint的实践指南

一、背景与价值

在流计算生产环境中,Flink on YARN的部署方式凭借其资源管理优势被广泛采用。Savepoint作为Flink任务状态的一致性快照,承载着故障恢复、版本升级、作业暂停等重要场景的核心保障。当集群中运行数十个Flink作业时,手动逐个触发Savepoint耗时且易出错。本文提出一种基于Python脚本的批量化操作方案,可显著提升运维效率。

二、技术实现原理

2.1 核心流程设计

  1. 作业发现机制:通过YARN REST API或yarn application命令获取RUNNING状态作业列表
  2. 元数据解析:提取Application ID和Job ID(需注意Per-Job模式与Session模式的区别)
  3. 并发控制:采用队列机制管理并行触发请求,避免集群资源过载
  4. 状态反馈:实时捕获flink cancel -s [targetDirectory]命令输出,记录成功/失败状态

2.2 关键实现步骤


#******************************************************************#
##author: david.zhou
##create time: 2025-03-27 16:56:34
#******************************************************************#
#!/usr/bin/env python3
# -*- coding: utf-8 -*-#"""
#获取并为指定的Flink任务创建savepoint的脚本
#"""import os
import re
import json
import time
import subprocess
import requests
from typing import List, Dict, Tuple, Optional# 设置不同版本Flink的路径
FLINK_PATHS = {"1.14": "/opt/flink-1.14/bin/flink","1.15": "/opt/flink-1.15/bin/flink","1.16": "/opt/flink-1.16/bin/flink","1.17": "/opt/flink-1.17/bin/flink","1.18": "/opt/flink-1.18/bin/flink"
}
DEFAULT_FLINK_PATH = "flink"  # 默认使用环境变量中的flink命令# 直接在脚本中定义过滤参数(可以根据需要修改)
# 留空列表表示处理所有任务,添加元素表示只处理匹配的任务
FILTERS = ["aaaa"]
# 如果要处理所有任务,请使用:FILTERS = []
# FILTERS = []def run_command(command: str) -> Tuple[str, int]:#"""执行shell命令并返回输出和状态码"""# 检查Python版本,决定使用哪个参数import sysif sys.version_info >= (3, 7):process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)else:process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)stdout, stderr = process.communicate()return stdout + stderr, process.returncodedef get_running_flink_jobs() -> List[Dict]:#"""获取所有运行中的Flink任务"""print("正在获取所有运行中的Flink任务...")output, _ = run_command("yarn application -list -appStates RUNNING")running_jobs = []for line in output.splitlines():if "Apache Flink" in line:# 提取应用IDapp_id_match = re.search(r"(application_\d+_\d+)", line)if app_id_match:app_id = app_id_match.group(1)# 提取任务名称job_name_match = re.search(r"\s+([^\s]+)\s+Apache\s+Flink", line)job_name = job_name_match.group(1) if job_name_match else app_idrunning_jobs.append({"app_id": app_id,"info": line,"name": job_name})print(f"- {line}")return running_jobsdef filter_jobs(jobs: List[Dict], filters: List[str]) -> List[Dict]:#"""根据过滤条件筛选任务"""if not filters:return jobsprint(f"\n应用过滤条件: {filters}")filtered_jobs = []for job in jobs:app_id = job["app_id"]app_info = job["info"]app_name = job["name"]matched = Falsefor filter_str in filters:if filter_str == app_id or filter_str in app_info:matched = Truebreakif matched:filtered_jobs.append(job)print(f"匹配任务: {app_id} ({app_name})")return filtered_jobsdef get_tracking_url(app_id: str) -> Optional[str]:#"""获取应用的Tracking URL"""print(f"  获取Tracking URL...")output, _ = run_command(f"yarn application -status {app_id}")tracking_url_match = re.search(r"Tracking-URL\s*:\s*(http://[^\s]+)", output, re.IGNORECASE)if tracking_url_match:tracking_url = tracking_url_match.group(1)print(f"  找到Tracking URL: {tracking_url}")return tracking_urlreturn Nonedef extract_host_from_url(url: str) -> Optional[str]:#"""从URL中提取主机名"""host_match = re.search(r"http://([^/]+)", url)if host_match:host = host_match.group(1)print(f"  Flink主机: {host}")return hostreturn Nonedef get_flink_version(host: str) -> str:#"""获取Flink版本"""print("  获取Flink版本...")config_api_url = f"http://{host}/config/"print(f"  访问配置API: {config_api_url}")try:response = requests.get(config_api_url, timeout=10)config_json = response.textprint(f"  配置API返回: {config_json}")# 尝试解析JSONtry:config_data = json.loads(config_json)flink_version = config_data.get("flink-version")if flink_version:print(f"  Flink版本: {flink_version}")return flink_versionexcept json.JSONDecodeError:pass# 使用正则表达式提取版本version_match = re.search(r'"flink-version":"([0-9\.]+)"', config_json)if version_match:flink_version = version_match.group(1)print(f"  Flink版本: {flink_version}")return flink_versionexcept Exception as e:print(f"  获取Flink版本出错: {e}")# 默认版本print("  无法获取Flink版本,假设为1.14版本")return "1.14"def get_flink_job_id(host: str) -> Optional[str]:#"""获取Flink JobID"""print("  通过REST API获取JobID...")jobs_api_url = f"http://{host}/jobs"print(f"  访问作业API: {jobs_api_url}")try:response = requests.get(jobs_api_url, timeout=10)jobs_json = response.textprint(f"  作业API返回: {jobs_json}")# 尝试解析JSONtry:jobs_data = json.loads(jobs_json)for job in jobs_data.get("jobs", []):if job.get("status") == "RUNNING":job_id = job.get("id")if job_id:print(f"  找到运行中的Flink JobID: {job_id}")return job_idexcept json.JSONDecodeError:pass# 使用正则表达式提取JobIDjob_id_match = re.search(r'"id":"([a-z0-9]+)","status":"RUNNING"', jobs_json)if job_id_match:job_id = job_id_match.group(1)print(f"  找到运行中的Flink JobID: {job_id}")return job_idexcept Exception as e:print(f"  获取Flink JobID出错: {e}")print("  无法从JSON响应中提取JobID")return Nonedef get_flink_command(version: str) -> str:#"""根据Flink版本选择对应的命令路径"""major_version, minor_version = version.split(".")[:2]version_key = f"{major_version}.{minor_version}"print(f"  Flink主版本: {major_version}, 次版本: {minor_version}")if major_version == "1":flink_path = FLINK_PATHS.get(version_key)if flink_path and os.path.isfile(flink_path):print(f"  使用Flink {version_key}路径: {flink_path}")return flink_pathelse:print(f"  Flink {version_key}路径不存在,使用默认路径")# 对于1.14版本,使用特定的默认路径if version_key == "1.14":return "/opt/flink-1.14/bin/flink"else:print(f"  未知的Flink主版本: {major_version},使用默认路径")return DEFAULT_FLINK_PATHdef check_savepoint_status(host: str, job_id: str, timeout: int = 3600) -> bool:#"""检查savepoint状态,直到完成或超时"""print("  Savepoint操作已触发,开始检查执行状态...")start_time = time.time()completed = Falsesavepoint_path = None#超时时间可以自定义,默认 1 小时while time.time() - start_time < timeout:checkpoints_api_url = f"http://{host}/jobs/{job_id}/checkpoints"print(f"  检查savepoint状态: {checkpoints_api_url}")try:response = requests.get(checkpoints_api_url, timeout=10)checkpoints_json = response.text# 尝试解析JSONin_progress = Falsetry:checkpoints_data = json.loads(checkpoints_json)# 检查历史记录中的savepointhistory = checkpoints_data.get("history", [])for checkpoint in history:if checkpoint.get("is_savepoint") == True:status = checkpoint.get("status")print(f"  历史记录中最新savepoint状态: {status}")if status == "IN_PROGRESS":in_progress = Trueprint("  Savepoint操作正在进行中")elif status == "COMPLETED":completed = Truesavepoint_path = checkpoint.get("external_path")if savepoint_path:print(f"  Savepoint保存路径: {savepoint_path}")return Truebreak# 如果历史记录中没有找到,检查最新的savepointlatest_savepoints = checkpoints_data.get("latest", {}).get("savepoints", [])if latest_savepoints:latest = latest_savepoints[0]status = latest.get("status")is_savepoint = latest.get("is_savepoint")print(f"  最新savepoint状态: {status}, 是否为savepoint: {is_savepoint}")if status == "COMPLETED" and is_savepoint == True:completed = Truesavepoint_path = latest.get("external_path")if savepoint_path:print(f"  Savepoint保存路径: {savepoint_path}")return Trueelif status == "IN_PROGRESS" and is_savepoint == True:in_progress = Trueprint("  Savepoint操作正在进行中")except json.JSONDecodeError:# 使用正则表达式检查if '"status":"COMPLETED"' in checkpoints_json and '"is_savepoint":true' in checkpoints_json:completed = Trueprint("  检测到savepoint已完成")path_match = re.search(r'"external_path":"([^"]+)"', checkpoints_json)if path_match:savepoint_path = path_match.group(1)print(f"  Savepoint保存路径: {savepoint_path}")return Trueelif '"status":"IN_PROGRESS"' in checkpoints_json and '"is_savepoint":true' in checkpoints_json:in_progress = Trueprint("  检测到savepoint正在进行中")if in_progress:print("  Savepoint操作正在进行中,等待30秒后再次检查...")else:print("  未检测到正在进行的savepoint操作,等待30秒后再次检查...")# 等待30秒后再次检查time.sleep(30)except Exception as e:print(f"  检查savepoint状态出错: {e}")time.sleep(30)# 超时elapsed = int(time.time() - start_time)print(f"  Savepoint操作超时或失败!已等待 {elapsed} 秒,超过最大等待时间 {timeout} 秒")return Falsedef create_savepoint(job: Dict, savepoint_dir: str) -> None:#"""为指定任务创建savepoint"""app_id = job["app_id"]app_name = job["name"]# 创建包含任务名称的savepoint路径task_savepoint_dir = f"{savepoint_dir}/{app_name}"print(f"\n处理任务: {app_id} ({app_name})")# 获取Tracking URLtracking_url = get_tracking_url(app_id)if not tracking_url:print("  无法获取Tracking URL")return# 从Tracking URL提取主机host = extract_host_from_url(tracking_url)if not host:print("  无法从Tracking URL提取主机信息")return# 获取Flink版本flink_version = get_flink_version(host)# 获取JobIDjob_id = get_flink_job_id(host)if not job_id:print("  无法获取Flink JobID")return# 提取主版本号和次版本号major_version, minor_version = flink_version.split(".")[:2]# 针对 Flink 1.18 版本跳过 savepoint 操作#if major_version == "1" and minor_version == "18":#    print("  检测到 Flink 1.18 版本任务,根据配置跳过 savepoint 操作")#    return# 获取对应版本的Flink命令flink_cmd = get_flink_command(flink_version)# 构建savepoint命令savepoint_cmd = f"{flink_cmd} savepoint {job_id} {task_savepoint_dir} -yid {app_id}"print(f"  使用Flink SAVEPOINT_CMD 的命令格式")print(f"  执行命令: {savepoint_cmd}")# 执行savepoint命令output, status = run_command(savepoint_cmd)print(f"  命令输出: {output}")print(f"  命令返回状态: {status}")# 检查savepoint状态success = check_savepoint_status(host, job_id)if success:print(f"  Savepoint创建成功!保存在: {task_savepoint_dir}")else:print(f"  任务: {app_id} ({app_name}):Savepoint操作失败!")def main():#"""主函数"""# 获取所有运行中的Flink任务running_jobs = get_running_flink_jobs()if not running_jobs:print("未找到正在运行的Flink任务。")return# 过滤任务filtered_jobs = filter_jobs(running_jobs, FILTERS)if not filtered_jobs:print("没有匹配的任务,退出操作。")returnprint(f"\n开始为匹配的 {len(filtered_jobs)} 个任务创建savepoint...")# 请在此处设置savepoint目录savepoint_dir = "hdfs:///flink-savepoints"  # hdfs     # 为每个任务创建savepointfor job in filtered_jobs:create_savepoint(job, savepoint_dir)print("\n所有匹配任务的savepoint操作已完成!")if __name__ == "__main__":main()

2.3 异常处理策略

超时重试机制:对于比较大的状态的作业,默认会检查是完成,超时1小时
状态验证:完成后检查HDFS目录是否存在_metadata文件
报警集成:告警可以按需添加即可

三、生产环境最佳实践

3.1 安全增强建议

  1. 权限隔离:为Savepoint目录设置专属HDFS账户,避免作业间相互覆盖
  2. 存储限额:通过HDFS Quota限制目录容量,防止磁盘写满
  3. 生命周期管理:添加定期清理脚本,保留最近3次Savepoint

3.2 性能优化方案

触发请求
集群负载>80%?
进入等待队列
立即执行
每5分钟重试检查

四、运维监控方案

通过Prometheus+Grafana实现可视化监控:

  1. 统计成功率指标
  2. 记录单次触发耗时
  3. 跟踪HDFS存储用量增长趋势

相关文章:

基于Python脚本实现Flink on YARN任务批量触发Savepoint的实践指南

基于Python脚本实现Flink on YARN任务批量触发Savepoint的实践指南 一、背景与价值 在流计算生产环境中&#xff0c;Flink on YARN的部署方式凭借其资源管理优势被广泛采用。Savepoint作为Flink任务状态的一致性快照&#xff0c;承载着故障恢复、版本升级、作业暂停等重要场景…...

Winform入门进阶企业级开发示例:http接口数据清洗转换、断线续传、mqtt数据传输实例详解(附代码资源下载)

场景 C#/Winform入门、进阶、强化、扩展、知识体系完善等知识点学习、性能优化、源码分析专栏分享: C#/Winform入门、进阶、强化、扩展、知识体系完善等知识点学习、性能优化、源码分析专栏分享_winform 强化学习-CSDN博客 如何将以上相关理论知识学以致用。下面针对Winform…...

PHP开发效率提升利器:通义灵码在VSCode中的应用与技巧

引言 在 PHP 开发领域&#xff0c;提高编码效率和质量是每位开发者追求的目标。通义灵码&#xff0c;作为一款由阿里云技术团队开发的智能编码助手&#xff0c;能够通过其强大的 AI 能力&#xff0c;为 PHP 开发者提供包括代码自动补全、智能注释、代码优化等多方面的支持。本…...

WHAT - React 错误边界处理 - react-error-boundary

目录 安装使用方式常用 Props使用场景 react-error-boundary 是一个由 Brian Vaughn 开发的 React 组件库&#xff0c;用于更方便地处理组件树中的错误&#xff08;错误边界&#xff09;。 阅读参考&#xff1a; React Error Boundariesreact-error-boundary 安装 npm inst…...

数据模型评估的四维黄金法则:从技术验证到业务价值证明

引言&#xff1a;为什么你的数据模型总被质疑&#xff1f; 在滴滴出行的一次核心业务会议上&#xff0c;数据团队与业务部门爆发了激烈争论&#xff1a;新上线的订单预测模型是否真的优于旧系统&#xff1f;数据工程师认为查询速度提升40%已是巨大成功&#xff0c;业务方却质疑…...

vscode ctrl+鼠标左键不能跳转

笔者使用的vscode版本是1.85.2&#xff08;一周前从1.99降下来的&#xff0c;因为版本过高连不上服务器&#xff09;。 使用python时突然发现代码看起来有些别扭&#xff0c;细看之下发现是import xxx语句中的包的颜色从之前的青色变成了现在的白色。再用ctrl左键点击包名试图…...

换动态IP对电脑有什么影响:全面解析与实用指南

在当今数字化时代&#xff0c;IP地址作为网络世界的"身份证"&#xff0c;对我们的网络体验有着重要影响。许多用户出于某些原因&#xff0c;会考虑更换动态IP地址。那么&#xff0c;这种操作究竟会对我们的电脑产生哪些影响&#xff1f;是利大于弊还是弊大于利&#…...

Go语言从零构建SQL数据库(6) - sql解析器(番外)- *号的处理

番外&#xff1a;处理SQL通配符查询 在SQL中&#xff0c;SELECT * FROM table是最基础的查询之一&#xff0c;星号&#xff08;*&#xff09;是一个通配符&#xff0c;表示"选择所有列"。虽然通配符查询看起来简单&#xff0c;但在解析器中需要特殊处理。下面详细介…...

大模型推理引擎选型与应用场景分析:SGLang、Ollama、VLLM 和 LLaMA.cpp

在当下的大模型技术生态中&#xff0c;SGLang、Ollama、VLLM 和 LLaMA.cpp 各具特色&#xff0c;适用于不同的应用场景和用户需求。以下是它们的核心特点及适用场景的深度剖析&#xff1a; 1. SGLang&#xff1a;高性能企业级推理引擎 核心优势&#xff1a; 零开销批处理&…...

参考平面跨分割情况下的信号回流

前言&#xff1a;弄清楚信号的回流路径&#xff0c;是学习EMC和高速的第一步&#xff01; 如果我们不管信号的回流路径&#xff0c;会造成什么后果&#xff1f;1、信号完整性问题&#xff0c;信号的回流路径不连续会导致信号反射、衰减和失真。2、信号衰减和噪声干扰&#xff…...

Vue2下载二进制文件

后端&#xff1a; controller: GetMapping(value "/get-import-template")public void problemTemplate(HttpServletRequest request, HttpServletResponse response) throws Exception {iUserService.problemTemplate(request, response);} service: void probl…...

AnimateCC基础教学:随机抽取花名册,不能重复

一.核心代码: this.btnStartObj.addEventListener("click", switchBtn); this.btnOkObj.addEventListener("click", oKBtn); createjs.Ticker.addEventListener("tick", updateRandom); var _this this; var nameArr ["张三", &quo…...

windows+cmake+vscode+NDK远程调试安卓端C++项目

windowscmakevscodeNDK远程调试安卓端C项目 windowscmakevscodeNDK远程调试安卓端C项目 windowscmakevscodeNDK远程调试安卓端C项目 使用C开发安卓端算法库时&#xff0c;需要使用NDK进行交叉编译。使用NDK编译代码时&#xff0c;需要编写.mk脚本进行代码的编译和链接&#xf…...

大语言模型(LLM)全解析:从原理到实战应用

在人工智能飞速发展的今天&#xff0c;大语言模型(LLM)已成为改变我们工作生活的重要技术。无论是ChatGPT的对话能力&#xff0c;还是DeepSeek的文本处理&#xff0c;背后都离不开LLM的强大支持。本文将用通俗易懂的语言&#xff0c;带您全面了解LLM的工作原理、训练方法、优化…...

Qt 入门 4 之标准对话框

Qt 入门 4 之标准对话框 Qt提供了一些常用的对话框类型,它们全部继承自QDialog类,并增加了自己的特色功能,比如获取颜色、显示特定信息等。下面简单讲解这些对话框,可以在帮助索引中查看Standard Dialogs关键字,也可以直接索引相关类的类名。 本文将以一个新的项目为主介绍不…...

PyTorch DataLoader 参数详解

在使用 PyTorch 的 DataLoader 时&#xff0c;有许多参数可以调整&#xff0c;这些参数能够帮助我们平衡数据加载效率、内存使用和训练过程的稳定性。下面介绍几个常用参数&#xff0c;并讲解它们的作用&#xff1a; dataset 含义&#xff1a; 数据集对象&#xff0c;必须实现 …...

PowerBI 计算时间用EDATE

我在原表基础上&#xff0c;根据日期字段&#xff0c;计算去年时间 CONCATENATEX(DISTINCT(SELECTCOLUMNS(VALUES(日期表),"去年", FORMAT(DATEADD([日期], -1, YEAR), "yyyyMM"))), [YearMonth],",") 我发现很奇怪的现象&#xff0c;假如某个日…...

GRBL运动控制算法(四)加减速运算

前言 在数控系统和运动控制领域&#xff0c;GRBL 作为一款高效、轻量化的开源固件&#xff0c;因其卓越的性能和简洁的架构被广泛应用于各类嵌入式运动控制场景。GRBL加减速算法的实现尤为关键——它直接决定了运动控制的精度、效率与设备稳定性。 本文深入解析加减速运算的核…...

CSS 学习提升网站或者项目

有几个不错的开源项目可以帮助你练习和提升CSS技能&#xff1a; CSS-Tricks CSS-Tricks 提供了很多关于CSS的技巧和教程&#xff0c;可以通过实践它们来提高CSS技能。你可以在CSS-Tricks上找到很多有趣的项目和代码示例。 Frontend Mentor Frontend Mentor 是一个非常适合练习…...

PolarDB 读已提交事务隔离级别 select ... for update, where条件未用索引,查不到数据的时候不会锁表

由于没有给字段设置唯一性&#xff0c;所以改为通过查询语句加锁确保唯一性&#xff0c;但是发现select count(*) 为0时&#xff0c;不会加锁&#xff0c;所以在insert方法后面需要加锁二次查询确保唯一性。 在 PolarDB 的读已提交事务隔离级别下&#xff0c;SELECT ... FOR UP…...

Python基础——Matplotlib库

绘图基础 Matplotlib 库太大&#xff0c;画图通常仅仅使用其中的核心模块 matplotlib.pyplot&#xff0c;并给其一个别名 plt&#xff0c;即 import matplotlib.pyplot as plt。为了使图形在展示时能很好的嵌入到 Jupyter 的 Out[ ] 中&#xff0c;需要使用%matplotlib inline…...

群晖Hyper Backup备份的东西怎么还原?

一、背景 前面写了一篇文章关于群晖NAS中最简单的备份方案&#xff0c;Hyper Backup 方案 群晖NAS最简单的备份教程&#xff08;只备份需要的目录到不同的硬盘&#xff09;&#xff0c;留了个尾&#xff0c;即怎么还原备份的东西&#xff0c;这里完结一下。 二、还原方案 2.…...

记录IBM服务器检测到备份GPT损坏警告排查解决过程

服务器设备&#xff1a;IBM x3550 M4 Server IMM默认IP地址&#xff1a;192.168.70.125 用户名&#xff1a;USERID 密码&#xff1a;PASSW0RD&#xff08;注意是零0&#xff09; 操作系统&#xff1a;Windows Hyper-V Server 2016 IMM Web System Status Warning&#xff1…...

蓝桥杯嵌入式十五届模拟二(串口DMA,占空比的另一种测量方式)

一.LED 先配置LED的八个引脚为GPIO_OutPut&#xff0c;锁存器PD2也是&#xff0c;然后都设置为起始高电平&#xff0c;生成代码时还要去解决引脚冲突问题 二.按键 按键配置&#xff0c;由原理图按键所对引脚要GPIO_Input 生成代码&#xff0c;在文件夹中添加code文件夹&#…...

22 | 如何继续提升 Go 开发技术?

提示&#xff1a; 所有体系课见专栏&#xff1a;Go 项目开发极速入门实战课&#xff1b;欢迎加入 云原生 AI 实战营 星球&#xff0c;12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力&#xff08;聚焦于 Go、云原生、AI Infra&#xff09;。 「Go 项目开发极速…...

一文详解OpenCV环境搭建:Windows使用CLion配置OpenCV开发环境

在计算机视觉和图像处理领域&#xff0c;OpenCV 是一个不可或缺的工具。其为开发者提供了一系列广泛的算法和实用工具&#xff0c;支持多种编程语言&#xff0c;并且可以在多个平台上运行。对于希望在其项目中集成先进视觉功能的开发者来说&#xff0c;掌握如何配置和使用OpenC…...

云原生周刊:深入探索 kube-scheduler-simulator

开源项目推荐 mcp-server-kubernetes mcp-server-kubernetes 是一个实现了模型上下文协议&#xff08;MCP&#xff09;的服务器&#xff0c;旨在通过自然语言与 K8s 集群进行交互。它支持连接到 K8s 集群&#xff0c;列出所有 Pod、服务、部署和节点&#xff0c;创建、描述、…...

总结一下常见的EasyExcel面试题

说一下你了解的POI和EasyExcel POI&#xff08;Poor Obfuscation Implementation&#xff09;&#xff1a;它是 Apache 软件基金会的一个开源项目&#xff0c;为 Java 程序提供了读写 Microsoft Office 格式文件的功能&#xff0c;支持如 Excel、Word、PowerPoint 等多种文件格…...

【Java设计模式】第2章 UML急速入门

2-1 本章导航 UML类图与时序图入门 UML定义 统一建模语言(Unified Modeling Language):第三代非专利建模语言。特点:开放方法,支持可视化构建面向对象系统,涵盖模型、流程、代码等。UML分类(2.2版本) 结构式图形:系统静态建模(类图、对象图、包图)。行为式图形:事…...

Excel处理控件Spire.XLS系列教程:C# 设置 Excel 中的数字格式

在 Excel 工作表中&#xff0c;原始数据通常显示为缺乏直观性的普通数字。通过设置数字格式&#xff0c;可以将这些数字转换成更容易理解的形式。例如&#xff0c;将销售额数据设置为货币格式&#xff0c;即添加货币符号和千位分隔符&#xff0c;可使所代表的金额一目了然。将市…...

脚本启动 Java 程序

如果你想在后台启动一个 Java 程序&#xff0c;并在终端窗口中显示一个自定义的名字&#xff0c;可以通过编写一个简单的脚本来实现。以下是一个基于 Linux/macOS 的解决方案&#xff0c;使用 Bash 脚本启动 Java 程序&#xff0c;并在终端窗口中显示自定义标题。 示例脚本 创建…...

UniappX动态引入在线字体图标,不兼容css时可用。

优缺点 优点&#xff1a;不需要占用本地存储&#xff0c;可直接在线同步库图标&#xff0c;不用再手动引入ttf文件&#xff0c;不用手动添加键值对对应表。 缺点&#xff1a;受网速影响&#xff0c;字体库cdn路径可能会更改&#xff0c;ios端首次加载&#xff0c;可能会无图标…...

机器学习 | 强化学习基本原理 | MDP | TD | PG | TRPO

文章目录 📚什么是强化学习🐇监督学习 vs 强化学习🐇马尔科夫决策过程(MDP)📚基本算法(value-based & policy-based)🐇时序差分算法(TD)🐇SARSA和Q-learning🐇策略梯度算法(PG)🐇REINFORCE和Actor-Critic🐇信任区域策略优化算法(TRPO)学习视频…...

k8s之Service类型详解

1.ClusterIP 类型 2.NodePort 类型 3.LoadBalancer 类型 4.ExternalName 类型 类型为 ExternalName 的 Service 将 Service 映射到 DNS 名称&#xff0c;而不是典型的选择算符&#xff0c; 例如 my-service 或者 cassandra。你可以使用 spec.externalName 参数指定这些服务…...

AI平台如何实现推理?数算岛是一个开源的AI平台(主要用于管理和调度分布式AI训练和推理任务。)

数算岛是一个开源的AI平台&#xff0c;主要用于管理和调度分布式AI训练和推理任务。它基于Kubernetes构建&#xff0c;支持多种深度学习框架&#xff08;如TensorFlow、PyTorch等&#xff09;。以下是数算岛实现模型推理的核心原理、架构及具体实现步骤&#xff1a; 一、数算岛…...

linux开发环境

1.虚拟机环境搭建 在 Ubuntu 系统中&#xff0c;打开&#xff08;如图中显示的窗口 &#xff09;常见快捷键有&#xff1a; Ctrl Alt T&#xff1a;这是最常用的打开终端的快捷键组合 &#xff0c;按下后会快速弹出一个新的终端窗口。 在 VMware 虚拟机环境中&#xff0c;若…...

OSPF复习

OSPF OSPF---开放最短路径优先协议 动态路由判定依据&#xff1a;选路&#xff0c;收敛速度&#xff0c;占用资源 OSPFV2和RIPV2的相同点&#xff1a; 1.都是无类别的路由协议&#xff1b; 2.都是通过组播来传播信息的&#xff1b;&#xff08;RIP&#xff1a;224.0.0.9&am…...

AWS S3深度剖析:云存储的瑞士军刀

1. 引言 在当今数据驱动的世界中,高效、可靠、安全的数据存储解决方案至关重要。Amazon Simple Storage Service (S3)作为AWS生态系统中的核心服务之一,为企业和开发者提供了一个强大而灵活的对象存储平台。本文将全面解析S3的核心特性,帮助读者深入理解如何充分利用这一&q…...

pyTorch中 tensorboard的使用

目录 01.导包、 transforms数据转化、torchvision数据集、创建dataloaders、展示图片的封装函数 02定义模型 03定义损失函数与优化器 1.tensorboard的安装 2.tensorboard的使用 2.1添加图片 2.2 添加模型结构图 2.3 添加损失的变化 #pyTorch中的tensorboard 与 tens…...

Android audio(2)-audioservice

AudioService是Android的系统服务&#xff08;systemservice&#xff09;&#xff0c;由SystemServer负责启动。提供Android APK 所需的非数据通路&#xff08;playback/capture&#xff09;相关的audio 功能实现&#xff0c;是binder通信中的server端&#xff0c;与之对应的 C…...

星城幻境:科技与千年文脉的交响诗-长沙

故事背景 故事发生在中国湖南长沙&#xff0c;通过六个充满未来感的城市景观&#xff0c;展现人工智能修复古建筑、生态摩天楼、全息水幕许愿等场景&#xff0c;描绘科技赋能下历史文脉与未来城市的共生图景。 故事内容 从岳麓书院清晨的智能修复到湘江夜空的数字烟花&#xff…...

记录学习的第二十三天

老样子&#xff0c;每日一题开胃。 我一开始还想着暴力解一下试试呢&#xff0c;结果不太行&#x1f602; 接着两道动态规划。 这道题我本来是想用最长递增子序列来做的&#xff0c;不过实在是太麻烦了&#xff0c;实在做不下去了。 然后看了题解&#xff0c;发现可以倒着数。 …...

sql-labs靶场 less-1

文章目录 sqli-labs靶场less 1 联合注入 sqli-labs靶场 每道题都从以下模板讲解&#xff0c;并且每个步骤都有图片&#xff0c;清晰明了&#xff0c;便于复盘。 sql注入的基本步骤 注入点注入类型 字符型&#xff1a;判断闭合方式 &#xff08;‘、"、’、“”&#xf…...

AI-人工智能-基于LC-MS/MS分子网络深度分析的天然产物成分解析的新策略

Anal Chem∣张卫东教授团队开发基于LC-MS/MS分子网络深度分析的天然产物成分解析的新策略 2024年9月23日&#xff0c;海军军医大学张卫东教授团队在Analytical Chemistry&#xff08;IF6.7&#xff09;上发表了题为“In-Depth Analysis of Molecular Network Based on Liquid …...

IntelliJ IDEA使用技巧(json字符串格式化)

文章目录 一、IDEA自动格式化json字符串二、配置/查找格式化快捷键 本文主要讲述idea中怎么将json字符串转换为JSON格式的内容并且有层级结构。 效果&#xff1a; 转换前&#xff1a; 转换后&#xff1a; 一、IDEA自动格式化json字符串 步骤一&#xff1a;首先创建一个临…...

【Java设计模式】第8章 单列模式讲解

8-1 单例模式讲解 定义与类型 定义:保证一个类仅有一个实例,并提供一个全局访问点。类型:创建型模式。适用场景 需要确保任何情况下绝对只有一个实例。实际应用: 网站计数器(单服务)。应用配置、线程池、数据库连接池。优点 减少内存开销(仅一个实例)。避免资源多重占…...

【Java设计模式】第4章 简单工厂讲解

4. 简单工厂模式 4.1 简单工厂讲解 定义:由一个工厂对象决定创建哪种产品类的实例,属于创建型模式,但不属于GoF 23种设计模式。适用场景: 工厂类负责创建的对象较少。客户端仅需传入参数,无需关心对象创建逻辑。优点: 客户端只需传入参数即可获取对象,无需知道创建细节…...

Spring Boot 常用依赖介绍

依赖总括 1. 核心依赖&#xff1a;Spring Web、Spring Data JPA、MySQL Driver。 2. 开发工具&#xff1a;Lombok、Spring Boot DevTools。 3. 安全与权限&#xff1a;Spring Security。 4. 测试与文档&#xff1a;Spring Boot Starter Test、Swagger。 5. 性能优化&#…...

判断矩阵A是否可以相似对角化

【例题1】 【例题2】...

第三方软件测试公司进行安全性测试有哪些好处?

在信息技术飞速发展的今天&#xff0c;软件已成为各行业运作的核心组成部分。然而&#xff0c;伴随而来的软件安全问题也愈发显著&#xff0c;因此软件产品安全性测试不容忽视。随着软件市场的激烈竞争&#xff0c;企业为了更好的专心产品开发&#xff0c;会将安全性测试服务交…...