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

使用docker创建minio镜像并上传文件,提供demo

使用docker创建minio镜像并上传文件,提供demo

  • 1. 整体描述
  • 2. 环境搭建
    • 2.1 windows环境搭建
    • 2.2 docker部署
  • 3. spring集成
    • 3.1 添加依赖
    • 3.2 配置文件
    • 3.3 创建config类
    • 3.4 创建minio操作类
    • 3.5 创建启动类
    • 3.6 测试controller
  • 4. 测试操作
    • 4.1 demo运行
    • 4.2 页面查看
    • 4.3 上传文件
    • 4.4 预览/下载文件
  • 5. demo下载
  • 6. 总结

1. 整体描述

MinIO是一个对象存储解决方案,它提供了一个Amazon Web Services S3兼容的API,并支持所有S3的核心特性。MinIO可以部署在任何地方——公共云或私有云、裸机基础设施、编排环境和边缘基础设施。

本文档介绍MinIO最新稳定版本RELEASE.2023-09-04T19-57-37Z在Windows平台上部署MinIO的操作、管理和开发。

上面是官网介绍,用有道翻译的,官网地址: 链接。

2. 环境搭建

使用docker搭建minio环境,可以直接用官网下载minio镜像,我们先用windows环境搭建一下。

2.1 windows环境搭建

在官网下载页面,选择windows,下载的是一个minion.exe文件。我放在了d:/minio目录下,在此再创建一个data文件夹,用来储存minio上传的文件。
然后在命令行执行如下指令启动minio:

setx MINIO_ROOT_USER minioadmin
setx MINIO_ROOT_PASSWORD minioadmin
D:\minio\minio.exe server D:\minio\data\ --console-address ":9001"

看到如下就说明启动成功了:
windowsminio启动
然后通过浏览器访问:
http://localhost:9001/
进入如下登录页面:
默认用户名和密码都是minioadmin
minio登录页面

2.2 docker部署

使用docker部署就更简单了,首先拉取官方镜像:

docker pull minio/minio

拉取成功之后,执行创建和启动容器:

docker run -p 9000:9000 -p 9001:9001 minio/minio server /data --console-address ":9001"

看到如下就说明启动成功:
docker启动minio
同样通过浏览器访问:
http://localhost:9001/
进入如下登录页面:
默认用户名和密码都是minioadmin

3. spring集成

通过springboot框架集成minio,实现上传文件的目的。

3.1 添加依赖

首先创建一个springboot工程,添加如下依赖:

<!-- lombok 自动生成方法--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency><!--io常用工具类 --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.5</version></dependency><!--常用工具类 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><!-- minio--><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.4.6</version></dependency>

3.2 配置文件

在springboot的yml配置文件中添加minio环境的配置:

#minio相关配置
minio:endpoint: http://127.0.0.1:9000accessKey: minioadminsecretKey: minioadmin

3.3 创建config类

package com.thcb.miniodemo.config;import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;/*** MinioUtil** @author thcb* @date 2023-09-05*/
@Component
public class MinioClientConfig {@Value("${minio.endpoint}")private String endpoint;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;/*** 注入minio 客户端** @return*/@Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();}}

3.4 创建minio操作类

minio操作类,用来写minio基础方法

