MinIO框架安装使用+实现上传需求

news2024/11/17 7:25:44

MinIO框架

  • 什么是MinIO框架
  • 如何安装(Docker版)
    • 安装步骤
      • 1. 查询MinIO的服务版本
      • 2. 拉取MinIO
      • 3.启动
        • 报错在docker中没有操作文件的权限
      • 4. 访问
  • 简单配置
    • 1.找到创建用户界面
    • 2. 设置用户信息
    • 3. 创建一个桶
  • 使用MinIO
    • 依赖搭建
    • MinIO的初始化
    • API
      • 存储桶的基本操作
        • 1. 检查桶是否存在
        • 2. 创建存储桶
        • 3. 查询所有桶的列表信息
        • 4. 删除存储桶
      • 对象的基本操作
        • 上传对象
          • PutObject方法
        • 获取对象
          • getObject方法
          • downloadObject方法
          • getPresignedObjectUrl方法
          • getPresignedPostFormData方法
        • 复制对象
          • copyObject方法
        • 删除对象
          • removeObject方法
          • removeObjects方法
        • 桶对象的信息查询
          • 查询桶下对象
          • 递归查询桶下对象
          • 条件查询
  • 总结

什么是MinIO框架

前置知识:对象存储

对象存储服务( Object Storage Service,OSS ):
是一种海量、安全、低成本、高可靠的云存储服务,适合存放任意类型的文件。
容量和处理能力弹性扩展,多种存储类型供选择,全面优化存储成本。

MinIO对象存储系统是为海量数据存储、人工智能、大数据分析而设计,基于Apache License v2.0开源协议的对象存储系统,它完全兼容Amazon S3接口,单个对象最大可达5TB,适合存储海量图片、视频、日志文件、备份数据和容器/虚拟机镜像等。

通常在企业中我们会将一些图片,视频,文档等相关数据存储在对象存储中,常见的对象存储服务有阿里云的OSS对象存储、FastDFS分布式文件系统以及公司的私有云平台等等,以便于数据的存储和快速获取。但随着业务的快速发展,我们需要存储一些身份信息用于审核和实名相关的数据,这部分数据较为敏感,因此对于敏感数据的存储也可以选择Minio来进行自建服务。

如何安装(Docker版)

MinIO安装非常的简单,在网上你很少会看到有关于MinIo的安装问题,所以基本上你去搜一下就能很容易成功安装,在这里我采用的是Docker去安装它。
但是Docker中会有一些坑在,我基本上凭实力全踩上一遍,所以你跟着我去安装,基本不会出什么问题 。

安装步骤

1. 查询MinIO的服务版本

docker search minio

2. 拉取MinIO

docker pull minio/minio
下载稳定版本的镜像
下载后使用docker images查看下载的镜像

操作如下图所示
在这里插入图片描述

3.启动

注意端口要起两个(一个9090,一个9000)!!!查了2个小时!!!
下面的代码不能完全套用,关于用户名,密码,数据卷的绑定记得

docker run -d -p 9000:9000 -p 9090:9090 --name=minio --restart=always -e "MINIO_ROOT_USER=xxx" -e "MINIO_ROOT_PASSWORD=xxx" -v /home/data:/data -v /home/config:/root/.minio  minio/minio server /data --console-address ":9000" --address ":9090"

报错在docker中没有操作文件的权限

docker: Error response from daemon: Mounts denied: 
The path /home/data is not shared from the host and is not known to Docker.
You can configure shared paths from Docker -> Preferences... -> Resources -> File Sharing.
See https://docs.docker.com/desktop/mac for more info.

解决:

  1. 打开Docker客户端的首选项(Preference)
  2. 找到 Resources下的 FILE SHARING
  3. 配置你允许让Docker访问使用的目录

在这里插入图片描述
然后就大功告成!!!
在这里插入图片描述

4. 访问

注意我们访问的地址为:http://127.0.0.1:9090
然后输入用户名和密码就可以登录进去了。

简单配置

1.找到创建用户界面

在导航栏中找到identity/user处创建一个用户,点击create user按钮
在这里插入图片描述

