1. 程式人生 > >阿里雲物件儲存服務,OSS使用經驗總結,圖片儲存,分頁查詢

阿里雲物件儲存服務,OSS使用經驗總結,圖片儲存,分頁查詢

阿里雲OSS-使用經驗總結,儲存,賬號-許可權,分頁,縮圖,賬號切換

最近專案中,需要使用雲端儲存,最後選擇了阿里雲-物件儲存服務OSS。
總的來說,比較簡單,但是仍然遇到了幾個問題,需要總結下。


1.OSS總的使用介紹
  https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_object.html?spm=5176.docoss/api-reference/abstract.6.264.Zq5Hof
  和其它各種技術類似,幫助文件常見的欄目主要是:新手指南(入門)、產品簡介、API手冊(講某個介面的用法)、SDK(API的具體化,具體到程式語言)
  最佳實踐、計量付費等。
  
2.服務的價值

  之前用過又拍雲,聽說過七牛雲端儲存。
  總的來說,不同的雲廠商做得都差不多,功能總體一致,細節有所差異。
  訪問量大的公司,還是最好比較下服務的細節,測試下各家的效能。
  
  就功能來說,物件儲存的雲服務或者就統一叫做“雲端儲存”,不就是:儲存(上傳)、下載、訪問(圖片,直接在網頁中展示)、批量查詢。
  周邊功能,賬戶許可權、檔案許可權等。
  
  具體到檔案儲存,和本地Java的API,第三方的API都類似,只不過這個時候,儲存的實際物理位置在遠端伺服器上。
  高階一點的說法,就是“雲”。
  
3.OSS和雲端儲存
  雲端儲存,是一種廣泛的稱謂。
  物件儲存,檔案儲存,其它儲存,則場景更加具體一些。
  雲資料庫,本質還是雲端儲存,只是不是標準檔案罷了。
  
4.API和SDK

  官方文件:https://help.aliyun.com/document_detail/oss/api-reference/abstract.html?spm=5176.docoss/sdk/java-sdk/manage_object.6.196.zg3gsg
  配置賬號和密碼,建立遠端連線,執行操作,關閉連線。
  太多太多的SDK,都是這麼幾步。
  
5.遇到的幾個問題
  a.賬戶許可權

    用自己的賬號,阿里雲的AccessKeyId和AccessSecret,沒有遇到任何問題。
但是,用別人給的賬號,建立bucket和批量查詢的時候,總是提示沒有許可權。
第1次遇到許可權問題的時候,還不能確認,以為是某個地方沒有配置正確。再次遇到的時候,就提交了工單,和官方的技術支援人員確定了。
不懂的問題,提交工單,阿里雲的工單服務,還是很不錯的。

問題原因:別人給的賬號密碼,是子賬戶,分配許可權不夠。

新手入門,直接使用最高許可權就好。
更深入的許可權管理,RAM和STS使用指南,可參考
https://help.aliyun.com/document_detail/oss/practice/ram_guide.html?spm=5176.docoss/api-reference/abstract.6.179.H0uY1x
  
  b.圖片

    普通的文字檔案,圖片,都是檔案,儲存方式沒啥區別。
需要注意的是,在雲端,圖片邏輯上是“目錄”儲存,實際物理層次不是,可以根據字首prefix,來模擬目錄。

圖片,可以有額外的雲服務,比如圖片縮圖、縮放、反轉、水印、防盜鏈等。
    目前遇到的問題是,大尺寸的高清圖片,縮圖的寬度很小時,不夠清晰,而官網上的縮圖案例卻還比較清晰,不清楚為啥。

  c.分頁訪問
    官方API,是根據nextMarker(可以理解為下1頁開始的id),來分頁的,每頁最多獲得1000條。
沒有提供,一次性獲得所有圖片的介面,只能多次迭代,拿到所有的key。

在實際需要中,後端管理系統,想分頁檢視圖片列表,但是由於阿里雲的API功能有限,只能有“上一頁”和“下一頁”。
類似“1 2 3 4 5 .. 100 101”這種分頁展示方式,只能自己去實現。

我在做的時候,是通過多次迭代獲得所有圖片列表,快取到Redis中,然後手動實現分頁來做的。


6.自己封裝的程式碼
   只貼自己的核心程式碼,周邊的實體類和第三方jar,不再列出。
   
 
 import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;


import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;


import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.aliyun.oss.model.PutObjectRequest;

//阿里雲物件儲存服務OSS工具
public class OssUtil {


	// 演示,建立Bucket的時候,endpoint不能帶上.
	// 圖片上傳和簡單的圖片訪問也可以用這個。
	public static String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";


	// 圖片處理,需要用單獨的地址。訪問、裁剪、縮放、效果、水印、格式轉換等服務。
	// public static String endpointImg = "http://img-cn-hangzhou.aliyuncs.com";


	public static String accessKeyId = "hi";
	public static String accessKeySecret = "hi";
	public static String bucketName = "hi";


	// 單例,只需要建立一次連結
	private static OSSClient client = null;
	// 是否使用另外一套本地賬戶
	public static final boolean MINE = false;


	static {
		if (MINE) {
			accessKeyId = "hi2";
			accessKeySecret = "hi2";
			bucketName = "hi2";
			endpoint = "http://oss-cn-shanghai.aliyuncs.com";
		}
	}


	//配置引數
	static ClientConfiguration config() {
		ClientConfiguration conf = new ClientConfiguration();
		conf.setMaxConnections(100);
		conf.setConnectionTimeout(5000);
		conf.setMaxErrorRetry(3);
		conf.setSocketTimeout(2000);
		return conf;
	}


	//客戶端
	public static OSSClient client() {
		if (client == null) {
			ClientConfiguration conf = config();
			client = new OSSClient(endpoint, accessKeyId, accessKeySecret, conf);
			makeBucket(client, bucketName);
		}
		return client;
	}


	//建立Bucket
	public static void makeBucket(String bucketName) {
		OSSClient client = client();
		makeBucket(client, bucketName);
	}


	//建立Bucket
	public static void makeBucket(OSSClient client, String bucketName) {
		boolean exist = client.doesBucketExist(bucketName);
		if (exist) {
			p("The bucket exist.");
			return;
		}
		client.createBucket(bucketName);
	}


	//上傳一個檔案,InputStream
	public static void uploadFile(InputStream is, String key) {
		OSSClient client = client();
		PutObjectRequest putObjectRequest = new PutObjectRequest(
				OssUtil.bucketName, key, is);
		client.putObject(putObjectRequest);
	}


	//上傳一個檔案,File
	public static void uploadFile(File file, String key) {
		OSSClient client = client();
		PutObjectRequest putObjectRequest = new PutObjectRequest(
				OssUtil.bucketName, key, file);
		client.putObject(putObjectRequest);
	}


	//下載一個檔案到本地
	public static OSSObject downloadFile(String key) {
		OSSClient client = client();
		GetObjectRequest getObjectRequest = new GetObjectRequest(
				OssUtil.bucketName, key);
		OSSObject object = client.getObject(getObjectRequest);
		return object;
	}


	//上傳某個檔案到某個目錄,key是自動生成的
	public static String uploadFile(MultipartFile file, String dir)
			throws IOException {
		if (null != file && !file.isEmpty() && file.getSize() > 0) {
			String fileName = UuidUtil.get32UUID()
					+ "."
					+ StringUtils.substringAfterLast(
							file.getOriginalFilename(), ".");
			String ymd = DateUtil.getDays();
			String key = dir + ymd + "/" + fileName;
			OssUtil.uploadFile(file.getInputStream(), key);
			return key;
		}
		return null;
	}


