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

news2024/11/27 13:51:51

华为云云服务器评测|基于云服务器的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,并配置好地址。

    

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

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

相关文章

降低LLM的幻觉风险:实用策略与技术

一、前言 近年来&#xff0c;大语言模型的快速发展为构建更智能和更人性化的AI系统提供了很多可能性。像GPT-3.5、GPT-4、Bard、Claude 2和LLaMa 2等大语言模型 (LLM) 在个人助理或聊天机器人应用领域展示了强大的潜力&#xff0c;可以生成流畅而令人惊叹的响应来回答用户的问…

新学期第一篇博客

文章目录 一、加入QQ群&#xff08;一&#xff09;QQ群号&#xff08;二&#xff09;加群要求 二、加入云班课三、使用思维导图&#xff08;一&#xff09;下载XMind软件&#xff08;二&#xff09;安装XMind软件&#xff08;三&#xff09;创建思维导图1、选择模板&#xff08…

【C++】拷贝对象时,编译器的偷偷优化

你知道吗&#xff1f;对于连续的”构造拷贝构造“&#xff0c;编译器其实是会默默做出优化的。&#x1f47b; 如果你不知道这个知识点的话&#xff0c;那下面这道笔试题就要失分了&#x1f635;。 本篇分享一个关于编译器优化的小知识&#xff0c;看完本篇&#xff0c;你就能…

阿里云服务器退款规则_退款政策全解析

阿里云退款政策全解析&#xff0c;阿里云退款分为五天无理由全额退和非全额退订两种&#xff0c;阿里云百科以云服务器为例&#xff0c;阿里云服务器包年包月支持五天无理由全额退订&#xff0c;可申请无理由全额退款&#xff0c;如果是按量付费的云服务器直接释放资源即可。阿…

C++ Primer Plus 第六章笔记

目录 if 语句 if else语句 if else if else结构 逻辑运算符--&&,||和! cctype字符函数库 条件运算符&#xff08;三目运算符) switch语句 continue和break语句 基本文件输入/输出 总结&#xff1a;本文主要介绍了分支语句和if判断语句&#xff0c;运算符和简…

vue 浏览器记住密码后,自动填充账号密码错位

亲测有效&#xff01;&#xff01;! 遇到的场景&#xff1a; 浏览器记住密码后&#xff0c;登录时自动填充账号密码&#xff0c;由于登录时只需要这两个字段所以没问题&#xff0c;见图一&#xff0c;但注册时&#xff0c;账号密码不在一处&#xff0c;见图二 原本账号应该在…

浅谈JVM内存模型与GC垃圾回收

目录 1. 摘要 2. JVM 简单介绍 3. 线程私有的有哪些&#xff1f; 4. 线程共享的有哪些&#xff1f; 5. JVM 栈中程序是如何操作数据的&#xff1f; 6. 内存泄露是什么意思&#xff1f; 7. 堆内存的分配规则 8. 垃圾回收算法 8.1 垃圾回收机制简单概括 8.2 标记清理算法…

UNIAPP之js/nvue混淆探索

因项目需要对UNIAPP的js混淆做了一些调研 混淆教程: https://uniapp.dcloud.net.cn/tutorial/app-sec-confusion.html 按照教程配置进行打包正式包进行混淆 下载正式包将 .ipa改为.zip 解压获取到HBuilder.app 右键显示包内容 获取到混淆的key 不同时间进行打包混淆同一文…

谷器数据被认证为全国信标委软工分委会全权成员单位

8月23日&#xff0c;全国信息技术标准化技术委员会软件与系统工程分技术委员会&#xff08;简称&#xff1a;全国信标委软工分委会&#xff0c;SAC/TC28/SC7&#xff09;批准通过新一批成员单位&#xff0c;北京谷器数据科技有限公司被成功授牌为全权成员单位。 全国信标委软件…

高校消防安全存在的问题与解决方案介绍 安科瑞 许敏

摘要 &#xff1a;本文分析了当前高校消防安全存在的问题&#xff0c;现有消防系统突出问题表现形式&#xff0c;提出高校智慧消防安全预警防控体系构建&#xff0c;并对智慧消防安全预警平台主要功能进行了简介&#xff0c;对高校智慧消防安全预警系统功能设计具有一定的指导意…