2. 设置用户信息

用户名密码以及权限写完之后,就可以使用该用户登录MinIO控制台了。
在这里插入图片描述
创建用户之后,点击用户弹出用户的基本信息,点击导航栏中的Service Accounts,出现下面的界面

在这里插入图片描述
点击右边的Create Access Key,系统会随机生成Create Access Key,点击create按钮后,会展示出它们的信息,这时记得将它们复制粘贴到你的笔记或者存储文件中,后续使用代码上传文件时需要用到这两个key。
在这里插入图片描述

3. 创建一个桶

在页面导航栏中找到Administrator/Buckets,点击右上角创建桶按钮
在这里插入图片描述
然后输入桶的名字,就大功告成了!
在这里插入图片描述

使用MinIO

依赖搭建

 <!-- minio依赖-->
    <dependency>
      <groupId>io.minio</groupId>
      <artifactId>minio</artifactId>
      <version>8.3.3</version>
    </dependency>
    <!-- 官方 miniodemo需要的依赖-->
    <dependency>
      <groupId>me.tongfei</groupId>
      <artifactId>progressbar</artifactId>
      <version>0.7.4</version>
    </dependency>
     <!-- 这个依赖最好是在4.8.1以上,就用下面这个一般不出什么问题-->
    <dependency>
      <groupId>com.squareup.okhttp3</groupId>
      <artifactId>okhttp</artifactId>
      <version>4.9.2</version>
    </dependency>

MinIO的初始化

MinioClient minioClient =
    MinioClient.builder()
        .endpoint("https://play.min.io")
        .credentials("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG")
        .build();
  • builder:用于构建一个Minio客户端的配置对象
  • endpoint:指定Minio服务的URL地址和端口号
  • credentials:提供认证凭证,这里使用的是用户名(admin)和密码(xxx)
  • build:客户端的创建
    我们获取到的了MinIOClient对象,就可以进行MinIo的API操作。

API

存储桶的基本操作

1. 检查桶是否存在

  • boolean bucketExists(BucketExistsArgs args):检查存储桶是否存在(注意里面的参数还需要创建)
    代码如下:
    public final static String endPoint = "xxx";
    public final static String accessKey = "xxxx";
    public final static String secretKey = "xxxx";
    public final static String BucketName = "xxxx";
 public static void uploadFile() throws  InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException  {
        try {
            // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
            MinioClient minoClient = MinioClient.builder()
                    .endpoint(endPoint)
                    .credentials(accessKey,secretKey)
                    .build();

            // 存储桶的基本使用,新版需要使用build来构造BucketExistsArgs对象
            BucketExistsArgs existsArgs = BucketExistsArgs.builder()
                    .bucket(BucketName)
                    .build();
            boolean existBucketFlag = minoClient.bucketExists(existsArgs);

            System.out.println("桶是否存在:"+existBucketFlag);
              } catch (MinioException e) {
            System.out.println("Error occurred: " + e);
        }
    }

2. 创建存储桶

  • public void makeBucket(MakeBucketArgs args):创建一个启用给定区域和对象锁定功能的存储桶。
    代码如下:
   public static void uploadFile() throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException {
        // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
        MinioClient minoClient = MinioClient.builder()
                .endpoint(endPoint)
                .credentials(accessKey,secretKey)
                .build();
        // 创建存储桶
        String bucketName="wang";
        //存储桶不存在则创建  if(!minoClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())){
            MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build();
            minoClient.makeBucket(makeBucketArgs);
            System.out.println("创建存储桶成功"+bucketName);
        }else{
            System.out.println("已存在");
        }
    }
}

结果如下:
在这里插入图片描述

3. 查询所有桶的列表信息

  • public List listBuckets():列出所有桶的桶信息
    代码如下:
 public static void uploadFile() throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException {
        // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
        MinioClient minoClient = MinioClient.builder()
                .endpoint(endPoint)
                .credentials(accessKey,secretKey)
                .build();

        List<Bucket> buckets = minoClient.listBuckets();
        buckets.forEach(bucket -> {
            System.out.println("存储桶名称:"+bucket.name()+"存储时间"+bucket.creationDate());
   });
 }

