若是想搭建一個優雅、簡單、功能完備的靜態資源服務,那就用MinIO吧。css
開發 Web 項目過程當中,常常須要處理靜態資源(如圖片、視頻、音頻,js庫 ,css 庫等),通常來講,若項目中須要用到這些資源文件,咱們經常使用的有如下幾種方法:html
對於本地存儲,缺點就很明顯,資源與代碼文件混合一塊兒,沒有必要,並且不方便擴展。對於本地內部部署的應用,顯然是本身搭建靜態資源服務比較穩妥。對於使用代理服務和第三方工具,相比起來,代理服務僅作映射,雖然可用,但功能單一,僅作映射,沒有其它管理功能,也不方便擴展。使用第三方文件或對象存儲工具,能夠對文件進行管理、也能考慮高擴展,高性能、高可用等因素,所以是很好的選擇,其中,MinIO 就是這樣一款好用的對象存儲工具,簡單,快捷並且功能完備。java
本文則是經過對 MinIO 的安裝、配置與使用,構建靜態資源服務,從而把圖片、視頻、音頻,第三方 js 庫等資源獨立部署,訪問;還會對 MinIO 提供的 Java API 進行使用簡單介紹,以便於進一步開發。linux
按 MinIO 官方介紹,MinIO 是高性能的對象存儲(塊存儲、文件存儲和對象存儲的區別,可參考架構師都知道的分佈式對象存儲解決方案),兼容 Amazon S3 接口,充分考慮開發人員的需求和體驗;支持分佈式存儲,具有高擴展性、高可用性;部署簡單但功能豐富。官方的文檔也很詳細。它有多種不一樣的部署模式(單機部署,分佈式部署)。爲何說 MinIO 簡單易用,緣由就在於它的啓動、運行和配置都很簡單。能夠經過 docker 方式進行安裝運行,也能夠下載二進制文件,而後使用腳本運行。nginx
本文以最簡單的方式進行講解,在 linux 機器中,單機部署,運行二進制文件。git
MinIO 開發文檔中,下載地址以下:github
https://dl.min.io/server/minio/release/linux-amd64/minio
https://dl.min.io/server/minio/release/windows-amd64/minio.exe
本文在 linux 中運行。spring
把下載的 minio 文件存放到某個目錄做爲運行目錄(如 /opt/minio),新建一個目錄(如/opt/minio-data)做爲 minio 數據存儲位置,便可啓動,以下腳本:docker
cd /opt/minio
chmod +x minio
./minio server /opt/minio-data
複製代碼
啓動後會輸出訪問地址 endpoint 和對應的 access_key 和 secret_key,使用瀏覽器訪問 endpoint 地址,若能夠訪問,則表示 minio 已經安裝成功。不過這樣啓動會有幾個缺點:shell
ctrl+c
就會結束進程,服務就中止針對這些問題,建議使用下面的方式進行啓動運行。
使用 nohup
在後臺運行程序,同時指定密碼參數,訪問地址參數和日誌輸出,以下所示。
MINIO_ACCESS_KEY=minio MINIO_SECRET_KEY=minio123 nohup /opt/minio/minio server --address "${MINIO_HOST}:${MINIO_PORT}" /opt/minio-data > /opt/minio/minio.log 2>&1 &
複製代碼
MINIO_ACCESS_KEY
及MINIO_SECRET_KEY
是訪問密碼
${MINIO_HOST}:${MINIO_PORT}
分別是訪問的 host 和端口,請按實際狀況修改。
這樣,經過瀏覽器訪問地址 ${MINIO_HOST}:${MINIO_PORT}
,使用指定的 MINIO_ACCESS_KEY
及 MINIO_SECRET_KEY
登陸便可。
在瀏覽器中登陸到 MinIO 存儲系統,點擊右下角建立 bucket 來存儲對象,分別建立對應的 bucket 以存放靜態資源:image,video,audio。這樣,就能夠按資源類型在對應的 bucket 中進行文件上傳了,上傳後能夠把文件分享,其它地方能夠經過分享的 url 獲取資源,以下圖所示。
MinIO 默認的策略是分享地址的有效時間最可能是7天,要突破這種限制,能夠在 bucket 中進行策略設置。點擊對應的 bucket ,edit policy
添加策略 *.*
,Read Only
,以下:
如此就放開了訪問,沒有時間限制,同時只須要按http://${MINIO_HOST}:${MINIO_PORT}/${bucketName}/${fileName}
則可直接訪問資源(不須要進行分享操做)。
關於 MinIO 目錄的誤區
- 其實對於對象存儲來講,其實不區分文件仍是目錄,全部文件和目錄都是對象,即 image/temp/xxx.jpg 和 image/temp/ 都是對象。它跟操做系統的文件系統的樹狀結構有本質區別。
- 上傳文件時,objectName 能夠是
/temp/xxx.jpg
,能夠認爲系統自動建立了temp目錄。- MinIO 不會提供像刪除目錄,同時刪除此目錄下全部文件的操做(即
rm -rf image/temp
),所以要想把目錄 image/temp 刪除,則須要先把以 image/temp 爲前綴的全部文件刪除。- 查詢多個文件時,可使用前綴匹配方式獲取,見 API 文檔
listObjects(bucketName, prefix, recursive)
經過上面的設置與運行,MinIO 做爲靜態資源服務器已經完成,能夠寫個 html 來引用 MinIO 中的靜態資源。以下是測試的 html 裏面的圖片、視頻、音頻均使用 MinIO 的資源地址。
<div class="img-list">
<img src="http://${MINIO_HOST}:${MINIO_PORT}/image/test.jpg" alt="圖片">
</div>
<div class="audio-list">
<audio src="http://${MINIO_HOST}:${MINIO_PORT}/audio/test.mp3" controls="controls"></audio>
</div>
<div class="video-list">
<video src="http://${MINIO_HOST}:${MINIO_PORT}/video/test.mp4" controls="controls"></video>
</div>
複製代碼
可發現資源是能夠正常加載訪問的。
MinIO 對開發者是很是友好的,提供了各類語言的 API 操做接口,具體能夠參考 MinIO開發文檔。下面以 Java 爲例作一下測試。
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>6.0.13</version>
</dependency>
複製代碼
創建 MinIO 的操做客戶端 minioClient = new MinioClient(endpoint, accessKey, secretKey);
,參數中endpoint
是 MinIO 的訪問地址,後面兩對應啓動時設置的密碼。
/** * 上傳文件 * @param minioClient 操做客戶端 * @param bucketName 上傳的bucket名稱 * @param objectName 上傳後存儲在bucket中的文件名 * @param filePath 上傳的本地文件路徑 */
public void uploadFile(MinioClient minioClient, String bucketName, String objectName, String filePath) throws XmlPullParserException, NoSuchAlgorithmException, InvalidKeyException, IOException {
try {
// 若不存在bucket,則新建
boolean isExist = minioClient.bucketExists(bucketName);
if (!isExist) {
minioClient.makeBucket(bucketName);
}
// 使用 putObject 上傳文件
minioClient.putObject(bucketName, objectName, filePath, null, null, null, null);
} catch (MinioException e) {
System.out.println("Error occurred: " + e);
}
}
複製代碼
/** * 下載文件 * * @param minioClient 操做客戶端 * @param bucketName 上傳的bucket名稱 * @param objectName 上傳後存儲在bucket中的文件名 * @param downloadPath 下載文件保存路徑 */
public void downloadFile(MinioClient minioClient, String bucketName, String objectName, String downloadPath) throws XmlPullParserException, NoSuchAlgorithmException, InvalidKeyException, IOException {
File file = new File(downloadPath);
try (OutputStream out = new FileOutputStream(file)) {
InputStream inputStream = minioClient.getObject(bucketName, objectName);
byte[] tempbytes = new byte[1024];
int byteread = 0;
while ((byteread = inputStream.read(tempbytes)) != -1) {
out.write(tempbytes, 0, byteread);
}
} catch (MinioException e) {
System.out.println("Error occurred: " + e);
}
}
複製代碼
刪除文件簡單,使用removeObject
便可。
minioClient.removeObject(bucketName, objectName);
複製代碼
/** * 羅列文件 * @param minioClient * @param bucketName */
public void listFile(MinioClient minioClient, String bucketName) throws XmlPullParserException, NoSuchAlgorithmException, InvalidKeyException, IOException {
try {
Iterable<Result<Item>> results = minioClient.listObjects(bucketName);
Iterator<Result<Item>> iterator = results.iterator();
while (iterator.hasNext()) {
Item item = iterator.next().get();
System.out.println(item.objectName() + ", " + item.objectSize() + "B");
}
} catch (MinioException e) {
System.out.println("Error occurred: " + e);
}
}
複製代碼
因爲有對靜態資源進行獨立訪問的需求,進行動靜分離,經過使用 MinIO ,能夠快速簡單的實現靜態資源服務器,以供訪問。本文經過對 MinIO 的下載、部署、啓動、運行、配置等描述,並以 html 引用靜態資源文件爲例,講解 MinIO 的使用,並提供 Java API 的簡單使用。但願對你們有幫助。
本文中使用了 nohup 對 MinIO 進行啓動,但命令太長,通常咱們都會寫成腳本,以實現啓動、關閉及狀態查詢,所以,我把腳本寫成完整的 sh 文件,以供你們使用。另外,MinIO Java API 的測試,本示例使用的是 Spring Boot 項目,以單元測試的方式進行。
sh腳本文件及 Spring Boot 工程一塊兒放在個人 minio github 示例 中(腳本minio-serviced.sh
在 scripts 目錄下),有須要的可下載參考。
腳本使用方法:
- 根據實際狀況修改sh腳本中的參數
- 修改執行權限:chmod +x minio-serviced.sh
- 按參數啓動/關閉/重啓/運行狀態:./minio-serviced.sh start/stop/restart/status
https://min.io/
https://docs.min.io/
https://mp.weixin.qq.com/s/MzA4ODg0NDkzOA==&mid=2247487119&idx=1&sn=6e09abb32392e015911be3a1d7f066e5&source=41
https://juejin.im/post/5cdc16e251882568651553f9
https://tonybai.com/2020/03/16/build-high-performance-object-storage-with-minio-part1-prototype
個人公衆號(搜索Mason技術記錄
),獲取更多技術記錄: