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

华为云云耀云服务器L实例评测|基于云服务器的minio部署手册

华为云云耀云服务器L实例评测|基于云服务器的minio部署手册

【软件安装版本】【集群安装(是)(否)】

                                 

版本

创建人

修改人

创建时间

备注

1.0

jz

jz

2023.9.2

minio华为云耀服务器

一.  部署规划与架构

1. 规划:(集群:网络规划,服务器规划)

  安装方式 :非集群安装

  服务器   :  华为云:192.168.0.147

  端口号   :A.minio管理界面:9000,33806 B.demo应用:8081

2. 架构(集群:拓扑图)

   

  3. 支撑业务

  小文件服务器:图片,文件,视频的存储管理。

二. 运行环境安装

  1. 硬件

   华为云耀服务器,2核2G 3m网络

     2. 操作系统

 uname -a

   为了springboot的demo运行,需要提前安装好Java运行环境。这里不再重述

    3. 环境配置

        软件安装路径:/opt/software/minio

        

mkdir -p /opt/software/minio

   

   数据文件路径:/opt/data/minio

mkdir -p /opt/data/minio

   日志文件路径: /opt/data/minio/logs

mkdir -p /opt/data/minio/logs

 

三. 单机部署步骤 

  1. 安装包获取与安装

  下载地址;https://min.io/download#/linux

cd /opt/software/minio/

wget https://dl.min.io/server/minio/release/linux-amd64/minio

 

安装成功:

查看下载文件:

ls

     2. 配置修改

  

vim /etc/default/minio

# 启动的时候看提示 新版本

MINIO_ROOT_USER=username

MINIO_ROOT_PASSWORD=password

# 如果MinIO版本比较旧,修改用户名密码为

MINIO_ACCESS_KEY=username

MINIO_SECRET_KEY=password

注意:创建的文件是个新文件。

修改环境变量

vim /etc/profile

增加两行

export  MINIO_ROOT_USER=username

export  MINIO_ROOT_PASSWORD=password

# 如果MinIO版本比较旧,修改用户名密码为

export MINIO_ACCESS_KEY=username

export MINIO_SECRET_KEY=password

配置文件生效

source /etc/profile

 

    3. 检测依赖环境是否就绪

   

java -version

    4.安装

   赋予文件安装权限:

   

chmod 777 minio

 ls -l

 

以守护进程方式启动,指定端口为9000固定端口,数据文件路径/opt/data/minio/

nohup /opt/software/minio/minio server --console-address :33806 --address 0.0.0.0:9000 /opt/data/minio >  /opt/data/minio/logs/minio.log &

ps -ef |grep minio

more minio.log

 

Minio启动成功

    5. 云服务器开通公网端口号:9000

   登录华为云账号:https://auth.huaweicloud.com/

配置到服务器

进入控制台,更改安全组

选择刚才创建的安全组

  1. 验证

 浏览器输入:公网ip:9000

会自动跳转到33806端口上。

用username/password登录

 四.应用部署

    1. 安装java

  请自行安装jdk文件,保证java -version可用。

  2.编写项目

  Pom文件中增加配置

<!--MinIO JAVA SDK-->
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>${minio.version}</version>
</dependency>

Yaml中增加配置

minio:
  endpoint: http://192.168.0.213:9000 #MinIO服务所在地址
  bucketName: mall #存储桶名称
  bucketImg: img # 图片桶
  bucketVideo: video # 视频桶
  accessKey: fileadmin #访问的key
  secretKey: fileadmin #访问的秘钥

编写工具类

package top.fairy.global.globalfairytoppi4j.utils;

import io.minio.*;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import top.fairy.global.globalfairytoppi4j.beans.ResultEntity;
import top.fairy.global.globalfairytoppi4j.config.MinioClientConfig;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;


@Slf4j
@Component
public class MinioUtil {

