世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程。
以下内容多数来自官网及github:https://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 /datadocker-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()); } }更多消息,请关注公众号