注意:桶的创建时间默认是美国时间,创建桶时我们可以指定桶的时区或者设置 MinIO服务器时区。
结果如下:
在这里插入图片描述

4. 删除存储桶

  • public void removeBucket(RemoveBucketArgs args):删除一个空桶
    注意,如果存储桶不是空桶,删除会报错
    代码如下:
    public static void uploadFile() throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException {
        // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
        MinioClient minoClient = MinioClient.builder()
                .endpoint(endPoint)
                .credentials(accessKey,secretKey)
                .build();
        String bucketName = "wang";
        RemoveBucketArgs bucketArgs=RemoveBucketArgs.builder().bucket(bucketName).build();
        if(minoClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
            minoClient.removeBucket(bucketArgs);
            System.out.println("删除存储桶成功!"+bucketName);
        }else {
            System.out.println("存储桶不存在,无法删除");
        }
    }

对象的基本操作

上传对象

PutObject方法
  • public ObjectWriteResponse putObject(PutObjectArgs args):将给定的流上传为存储桶的对象
    InputStream上传:
    public static void uploadFile() throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException {
        // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
        MinioClient minoClient = MinioClient.builder()
                .endpoint(endPoint)
                .credentials(accessKey,secretKey)
                .build();
        String bucketName= "testdemo";
        //创建InputStream上传
        File file = new File("D:\\testUploadFile\\test1.webp");
        InputStream inputStream = new FileInputStream(file);
        long start = System.currentTimeMillis();
        //上传流
        minoClient.putObject(
                PutObjectArgs.builder().
                        bucket(bucketName)
                        .object("one/"+file.getName())
                        .stream(inputStream,inputStream.available(),-1)
                  .build());
        inputStream.close();
        long over = System.currentTimeMillis();
        System.out.println("uploaded successfully 耗时:"+(over-start));
    }

结果如下:
在这里插入图片描述
需要注意几个点:

  • 添加的Object大小不能超过 5GB。
  • 默认情况下,如果已存在同名Object且对该Object有访问权限,则新添加的Object将覆盖原有的Object,并返回 200 OK。
  • OSS没有文件夹的概念,所有资源都是以文件来存储,但您可以通过创建一个以正斜线(/)结尾,大小为 0的Object来创建模拟文件夹(指定 /后,默认会自动创建)。
  • 上传文件是也可以使用SSE-C加密,添加自定义元数据及消息头等操作。

获取对象

getObject方法
  • public GetObjectResponse getObject(GetObjectArgs args):获取对象的数据
    代码如下:
    public static void uploadFile() throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException {
        // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
        MinioClient minoClient = MinioClient.builder()
                .endpoint(endPoint)
                .credentials(accessKey, secretKey)
                .build();
        String bucketName = "testdemo";
        GetObjectArgs getObjectArgs = GetObjectArgs.builder()
                .bucket(bucketName)
                .object("one/test1.webp")
                .build();
        GetObjectResponse objectResponse = minoClient.getObject(getObjectArgs);
        System.out.println(objectResponse.bucket());
        System.out.println(objectResponse);
    }

结果如下:
在这里插入图片描述

downloadObject方法
  • public void downloadObject(downloadObjectArgs args):将对象的数据下载到磁盘。
        //将对象数据下载到磁盘
        DownloadObjectArgs objectArgs = DownloadObjectArgs.builder()
                .bucket(bucketName)
                .object("one/test1.webp")
                .filename("D:\\testUploadFile\\download\\test1.webp")
                .build();
        minoClient.downloadObject(objectArgs);

结果
在这里插入图片描述