    /**
     * Minio文件上传
     *
     * @param file       文件实体
     * @param fileName   修饰过的文件名 非源文件名
     * @param bucketName 所存文件夹(桶名)
     * @return
     */
    public ResultEntity<Map<String, Object>> minioUpload(MultipartFile file, String fileName, String bucketName) {
        ResultEntity<Map<String, Object>> resultEntity = new ResultEntity();
        try {
            MinioClient minioClient = MinioClientConfig.getMinioClient();
            // fileName为空,说明要使用源文件名上传
            if (fileName == null) {
                fileName = file.getOriginalFilename();
                fileName = fileName.replaceAll(" ", "_");
            }
            InputStream inputStream = file.getInputStream();
            PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName)
                    .stream(inputStream, file.getSize(), -1).contentType(file.getContentType()).build();
            //文件名称相同会覆盖
            minioClient.putObject(objectArgs);
            return resultEntity;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 检查存储桶是否存在
     *
     * @param bucketName 存储桶名称
     * @return
     */
    public boolean bucketExists(String bucketName) {
        boolean flag = false;
        try {
            flag = MinioClientConfig.bucketExists(bucketName);
            if (flag) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    /**
     * 获取文件流
     *
     * @param fileName   文件名
     * @param bucketName 桶名(文件夹)
     * @return
     */
    public InputStream getFileInputStream(String fileName, String bucketName) {
        try {
            MinioClient minioClient = MinioClientConfig.getMinioClient();
            return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(fileName).build());
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return null;
    }


    /**
     * @param bucketName:
     * @author
     * @description: 创建桶
     * @date 2022/8/16 14:36
     */
    public void createBucketName(String bucketName) {
        try {
            if (StringUtils.isBlank(bucketName)) {
                return;
            }
            MinioClient minioClient = MinioClientConfig.getMinioClient();
            boolean isExist = MinioClientConfig.bucketExists(bucketName);
            if (isExist) {
                log.info("Bucket {} already exists.", bucketName);
            } else {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
    }

    /**
     * 下载文件
     *
     * @param originalName 文件路径
     */
    public InputStream downloadFile(String bucketName, String originalName, HttpServletResponse response) {
        try {
            MinioClient minioClient = MinioClientConfig.getMinioClient();
            InputStream file = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(originalName).build());
            String filename = new String(originalName.getBytes("ISO8859-1"), StandardCharsets.UTF_8);
            if (StringUtils.isNotBlank(originalName)) {
                filename = originalName;
            }
            response.setHeader("Content-Disposition", "attachment;filename=" + filename);
            ServletOutputStream servletOutputStream = response.getOutputStream();
            int len;
            byte[] buffer = new byte[1024];
            while ((len = file.read(buffer)) > 0) {
                servletOutputStream.write(buffer, 0, len);
            }
            servletOutputStream.flush();
            file.close();
            servletOutputStream.close();
            return file;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @param bucketName:
     * @description: 删除桶
     * @date 2022/8/16 14:36
     */
    public void deleteBucketName(String bucketName) {
        try {
            if (StringUtils.isBlank(bucketName)) {
                return;
            }
            MinioClient minioClient = MinioClientConfig.getMinioClient();
            boolean isExist = MinioClientConfig.bucketExists(bucketName);
            if (isExist) {
                minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
    }

    /**
     * @param bucketName:
     * @description: 删除桶下面所有文件
     * @date 2022/8/16 14:36
     */
    public void deleteBucketFile(String bucketName) {
        try {
            if (StringUtils.isBlank(bucketName)) {
                return;
            }
            MinioClient minioClient = MinioClientConfig.getMinioClient();
            boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (isExist) {
                minioClient.deleteBucketEncryption(DeleteBucketEncryptionArgs.builder().bucket(bucketName).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
    }

    /**
     * 根据文件路径得到预览文件绝对地址
     *
     * @param bucketName
     * @param fileName
     * @return
     */
    public String getPreviewFileUrl(String bucketName, String fileName) {
        try {
            MinioClient minioClient = MinioClientConfig.getMinioClient();
            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucketName).object(fileName).build());
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}

编写配置文件

package top.fairy.global.globalfairytoppi4j.config;

import io.minio.BucketExistsArgs;
import io.minio.MinioClient;
import io.minio.messages.Bucket;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;


@Slf4j
@Component
@Configuration
public class MinioClientConfig {

    @Autowired
    private StorageProperty storageProperty;

    private static MinioClient minioClient;


    /**
     * @description: 获取minioClient
     * @date 2021/6/22 16:55
     * @return io.minio.MinioClient
     */
    public static MinioClient getMinioClient(){
        return minioClient;
    }

    /**
     * 判断 bucket是否存在
     *
     * @param bucketName:
     *            桶名
     * @return: boolean
     * @date : 2020/8/16 20:53
     */
    @SneakyThrows(Exception.class)
    public static boolean bucketExists(String bucketName) {
        return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
    }


    /**
     * 获取全部bucket
     *
     * @param :
     * @return: java.util.List<io.minio.messages.Bucket>
     * @date : 2020/8/16 23:28
     */
    @SneakyThrows(Exception.class)
    public static List<Bucket> getAllBuckets() {
        return minioClient.listBuckets();
    }

    /**
     * 初始化minio配置
     *
     * @param :
     * @return: void
     * @date : 2020/8/16 20:56
     */
    @PostConstruct
    public void init() {
        try {
            minioClient = MinioClient.builder()
                    .endpoint(storageProperty.getEndpoint())
                    .credentials(storageProperty.getAccessKey(), storageProperty.getSecretKey())
                    .build();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("初始化minio配置异常: 【{}】", e.fillInStackTrace());
        }
    }

}

编写业务类

package top.fairy.global.globalfairytoppi4j.action;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.fairy.global.globalfairytoppi4j.api.CommonResult;
import top.fairy.global.globalfairytoppi4j.beans.BucketPolicyConfigDto;
import top.fairy.global.globalfairytoppi4j.beans.FileVo;
import top.fairy.global.globalfairytoppi4j.beans.MinioUploadDto;
import top.fairy.global.globalfairytoppi4j.beans.PageUtil;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * MinIO对象存储管理
 * Created by macro on 2019/12/25.
 */
//@Api(tags = "MinioController", description = "MinIO对象存储管理")
@Controller
@RequestMapping("/minio")
public class MinioController {

    private static final Logger LOGGER = LoggerFactory.getLogger(MinioController.class);
    @Value("${minio.endpoint}")
    private String ENDPOINT;
    @Value("${minio.bucketName}")
    private String BUCKET_NAME;
    @Value("${minio.bucketImg}")
    private String BUCKET_IMG;
    @Value("${minio.bucketVideo}")
    private String BUCKET_VIDEO;
    @Value("${minio.accessKey}")
    private String ACCESS_KEY;
    @Value("${minio.secretKey}")
    private String SECRET_KEY;

//    @ApiOperation("文件上传")
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult upload(@RequestPart("file") MultipartFile file) {
        try {
            //创建一个MinIO的Java客户端
            MinioClient minioClient =MinioClient.builder()
                    .endpoint(ENDPOINT)
                    .credentials(ACCESS_KEY,SECRET_KEY)
                    .build();
            boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(BUCKET_NAME).build());
            if (isExist) {
                LOGGER.info("存储桶已经存在!");
            } else {
                //创建存储桶并设置只读权限
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(BUCKET_NAME).build());
                BucketPolicyConfigDto bucketPolicyConfigDto = createBucketPolicyConfigDto(BUCKET_NAME);
                SetBucketPolicyArgs setBucketPolicyArgs = SetBucketPolicyArgs.builder()
                        .bucket(BUCKET_NAME)
                        .config(JSONUtil.toJsonStr(bucketPolicyConfigDto))
                        .build();
                minioClient.setBucketPolicy(setBucketPolicyArgs);
            }
            String filename = file.getOriginalFilename();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            // 设置存储对象名称
            String objectName = sdf.format(new Date()) + "/" + filename;
            // 使用putObject上传一个文件到存储桶中
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(BUCKET_NAME)
                    .object(objectName)
                    .contentType(file.getContentType())
                    .stream(file.getInputStream(), file.getSize(), ObjectWriteArgs.MIN_MULTIPART_SIZE).build();
            minioClient.putObject(putObjectArgs);
            LOGGER.info("文件上传成功!");
            MinioUploadDto minioUploadDto = new MinioUploadDto();
            minioUploadDto.setName(filename);
            minioUploadDto.setUrl(ENDPOINT + "/" + BUCKET_NAME + "/" + objectName);
            return CommonResult.success(minioUploadDto);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.info("上传发生错误: {}!", e.getMessage());
        }
        return CommonResult.failed();
    }

    private BucketPolicyConfigDto createBucketPolicyConfigDto(String bucketName) {
        BucketPolicyConfigDto.Statement statement = BucketPolicyConfigDto.Statement.builder()
                .Effect("Allow")
                .Principal("*")
                .Action("s3:GetObject")
                .Resource("arn:aws:s3:::"+bucketName+"/*.**").build();
        return BucketPolicyConfigDto.builder()
                .Version("2012-10-17")
                .Statement(CollUtil.toList(statement))
                .build();
    }

    /**
     * 获取文件列表
     *
     * @param pageNum  页码
     * @param pageSize 一页的数量
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "/fileList", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    public String getFileList(Integer pageNum, Integer pageSize) throws Exception {
        String bucketName = "img";
        //创建一个MinIO的Java客户端
        MinioClient minioClient =MinioClient.builder()
                .endpoint(ENDPOINT)
                .credentials(ACCESS_KEY,SECRET_KEY)
                .build();
        DecimalFormat df = new DecimalFormat("0.00");
        List<Bucket> buckets = minioClient.listBuckets();
        List<FileVo> list = new ArrayList<>(32);
        if (!buckets.isEmpty()) {
            buckets.forEach(s -> {
                try {
                    // 得到bucket下的文件
                    Iterable<Result<Item>> results = minioClient.listObjects(s.name());

                    // 循环遍历获取每一个文件对象

                    results.forEach(g -> {
                        try {
                            FileVo fileVo = new FileVo();
                            fileVo.setBucketName(s.name());  // 文件夹名称
                            fileVo.setFileName(g.get().objectName());  // 文件名称
                            fileVo.setUpdateTime(localDateTime2Date(g.get().lastModified().toLocalDateTime()));  // 文件上传时间
                            Long size = g.get().size();
                            if (size > (1024 * 1024)) {
                                fileVo.setFileSize(df.format(((double) size / 1024 / 1024)) + "MB");  // 文件大小,如果超过1M,则把单位换成MB
                            } else if (size > 1024) {
                                fileVo.setFileSize(df.format(((double) size / 1024)) + "KB"); // 文件大小,如果没超过1M但是超过1000字节,则把单位换成KB
                            } else {
                                fileVo.setFileSize( size + "bytes");  // // 文件大小,如果没超过1000字节,则把单位换成bytes
                            }
                            list.add(fileVo);
                        } catch (ErrorResponseException e) {
                            e.printStackTrace();
                        } catch (InsufficientDataException e) {
                            e.printStackTrace();
                        } catch (InternalException e) {
                            e.printStackTrace();
                        } catch (InvalidBucketNameException e) {
                            e.printStackTrace();
                        } catch (InvalidKeyException e) {
                            e.printStackTrace();
                        } catch (InvalidResponseException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (NoSuchAlgorithmException e) {
                            e.printStackTrace();
                        } catch (XmlParserException e) {
                            e.printStackTrace();
                        } catch (ServerException e) {
                            e.printStackTrace();
                        }
                    });
                } catch (XmlParserException e) {
                    e.printStackTrace();
                }
            });
        }
        JSONObject res = new JSONObject();
        res.put("code", 200);
        res.put("message", "获取文件列表成功");
        // 按最后上传时间排序
        list.sort(new Comparator<FileVo>() {
            @Override
            public int compare(FileVo o1, FileVo o2) {
                return o2.getUpdateTime().compareTo(o1.getUpdateTime());
            }
        });
        // 分页
        List returnList = PageUtil.startPage(list, pageNum, pageSize);
        res.put("list", returnList);
        ObjectMapper mapper = new ObjectMapper();
        String s = mapper.writeValueAsString(res);
        return s;
    }

    private Date localDateTime2Date(LocalDateTime toLocalDateTime) {
        Date date = Date.from( toLocalDateTime.atZone( ZoneId.systemDefault()).toInstant());
        return date;
    }

    //    @ApiOperation("文件删除")文件删除
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult delete(@RequestParam("objectName") String objectName) {
        try {
            MinioClient minioClient = MinioClient.builder()
                    .endpoint(ENDPOINT)
                    .credentials(ACCESS_KEY,SECRET_KEY)
                    .build();
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(BUCKET_NAME).object(objectName).build());
            return CommonResult.success(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return CommonResult.failed();
    }
}

业务类service,dao入库等操作请自行补充。

源码下载地址:

global-fairy-top-pi4j: java语言读取dth11温湿度传感器参数,通过接口对外提供

具体版本参考:v0.3.1

  1. 打包部署

  Idea中maven package项目之后,拷贝jar包到云服务器

  1. 启动

  nohup java -jar global-fairy-top-pi4j-0.0.1-SNAPSHOT.jar &

  1. 测试:

  localhost:8082/minio/fileList

  • 注意事项
  1. 常见问题

 部署demo前请先安装mysql,并配置好地址。

    

相关文章:

华为云云耀云服务器L实例评测|基于云服务器的minio部署手册

华为云云耀云服务器L实例评测|基于云服务器的minio部署手册 【软件安装版本】【集群安装&#xff08;是&#xff09;&#xff08;否&#xff09;】 版本 创建人 修改人 创建时间 备注 1.0 jz jz 2023.9.2 minio华为云耀服务器 一. 部署规划与架…...

龙智携手Atlassian和JFrog举办线下研讨会,探讨如何提升企业级开发效率与质量

2023年9月8日&#xff0c;龙智将携手Atlassian和JFrog于上海举办线下研讨会&#xff0c;以“大规模开发创新&#xff1a;如何提升企业级开发效率与质量”为主题&#xff0c;邀请龙智高级咨询顾问、Atlassian认证专家叶燕秀&#xff0c;紫龙游戏上海研发中心高级项目管理主管叶凯…...

2023数学建模国赛A题定日镜场的优化设计- 全新思路及代码

背景资料关键信息和要点如下&#xff1a; 定日镜&#xff1a;塔式太阳能光热发电站的基本组件&#xff0c;由纵向转轴和水平转轴组成&#xff0c;用于反射太阳光。 定日镜场&#xff1a;由大量的定日镜组成的阵列。 集热器&#xff1a;位于吸收塔顶端&#xff0c;用于收集太…...

CSS笔记(黑马程序员pink老师前端)圆角边框

圆角边框 border-radius:length; 效果显示 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Documen…...

水表电表集中远程抄表系统分析

电表水表远程抄表系统石家庄光大远通电气有限公司主要经营自动抄表,远程抄表,集中抄表,新供应信息&#xff0c;是石家庄光大远通电气有限公司自动远程抄表系统集信号采集、网络通信于一体的高性能抄表装置&#xff0c;该系统以485通讯方式读取水表电表的数据,以MBUS通讯方式读取…...

Android 通知

1. 原生Android通知的几种显示方式&#xff1a; 状态栏的图标&#xff1a;发出通知后&#xff0c;通知会先以图标的形式显示在状态栏中。 抽屉式通知栏&#xff1a;用户可以在状态栏向下滑动以打开抽屉式通知栏&#xff0c;并在其中查看更多详情及对通知执行操作。在应用或用户…...

【Unittest】Requests实现小程序项目接口测试

文章目录 一、搭建接口测试框架二、初始化日志三、定义全局变量四、封装接口五、编写测试用例六、生成测试报告 一、搭建接口测试框架 目录结构如下。 二、初始化日志 在utils.py文件中编写如下如下代码&#xff0c;初始化日志。 # 导入app.py全局变量文件 import app import l…...

Mac 搭建本地服务器

文章目录 一、启动服务器二、添加文件到本地服务三、手机/其他电脑 访问本机服务器 MacOS 自带Apatch 服务器。所以我这里选择Apatch服务器搭建 一、启动服务器 在safari中输入 http://127.0.0.1/ &#xff0c;如果页面出现 it works&#xff0c;则代表访问成功。启动服务器 …...

区块链基础之编写合约二

一、了解solidity中的关键字。 二、了解solidity中的类型。 三、编写合约 1.这里列出一些solidity中的关键字&#xff0c;有哪些。 pragma 作用&#xff1a;是告知编译器如何处理源代码的通用指令&#xff08;例如&#xff0c; pragma once &#xff09;。public 作用&#…...

【前端基础】js 如何判断一个值是数组

在JavaScript中&#xff0c;可使用不同的方法来判断一个值是否是一个数组。以下是一些常用的方法&#xff1a; 使用 Array.isArray() 方法&#xff1a; if (Array.isArray(value)) {// 值是一个数组 } else {// 值不是一个数组 }Array.isArray() 方法是最简单和推荐的方法&…...

Linux之NFS服务器

目录 Linux之NFS服务器 简介 NFS背景介绍 生产应用场景 NFS工作原理 NFS工作流程图 流程 NFS的安装 安装nfs服务 安装rpc服务 启动rpcbind服务同时设置开机自启动 启动nfs服务同时设置开机自启动 NFS的配置文件 主配置文件分析 示例 案例 --- 建立NFS服务器&#…...

ES delete_by_query条件删除的几种方式

es 查询删除的几种方式 1.根据id删除 #根据id删除 POST /indexname/_delete_by_query {"query": { "match": {"id": "100000"}} } 2.根据多个id删除 #根据多个id删除 POST /indexname/_delete_by_query {"query": {"…...

1.springboot 集成elasticsearch组件

1.前置条件已经安装和搭建好了elasticsearch中间件 一&#xff1a;项目中引入elasticsearch相关依赖 我安装的elasticsearch版本是7.10.2 对应依赖的版本保持一致 此处省略springboot 搭建及必要的依赖项 <dependency><groupId>org.elasticsearch.client</group…...

【学习笔记】元学习如何解决计算机视觉少样本学习的问题?

目录 1 计算机视觉少样本学习 2 元学习 3 寻找最优初始参数值方法&#xff1a;MAML 3.1 算法步骤 3.2 代码&#xff1a;使用MAML 和 FO-MAML、任务增强完成Few-shot Classification 4 距离度量方法&#xff1a;Siamese Network,ProtoNet,RN 4.1 孪生网络&#xff08;Sia…...

【C语言】17-函数-3

1. 链接属性 当组成一个程序的各个源文件分别被编译之后,所有的目标文件以及那些从一个或多个函数库中引用的函数将链接在一起,形成可执行程序。然而,如果相同的标识符出现在几个不同的源文件中时,它们是表示同一个实体,还是表示不同的实体?标识符的链接属性决定如何处理…...

人工智能:为你提供的未来工作岗位

随着科技的快速发展&#xff0c;人工智能(Artificial Intelligence,AI)正逐渐渗透到各个领域。本文探讨一下人工智能可以提供的工作岗位&#xff0c;以期帮助大家更好地了解这个新兴行业的就业前景。 文章目录 1 机器学习工程师2 数据科学家3 自然语言处理工程师4 机器视觉工程…...

HashMap、LinkedHashMap、ConcurrentHashMap、ArrayList、LinkedList的底层实现。

HashMap、LinkedHashMap、ConcurrentHashMap、ArrayList、LinkedList的底层实现。 HashMap相关问题 1、你用过HashMap吗&#xff1f;什么是HashMap&#xff1f;你为什么用到它&#xff1f;用过&#xff0c;HashMap是基于哈希表的Map接口的非同步实现&#xff0c; 它允许null键…...

flink学习之广播流与合流操作demo

广播流是什么&#xff1f; 将一条数据广播到所有的节点。使用 dataStream.broadCast() 广播流使用场景&#xff1f; 一般用于动态加载配置项。比如lol&#xff0c;每天不断有人再投诉举报&#xff0c;客服根本忙不过来&#xff0c;腾讯内部做了一个判断&#xff0c;只有vip3…...

PPT架构师架构技能图

PPT架构师架构技能图 目录概述需求&#xff1a; 设计思路实现思路分析1.软素质2.核心输出&#xff08;office输出&#xff09; 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,ma…...

STM32微控制器的低功耗模式

STM32微控制器的低功耗模式(Low-power modes):Sleep mode、Stop mode 和 Standby mode。 1.1 Sleep Mode(睡眠模式): 把STM32微控制器当作一位劳累的工人,他在工作过程中需要短暂的休息。在Sleep模式下,微控制器会关闭一部分电路,减小功耗,但仍然保持对中央处理单…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文通过代码驱动的方式&#xff0c;系统讲解PyTorch核心概念和实战技巧&#xff0c;涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙

WebGL&#xff1a;在浏览器中解锁3D世界的魔法钥匙 引言&#xff1a;网页的边界正在消失 在数字化浪潮的推动下&#xff0c;网页早已不再是静态信息的展示窗口。如今&#xff0c;我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室&#xff0c;甚至沉浸式的V…...

Java数组Arrays操作全攻略

Arrays类的概述 Java中的Arrays类位于java.util包中&#xff0c;提供了一系列静态方法用于操作数组&#xff08;如排序、搜索、填充、比较等&#xff09;。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序&#xff08;sort&#xff09; 对数组进行升序…...