package com.thcb.miniodemo.minio;import com.thcb.miniodemo.utils.*;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;/*** MinioUtil** @author thcb* @date 2023-09-05*/
@Component
@Slf4j
@RequiredArgsConstructor
public class MinioUtil {private final MinioClient minioClient;/*** 两票数据桶*/public static String TEST_BUCKET = "test";private static String POLICY = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::%s\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\"],\"Resource\":[\"arn:aws:s3:::%s/*\"]}]}";public void initMinIo() {log.warn("start initMinIo.");if (!bucketExists(TEST_BUCKET)) {log.warn("start makeBucket {}.", TEST_BUCKET);makeBucket(TEST_BUCKET);log.warn("finish makeBucket {}.", TEST_BUCKET);}try {log.warn("start setBucketPolicy {}.", TEST_BUCKET);minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(TEST_BUCKET).config(String.format(POLICY, TEST_BUCKET, TEST_BUCKET)).build());log.warn("finish setBucketPolicy {}.", TEST_BUCKET);} catch (Exception e) {log.error("setBucketPolicy from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));}}/*** 查看存储bucket是否存在** @return boolean*/public Boolean bucketExists(String bucketName) {Boolean found;try {found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());} catch (Exception e) {log.error("bucketExists from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));return false;}return found;}/*** 创建存储bucket** @return Boolean*/public synchronized Boolean makeBucket(String bucketName) {try {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {log.error("makeBucket from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));return false;}return true;}/*** 删除存储bucket** @return Boolean*/public synchronized Boolean removeBucket(String bucketName) {try {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {log.error("removeBucket from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));return false;}return true;}/*** 获取全部bucket*/public List<Bucket> getAllBuckets() {try {List<Bucket> buckets = minioClient.listBuckets();return buckets;} catch (Exception e) {log.error("getAllBuckets from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));}return null;}/*** 文件上传** @param file       文件* @param bucketName 桶名称* @return Boolean*/public synchronized String upload2Bucket(MultipartFile file, String bucketName) {return String.format("/%s/%s", bucketName, upload(file, bucketName));}/*** 文件上传** @param file       文件* @param bucketName 桶名称* @return Boolean*/public synchronized String upload(MultipartFile file, String bucketName) {String originalFilename = file.getOriginalFilename();if (StringUtils.isBlank(originalFilename)) {throw new CustomException("文件格式错误");}String fileName = UUIDUtil.UUID() + originalFilename.substring(originalFilename.lastIndexOf("."));String objectName = DateUtils.dateTimeNow(DateUtils.YYYYMMDD) + "/" + fileName;try {PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(objectName).stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();//文件名称相同会覆盖minioClient.putObject(objectArgs);} catch (Exception e) {log.error("upload file to minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));return null;}return objectName;}/*** 文件上传** @param file 文件* @return Boolean*/public synchronized String upload(MultipartFile file) {return upload(file, TEST_BUCKET);}/*** 预览** @param fileName* @return*/public String preview(String fileName) {return preview(fileName, TEST_BUCKET);}/*** 预览** @param fileName* @param bucketName 桶名称* @return*/public String preview(String fileName, String bucketName) {// 查看文件地址GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(fileName).method(Method.GET).build();try {String url = minioClient.getPresignedObjectUrl(build);return url;} catch (Exception e) {log.error("preview file to minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));}return null;}/*** 文件下载** @param fileName         文件名称* @param originalFileName 原文件名称* @param res              response* @return Boolean*/public void download(String fileName, String originalFileName, HttpServletRequest req, HttpServletResponse res) {download(fileName, TEST_BUCKET, req, res);}/*** 文件下载** @param fileName         文件名称* @param bucketName       桶名称* @param originalFileName 原文件名称* @param res              response* @return Boolean*/public void download(String fileName, String bucketName, String originalFileName, HttpServletRequest req, HttpServletResponse res) {GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName).object(fileName).build();try (GetObjectResponse response = minioClient.getObject(objectArgs)) {byte[] buf = new byte[1024];int len;try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {while ((len = response.read(buf)) != -1) {os.write(buf, 0, len);}os.flush();byte[] bytes = os.toByteArray();res.setCharacterEncoding("utf-8");String type = req.getHeader("User-Agent").toLowerCase();String firefox = "firefox", chrome = "chrome";String encodedFileName;if (type.indexOf(firefox) > 0 || type.indexOf(chrome) > 0) {encodedFileName = new String(originalFileName.getBytes(StandardCharsets.UTF_8), "iso8859-1");} else {encodedFileName = URLEncoder.encode(originalFileName, StandardCharsets.UTF_8.name());}// 设置强制下载不打开// res.setContentType("application/force-download");// res.setContentType("application/octet-stream");res.setContentType(FileDownloadUtils.getFileContentType(fileName));res.addHeader("Content-Disposition", "attachment;fileName=" + encodedFileName + ";filename*=utf-8''" + encodedFileName);res.addHeader("Content-Length", bytes.length + "");try (ServletOutputStream stream = res.getOutputStream()) {stream.write(bytes);stream.flush();}}res.flushBuffer();} catch (Exception e) {log.error("download file from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));}}/*** 删除** @param fileName* @return* @throws Exception*/public boolean remove(String fileName) {return remove(fileName, TEST_BUCKET);}/*** 删除** @param fileName* @return* @throws Exception*/public synchronized boolean remove(String fileName, String bucketName) {try {minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());} catch (Exception e) {log.error("remove file from minio occur exception. e={}", ExceptionUtil.getExceptionMessage(e));return false;}return true;}}

3.5 创建启动类

在springboot启动成功后连接minio

package com.thcb.miniodemo.listener;import com.thcb.miniodemo.minio.MinioUtil;
import com.thcb.miniodemo.utils.ExceptionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;/*** ApplicationReadyListener** @author thcb* @date 2023-09-05*/
@Component
public class ApplicationReadyListener implements ApplicationListener<ApplicationReadyEvent> {private static final Logger log = LoggerFactory.getLogger(ApplicationReadyListener.class);@Autowiredprivate MinioUtil minioUtil;@Overridepublic void onApplicationEvent(ApplicationReadyEvent event) {try {doPostConstruct();} catch (Exception e) {log.error("e={}", ExceptionUtil.getExceptionMessage(e));}}private void doPostConstruct() {log.info("initMinIo");initMinIo();}/*** 初始化minio桶文件*/private void initMinIo() {minioUtil.initMinIo();}
}

3.6 测试controller

写一个测试的controller,测试minio相关功能

package com.thcb.miniodemo.controller;import com.thcb.miniodemo.minio.MinioUtil;
import com.thcb.miniodemo.utils.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;/*** TestController** @author thcb* @date 2023-09-05*/
@RestController
@RequestMapping("/TestController")
public class TestController {private static final Logger log = LoggerFactory.getLogger(TestController.class);@Autowiredprivate MinioUtil minioUtil;@RequestMapping("/test")@ResponseBodypublic String test() {return "test success";}@PostMapping("/uploadFile")public AjaxResult uploadFile(MultipartFile file) throws Exception {try {String pathUrl = minioUtil.upload2Bucket(file, MinioUtil.TEST_BUCKET);return AjaxResult.success(pathUrl);} catch (Exception e) {return AjaxResult.error(e.toString());}}
}

4. 测试操作

4.1 demo运行

运行工程,如下log说明连接成功:
miniodemo运行

4.2 页面查看

运行完成,在页面应该能看到我们创建的桶:
桶

4.3 上传文件

使用postman调用我们写的测试接口,上传一个文件到minio
postman调用
上传成功,在页面上也可以看到这个文件:
文件查看

4.4 预览/下载文件

如果上传的是图片,通过返回的url,浏览器可以直接访问预览,如果是其他类型的文件,是可以通过这个返回的url进行下载的:
http://localhost:9000/test/20230908/2b31664c4a004a5cb4b2934ebf5300cd.jpg

5. demo下载

minio的demo已经上传到csdn,需要的可以自行下载,在本文基本也把主要的核心代码都贴出来了,这个demo使用的是springboot框架,加了一些工具类,可以直接拿来用,或者新工程改个名字就能用了。demo结构截图:
demo结构
demo工程地址:demo下载地址,传到了gitcode上,应该是csdn弄的一个代码仓库,和git差不多。

6. 总结

minio还是很方便的,从部署到使用,都可以非常快速的搭建,而且比较稳定。

相关文章:

使用docker创建minio镜像并上传文件,提供demo

使用docker创建minio镜像并上传文件&#xff0c;提供demo 1. 整体描述2. 环境搭建2.1 windows环境搭建2.2 docker部署 3. spring集成3.1 添加依赖3.2 配置文件3.3 创建config类3.4 创建minio操作类3.5 创建启动类3.6 测试controller 4. 测试操作4.1 demo运行4.2 页面查看4.3 上…...

02 java ---- Android 基础app开发

目录 相对布局 显示一个美女 显示两个美女 安卓APP启动过程 安卓布局控件 常用布局之相对布局 常用布局之相对布局 padding和margin 按键美化 常用布局之线性布局 安卓按键响应的几种方式 直接设置按键的onClick绑定的函数 自定义类实现按键监听事件的接口 匿名内…...

鲁棒性与稳定性区别

鲁棒性 所谓“鲁棒性”&#xff0c;是指控制系统在一定&#xff08;结构&#xff0c;大小&#xff09;的参数摄动下&#xff0c;维持其它某些性能的特性粗携。 稳定性 所谓“稳定性”&#xff0c;是指控制系统在使它偏离平衡状态的扰动作用消失后&#xff0c;返回原来平衡状…...

C++项目实战——基于多设计模式下的同步异步日志系统-⑦-日志输出格式化类设计

文章目录 专栏导读日志格式化类成员介绍patternitems 格式化子项类的设计抽象格式化子项基类日志主体消息子项日志等级子项时间子项localtime_r介绍strftime介绍 源码文件名子项源码文件行号子项线程ID子项日志器名称子项制表符子项换行符子项原始字符串子项 日志格式化类的设计…...

Android---底部弹窗之BottomSheetDialog

BottomSheetDialog 是Android开发中的一个弹出式对话框&#xff0c;它从屏幕底部弹出并覆盖部分主界面。 1. BottomSheetDialog的使用 // 参数2&#xff1a;设置BottomSheetDialog的主题样式&#xff1b;将背景设置为transparent&#xff0c;这样我们写的shape_bottom_sheet_…...

Cesium 地球网格构造

Cesium 地球网格构造 Cesium原理篇&#xff1a;3最长的一帧之地形(2&#xff1a;高度图) HeightmapTessellator 用于从高程图像创建网格。提供了一个函数 computeVertices&#xff0c;可以根据高程图像创建顶点数组。 该函数的参数包括高程图像、高度数据的结构、网格宽高、…...

C++深度优化——cacheline测试

cacheline是内存调度的基本结构&#xff0c;其大小一般为32B或者64B。关于本机具体的配置信息可以在配置文件中看到&#xff1a; 这里可以看到我的这台机器的cacheline大小是64B。对于cacheline在多核处理器中有一个伪共享的状态&#xff0c;具体可以参考以下博客&#xff1a;高…...

【数字IC/FPGA】Verilog中的递归调用

参考文章 在Verilog2001中,模块的递归调用是可能的,引用下面的一段话(出自上面的参考文章) Many designers think that recursive techniques cannot be applied to hardware design. I’m not really sure where this misconception comes from. While it is true that i…...

禁用Win10自动更新

第一步&#xff0c;winr&#xff0c;输入 gpedit.msc 并回车&#xff0c;打开【组策略】 第二步&#xff0c;依次点击 管理模板->Windows组件->Windows更新 第三步&#xff0c;双击Windows更新&#xff0c;然后在设置中双击 指定 intranet Microsoft 更新服务位置 第…...

算法通关村-----动态规划高频问题

最少硬币数问题 问题描述 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。你可以认为每种硬…...

记一起小意外事件引起的批量重命名文件名

一、事件描述 某次,因某业务系统迁移,一线人员对业务目录误操作,执行打包命令过程中导致Tomcat下的web应用程序无法使用,检查后发现项目下所有文件名都加了gz格式;询问一线,发现是对项目目录执行了:gzip -r ./tomcat导致程序文件找不到;报错如下: 二、事件处理 1、查看…...

【Excel函数】Excel的Len函数求对象的字符数

在Excel中&#xff0c;LEN函数用于计算文本字符串中的字符数。它的语法如下。 LEN(text) 其中&#xff0c;text是要计算字符数的文本字符串。 例如&#xff0c;如果你想计算单元格A1中文本的字符数&#xff0c;可以使用以下公式&#xff1a; A2len(a1) 结果将返回单元格A1中文…...

小白备战大厂算法笔试(八)——搜索

搜索 二分查找 二分查找是一种基于分治策略的高效搜索算法。它利用数据的有序性&#xff0c;每轮减少一半搜索范围&#xff0c;直至找到目标元素或搜索区间为空为止。 Question&#xff1a; 给定一个长度为n的数组 nums &#xff0c;元素按从小到大的顺序排列&#xff0c;数组…...

〔022〕Stable Diffusion 之 生成视频 篇

✨ 目录 &#x1f388; 视频转换 / mov2mov&#x1f388; 视频转换前奏准备&#x1f388; 视频转换 mov2mov 使用&#x1f388; 视频转换 mov2mov 效果预览&#x1f388; 视频无限缩放 / Infinite Zoom&#x1f388; 视频无限缩放 Infinite Zoom 使用 &#x1f388; 视频转换 /…...

网络安全深入学习第三课——热门框架漏洞(RCE—Struts2远程代码执行)

文章目录 一、Struts2框架介绍二、Struts2远程代码执行漏洞三、Struts2执行代码的原理四、Struts2框架特征五、漏洞手工POC六、漏洞工具复现 一、Struts2框架介绍 ------ Struts2是apache项目下的一个web 框架&#xff0c;普遍应用于阿里巴巴、京东等互联网、政府、企业门户网…...

【uni-app】

准备工作&#xff08;Hbuilder&#xff09; 1.下载hbuilder&#xff0c;插件使用Vue3的uni-app项目 2.需要安装编译器 3.下载微信开发者工具 4.点击运行->微信开发者工具 5.打开微信开发者工具的服务端口 效果图 准备工作&#xff08;VScode&#xff09; 插件 uni-cr…...

Pytorch 多卡并行(3)—— 使用 DDP 加速 minGPT 训练

前文 并行原理简介和 DDP 并行实践 和 使用 torchrun 进行容错处理 在简单的随机数据上演示了使用 DDP 并行加速训练的方法&#xff0c;本文考虑一个更加复杂的 GPT 类模型&#xff0c;说明如何进行 DDP 并行实战MinGPT 是 GPT 模型的一个流行的开源 PyTorch 复现项目&#xff…...

IAM、EIAM、CIAM、RAM、IDaaS 都是什么?

后端程序员在做 ToB 产品或者后台系统时&#xff0c;都不可避免的会遇到账号系统、登录系统、权限系统、日志系统等这些核心功能。这些功能一般都是以 SSO 系统、RBAC 权限管理系统等方式命名&#xff0c;但这些系统合起来有一个专有名词&#xff1a;IAM。 IAM IAM 是 Identi…...

STM32 Cubemx 通用定时器 General-Purpose Timers同步

文章目录 前言简介cubemx配置 前言 持续学习stm32中… 简介 通用定时器是一个16位的计数器&#xff0c;支持向上up、向下down与中心对称up-down三种模式。可以用于测量信号脉宽&#xff08;输入捕捉&#xff09;&#xff0c;输出一定的波形&#xff08;比较输出与PWM输出&am…...

Ubuntu 20.04降级clang-format

1. 卸载clang-format sudo apt purge clang-format 2. 安装clang-format-6.0 sudo apt install clang-format-6.0 3. 软链接clang-format sudo ln -s /usr/bin/clang-format-6.0 /usr/bin/clang-format...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

恶补电源:1.电桥

一、元器件的选择 搜索并选择电桥&#xff0c;再multisim中选择FWB&#xff0c;就有各种型号的电桥: 电桥是用来干嘛的呢&#xff1f; 它是一个由四个二极管搭成的“桥梁”形状的电路&#xff0c;用来把交流电&#xff08;AC&#xff09;变成直流电&#xff08;DC&#xff09;。…...

书籍“之“字形打印矩阵(8)0609

题目 给定一个矩阵matrix&#xff0c;按照"之"字形的方式打印这个矩阵&#xff0c;例如&#xff1a; 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为&#xff1a;1&#xff0c;…...