	//刪除某個檔案
	public static void delete(String key) {
		if (BackendConst.OSS_DELTE_IMG) {
			try {
				client().deleteObject(OssUtil.bucketName, key);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}


	//建立目錄,不能以斜槓“/”開頭
	public static void makeDir(String keySuffixWithSlash) {
		OSSClient client = client();
		/*
		 * Create an empty folder without request body, note that the key must
		 * be suffixed with a slash
		 */
		if (StringUtils.isEmpty(keySuffixWithSlash)) {
			return;
		}
		if (!keySuffixWithSlash.endsWith("/")) {
			keySuffixWithSlash += "/";
		}
		client.putObject(bucketName, keySuffixWithSlash,
				new ByteArrayInputStream(new byte[0]));
	}


	// 實時的分頁查詢
	public static OssPage listPage(String dir, String nextMarker,
			Integer maxKeys) {
		OSSClient client = client();
		ListObjectsRequest listObjectsRequest = new ListObjectsRequest(
				bucketName);
		if (StringUtils.isNoneBlank(dir)) {
			listObjectsRequest.setPrefix(dir);
		}
		if (StringUtils.isNoneBlank(nextMarker)) {
			listObjectsRequest.setMarker(nextMarker);
		}
		if (maxKeys != null) {
			listObjectsRequest.setMaxKeys(maxKeys);
		}
		ObjectListing objectListing = client.listObjects(listObjectsRequest);


		List<OSSObjectSummary> summrayList = objectListing.getObjectSummaries();
		List<OssItem> itemList = summaryToItem(summrayList);
		OssPage page = new OssPage();


		String newxNextMarker = objectListing.getNextMarker();
		page.setNextMarker(newxNextMarker);
		page.setSummrayList(itemList);
		return page;
	}


	//把OSS的物件,轉換成自己的。因為OSS的物件沒有實現Serialiable,不能序列化。
	private static List<OssItem> summaryToItem(
			List<OSSObjectSummary> summrayList) {
		List<OssItem> itemList = new ArrayList<OssItem>();
		for (OSSObjectSummary summary : summrayList) {
			OssItem item = new OssItem();
			try {
				BeanUtils.copyProperties(item, summary);
				itemList.add(item);
			} catch (IllegalAccessException | InvocationTargetException e) {
				e.printStackTrace();
			}
		}
		return itemList;
	}


	//一次迭代,獲得某個目錄下的所有檔案列表
	public static List<OssItem> listAll(String dir) {
		OSSClient client = client();
		List<OssItem> list = new ArrayList<OssItem>();
		// 查詢
		ObjectListing objectListing = null;
		String nextMarker = null;
		final int maxKeys = 1000;


		do {
			ListObjectsRequest listObjectsRequest = new ListObjectsRequest(
					bucketName).withPrefix(dir).withMarker(nextMarker)
					.withMaxKeys(maxKeys);
			objectListing = client.listObjects(listObjectsRequest);


			List<OSSObjectSummary> summrayList = objectListing
					.getObjectSummaries();
			List<OssItem> itemList = summaryToItem(summrayList);
			list.addAll(itemList);
			nextMarker = objectListing.getNextMarker();
		} while (objectListing.isTruncated());
		return list;
	}


	public static void p(Object str) {
		System.out.println(str);
	}


	public static void print(OSSException oe) {
		p("Caught an OSSException, which means your request made it to OSS, "
				+ "but was rejected with an error response for some reason.");
		p("Error Message: " + oe.getErrorCode());
		p("Error Code:       " + oe.getErrorCode());
		p("Request ID:      " + oe.getRequestId());
		p("Host ID:           " + oe.getHostId());
	}
}


7.圖片展示和縮圖
展示圖片,需要使用單獨的域名
${imgDomain}/${imgUrl}@100w @100w是縮圖語法
http://b.img-cn-hangzhou.aliyuncs.com/product/[email protected]


oss.properties
oss.endpoint = http://oss-cn-hangzhou.aliyuncs.com
oss.accessKeyId=hi
oss.accessKeySecret=hi
oss.bucketName=b


oss.fileDomain=http://b.oss-cn-hangzhou.aliyuncs.com
oss.imgDomain=http://b.img-cn-hangzhou.aliyuncs.com



8.小結
  先去官網看文件,大概1天可以實現基礎功能。
  圖片批量查詢、高階的賬戶許可權配置、圖片服務(縮圖、CDN、防盜鏈、自定義域名),稍微麻煩一點.
  按道理來講,一週可以掌握絕大部分內容。
  先快速瀏覽文件,把專案中最需要的先實現,更多高階功能,用到的時候,再深入研究也是不錯的。
  
  在遇到問題的時候,網上搜索了下,基本還沒有資料,只能去官網,實現不行,就提交工單,和權威的官方技術支援人員交流。

相關推薦

基於Metronic的Bootstrap開發框架經驗總結(2)--列表處理和外掛JSTree的使用

在上篇《基於Metronic的Bootstrap開發框架經驗總結(1)-框架總覽及選單模組的處理》介紹了Bootstrap開發框架的一些基礎性概括,包括總體介面效果,以及佈局、選單等內容,本篇繼續這一主題,介紹頁面內容常用到的資料分頁處理,以及Bootstrap外掛JSTree的使用。在資料的介面顯示當中,表

阿里物件儲存服務OSS使用經驗總結圖片儲存查詢

阿里雲OSS-使用經驗總結,儲存,賬號-許可權,分頁,縮圖,賬號切換最近專案中,需要使用雲端儲存,最後選擇了阿里雲-物件儲存服務OSS。總的來說,比較簡單,但是仍然遇到了幾個問題,需要總結下。1.OSS總的使用介紹  https://help.aliyun.com/docum

OSS阿里物件儲存服務前端JS下載日誌檔案

function downurl(path) {  var client = new OSS({ region: '地區', accessKeyId: 'accessKeyId', accessKeySecret: 'accessKeySecret', bucket: '域

react使用阿里物件儲存,ali-oss, antd upload to ali-oss

最近寫阿里雲圖片上傳,碰到一些小問題,在此總結一下. 專案環境: create-react-app antd node6.1.0 看了阿里雲oss物件儲存sdk 直接採用node 的安裝方式. 在使用的時候碰到了問題. yield client.put('file',

阿里-物件儲存OSS

文件地址 https://help.aliyun.com/document_detail/32099.html?spm=a2c4g.11186623.6.766.74cdc839H0RSId 安裝(此處為composer安裝) 1、PHP 5.3+ 2、擴

阿里物件儲存OSS)使用小結

本文為使用OSS物件儲存小結,無廣告之嫌。 一.建立javaOSS上傳工具類 需要匯入的jar包在網站有,需要注意的是,httpclient.jar和httpcore.jar的版本需要保持一致,不然會上傳出錯。slf4j.jar 系列的也需要保持一致,上程式碼。 i

阿里物件儲存OSS使用記錄: 如何把oss中Bucket的檔案URL連線設定成永久有效

一、OSS本身的許可權控制 1.許可權型別 Bucket目前有三種訪問許可權:public-read-write,public-read和private; 2.許可權設定與獲取 通過控制檯設定Bucket級別和object級別的操作; 控制檯: Bucket:

在 Laravel 5.5+ 應用中配置使用阿里提供的簡訊服務及檔案儲存服務OSS

  配置簡訊服務 基於Laravel框架的使用方法 安裝 composer require mrgoon/aliyun-sms dev-master 在config/app.php中新增如下程式碼 'providers' => [

阿里物件儲存OSS之通過URL形式進行圖片處理

文章目錄 1. 什麼是OSS 2. OSS圖片服務 3. 圖片處理訪問規則 4. 通過URL的形式 5. 多個action之間組合形式 5.1 示例 5.2 圖片旋轉 5.3 圖片裁剪

阿里物件儲存OSS--實現隨時隨地上傳檔案到阿里

需求背景:消費者多批次回饋我司生產的車載智慧後視鏡出現宕機、連不上伺服器等問題,因產品已經出到全國各地不方便去取異常log,也不可能要求消費者把log傳給我們分析。 需求目標:公司內部實現遠端後臺上傳問題機型的log。 必備條件:後視鏡有SIM卡且能夠聯網(

第八彈——阿里物件雲端儲存OSS

筆者也是剛剛接觸這種新東西,研究了一會搞懂了它的簡單的用法,我主要把一些圖片存在上面,通過外網連線供我的網頁呼叫,這樣直接省了一部分頻寬,額,我感覺有些用叉了,有點當成CDN的感覺………… 不說了,先來看看阿里雲官方的介紹: 阿里雲物件儲存服務(Obj

關於阿裏OSS故障排查解決以及經驗總結

family spa 經驗總結 需要 至少 聯系 訪問 宋體 ces 背景描述 在2018年1月22日星期一,早上發現部署在阿裏雲所有服務無法訪問,登錄到阿裏雲控制臺,首先查看SLB負載均衡器狀態,發現所有公網負載均衡器被停用,專網負載均衡器工作正常。電話聯系

第一步阿里資料傳輸服務DTS上攻略之遷移能力

由於雲的便利性及高可靠等特性,越來越多的企業客戶選擇上雲。大家上雲遇到的第一個問題就是如何在業務不受影響的情況下,平滑得完成業務的上雲遷移。在上雲過程中,最重要的環節是資料遷移。阿里雲資料傳輸服務DTS提供的不停服資料遷移能力,能夠在源資料庫正常提供服務的情況下,平滑得完成業務的上雲遷移。

阿里智慧媒體服務 oss文件轉換及預覽

本人 在工作中 也是接觸到這個需求 我們本身的文件 都儲存在阿里雲的oss上 ,由於瀏覽文件需要下載後觀看 為了方便瀏覽文件方便 開了這樣一個功能 將文件轉換成圖片來進行預覽 好了 廢話就不多說了 下面給大家來點實實在在的乾貨,以防大家在以後工作中遇到這些問題。 當

阿里apache伺服器外網無法訪問(配置安全組新增80服務

背景:暑假 給學校校長辦公室做網站,因為都回家,外網需要能訪問到的原因,所以把 網站搬到了阿里雲主機上 CentOS的系統 ,已經安裝好了 apache php mysql 常規排錯過程(ps:沒耐心的童鞋請直接看最後一步,學習在阿里雲控制檯配置 安全組

通過雲端儲存閘道器實現阿里物件儲存跨地域訪問

某客戶在阿里雲的上海地域內有一臺位於VPC內部的ECS,想訪問同一阿里雲賬號下位於北京地域的一個OSS Bucket裡面的資料,同時又希望走阿里雲的內網流量以享受內網的頻寬。因為北京上海屬於不同的地域,所以如果使用ossutil或者ossfs這樣的工具進行Bucket裡面的檔案的直接訪問,只能

Java呼叫阿里簡訊通道服務

這裡我們使用SpringBoot 來呼叫阿里通訊的服務。 (用哪個框架無所謂,即便是統Java工程也能實現,但需要連網) 阿里通訊,雙11.收到簡訊,日傳送達6億條。保障力度非常高。 使用的步驟: 第一步:需要開通賬戶 第二步:閱讀介面文件 祕鑰管理 簡訊簽名 簡訊模板

阿里建立svn服務

原文連結 SVN的搭建和使用   簡介 Subversion(SVN) 是一個開源的版本控制系統, 也就是說 Subversion 管理著隨時間改變的資料。 這些資料放置在一箇中央資料檔案庫(repository) 中。 這個檔案庫很像一個普通的檔案伺服器, 不過它

EduSoho 二次開發接入阿里視訊點播服務mp4格式視訊會被直接下載問題解決方案

EduSoho 阿里雲視訊點播服務mp4視訊會被直接下載的問題解決方案 開發遇到一個問題就是視訊點播服務接入後暴露直接地址設定很多地方都無法解決尤其是面對一些流氓軟體 解決辦法,設定URL鑑權和Ref

Swoole一鍵操作基於阿里的RDS資料庫遷移+OSS檔案搬遷

    傳統的資料庫搬遷思路是把資料庫表的結構及資料都查詢出來,然後通過迴圈進行資料結構重組拼接。然後匯出!資料量少的話,這樣當然是沒毛病。當資料量太大的時候,伺服器的記憶體開銷就吃不住了,很容易炸掉,導致伺服器癱掉。當然我之前也這麼幹的 ,所以也一直想辦法解決這個問題  ,