getPresignedObjectUrl方法
  • public String getPresignedObjectUrl(GetPresignedObjectUrlArgs args):获取HTTP方法,到期时间和自定义请求参数的对象的预签名URL。
    这个方法的用途在于:
    可以提供给不用登录进行图片浏览,第三方共享访问等。
    我们还可以对返回 URL,根据业务做一些参数验签等控制。
    代码如下:
    public static void uploadFile() throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException {
        // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
        MinioClient minoClient = MinioClient.builder()
                .endpoint(endPoint)
                .credentials(accessKey, secretKey)
                .build();

        String bucketName = "testdemo";
        GetPresignedObjectUrlArgs urlArgs = GetPresignedObjectUrlArgs.builder()
                .bucket(bucketName)
                .object("one/test1.webp")
                .method(Method.GET)
                .expiry(120, TimeUnit.SECONDS)
                .build();
        String presignedObjectUrl = minoClient.getPresignedObjectUrl(urlArgs);
        System.out.println(presignedObjectUrl);
    }


结果如下
http://127.0.0.1:9090/testdemo/one/test1.webp?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=wang%2F20230829%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230829T032634Z&X-Amz-Expires=120&X-Amz-SignedHeaders=host&X-Amz-Signature=aa1bbaac4906eeac505cd2602954973ab99189f4674570f078f412b6e7dc7109
返回带签名的URL有点小长,过期之后访问会报错。

getPresignedPostFormData方法
  • public Map<String,String> getPresignedPostFormData(PostPolicy policy):获取对的PostPolicy的表单数据以使用POST方法上传其数据。
  • 使用此方法,获取对象的上传策略(包含签名、文件信息、路径等),然后使用这些信息采用 POST 方法的表单数据上传数据。也就是可以生成一个临时上传的信息对象,第三方可以使用这些信息,就可以上传文件。
    注意:第三方请求中的签名必须和 创建策略中的签名参数等一致,不符合策略要求的就会上传失败。
    一般使用场景:
  1. 第三方请求应用服务器接口,来获取一个上传策略信息
  2. 第三方使用 Http+访问策略信息直接请求应用服务器接口进行上传文件。

代码如下:

public static void uploadFile() throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException {
        // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
        MinioClient minoClient = MinioClient.builder()
                .endpoint(endPoint)
                .credentials(accessKey, secretKey)
                .build();

        String bucketName = "testdemo";
        String objectName = "one/test2.webp";
        //1.为存储桶创建一个上传策略,过期时间为7天
        PostPolicy policy = new PostPolicy(bucketName, ZonedDateTime.now().plusDays(7));
        //设置一个参数key-value,值为上传对象的名称(保留为桶中的名字)
        policy.addEqualsCondition("key",objectName);
        //添加 Content-Type以”image/“开头,表示只能上传照片
        policy.addStartsWithCondition("Content-Type","image/");
        //设置上传文件的大小 10 KiB to 10MiB
        policy.addContentLengthRangeCondition(10*1024,10*1024*1024);

        //2. 获取策略的认证令牌,签名等信息
        Map<String, String> formData = minoClient.getPresignedPostFormData(policy);

        //3. 模拟第三方,使用OkHttp调用Post上传对象
        //创建MultipartBody对象
        MultipartBody.Builder multipartBuilder = new MultipartBody.Builder();
        multipartBuilder.setType(MultipartBody.FORM);
        for (Map.Entry<String,String> entry : formData.entrySet()){
            multipartBuilder.addFormDataPart(entry.getKey(),entry.getValue());
        }

        multipartBuilder.addFormDataPart("key",objectName);
        multipartBuilder.addFormDataPart("Content-Type","image/webp");
        //todo
       File uploadFile =new File("D:\\testUploadFile\\test2.webp");
       multipartBuilder.addFormDataPart("file",objectName, RequestBody.create(uploadFile,null));
       Request request =
               new Request.Builder()
                       .url(endPoint+bucketName)
                       .post(multipartBuilder.build())
                       .build();
        OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
        Response response = httpClient.newCall(request).execute();
        if(response.isSuccessful()){
            System.out.println("successfully");
        }else{
            System.out.println("error");
        }
    }

结果:
在这里插入图片描述

复制对象

