MinIO快速入门

news/2024/4/20 17:40:50/文章来源:https://blog.csdn.net/qq_46921028/article/details/130279107

一、MinIO概述


官网地址:http://www.minio.org.cn/

文档地址:http://docs.minio.org.cn/docs/

MinIO是一款基于Apache License v2.0开源协议的分布式文件系统(或者叫对象存储服务),可以做为云存储的解决方案用来保存海量的图片、视频、文档等。由于采用Golang实现,服务端可以工作在Windows、Linux、 OS X和FreeBSD上。配置简单,基本是复制可执行程序,单行命令就可以运行起来。

MinIO兼容亚马逊S3(Simple Storage Service,简单存储服务)云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而且每个对象文件可以是任意大小,从几kb到最大5T不等。
在这里插入图片描述


MinIO特点:

  1. 高性能:作为高性能对象存储,在标准硬件条件下它能达到55GB/s的读、35GB/s的写速率;
  2. 可扩容:不同MinIO集群可以组成联邦,并形成一个全局的命名空间,并跨越多个数据中心;
  3. SDK支持: 基于Minio轻量的特点,它得到类似Java、Python或Go等语言的sdk支持;
  4. 支持纠删码:MinIO使用纠删码、Checksum来防止硬件错误和静默数据污染。在最高冗余度配置下,即使丢失1/2的磁盘也能恢复数据;

MinIO基本概念:

  • bucket(桶) :类似文件系统的目录(文件夹);
  • Object : 类似文件系统的文件;
  • Keys :类似文件名;
  • MINIO_ACCESS_KEY:访问key,类似账号;
  • MINIO_SECRET_KEY:秘钥,类似密码。

文件存储方式对比:

存储方式优点缺点
服务器磁盘开发便捷,成本低扩展困难
分布式文件系统(开源:FastDFS、MinIO)容易实现扩展复杂度高
第三方存储(阿里云OSS、七牛云)开发简单,功能强大,免维护收费

分布式文件系统对比:

  • FastDFS是阿里余庆做的个人项目,也是一款开源高性能的分布式文件系统,适合小规模文件数据存储,默认不提供UI界面,安装部署(运维)复杂,很难达到以G为单位的每秒读写速度,没有完备的官方文档,环境搭建较为复杂;
  • MinIO是由MinIO.Inc运营的开源项目,号称世界上速度最快的对象存储服务器,并且社区活跃度高,标准硬件条件下它能达到55GB/s的读、35GB/s的写速率,而且MinIO部署自带管理界面,不需要额外安装;MinIO提供了所有主流开发语言的SDK,并且兼容亚马逊S3云存储服务接口,在MinIO中一个对象文件可以是任意大小,从几KB到最大的5T不等;最后它提供了与k8s、etcd、docker等容器技术深度集成方案,可以说就是为云原生而生的。(缺点,不支持动态增加节点)
  • 更详细文章参考:https://www.cnblogs.com/loveer/p/16857625.html

二、MinIO环境搭建


本文基于Docker实现MinIO环境快速部署,Docker安装参考:https://blog.csdn.net/qq_46921028/article/details/129096134

