目錄
對象存儲背景? ? ? ??
阿里云OSS
對象存儲背景? ? ? ??
????????單節點環境下,文件往往存儲在tomcat服務器內,隨著業務需求的增多,單節點已不能滿足需求,項目架構需要擴展到多節點(見下圖),此時文件經過nginx轉發存儲到某一個節點,在分布式架構下對文件的訪問就存在問題(文件存儲到節點A,查看文件請求到節點B訪問不了文件)。
? ? ? ? 在分布式環境下,需要引入集中管理文件的節點服務,改進如下:
? ? ? ? 分布式文件服務解決方案有很多,常見的有:獨立搭建文件服務器,如基于開源FastDFS搭建;引入第三方云儲存方案,如基于阿里云的OSS;相比獨立搭建文件服務器,云存儲方案有諸多優勢:SDK使用簡單、運維成本低、圖形化的管理控制臺、提供強大的文件處理功能、CDN加速、服務擴展簡單等,本文重點講述基于阿里云的OSS方案。
阿里云OSS
? ? ? ? 使用步驟如下:
? ? ? ? 1、【阿里云官網】開通OSS服務
? ? ? ? 2、【阿里云官網】創建Bucket
? ? ? ? 重點關注標簽有:Bucket 名稱、Endpoint,本文新建的Bucket 名稱 =?gingko-sawyer,Endpoint =?oss-cn-beijing.aliyuncs.com
? ? ? ? 3、【阿里云官網】創建并使用RAM賬號進行API訪問或日常運維,請登錄RAM控制臺創建RAM賬號,創建AccessKey,并將AccessKeyId和AccessKeySecret設置到本地電腦環境變量中。
? ? ? ? 4、后臺編寫代碼實現基于阿里云OSS文件上傳及下載
? ? ? ? 4.1、添加aliyun.oss依賴
<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.17.4</version>
</dependency>
????????4.2、修改配置,增加對oss的支持
server:port: 8080
#aliyun oss config
aliyun:oss:endpoint: oss-cn-beijing.aliyuncs.comregion: cn-beijingbucket-name: gingko-sawyerfoler-prefix: oss/host: https://gingko-sawyer.oss-cn-beijing.aliyuncs.com
? ? ? ? 4.3 文件上傳&下載程序
package com.ginko.aliyunoss.controller;import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.Protocol;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.InputStream;@RestController
@RequestMapping("oss")
@Slf4j
public class OSSController {@Value("${aliyun.oss.endpoint}")private String endpoint;@Value("${aliyun.oss.region}")private String region;@Value("${aliyun.oss.bucket-name}")private String bucketName;@Value("${aliyun.oss.foler-prefix}")private String folerPrefix;//上傳到oss中具體的文件夾目錄@Value("${aliyun.oss.host}")private String host;@PostMapping("/upload")public String upload(@RequestParam("file") MultipartFile file) throws Exception {// 創建 ClientBuilderConfiguration 實例,用于配置 OSS 客戶端參數ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();// 設置簽名算法版本為 V4clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);// 設置使用 HTTPS 協議訪問 OSS,保證傳輸安全性clientBuilderConfiguration.setProtocol(Protocol.HTTPS);// 創建 OSS 客戶端實例OSS ossClient = OSSClientBuilder.create()// endpoint.endpoint(this.endpoint)// 從環境變量中獲取訪問憑證(需提前配置 OSS_ACCESS_KEY_ID 和 OSS_ACCESS_KEY_SECRET).credentialsProvider(CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider())// 設置客戶端配置.clientConfiguration(clientBuilderConfiguration)// 設置region.region(this.region).build();try {// 填寫Bucket名稱String bucketName = this.bucketName;// 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。String objectName = this.folerPrefix + file.getOriginalFilename();InputStream inputStream = file.getInputStream();// 創建PutObjectRequest對象。PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);// 創建PutObject請求。PutObjectResult result = ossClient.putObject(putObjectRequest);System.out.println(result);} finally {// 當OSSClient實例不再使用時,調用shutdown方法以釋放資源ossClient.shutdown();}return "success";}@PostMapping("/download")public String download() throws Exception {// Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。String endpoint = this.endpoint;//從環境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設置環境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();// 填寫Bucket名稱,例如examplebucket。String bucketName = this.bucketName;// 填寫不包含Bucket名稱在內的Object完整路徑,例如testfolder/exampleobject.txt。String objectName = this.folerPrefix + "1.png";// 填寫Object下載到本地的完整路徑。String pathName = "D:\\rename.png";// 填寫Bucket所在地域。以華東1(杭州)為例,Region填寫為cn-hangzhou。String region = this.region;// 創建OSSClient實例。// 當OSSClient實例不再使用時,調用shutdown方法以釋放資源。ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);OSS ossClient = OSSClientBuilder.create().endpoint(endpoint).credentialsProvider(credentialsProvider).clientConfiguration(clientBuilderConfiguration).region(region).build();try {// 下載Object到本地文件,并保存到指定的本地路徑中。如果指定的本地文件存在會覆蓋,不存在則新建。// 如果未指定本地路徑,則下載后的文件默認保存到示例程序所屬項目對應本地路徑中。ObjectMetadata object = ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(pathName));} catch (OSSException oe) {System.out.println("Caught an OSSException, which means your request made it to OSS, "+ "but was rejected with an error response for some reason.");System.out.println("Error Message:" + oe.getErrorMessage());System.out.println("Error Code:" + oe.getErrorCode());System.out.println("Request ID:" + oe.getRequestId());System.out.println("Host ID:" + oe.getHostId());} catch (ClientException ce) {System.out.println("Caught an ClientException, which means the client encountered "+ "a serious internal problem while trying to communicate with OSS, "+ "such as not being able to access the network.");System.out.println("Error Message:" + ce.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}return "success";}
}
? ? ? ? 5、測試,通過postman模擬上傳及下載文件
? ? ? ? 如下圖所示,1.png文件已經被上傳到oss中,rename.png是從oss下載到本地的文件