copyObject方法
  • public ObjectWriteResponse copyObject(CopyObjectArgs args):通过服务器端从另一个对象复制数据来创建一个对象。
    代码如下:
  public static void uploadFile() throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException {
        // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
        MinioClient minoClient = MinioClient.builder()
                .endpoint(endPoint)
                .credentials(accessKey, secretKey)
                .build();
        String bucketName = "testdemo";
        String bucketName2 = "hao";
        CopyObjectArgs objectArgs = CopyObjectArgs.builder()
                .source(CopySource.builder()
                        .bucket(bucketName)
                        .object("one/test2.webp")
                        .build())
                .bucket(bucketName2)
                .object("two/test1.webp")
                .build();
        minoClient.copyObject(objectArgs);
    }

结果如下:
在这里插入图片描述

删除对象

removeObject方法
  • public void removeObject(RemoveObjectArgs args):移除一个对象。
    代码如下:
    public static void uploadFile() throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException {
        // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
        MinioClient minoClient = MinioClient.builder()
                .endpoint(endPoint)
                .credentials(accessKey, secretKey)
                .build();
        RemoveObjectArgs objectArgs = RemoveObjectArgs.builder()
                .bucket(BucketName)
                .object("one/test2.webp")
                .build();
        minoClient.removeObject(objectArgs);
    }

结果如下:
在这里插入图片描述

removeObjects方法
  • public Iterable removeObjects(RemoveObjectsArgs args):懒惰地删除多个对象。它需要迭代返回的 Iterable 以执行删除。
    代码如下:
        //构建需要删除的对象
        List<DeleteObject> objects = new LinkedList<>();
        objects.add(new DeleteObject("2023/07/05/1189f7file01.jfif"));
        objects.add(new DeleteObject("onetest1.webp"));
        objects.add(new DeleteObject("onetest3.webp"));
        RemoveObjectsArgs objectsArgs = RemoveObjectsArgs.builder()
                .bucket(BucketName)
                .objects(objects)
                .build();
        Iterable<Result<DeleteError>> results = minoClient.removeObjects(objectsArgs);

结果如下:
在这里插入图片描述

桶对象的信息查询

查询桶下对象
  • public Iterable listObjects(ListObjectsArgs args):列出桶的对象信息。
    代码如下:
  public static void uploadFile() throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException {
        // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
        MinioClient minoClient = MinioClient.builder()
                .endpoint(endPoint)
                .credentials(accessKey, secretKey)
                .build();
        ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder()
                .bucket(BucketName)
                .build();
        Iterable<Result<Item>> results = minoClient.listObjects(listObjectsArgs);
        for (Result<Item> result : results) {
            Item item = result.get();
       System.out.println(item.objectName()+"\t"+item.size());
        }
    }

结果如下:
在这里插入图片描述

递归查询桶下对象

代码如下:

  public static void uploadFile() throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException {
        // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
        MinioClient minoClient = MinioClient.builder()
                .endpoint(endPoint)
                .credentials(accessKey, secretKey)
                .build();
        ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder()
                .bucket(BucketName)
                .recursive(true)
                .build();
        Iterable<Result<Item>> results = minoClient.listObjects(listObjectsArgs);

        for (Result<Item> result : results) {
            Item item = result.get();
            System.out.println(item.objectName()+"\t"+item.size());
        }
    }

结果如下:
在这里插入图片描述

条件查询

代码如下:

 public static void uploadFile() throws InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException, ServerException {
        // 使用MinIO服务的URL,端口,Access key和Secret key创建一个MinioClient对象
        MinioClient minoClient = MinioClient.builder()
                .endpoint(endPoint)
                .credentials(accessKey, secretKey)
                .build();
        ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder()
                .bucket(BucketName)
                .startAfter("VipSongsDownload/陶喆 - 爱是个什么东西.mflac")
                .maxKeys(10)
                .recursive(true)
                .build();
        Iterable<Result<Item>> results = minoClient.listObjects(listObjectsArgs);

        for (Result<Item> result : results) {
            Item item = result.get();
            System.out.println(item.objectName()+"\t"+item.size());
        }
    }

在这里插入图片描述

总结

这里列举了一些基本的用法,后面需求方面的慢慢更

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

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

相关文章

uniapp 开发小程序,封装一个方法,让图片使用线上地址

1.在main.js文件中&#xff0c;添加以下代码&#xff1a; 复制使用&#xff1a; // 图片使用网络地址 Vue.prototype.localImgSrc function(img){//项目的地址域名&#xff0c;例如百度return "https://baidu.cn/static/index/images/" img; }2.在页面中直接使用&…

PMP是什么?项目管理证书好考吗?

PMP是由项目管理协会&#xff08;Project Management Institute&#xff0c;简称PMI&#xff09;发起的项目管理专业人士资格认证&#xff0c;严格评估项目管理人员知识技能是否具有高品质的资格认证考试。PMP证书究竟难不难考呢&#xff1f;接下来的文章将简要讨论PMP证书的考…

git 基础

1.下载安装Git&#xff08;略&#xff09; 2.打开git bash窗口 3.查看版本号、设置用户名和邮箱 用户名和邮箱可以随意起&#xff0c;与GitHub的账号邮箱没有关系 4.初始化git 在D盘中新建gitspace文件夹&#xff0c;并在该目录下打开git bash窗口 git init 初始化完成后会…

【微服务部署】06-日志集成

文章目录 1. EFK日志三件套集成1.1 核心组件1.2 部署 2. Exceptionless日志系统2.1 Exceptionless核心特性2.2 Exceptionless部署文件2.3 K8s中使用Exceptionless 1. EFK日志三件套集成 1.1 核心组件 Elasticsearch&#xff08;存储&#xff09;Fluentd&#xff08;收集器&am…

文件上传漏洞-upload靶场3-4(全网最详细解读)

文件上传漏洞-upload靶场3-4关通关笔记&#xff08;全网最详细解读&#xff09; upload 第三关&#xff08;特殊后缀&#xff09; 思路 按照第一关和第二关的思路&#xff0c;先随便上传一个文件用burpsuite工具抓包&#xff0c;看它到底是前段验证还是后端验证。 上传一个we…

ADB安装及命令-自用查询

常用ADB命令整理 ADB简介常用命令整理查看设备及安装卸载屏幕事件⽇志查询查询系统服务情况其它 adb 命令 ADB安装ADB连接设备Android 实体机连接准备Android 虚拟机连接准备 ADB简介 ADB&#xff0c;即 安卓调试桥 (Android Debug Bridge, adb)&#xff0c;它是 Android 开发…

分布式系统的多数据库,实现分布式事务回滚(1.7.0 seata整合2.0.4nacos)

正文 1、解决的应用场景是分布式事务&#xff0c;每个服务有独立的数据库。 2、例如&#xff1a;A服务的数据库是A1&#xff0c;B服务的数据库是B2&#xff0c;A服务通过feign接口调用B服务&#xff0c;B涉及提交数据到B2&#xff0c;业务是在B提交数据之后&#xff0c;在A服…

数学建模:层次分析法

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 层次分析法 步骤描述 将问题条理化&#xff0c;层次化&#xff0c;构建出一个有层次的结构模型。层次分为三类&#xff1a;目标层&#xff0c;准则&#xff08;指标&#xff09;层&#xff0c;方案层。比…

Mybatis1.6 添加数据

1.6 添加数据 1.6.1 编写接口方法1.6.2 编写SQL语句1.6.3 编写测试方法1.6.4 添加-主键返回 如上图是我们平时在添加数据时展示的页面&#xff0c;而我们在该页面输入想要的数据后添加 提交 按钮&#xff0c;就会将这些数据添加到数据库中。接下来我们就来实现添加数据的操作。…

前端调用电脑摄像头

项目中需要前端调用&#xff0c;所以做了如下操作 先看一下效果吧 主要是基于vue3&#xff0c;通过canvas把画面转成base64的形式&#xff0c;然后是把base64转成 file文件&#xff0c;最后调用了一下上传接口 以下是代码 进入页面先调用一下摄像头 navigator.mediaDevices.ge…

低成本32位单片机电动工具无感方波控制方案

RAMSUN介绍基于灵动32位微处理器MM32SPIN0230的BLDC电动工具无感方波控制方案&#xff0c;包括MM32SPIN0230芯片资源。 以下是电动工具无感方波控制方案的简述&#xff1a; MM32SPIN0230电动工具专用板 芯片介绍 MM32SPIN0230系列是灵动微MindSPIN旗下高性能的单电机控制产品…