0基础学习VR全景平台篇 第96篇:VR电子楼书

大家好&#xff0c;欢迎观看蛙色VR官方系列课程——VR电子楼书&#xff01; 作为2021年底全新上线的行业解决方案&#xff0c;是专门针对地产、园区数字化营销的一站式VR解决方案&#xff0c;为行业潜在客户提供优质的7x24小时线上看房体验。 本期教程将通过功能介绍后台操作&…

koa2快速2分钟搭建web服务器

koa简介&#xff1a; Koa是一个基于Node的web服务web服务器开发框架。类似于Express。 Koa1它的主要特点是&#xff0c;使用了ES6的Generator函数。 koa2依赖Node.js 7.6.0或者更高版本。 koa不在内核方法中绑定任何中间件&#xff0c;它仅仅是一个轻量级的函数库&#xff0c;几…

【QT】QMessageBox消息框的使用(16)

在实际项目中&#xff0c;弹出消息框是一个很常见的操作&#xff0c;包含错误信息提示、警告信息提示、关于信息提示、还包括判断信息选择等操作&#xff0c;那么今天通过这一节来好好了解下消息框的使用方法。 一.环境配置 1.python 3.7.8 可直接进入官网下载安装&#xf…

图:关键路径

1. AOE网 与AOV网不同&#xff0c;AOE是用边表示活动的图或者网。 1.AOE网的概念 在带权有向图中&#xff0c;以顶点表示事件&#xff0c;以有向边表示活动&#xff0c; 以边上的权值表示完成该活动的开销(如完成活动所需的时间)&#xff0c; 称之为用边表示活动的网络&…

如何尽快了解企业文化并融入团队

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ 每个公司都有自己独特的企业文化&#xff0c;企业文化分为两个部分&#xff0c;一个部分是对外的企业文化&#xff0c;一个部分是企业内部的文化。对外的是公司的形象&…

并行计算之计算平台体系结构(流水线,异构处理器与异构并行)

并行计算粒度 分布式并行(多主机&#xff0c;多进程) &#xff1a; MPI 共享存储式并行 (多线程) &#xff1a;OpenMP OpenCL OpenACC 指令级并行 CPU流水线 CPU流水线 指将一条指令的执行过程划分为多个阶段&#xff0c;使得在每个时钟周期内能够并行执行多条指令&#…

前端开源代码

vue大屏&#xff1a; PublicbigScreenPage–Vue3tsWindcssEchartThree.js大屏案例 PublicbigScreenPage—基于 Vue3、TypeScript、DataV、ECharts 框架的 " 数据大屏项目 介绍&#xff1a;https://blog.csdn.net/qq_40282732/article/details/105656848 Vue3.2 Echar…

AutoDock Vina 对接计算(大批量)

AutoDock Vina 1.2.0 对接计算&#xff08;大批量&#xff09; AutoDockVina 1.2.0 的示例应用&#xff1a;A) 对接多个配体 (PDB 5x72)&#xff1b;B) 使用 AutoDock4 (PDB 4ykq) 的水合对接方案与水分子对接&#xff1b;C)在锌存在的情况下使用 AutoDock4Zn 力场 (PDB 1s63)&…

ChatGLM2 源码解析:`ChatGLMModel`

# 完整的 GLM 模型&#xff0c;包括嵌入层、编码器、输出层 class ChatGLMModel(ChatGLMPreTrainedModel):def __init__(self, config: ChatGLMConfig, deviceNone, empty_initTrue):super().__init__(config)# 如果设置了empty_init&#xff0c;创建任何 PyTorch 模块时&#…

【软件测试】单元测试、集成测试、系统测试有什么区别?

单元测试、集成测试、系统测试有什么区别 1、粒度不同 集成测试bai粒度居中&#xff0c;单元测试粒度最小&#xff0c;系统du测试粒度最大。 2、测试方式不同 集成测试一般由开发zhi小组采用白盒加黑盒的方式来测试&#xff0c;单元测试一般由开发小组采用白盒方式来测试&a…