1、拉取镜像(https://hub.docker.com/r/minio/minio/tags)

# 下载新版minio
docker pull minio/minio# 或者下载指定版本的minio
docker pull minio/minio:RELEASE.2021-04-06T23-11-00Z  

2、创建容器

docker run -p 9000:9000 --name minio -d --restart=always -e "MINIO_ACCESS_KEY=minio" -e "MINIO_SECRET_KEY=minio123" -v /docker/minio/data:/data -v /docker/minio/config:/root/.minio minio/minio server /data# 或者指定镜像版本并创建容器
docker run -p 9000:9000 --name minio -d --restart=always -e "MINIO_ACCESS_KEY=minio" -e "MINIO_SECRET_KEY=minio123" -v /docker/minio/data:/data -v /docker/minio/config:/root/.minio minio/minio:RELEASE.2021-04-06T23-11-00Z server /data
  • -p 9000:9000 ,端口映射
  • -e,环境变量
  • -d,后台运行
  • –name,给容器起名字
  • –restart=always,开机自启
  • -e “MINIO_ACCESS_KEY=minio”,设置账号
  • -e “MINIO_SECRET_KEY=minio123”,设置密码
  • -v 挂载数据卷

在这里插入图片描述


3、测试访问MinIO后台系统,直接浏览器访问 http://ip:9000 即可,账号minio,密码minio123

在这里插入图片描述

管理界面:

在这里插入图片描述


4、创建 bucket(桶)

首先点击右下角的"+"号,创建一个桶

在这里插入图片描述

给创建的桶起个名字:

在这里插入图片描述

最后在minio管理界面就能看到刚刚创建的桶结构:

在这里插入图片描述


三、快速入门


基于SpringBoot快速整合MinIO

1、创建springboot工程

2、导入相关依赖

<dependencies><!--minio--><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>7.1.0</version></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--test--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><!--knife4j(swagger) --><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.2</version></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
</dependencies>

3、整合swagger

3.1、编写Swagger配置类

package com.baidou.config;import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;/*** Swagger2配置类(生成接口文档)** @author 白豆五* @version 2023/04/21* @since JDK8*/
@Configuration
@EnableSwagger2 //开启swagger2注解支持
@EnableKnife4j  //开启Knife4j注解支持
public class SwaggerConfig {@Beanpublic Docket webApiConfig() { //生成接口文档的清单// 文档类型return new Docket(DocumentationType.SWAGGER_2).groupName("webApi").apiInfo(webApiInfo()).select()//指定controller包扫描路径.apis(RequestHandlerSelectors.basePackage("com.baidou.controller")).paths(PathSelectors.any()).build();}//配置在线api文档信息private ApiInfo webApiInfo() {return new ApiInfoBuilder().title("网站-API文档").description("本文档描述了xxx管理系统微服务接口定义").version("1.0").contact(new Contact("白豆五", "https://blog.csdn.net/qq_46921028", "13212341234@163.com")).build();}
}

3.2、设置静态资源映射(对Swagger的静态资源放行)

package com.baidou.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;// 对WebMvc进行一些配置,为swagger静态资源进行放行
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {// 静态资源放行@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/web/**").addResourceLocations("classpath:/web/");// 对swaggger静态资源放行registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");}
}

4、编写 MinIO属性配置类

package com.baidou.dto;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;import java.io.Serializable;@Data
@Component
@ConfigurationProperties(prefix = "minio")  //自动注入属性前缀为minio的配置
public class MinIOConfigProperties implements Serializable {private String accessKey; // 访问keyprivate String secretKey; // 秘钥private String bucket;    // 桶private String endpoint;  // 地域节点private String readPath;  // 读取路径
}

5、编写MinIO配置类,注册MinioClient客户端的Bean对象

package com.baidou.config;import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** MinIO配置类** @author 白豆五* @version 2023/04/21* @since JDK8*/
@Configuration
public class MinIOConfig {@Autowiredprivate MinIOConfigProperties minIOConfigProperties;// 注册MinIO实例@Beanpublic MinioClient buildMinioClient(){return MinioClient.builder().credentials(minIOConfigProperties.getAccessKey(), minIOConfigProperties.getSecretKey()).endpoint(minIOConfigProperties.getEndpoint()).build();}
}

6、在application.yml文件中配置minio自定义属性和文件上传大小

minio:accessKey: miniosecretKey: minio123bucket: testminioendpoint: http://192.168.200.128:9000readPath: http://192.168.200.128:9000servlet:multipart:# 单个上传文件的最大值是200mbmax-file-size: 200MB# 单次请求的最大值max-request-size: 200MB

在这里插入图片描述


7、编写操作minio相关业务接口

package com.baidou.service;import java.io.InputStream;/*** 操作minio相关业务接口** @author 白豆五* @version 2023/04/21* @since JDK8*/
public interface FileStorageService {/*** 上传图片文件** @param prefix      文件前缀* @param filename    文件名* @param inputStream 文件流* @return 文件全路径*/public String uploadImgFile(String prefix, String filename, InputStream inputStream);/*** 上传html文件** @param prefix      文件前缀* @param filename    文件名* @param inputStream 文件流* @return 文件全路径*/public String uploadHtmlFile(String prefix, String filename, InputStream inputStream);/*** 删除文件** @param pathUrl 文件全路径*/public void delete(String pathUrl);/*** 下载文件** @param pathUrl 文件全路径* @return*/public byte[] downLoadFile(String pathUrl);}

业务接口实现类:

package com.baidou.service.impl;import com.baidou.config.MinIOConfigProperties;
import com.baidou.service.FileStorageService;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;@Slf4j
@Service
public class MinIOFileStorageService implements FileStorageService {@Autowiredprivate MinioClient minioClient;@Autowiredprivate MinIOConfigProperties minIOConfigProperties;private final static String separator = "/"; //文件夹分隔符/*** 构建文件的绝对路径** @param dirPath  文件路径* @param filename 文件名  yyyy/mm/dd/file.jpg* @return /test*/public String builderFilePath(String dirPath, String filename) {StringBuilder stringBuilder = new StringBuilder(50);if (!StringUtils.isEmpty(dirPath)) {stringBuilder.append(dirPath).append(separator);}SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");String todayStr = sdf.format(new Date());stringBuilder.append(todayStr).append(separator);stringBuilder.append(filename);return stringBuilder.toString();}/*** 上传图片文件** @param prefix      文件前缀* @param filename    文件名* @param inputStream 文件流* @return 文件全路径*/@Overridepublic String uploadImgFile(String prefix, String filename, InputStream inputStream) {String filePath = builderFilePath(prefix, filename);try {PutObjectArgs putObjectArgs = PutObjectArgs.builder().object(filePath).contentType("image/jpg").bucket(minIOConfigProperties.getBucket()).stream(inputStream, inputStream.available(), -1).build();minioClient.putObject(putObjectArgs);StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());urlPath.append(separator + minIOConfigProperties.getBucket());urlPath.append(separator);urlPath.append(filePath);return urlPath.toString();} catch (Exception ex) {log.error("minio put file error.", ex);throw new RuntimeException("上传文件失败");}}/*** 上传html文件** @param prefix      文件前缀* @param filename    文件名* @param inputStream 文件流* @return 文件全路径*/@Overridepublic String uploadHtmlFile(String prefix, String filename, InputStream inputStream) {String filePath = builderFilePath(prefix, filename);try {PutObjectArgs putObjectArgs = PutObjectArgs.builder().object(filePath) //文件名.contentType("text/html")//文件类型.bucket(minIOConfigProperties.getBucket())//桶名称与minio创建的桶一致.stream(inputStream, inputStream.available(), -1)//文件流.build();minioClient.putObject(putObjectArgs);StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());urlPath.append(separator + minIOConfigProperties.getBucket());urlPath.append(separator);urlPath.append(filePath);return urlPath.toString(); //文件全路径} catch (Exception ex) {log.error("minio put file error.", ex);ex.printStackTrace();throw new RuntimeException("上传文件失败");}}/*** 删除文件** @param pathUrl 文件全路径*/@Overridepublic void delete(String pathUrl) {String key = pathUrl.replace(minIOConfigProperties.getEndpoint() + "/", "");int index = key.indexOf(separator);String bucket = key.substring(0, index);String filePath = key.substring(index + 1);// 删除ObjectsRemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();try {minioClient.removeObject(removeObjectArgs);} catch (Exception e) {log.error("minio remove file error.  pathUrl:{}", pathUrl);e.printStackTrace();}}/*** 下载文件** @param pathUrl 文件全路径* @return 文件流*/@Overridepublic byte[] downLoadFile(String pathUrl) {String key = pathUrl.replace(minIOConfigProperties.getEndpoint() + "/", "");int index = key.indexOf(separator);String bucket = key.substring(0, index);String filePath = key.substring(index + 1);InputStream inputStream = null;try {inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(minIOConfigProperties.getBucket()).object(filePath).build());} catch (Exception e) {log.error("minio down file error.  pathUrl:{}", pathUrl);e.printStackTrace();}//字节数组输出流ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byte[] buff = new byte[100];int rc = 0;while (true) {try {if (!((rc = inputStream.read(buff, 0, 100)) > 0)) break;} catch (IOException e) {e.printStackTrace();}byteArrayOutputStream.write(buff, 0, rc);}return byteArrayOutputStream.toByteArray();}
}

8、编写统一结果处理类

package com.baidou.dto;import lombok.Data;/*** 统一结果处理类** @author 白豆五* @version 2023/04/21* @since JDK8*/
@Data
public class Result<T> {private Integer code; //响应状态码private String msg;   //响应消息private T data;       //响应数据/*** 处理成功的返回结果** @param data 数据* @param <T>* @return R<T>*/public static <T> Result<T> success(T data, String msg) {Result<T> r = new Result<>();r.setCode(200);r.setData(data);r.setMsg(msg);return r;}/*** 处理成功的返回结果** @param msg 错误信息* @param <T>* @return R<T>*/public static <T> Result<T> error(String msg) {Result<T> r = new Result<>();r.setCode(503);r.setMsg(msg);return r;}
}

9、编写controller

package com.baidou.controller;import com.baidou.dto.Result;
import com.baidou.service.FileStorageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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.RestController;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;/*** 操作minio的控制器类** @author 白豆五* @version 2023/04/21* @since JDK8*/
@RestController
@RequestMapping("/minio")
@Api(tags = "minio相关接口")
public class MinioController {@Autowiredprivate FileStorageService fileStorageService;/*** 上传图片到minio** @param file* @return*/@PostMapping("upload")@ApiOperation(value = "图片上传接口")public Result uploadFile(MultipartFile file) throws IOException {try {// 获取文件名称String fileName = file.getOriginalFilename();/*解决多次上传同名文件覆盖问题*/// 在文件名称里面添加随机唯一的值String uuid = UUID.randomUUID().toString().replaceAll("-", "");fileName = uuid + fileName;// 获取文件输入流InputStream is = file.getInputStream();String imgUrl = fileStorageService.uploadImgFile("img", fileName, is);return Result.success(imgUrl, "上传成功");} catch (IOException e) {e.printStackTrace();return Result.error("上传失败");}}
}

10、启动项目,然后用postman测试

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp + vue3开发中组合式函数必须是一个同步函数

目录 vue3中的组合式函数用法&#xff1a; 官网示例异步组合式函数&#xff1a;同步函数写法 改造成导出async组合式函数时&#xff1a; uniapp无法使用async组合式函数的原因&#xff1a; vue3中的组合式函数使用时&#xff0c;导出的组合式函数必须是一个同步函数。 vue3…

推荐一个开源的区块链开发者工具网站

开源区块链开发者工具箱 https://ChainTool.tech 今天可以正式上线了。ChainTool 使用完全开源的方式编写一些开发者日常经常使用的工具。 关于 ChainToolDAO 大约在两个月前&#xff0c; ChainToolDAO 成立了&#xff0c;成立 ChainToolDAO 的来由是这样的&#xff1a;我是一…

【14】SCI易中期刊推荐——计算机 | 人工智能(中科院2区)

💖💖>>>加勒比海带,QQ2479200884<<<💖💖 🍀🍀>>>【YOLO魔法搭配&论文投稿咨询】<<<🍀🍀 ✨✨>>>学习交流 | 温澜潮生 | 合作共赢 | 共同进步<<<✨✨ 📚📚>>>人工智能 | 计算机视觉…

QMS-云质说质量 - 10 我和我的客户投诉(2) - 客户逐利 驱除良币

云质QMS原创 转载请注明来源 作者&#xff1a;王洪石 上策伐谋 中策伐交 前面发过一篇关于客户投诉的文章“逢年过节要祈祷”&#xff0c;引起了很多质量人的共鸣&#xff0c;特别是汽车零部件行业曾经和正在负责客诉的质量同行们。 真实的产品质量问题&#xff0c;是否发生只…

【GoodERP专题】第一章 GoodERP应用专题之good_expense 费用报销 的使用

文章目录 一、模块设计二、模块1.主数据2.费用申请单3.借款单【付款】4.费用报销单【挂账/付款】5.出差申请单6.出差借款单【付款】7.差旅费报销单【挂账/付款】 总结 一、模块设计 费用报销模块是基于GoodERP框架设计的&#xff0c;该模块是为了解决企业内外费用相关报销任务处…

idea 2023版本创建maven管理的Scala项目教程

目录 1、创建项目1.1、创建项目名及简单配置1、2 刚开始创建好后的项目是这样的1、3 进行相关设置1&#xff09;增加maven管理2&#xff09;增加scala目录&#xff0c;并设置成resource目录 注意&#xff1a; 本项目写得教程是基于您得Java jdk、Scala jdk、maven这些都是安装配…

我们都被 ChatGPT 给骗了?

引言&#xff1a; 用过 ChatGPT 的人都知道&#xff0c;当你与 chatgpt 对话的时候&#xff0c;它是“逐字输出”的&#xff0c;就像真的有个人在跟你打字一样。其实&#xff0c;这种技术并没有那么神奇&#xff0c;这种技术叫做“实时文本生成”或“逐字输出”技术&#xff0…

软件测试好学习吗?

软件测试好不好学习其实各自的认知都不同&#xff0c;想要知道自己能不能学会&#xff0c;对于自己怎么样&#xff0c;最简单的方法就是找个基础教程先去学习一下了~ 其实软件测试这个行业与其他岗位相比&#xff0c;对零基础的学习者更加友好。即使你不懂互联网&#xff0c;不…

蔡春久:主数据标准化如何建设

亿信华辰「2023数字赋能季」主数据管理专场第一期成功举办。我们邀请到了中国数据标准化及治理专家蔡春久为大家带来主数据管理从理论到工具层面的分享&#xff0c;全程干货&#xff0c;深度解读&#xff0c;以下是演讲全文。 蔡春久&#xff1a;中国大数据技术标准推进委员会…

这些美国名校的AI人工智能大牛,你知道几个?

CS专业被US News评为就业TOP 100职业第一名、STEM职业第一名、技术类职业第一名。 AI人工智能&#xff0c;随着GPT的横空出世已成为最热门的CS专业。“深度学习”和“神经网络”等是新一代人工智能的重要代表&#xff0c;如今在面部识别、语音输入、基因医疗等重要领域被广泛应…

轻量级服务器nginx:配置虚拟主机的两种方式

虚拟主机是指&#xff0c;在一台服务器中&#xff0c;通过nginx的代理&#xff0c;我们可以访问多个网站。区分不同的网站&#xff0c;可以通过端口、域名两种方式 这里写目录标题 一 端口不同区分不同的虚拟主机二 通过域名区分不同的主机名1.配置域名映射2.显示登录效果 一 …

如何写好学位论文

昨天刚提交了学位论文&#xff0c;今天准备来总结一下一些常用的Word写作技巧。 样式与多级列表 论文一般都会对章节条目的标题、参考文献、表格内容、题注的字体字号、行间距、段落间距等作出规定。为每一类文字设置一种样式&#xff0c;在写的时候直接应用样式可以方便地对全…

访问者模式解读

目录 问题引进 访问者模式基本介绍 基本介绍 访问者模式的原理类图 对原理类图的说明 访问者模式应用实例 思路分析和图解(类图) 代码实战 应用案例的小结 访问者模式的注意事项和细节 优点 问题引进 测评系统的需求 1) 将观众分为男人和女人&#xff0c;对歌手进行…

Idea 配置 maven 离线使用

首先&#xff0c;项目中的依赖已经下载到本地仓库&#xff0c;在没有网络或者没办法连通公司的maven仓库时&#xff0c;需要配置离线使用。 1. 配置 setting.xml 在 maven 使用的 setting.xml 文件中&#xff0c;加入以下配置。 默认在 maven安装目录下的 conf 文件夹下 。 &…

【C++】从C语言入门C++的基础知识

C基础知识 前言1. C关键字2. 命名空间namespace命名空间的创建命名空间的使用命名空间的注意事项 3. C输入&输出4. 缺省参数概念分类全缺省参数半缺省参数 5. 函数重载概念实现C为什么能进行函数重载C和C的相互调用&#xff08;可以不用看&#xff09; 6. 引用概念注意事项…

【软考备战·希赛网每日一练】2023年4月24日

文章目录 一、今日成绩二、错题总结第一题第二题第三题第四题第五题 三、知识查缺 题目及解析来源&#xff1a;2023年04月24日软件设计师每日一练 一、今日成绩 二、错题总结 第一题 解析&#xff1a; 第二题 解析&#xff1a; DPI表示每英寸像素点的个数。 300DPI表示每英寸…

人生中最好的等待叫做来日可期,社科院与杜兰大学金融管理硕士等你惊艳岁月

有句话说&#xff1a;“去日不可追&#xff0c;来日犹可期”。过去的已经过去&#xff0c;不管好的、坏的都已成为我们的回忆。人生中最好的等待就是未来可期。别辜负现在的好时光&#xff0c;努力做想做的事。社科院与杜兰大学金融管理硕士项目等你惊艳时光。 所有出众者的背…

塔望3W消费战略全案丨品类重新定义 打造金皇品高端速食第一面

金皇品 客户&#xff1a;上海皇品食品有限公司 品牌&#xff1a;金皇品 服务&#xff1a;3W消费战略 品牌全案 项目背景 金皇品隶属于上海皇品食品有限公司&#xff0c;品牌创立于1995年。产品以原汁作为核心卖点&#xff0c;通过线下渠道的密集耕耘&#xff0c;在浙江&…

掌握这些移动测试技巧,棘手的问题也能游刃有余解决了

目录&#xff1a;导读 引言 一、测试的程序 二、功能测试点 三、移动端安卓环境变量 性能测试 四、实操通过USB连接到手机设备 五、adb操作命令 写在最后 引言 你是否曾经遇到过打开一个移动应用后出现各种问题&#xff0c;比如卡顿、闪退等&#xff1f; 这些问题可能会…

重塑元宇宙体验!元宇宙实时云渲染解决方案来了

元宇宙作为人工智能、云计算和数字孪生等前沿技术的结合体&#xff0c;近年来越发受到各大企业重视。 元宇宙的应用场景层出不穷&#xff0c;不仅包括营销推广场景&#xff0c;还有品牌活动和电商销售&#xff0c;能有效提升品宣和商业转化效果。 元宇宙也具有极大的建设价值…