邢臺(tái)123生活最新帖子武漢企業(yè)seo推廣
基本介紹
什么是?MinIO
????????MinIO 是一款基于 Go 語言的高性能、可擴(kuò)展、云原生支持、操作簡單、開源的分布式對(duì)象存儲(chǔ)產(chǎn)品?;?Apache License v2.0 開源協(xié)議,雖然輕量,卻擁有著不錯(cuò)的性能。它兼容亞馬遜S3云存儲(chǔ)服務(wù)接口??梢院芎唵蔚暮推渌麘?yīng)用結(jié)合使用,例如 NodeJS、Redis、MySQL 等。
官網(wǎng):www.minio.org.cn/
MinIO
?特點(diǎn)
- 高性能:作為高性能對(duì)象存儲(chǔ),在標(biāo)準(zhǔn)硬件條件下它能達(dá)到55GB/s的讀、35GG/s的寫速率
- 可擴(kuò)容:不同MinIO集群可以組成聯(lián)邦,并形成一個(gè)全局的命名空間,并跨越多個(gè)數(shù)據(jù)中心
- 云原生:容器化、基于K8S的編排、多租戶支持
- Amazon S3兼容:Minio使用Amazon S3 v2 / v4 API??梢允褂肕inio SDK,Minio Client,AWS SDK和AWS CLI訪問Minio服務(wù)器。
- 可對(duì)接后端存儲(chǔ): 除了Minio自己的文件系統(tǒng),還支持DAS、 JBODs、NAS、Google云存儲(chǔ)和Azure Blob存儲(chǔ)。
- SDK支持: 基于Minio輕量的特點(diǎn),它得到類似Java、Python或Go等語言的sdk支持
- Lambda計(jì)算: Minio服務(wù)器通過其兼容AWS SNS / SQS的事件通知服務(wù)觸發(fā)Lambda功能。支持的目標(biāo)是消息隊(duì)列,如Kafka,NATS,AMQP,MQTT,Webhooks以及Elasticsearch,Redis,Postgres和MySQL等數(shù)據(jù)庫。
- 有操作頁面
- 功能簡單: 這一設(shè)計(jì)原則讓MinIO不容易出錯(cuò)、更快啟動(dòng)
- 支持糾刪碼:MinIO使用糾刪碼、Checksum來防止硬件錯(cuò)誤和靜默數(shù)據(jù)污染。在最高冗余度配置下,即使丟失1/2的磁盤也能恢復(fù)數(shù)據(jù)
docker 安裝 minio
下載鏡像(最新版本)
docker pull minio/minio
查看已經(jīng)下載的鏡像
docker images
創(chuàng)建并啟動(dòng)minIO容器:
這里的 \ 指的是命令還沒有輸入完,還需要繼續(xù)輸入命令,先不要執(zhí)行的意思。
這里的9090端口指的是minio的客戶端端口。雖然設(shè)置9090,但是我們在訪問9000的時(shí)候,他也會(huì)自動(dòng)跳到9090。
9000端口是minio的服務(wù)端端口,我們程序在連接minio的時(shí)候,就是通過這個(gè)端口來連接的。
-v就是docker run當(dāng)中的掛載,這里的/usr/local/mydata/minio/data:/data意思就是將容器的/data目錄和宿主機(jī)的/mydata/minio/data目錄做映射,這樣我們想要查看容器的文件的時(shí)候,就不需要看容器當(dāng)中的文件了。
注意在執(zhí)行命令的時(shí)候,他是會(huì)自動(dòng)在宿主機(jī)當(dāng)中創(chuàng)建目錄的。我們不需要手動(dòng)創(chuàng)建。
minio所上傳的文件默認(rèn)都是存儲(chǔ)在容器的data目錄下的!
假如刪除容器了宿主機(jī)當(dāng)中掛載的目錄是不會(huì)刪除的。假如沒有使用-v掛載目錄,那他在宿主機(jī)的存儲(chǔ)位置的文件會(huì)直接刪除的。
宿主機(jī)的掛載目錄一定是根目錄,如果是相對(duì)路徑會(huì)有問題。還有容器當(dāng)中的目錄也是必須是絕對(duì)路徑(根路徑就是帶/的)。
所謂的掛載其實(shí)就是將容器目錄和宿主機(jī)目錄進(jìn)行綁定了,操作宿主機(jī)目錄,容器目錄也會(huì)變化,操作容器目錄,宿主機(jī)目錄也會(huì)變化。這樣做的目的 可以間接理解為就是數(shù)據(jù)持久化,防止容器誤刪,導(dǎo)致數(shù)據(jù)丟失的情況。
MINIO_ACCESS_KEY:賬號(hào) MINIO_SECRET_KEY:密碼 (正常賬號(hào)應(yīng)該不低于3位,密碼不低于8位,不然容器會(huì)啟動(dòng)不成功)
–console-address 指定客戶端端口
-d --restart=always 代表重啟linux的時(shí)候容器自動(dòng)啟動(dòng)
–name minio 容器名稱
?docker run -p 9000:9000 -p 9090:9090 ?--name minio ?-d --restart=always ?-e "MINIO_ACCESS_KEY=minioadmin" ?-e "MINIO_SECRET_KEY=minioadmin" ?-v /usr/local/mydata/minio/data:/data ?minio/minio server ?/data --console-address ":9090" -address ":9000"
springboot集成minio
一、配置yml文件
#yml配置文件增加如下配置minio:endpoint: http://ip:9000fileUploadUrl: http://ip:9000accessKey: minioadmin (用戶名)secretKey: minioadmin (密碼)bucketName: file (文件組:桶名)
二、引入pom(8與7的方法不適用,以下使用8.0.3)
? ? ? ? <dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.0.3</version></dependency>
三、系統(tǒng)加載minio配置
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {private String endpoint;private String accessKey;private String secretKey;private String bucketName;@Beanpublic MinioClient minioClient() {MinioClient minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();return minioClient;}}
四、minio工具類(上傳文件,返回訪問鏈接)
package org;import cn.hutool.core.io.FastByteArrayOutputStream;
import com.alibaba.fastjson.JSONObject;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;/*** 功能描述 文件服務(wù)器工具類** @author: * @date: */
@Component
public class MinioUtil {@Resourceprivate MinioClient minioClient;/*** 查看存儲(chǔ)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;}/*** 創(chuàng)建存儲(chǔ)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;}/*** 刪除存儲(chǔ)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;}/*** 獲取全部bucket*/public List<Bucket> getAllBuckets() {try {return minioClient.listBuckets();} catch (Exception e) {e.printStackTrace();}return null;}/*** 文件上傳* @param file 文件* @return Boolean*/public Boolean upload(String bucketName, String fileName, MultipartFile file, InputStream inputStream) {try {PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(inputStream,file.getSize(),-1).contentType(file.getContentType()).build();//文件名稱相同會(huì)覆蓋minioClient.putObject(objectArgs);} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 預(yù)覽圖片* @param fileName* @return*/public String preview(String fileName,String bucketName){// 查看文件地址GetPresignedObjectUrlArgs build = new GetPresignedObjectUrlArgs().builder().bucket(bucketName).object(fileName).method(Method.GET).build();try {String url = minioClient.getPresignedObjectUrl(build);return url;} catch (Exception e) {e.printStackTrace();}return null;}/*** 文件下載* @param fileName 文件名稱* @param res response* @return Boolean*/public void download(String fileName,String bucketName, 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");//設(shè)置強(qiáng)制下載不打開//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();}}/*** 查看文件對(duì)象* @return 存儲(chǔ)bucket內(nèi)文件對(duì)象信息*/public List<Item> listObjects(String bucketName) {Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());List<Item> items = new ArrayList<>();try {for (Result<Item> result : results) {items.add(result.get());}} catch (Exception e) {e.printStackTrace();return null;}return items;}/*** 刪除* @param fileName* @return* @throws Exception*/public boolean remove(String fileName,String bucketName){try {minioClient.removeObject( RemoveObjectArgs.builder().bucket(bucketName).object(fileName).build());}catch (Exception e){return false;}return true;}/*** 批量刪除文件對(duì)象(沒測試)* @param objects 對(duì)象名稱集合*/public Iterable<Result<DeleteError>> removeObjects(List<String> objects, String bucketName) {List<DeleteObject> dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder().bucket(bucketName).objects(dos).build());return results;}//上傳文件,返回路徑public Object upload(HashMap<String, Object> paramMap) {MultipartFile file=(MultipartFile)paramMap.get("file");if (file.isEmpty() || file.getSize() == 0) {return "文件為空";}try {if (!this.bucketExists("file")) {this.makeBucket("file");}InputStream inputStream = file.getInputStream();String fileName = file.getOriginalFilename();String newName = UUID.randomUUID().toString().replaceAll("-", "")+ fileName.substring(fileName.lastIndexOf("."));this.upload("file", newName,file, inputStream);inputStream.close();String fileUrl = this.preview(newName,"file");String fileUrlNew=fileUrl.substring(0, fileUrl.indexOf("?"));JSONObject jsonObject=new JSONObject();jsonObject.put("url",fileUrlNew);return jsonObject.toJSONString();} catch (Exception e) {e.printStackTrace();return "上傳失敗";}}
}
項(xiàng)目中實(shí)踐