世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程。
以下内容多数来自官网及github:docs.min.io/cn/
MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。
docker构建服务:单体
docker pull minio/minio
docker run -p 9000:9000 minio/minio server /data
docker-compose集群+nginx负载均衡:
version: '3.7'
# starts 4 docker containers running minio server instances.
# using nginx reverse proxy, load balancing, you can access
# it through port 9000.
services:
minio1:
image: minio/minio:RELEASE.2020-10-18T21-54-12Z
volumes:
- data1-1:/data1
- data1-2:/data2
expose:
- "9000"
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
minio2:
image: minio/minio:RELEASE.2020-10-18T21-54-12Z
volumes:
- data2-1:/data1
- data2-2:/data2
expose:
- "9000"
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
minio3:
image: minio/minio:RELEASE.2020-10-18T21-54-12Z
volumes:
- data3-1:/data1
- data3-2:/data2
expose:
- "9000"
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
minio4:
image: minio/minio:RELEASE.2020-10-18T21-54-12Z
volumes:
- data4-1:/data1
- data4-2:/data2
expose:
- "9000"
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
nginx:
image: nginx:1.19.2-alpine
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "9002:9000"
depends_on:
- minio1
- minio2
- minio3
- minio4
## By default this config uses default local driver,
## For custom volumes replace with volume driver configuration.
volumes:
data1-1:
data1-2:
data2-1:
data2-2:
data3-1:
data3-2:
data4-1:
data4-2:
nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
# include /etc/nginx/conf.d/*.conf;
upstream minio {
server minio1:9000;
server minio2:9000;
server minio3:9000;
server minio4:9000;
}
server {
listen 9000;
listen [::]:9000;
server_name localhost;
# To allow special characters in headers
ignore_invalid_headers off;
# Allow any size file to be uploaded.
# Set to a value such as 1000m; to restrict file size to a specific value
client_max_body_size 0;
# To disable buffering
proxy_buffering off;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 300;
# Default is HTTP/1, keepalive is only enabled in HTTP/1.1
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://minio;
}
}
}
访问:其中9000为对外映射的端口,可以根据实际情况设置,比如我用docker-compose操作时,对外映射端口是9002
http://localhost:9000
Java客户端使用实例:
依赖:
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.1.4</version>
</dependency>
使用:
public class Test1 {
MinioClient minioClient;
/**
* 创建客户端并连接服务器
* @throws Exception
*/
@Before
public void test1() throws Exception{
minioClient = MinioClient.builder().endpoint("http://192.168.2.45:9002")
.credentials("minio", "minio123")
.build();
}
/**
* 创建桶
*/
@Test
public void test2() throws Exception {
BucketExistsArgs bg = BucketExistsArgs.builder().bucket("test1").build();
boolean b = minioClient.bucketExists(bg);
if(b){
System.out.println("bucket exists");
}else{
MakeBucketArgs mg = MakeBucketArgs.builder().bucket("test1").build();
minioClient.makeBucket(mg);
}
}
/**
* 上传文件
*/
@Test
public void test3() throws Exception {
minioClient.uploadObject(UploadObjectArgs.builder()
.bucket("test1")
.filename("G://hello.jpg")
.object("hello-upload")
.bucket("test1")
.build());
}
/**
* put上传
*/
@Test
public void test4() throws Exception {
minioClient.putObject(PutObjectArgs.builder()
.bucket("test1")
.stream(new FileInputStream("G://hello.jpg"), 27066, 5*1024*1024)
.object("hello-put")
.build());
}
/**
* 获取对象
*/
@Test
public void test5() throws Exception {
try(InputStream in = minioClient.getObject(GetObjectArgs.builder()
.bucket("test1")
.object("hello-upload")
.build())){
System.out.println("getObject : " + in.read());
}
}
/**
* 获取桶bucket列表
*/
@Test
public void test6() throws Exception {
List<Bucket> buckets = minioClient.listBuckets();
buckets.forEach(bucket -> {
System.out.println("bucket createDate : " + bucket.creationDate());
System.out.println("bucket name : " + bucket.name());
});
}
/**
* 获取对象列表
*/
@Test
public void test7(){
Iterable<Result<Item>> objs = minioClient.listObjects(ListObjectsArgs.builder()
.bucket("test1")
.prefix("hello")
.build());
objs.forEach(obj -> {
try {
System.out.println("obj name : " + obj.get().objectName());
System.out.println("obj size : " + obj.get().size());
} catch (Exception e){
e.printStackTrace();
}
});
}
/**
* 删除对象 删除桶
* @throws Exception
*/
@Test
public void test8() throws Exception{
minioClient.removeObjects(RemoveObjectsArgs.builder()
.bucket("test1")
.objects(Arrays.asList(new DeleteObject("hello-upload"), new DeleteObject("hello-put")))
.build());
minioClient.removeBucket(RemoveBucketArgs.builder().bucket("test1").build());
}
/**
* 复制对象
*/
@Test
public void test9() throws Exception {
minioClient.copyObject(CopyObjectArgs.builder()
.bucket("test1")
.object("hello-copy")
.source(CopySource.builder()
.bucket("test1")
.object("hello-upload")
.build())
.build());
}
/**
* 下载对象
*/
@Test
public void test10() throws Exception{
minioClient.downloadObject(DownloadObjectArgs.builder()
.bucket("test1")
.object("hello-upload")
.filename("G://hello-file.jpg")
.build());
}
/**
* 获取对象的url
*/
@Test
public void test11() throws Exception{
String url = minioClient.getObjectUrl("test1", "hello-upload");
System.out.println("url : " + url);
}
/**
* 以sql的形式获取对象的内容
*/
@Test
public void test12() throws Exception {
SelectResponseStream responseStream = minioClient.selectObjectContent(SelectObjectContentArgs.builder()
.bucket("test1")
.object("hello-upload")
.inputSerialization(new InputSerialization())
.outputSerialization(new OutputSerialization(new Character('1')))
.sqlExpression("select * from hello-upload")
.build());
byte[] buf = new byte[521];
responseStream.read(buf);
System.out.println(StrUtil.str(buf, CharsetUtil.CHARSET_UTF_8));
}
@Test
public void test13() throws Exception{
minioClient.removeObject(RemoveObjectArgs.builder().bucket("test1").object("hello").build());
minioClient.removeObject(RemoveObjectArgs.builder().bucket("test1").object("hello1").build());
minioClient.removeObject(RemoveObjectArgs.builder().bucket("test1").object("hello2").build());
minioClient.removeObject(RemoveObjectArgs.builder().bucket("test1").object("hello3").build());
}
}
更多消息,请关注公众号