利用 MinIO 輕鬆搭建靜態資源服務

若是想搭建一個優雅、簡單、功能完備的靜態資源服務,那就用MinIO吧。css

1 引言

開發 Web 項目過程當中,常常須要處理靜態資源(如圖片、視頻、音頻,js庫 ,css 庫等),通常來講,若項目中須要用到這些資源文件,咱們經常使用的有如下幾種方法:html

  • 本地存儲:即在項目工程中的 static 目錄下,創建 js/css/icon/font/image/lib/audio/video 等目錄,分別存放對應格式的資源文件。使用時,在 html 文件中使用相對位置引用進行。
  • 使用代理搭建靜態資源服務:即把資源存放於某一文件目錄,使用代理服務器(如 nginx ,apache等)對目錄進行映射,構建成資源服務。使用時,在 html 文件中使用代理服務的 url 地址進行引用。
  • 使用第三方工具搭建靜態資源服務:使用第三方開源的文件存儲或對象存儲工具,或者本身寫個程序實現能夠獲取文件的接口。使用時,使用對應的 url 地址或接口地址。
  • 使用在線靜態資源服務:如CDN等服務。

對於本地存儲,缺點就很明顯,資源與代碼文件混合一塊兒,沒有必要,並且不方便擴展。對於本地內部部署的應用,顯然是本身搭建靜態資源服務比較穩妥。對於使用代理服務和第三方工具,相比起來,代理服務僅作映射,雖然可用,但功能單一,僅作映射,沒有其它管理功能,也不方便擴展。使用第三方文件或對象存儲工具,能夠對文件進行管理、也能考慮高擴展,高性能、高可用等因素,所以是很好的選擇,其中,MinIO 就是這樣一款好用的對象存儲工具,簡單,快捷並且功能完備。java

本文則是經過對 MinIO 的安裝、配置與使用,構建靜態資源服務,從而把圖片、視頻、音頻,第三方 js 庫等資源獨立部署,訪問;還會對 MinIO 提供的 Java API 進行使用簡單介紹,以便於進一步開發。linux

2 MinIO 簡介

MinIO 官方介紹,MinIO 是高性能的對象存儲(塊存儲、文件存儲和對象存儲的區別,可參考架構師都知道的分佈式對象存儲解決方案),兼容 Amazon S3 接口,充分考慮開發人員的需求和體驗;支持分佈式存儲,具有高擴展性、高可用性;部署簡單但功能豐富。官方的文檔也很詳細。它有多種不一樣的部署模式(單機部署,分佈式部署)。爲何說 MinIO 簡單易用,緣由就在於它的啓動、運行和配置都很簡單。能夠經過 docker 方式進行安裝運行,也能夠下載二進制文件,而後使用腳本運行。nginx

本文以最簡單的方式進行講解,在 linux 機器中,單機部署,運行二進制文件。git

3 MinIO 運行與靜態資源使用

3.1 MinIO 獲取

MinIO 開發文檔中,下載地址以下:github

  • linux: https://dl.min.io/server/minio/release/linux-amd64/minio
  • windows: https://dl.min.io/server/minio/release/windows-amd64/minio.exe

本文在 linux 中運行。spring

3.2 MinIO 啓動與運行

3.2.1 前臺簡單啓動

把下載的 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 就會結束進程,服務就中止
  • 沒有自定義訪問的用戶名密碼
  • 沒有指定訪問IP和端口
  • 日誌沒有保留到文件

針對這些問題,建議使用下面的方式進行啓動運行。

3.2.2 後臺指定參數運行

使用 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_KEYMINIO_SECRET_KEY 是訪問密碼

${MINIO_HOST}:${MINIO_PORT} 分別是訪問的 host 和端口,請按實際狀況修改。

這樣,經過瀏覽器訪問地址 ${MINIO_HOST}:${MINIO_PORT} ,使用指定的 MINIO_ACCESS_KEYMINIO_SECRET_KEY 登陸便可。

3.2.3 建立 bucket 並指定訪問策略

在瀏覽器中登陸到 MinIO 存儲系統,點擊右下角建立 bucket 來存儲對象,分別建立對應的 bucket 以存放靜態資源:image,video,audio。這樣,就能夠按資源類型在對應的 bucket 中進行文件上傳了,上傳後能夠把文件分享,其它地方能夠經過分享的 url 獲取資源,以下圖所示。

分享文件

MinIO 默認的策略是分享地址的有效時間最可能是7天,要突破這種限制,能夠在 bucket 中進行策略設置。點擊對應的 bucket ,edit policy 添加策略 *.*Read Only,以下:

edit policy

如此就放開了訪問,沒有時間限制,同時只須要按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)

3.3 在 html 文件中引用靜態資源

經過上面的設置與運行,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>
複製代碼

可發現資源是能夠正常加載訪問的。

4 Java 客戶端 API 操做

MinIO 對開發者是很是友好的,提供了各類語言的 API 操做接口,具體能夠參考 MinIO開發文檔。下面以 Java 爲例作一下測試。

4.1 添加依賴

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>6.0.13</version>
</dependency>
複製代碼

4.2 使用 Java API 進行文件操做

創建 MinIO 的操做客戶端 minioClient = new MinioClient(endpoint, accessKey, secretKey);,參數中endpoint 是 MinIO 的訪問地址,後面兩對應啓動時設置的密碼。

4.2.1 上傳文件

/** * 上傳文件 * @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);
    }
}
複製代碼

4.2.2 下載文件

/** * 下載文件 * * @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);
    }
}
複製代碼

4.2.3 刪除文件

刪除文件簡單,使用removeObject便可。

minioClient.removeObject(bucketName, objectName);
複製代碼

4.2.4 列出文件

/** * 羅列文件 * @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);
    }
}
複製代碼

5 總結

因爲有對靜態資源進行獨立訪問的需求,進行動靜分離,經過使用 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

參考資料

往期文章

個人公衆號(搜索Mason技術記錄),獲取更多技術記錄:

mason
相關文章
相關標籤/搜索