一、使用minio的原因
1、高性能:
minio是全球领先的对象存储先锋,在标准硬件上,读/写速度上高达183 GB / 秒 和 171 GB / 秒。
2、可扩展性:
minio利用了web缩放器的来之不易的知识,为对象存储带来了简单的存储缩放模型, 在 MinIO, 扩展从单个群集开始,该群集可以与其他MinIO群集联合以创建全局名称空间, 并在需要时可以跨越多个不同的数据中心。 通过添加更多集群可以扩展名称空间, 更多机架,直到实现目标。
3、云原生支持:
MinIO 是在过去4年的时间内从0开始打造的一款软件 ,符合一切原生云计算的架构和构建过程,并且包含最新的云计算的全新的技术和概念。 其中包括支持Kubernetes 、微服和多租户的的容器技术。使对象存储对于 Kubernetes更加友好。
4、源码开放与企业级支持:
MinIO 基于Apache V2 license 100% 开放源代码 。 这就意味着 MinIO的客户能够自动的、无限制、自由免费使用和集成MinIO、自由的创新和创造、 自由的去修改、自由的再次发行新的版本和软件. 确实, MinIO 强有力的支持和驱动了很多世界500强的企业。 此外,其部署的多样性和专业性提供了其他软件无法比拟的优势。
二、minio的下载和部署
1、Linux中minio的下载安装:
访问MinIO Quickstart Guide| Minio中文文档下载minio并部署
部署命令:./minio server /data --console-address “:9000” 解释:/data 是minio存放数据的路径,–console-address “:9000” 指定的是minio控制台启动的端口号。
注意:需要在在防火墙中开启9000端口和你指定的控制台端口,minio启动成功后默认账号密码为minioadmin
在linux中输入 ps -aux | grep minio,若出现下图所示,则启动成功,我这里控制台使用的是49000端口
启动成功后访问ip:端口号,出现以下页面则成功
三、springboot中引入minio
1、maven坐标引入
io.minio
minio
8.2.1
2、minio配置 yml文件中的配置
# Minio配置
minio:
# minio配置的地址,端口9000
url: http://192.168.31.2:9000
# 账号
accessKey: minioadmin
# 密码
secretKey: minioadmin
# MinIO桶名字
bucketName: test-bucket
3、minio使用的util
/**
* minio存储
*
* @author zhifeng
* @date 2022-05-05
* @since 1.0.0
*/
@Component
public class MinioUtil {
@Autowired
private MinioClient minioClient;
/**
* 查看存储bucket是否存在
*
* @param bucketName 存储bucket
* @return boolean
*/
public Boolean bucketExists(String bucketName) {
Boolean found;
try {
found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return found;
}
/**
* 创建存储bucket
*
* @param bucketName 存储bucket名称
* @return Boolean
*/
public Boolean makeBucket(String bucketName) {
try {
minioClient.makeBucket(MakeBucketArgs.builder()
.bucket(bucketName)
.build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 删除存储bucket
*
* @param bucketName 存储bucket名称
* @return Boolean
*/
public Boolean removeBucket(String bucketName) {
try {
minioClient.removeBucket(RemoveBucketArgs.builder()
.bucket(bucketName)
.build());
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 文件上传
*
* @param file 文件
* @param bucketName 存储bucket
* @return Boolean
*/
public Boolean upload(MultipartFile file, String fileName, String bucketName) {
try {
PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName)
.stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
//文件名称相同会覆盖
minioClient.putObject(objectArgs);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 文件下载
*
* @param bucketName 存储bucket名称
* @param fileName 文件名称
* @param res response
* @return Boolean
*/
public void download(String bucketName, String fileName, HttpServletResponse res) {
GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName)
.object(fileName).build();
try (GetObjectResponse response = minioClient.getObject(objectArgs)) {
byte[] buf = new byte[1024];
int len;
try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {
while ((len = response.read(buf)) != -1) {
os.write(buf, 0, len);
}
os.flush();
byte[] bytes = os.toByteArray();
res.setCharacterEncoding("utf-8");
//设置强制下载不打开
res.setContentType("application/force-download");
res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
try (ServletOutputStream stream = res.getOutputStream()) {
stream.write(bytes);
stream.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 查看文件对象
*
* @param bucketName 存储bucket名称
* @return 存储bucket内文件对象信息
*/
public List listObjects(String bucketName) {
Iterable> results = minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucketName).build());
List objectItems = new ArrayList<>();
try {
for (Result- result : results) {
Item item = result.get();
ObjectItem objectItem = new ObjectItem();
objectItem.setObjectName(item.objectName());
objectItem.setSize(item.size());
objectItems.add(objectItem);
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return objectItems;
}
/**
* 批量删除文件对象
*
* @param bucketName 存储bucket名称
* @param objects 对象名称集合
*/
public Iterable
> removeObjects(String bucketName, List objects) {
List dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());
Iterable> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());
return results;
}
}
4、minio使用的config配置类
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
/**
* 服务地址
*/
public String url;
/**
* 用户名
*/
public String accessKey;
/**
* 密码
*/
public String secretKey;
/**
* 存储桶名称
*/
public String bucketName;
// "如果是true,则用的是https而不是http,默认值是true"
public static Boolean secure = false;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getBucketName() {
return bucketName;
}
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
public static Boolean getSecure() {
return secure;
}
public static void setSecure(Boolean secure) {
MinioConfig.secure = secure;
}
@Bean
public MinioClient getMinioClient() {
return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();
}
}
5、使用minio进行文件上传
controller层:
@RestController
@RequestMapping("/system/file")
public class SysFileController extends BaseController {
@Autowired
private ISysFileService sysFileService;
/**
* 图片上传minio
*
* @param file 图片文件
* @return 返回
*/
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public Result uploadFileMinio(MultipartFile file) {
String url = sysFileService.uploadFileMinio(file);
if (StringUtils.isNotEmpty(url)) {
return Result.success(url);
}
return Result.error("上传失败!");
}
}
serviceImpl层
@Service
public class SysFileServiceImpl implements SysFileService {
@Autowired
private MinioConfig minioConfig;
@Autowired
private MinioUtil minioUtil;
@Override
public String uploadFileMinio(MultipartFile file) {
boolean flag = false;
if (file.isEmpty()) {
throw new RuntimeException("文件不存在!");
}
// 判断存储桶是否存在
if (!minioUtil.bucketExists(minioConfig.getBucketName())) {
minioUtil.makeBucket(minioConfig.getBucketName());
}
// 生成文件名
String fineName = FileUploadUtils.extractFilename(file);
try {
// 上传文件
flag = minioUtil.upload(file, fineName, minioConfig.getBucketName());
} catch (Exception e) {
return null;
}
// 判断是否上传成功,成功就返回url,不成功就返回null
if (flag){
return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fineName;
}
return null;
}
}
返回的url就是文件上传后的url,访问url就能看到上传的图片。
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