04-基础例程4

基础例程4 1、RGB彩灯 实验介绍 ​ WS2812B是一款智能控制的LED光源&#xff0c;控制电路和RGB芯片集成在一个5050组件的封装中。 ​ 可以将多个RGB灯珠级联&#xff0c;如下图所示&#xff1a; ​ 3个最基本的颜色为红、绿、蓝&#xff08;RGB&#xff09;&#xff0c;均是…

Elasticsearch实战(三):Springboot实现Elasticsearch搜索推荐

文章目录 系列文章索引一、什么是搜索推荐二、新增测试数据三、搜索推荐的实现1、es官网2、Java实现搜索推荐3、总结 系列文章索引 Elasticsearch实战&#xff08;一&#xff09;&#xff1a;Springboot实现Elasticsearch统一检索功能 Elasticsearch实战&#xff08;二&#x…

Python asyncio 性能分析

文章目录 1. 工具1.1 cProfile2.1 yappi 2. 可视化2.1 SnakeViz2.2 gprof2dot 1. 工具 1.1 cProfile 一般对分析python性能的工具都会用cprofile。但是这玩意对多线程和asyncio的支持并不友好&#xff0c;如果用它对asyncio分析&#xff0c;会发现CPU都耗费在了poll上面&…

动态维护直径 || 动态维护树上路径 || 涉及LCA点转序列 || 对欧拉环游序用数据结构维护:1192B

https://www.luogu.com.cn/problem/CF1192B 对于直径的求法&#xff0c;常用dp或两次dfs&#xff0c;但如果要动态维护似乎都不太方面&#xff0c;那么可以维护树上路径最大值。 树上路径为&#xff1a; d e p u d e p v − 2 d e p l c a ( u , v ) dep_udep_v-2\times de…

如何实现AI的矢量数据库

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建3D应用场景 然而&#xff0c;人工智能模型有点像美食厨师。他们可以创造奇迹&#xff0c;但他们需要优质的成分。人工智能模型在大多数输入上都做得很好&#xff0c;但如果它们以最优化的格式接收输入&#xff0c;它们就会真正…

Python的pymysql模块与MySQL数据库的互动:基础与实例

Python的pymysql模块与MySQL数据库的互动&#xff1a;基础与实例 一、连接数据库二、创建游标三、执行SQL命令四、关闭连接 在Python的世界里&#xff0c;操作MySQL数据库最常用的库就是pymysql。 pymysql是一个灵活且易于使用的库&#xff0c;它允许我们以Python的方式操作MyS…

网络安全研究和创新:探讨网络安全领域的最新研究成果、趋势和创新技术,以及如何参与其中。

第一章&#xff1a;引言 随着数字化时代的到来&#xff0c;网络安全变得比以往任何时候都更加重要。无论是个人、企业还是国家&#xff0c;都面临着日益复杂和隐蔽的网络威胁。为了确保我们的信息和资产的安全&#xff0c;网络安全研究变得至关重要。本文将深入探讨网络安全领…

搭建 Qt6 + Visual Studio 开发环境

作者&#xff1a; 一去、二三里 个人微信号&#xff1a; iwaleon 微信公众号&#xff1a; 高效程序员 在 Windows 中&#xff0c;如果想要开发 Qt 应用程序&#xff0c;可以选择多种方式&#xff1a; Qt Creator MinGW 编译器Qt Creator MSVC 编译器Visual Studio&#xff0…

【前车之鉴】: 2023最新教程-将java程序打包到maven私服的正确打开方式,详细流程介绍不怕你掌握不了

文章目录 为什么看这篇整体流程1. 注册账号【首次需要】2. 工单申请【新项目必须】3. 项目配置【新项目必须】4. 授权认证【新项目必须】5. 一键发布 最后也很重要 为什么看这篇 一是当前网络上一些博客有遗漏部分&#xff0c;这里做补充&#xff0c;二是网上思路没错&#xff…