MinIO的使用
minio提供高性能、与S3兼容的对象存储系统,让你自己能够构建自己的云存储服务。minio是世界上最快的对象存储,没有之一。
1 docker下载镜像和容器创建
docker 镜像官网: https://hub.docker.com 好像被墙了,正常进不去。
下载最新版镜像
docker pull minio/minio
启动容器
docker run -p 9000:9000 --name minio
-d --restart=always
-e "MINIO_ACCESS_KEY=admin"
-e "MINIO_SECRET_KEY=admin123"
-v /home/data:/data
-v /home/config:/root/.minio
minio/minio server /data
Console endpoint is listening on a dynamic port (38162), please use --console-address “:PORT” to choose a static port.
如果使用上面的命令启动容器,查看docker 日志,会报上述警告,所以需要在启动的时候加上
--console-address
,使用下面命令:docker run -p 9000:9000 -p 9001:9001 --name minio -d --restart=always -e "MINIO_ACCESS_KEY=admin" -e "MINIO_SECRET_KEY=admin123" -v /home/data:/data -v /home/config:/root/.minio minio/minio server /data --console-address ":9001"
注意: 其中 9000是api访问端口,9001是控制台访问端口
启动成功浏览器输入:
http://虚拟机ip:9001/
访问在启动容器的时候,有可能会报错:
Error response from daemon: driver failed programming external connectivity on endpoint minio (ac6098dcff73265df5a33a371f848228562fb33541ed38d9e0a9eb7ba698737e): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9001 -j DNAT --to-destination 172.17.0.2:9001 ! -i docker0: iptables: No chain/target/match by that name.
原因是修改了防火墙的配置(我这里为了简单直接将防火墙关了,应该只开放指定端口的。),需要重启docker
systemctl restart docker
2 SDK操作
1 上传文件
1 添加maven依赖
<!--添加MinIO依赖-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.7</version>
</dependency>
2 编写测试代码
public class TestMinIo {
public static void main(String[] args) throws IOException, ServerException, InsufficientDataException, InternalException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, XmlParserException, ErrorResponseException {
//1 构建MinIO的客户端
MinioClient minioClient = MinioClient.builder()
.endpoint("http://192.168.200.144:9000/") //终端
.credentials("admin", "admin123") //凭据
.build();
//2 构建上传对象的参数
UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder()
.bucket("test")
.object("a.jpg") //文件名
//文件的全路径,如果是流,该咋上传呢?
.filename("D:\\summer\\b.jpg")
.build();
//3 上传
minioClient.uploadObject(uploadObjectArgs);
}
}
使用流的形式上传文件
public static void main(String[] args) throws IOException, ServerException, InsufficientDataException, InternalException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, XmlParserException, ErrorResponseException {
long start = System.currentTimeMillis();
//1 构建MinIO的客户端
MinioClient minioClient = MinioClient.builder()
.endpoint("http://192.168.200.144:9000/") //终端
.credentials("admin", "admin123") //凭据
.build();
FileInputStream fis = new FileInputStream("D:\\summer\\b.mp4");
minioClient.putObject( PutObjectArgs.builder()
.bucket("test")
.object("b.mp4")
.stream(fis,fis.available(),-1) //objectSize: 文件大小 partSize:分片大小,5m-5g之间。传入-1,默认5mb
.build());
}
2 删除文件
public static void main(String[] args) throws IOException, ServerException, InsufficientDataException, InternalException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, XmlParserException, ErrorResponseException {
//1 构建MinIO的客户端
MinioClient minioClient = MinioClient.builder()
.endpoint("http://192.168.200.144:9000/") //终端
.credentials("admin", "admin123") //凭据
.build();
//删除指定桶中的文件
minioClient.removeObject(
RemoveObjectArgs.builder()
.bucket("test")
.object("a.jpg")
.build());
}
3 查询文件
public static void main(String[] args) throws IOException, ServerException, InsufficientDataException, InternalException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, XmlParserException, ErrorResponseException {
//1 构建MinIO的客户端
MinioClient minioClient = MinioClient.builder()
.endpoint("http://192.168.200.144:9000/") //终端
.credentials("admin", "admin123") //凭据
.build();
//查询文件
InputStream inputStream = minioClient.getObject(GetObjectArgs
.builder()
.bucket("test")
.object("b.jpg")
.build());
FileOutputStream fos = new FileOutputStream(
"D:\\summer\\data1\\a.jpg");
IOUtils.copy(inputStream,fos);
}
有个问题: 主线程存活时间过长
经过测试,获取图片使用了974毫秒,但是程序还是没有结束,必须要等待好一会,这是什么原因呢?
如果使用Junit测试程序执行完即结束。
3 文件上传案例
1 maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!--添加MinIO依赖-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.7</version>
</dependency>
</dependencies>
2 controller
@RestController
public class UploadController {
@PostMapping("uploadMinIO")
public String uploadMinIO(MultipartFile multipartFile) throws IOException {
InputStream is = multipartFile.getInputStream();
String originalFilename = multipartFile.getOriginalFilename();
return MinIOUtils.upload(is,originalFilename);
}
}
3 MinIO工具类
package com.example.upload;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class MinIOUtils {
private static final String URL_PREFIX= "http://192.168.200.144:9000/";
private static MinioClient minioClient;
static {
minioClient = MinioClient.builder()
.endpoint("http://192.168.200.144:9000/")
.credentials("admin", "admin123")
.build();
}
public static String upload(InputStream inputStream,String originName){
//获取文件后缀
String suffix = originName.substring(originName.lastIndexOf(".")+1);
String bucketName;
//假如只有图片和视频两种
if(StringUtils.equals(suffix,"jpg") ||StringUtils.equals(suffix,"jpeg")|| StringUtils.equals(suffix,"png")){
//图片
bucketName="img";
}else {
bucketName="video";
}
//为了构建文件名
//当前时间的年月日
String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
//当前系统时间的毫秒值+随机数
// String time = System.currentTimeMillis() + "_" + RandomUtils.nextInt(100, 1000);
StringBuilder fileName = new StringBuilder();
fileName.append(date).append("/")
.append(System.currentTimeMillis())
.append("_")
.append( RandomUtils.nextInt(100, 1000))
.append(".").append(suffix);
try {
//判断bucket是否存在,如果不存在,则创建一个
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
}
minioClient.putObject(PutObjectArgs.builder()
.bucket(bucketName)
.object(fileName.toString())
.stream(inputStream,inputStream.available(),-1)
.build());
} catch (Exception e) {
e.printStackTrace();
}
//将访问该文件的url返回
String url = new StringBuilder(URL_PREFIX).append(bucketName).append("/").append(fileName.toString()).toString();
return url;
}
}
3 静态页面
<form action="/uploadMinIO" method="post" enctype="multipart/form-data">
<input type="file" name="multipartFile"> <br>
<input type="submit" value="提交">
</form>