寧夏銀川網(wǎng)站建設(shè)游戲app拉新平臺(tái)
前言:
這段時(shí)間來(lái)到了某大數(shù)據(jù)平臺(tái),做平臺(tái)技術(shù)底座封裝和一些架構(gòu)等等,有結(jié)構(gòu)化數(shù)據(jù)也有非結(jié)構(gòu)數(shù)據(jù),涉及到很多技術(shù),自己也私下花時(shí)間去研究了很多,有很多純技術(shù)類的還是需要梳理并記錄,鞏固以及復(fù)習(xí)。一個(gè)項(xiàng)目用到了幾個(gè)云存儲(chǔ),其中就包括Amazon S3,這邊就學(xué)習(xí)并記錄和復(fù)習(xí)一下。
Amazon S3簡(jiǎn)介
Amazon 最早推出的兩項(xiàng)云服務(wù):EC2 和 S3。
- Amazon S3:Amazon Simple Storage Service(亞馬遜簡(jiǎn)易存儲(chǔ)服務(wù));
- EC2 :Elastic Compute Cloud(彈性計(jì)算云,即云中的虛擬服務(wù)器);
- Amazon S3支持REST風(fēng)格,即通過(guò)GET、PUT、DELETE、POST、PATCH操作服務(wù)端的資源;
- Amazon S3 操作:Service,Buckets和Objects。
- Service 只包括 GET 操作,就是返回所有的 Buckets 的列表。
- Object 顧名思義,是指存儲(chǔ)在云端的文件,值得注意的是,S3 中并沒(méi)有明確的文件夾的概念,而是通過(guò)指定 object 的路徑來(lái)實(shí)現(xiàn),比如說(shuō),object 可以為 “photos/1.jpg”。
- Bucket 擁有全局名,名稱由用戶定義,用來(lái)存放 Object,由于是全局名,所以要確保名字是別人沒(méi)用過(guò)的。
S3 Http request headers
具體可以查看亞馬孫官網(wǎng)
訪問(wèn) Web 服務(wù)時(shí),Http request headers 需要一些參數(shù)。主要包括:
- Date:當(dāng)前 UTC 時(shí)間,形式為 “Wed, 01 Mar 2009 12:00:00 GMT”。
- Content-Length: 當(dāng)對(duì) Object 進(jìn)行操作的時(shí)候,返回內(nèi)容的長(zhǎng)度,注意不要包括 headers 中的內(nèi)容。
- Content-MD5:用 base64 編碼文件內(nèi)容的 MD5 值。
- Content-Type:資源的類型,比如:text/plain。
- Host:Get Service 時(shí)為“ s3.amazonaws.com”。在對(duì) bucket 和 object 進(jìn)行操作時(shí),例如bucket的名字是“bucketname”,那么 Host
就是“bucketname.s3.amazonaws.com”。- x-amz-meta- 和 x-am- 開頭的:包括 Amazon 定義的一些元數(shù)據(jù)和一些特定的 header。后面如果出現(xiàn)會(huì)提到。
- Authorization:這個(gè)是最重要的,主要作用是簽名,Amazon 根據(jù)的請(qǐng)求計(jì)算出一個(gè)簽名值和這里計(jì)算的簽名值進(jìn)行比對(duì),只有相同時(shí),訪問(wèn)才是合法的。接下來(lái)對(duì) Authorization 的計(jì)算方法進(jìn)行詳述。
Authorization 的計(jì)算方法
根據(jù)亞馬遜Amazon 文檔說(shuō)明:
Authorization = "AWS" + " " + AWSAccessKeyId + ":" + Signature;Signature = Base64( HMAC-SHA1( UTF-8-Encoding-Of(YourSecretAccessKey), UTF-8-Encoding-Of( StringToSign ) ) );StringToSign = HTTP-Verb + "\n" +Content-MD5 + "\n" +Content-Type + "\n" +Date + "\n" +CanonicalizedAmzHeaders +CanonicalizedResource;CanonicalizedResource = [ "/" + Bucket ] +<HTTP-Request-URI, from the protocol name up to the query string> +[ subresource, if present. For example "?acl", "?location", or "?logging"];CanonicalizedAmzHeaders = <described below>
- Authorization 是由”AWS {0}:{1}“組成的,第0個(gè)參數(shù)為你的 Access Key ID,需要注冊(cè)了 AWS 之后得到,AWS
注冊(cè);第1個(gè)參數(shù)是計(jì)算出來(lái)的簽名值。- 簽名值的計(jì)算方法是對(duì)一個(gè) UTF-8 的字符串,用你的 Secret Access Key(同樣在 Access Key ID 處獲取)進(jìn)行 SHA1 加密。
- StringToSign 字符串也需要滿足一定的格式。如上所示,第一行是你的操作名,應(yīng)該為 PUT、GET、DELETE、HEAD 和 POST 中的一種。第二行是內(nèi)容的 MD5 值的 base64 編碼,和 headers 中的 Content-MD5
值應(yīng)保持一致。第三行是Content-Type,同樣需要和headers中的一致。第四行 Date,和 headers 中的 Date
一致。- 需要說(shuō)明的是 CanonicalizedAmzHeaders 和 CanonicalizedResource。
- CanonicalizedAmzHeaders 就是把 headers 中的 x-amz- 開頭的作為 key 轉(zhuǎn)化為小寫并按順序排列,key 和 value 之間用冒號(hào)相連,用換行符“\n”把它們給連接起來(lái)。
比如說(shuō) headers 中有:
X-Amz-Meta-ReviewedBy: joe@johnsmith.net
X-Amz-Meta-ReviewedBy: jane@johnsmith.net
X-Amz-Meta-FileChecksum: 0x02661779
X-Amz-Meta-ChecksumAlgorithm: crc32
那么CanonicalizedAmzHeaders就是:
x-amz-meta-checksumalgorithm:crc32\n
x-amz-meta-filechecksum:0x02661779\n
x-amz-meta-reviewedby:joe@johnsmith.net,jane@johnsmith.net
- CanonicalizedResource 是指規(guī)范化的資源。
- 如果訪問(wèn)資源沒(méi)有指定 bucket,那么就是“/”;
- 如果包括 bucket,而不包括 object,那就是“/bucket_name/”,注意前后的“/”不要落了;
- 如果既包括 bucket,也包括 object,那么就是“/bucket_name/object_name”;
- 另外,有時(shí)候比如是訪問(wèn) bucke t的 acl(訪問(wèn)控制列表 acess control list)時(shí),object_name 就是 ?acl,因此這時(shí) CanonicalizedResource就是“/bucket_name/?acl”,訪問(wèn) object 的 acl
時(shí),CanonicalizedResource 就是“/bucket_name/object_name?acl”。- 需要說(shuō)明的是,如果計(jì)算出的 CanonicalizedAmzHeaders 不為空時(shí),要確保 CanonicalizedAmzHeaders 和 CanonicalizedResource 之間有換行符“\n”連接。
Amazon S3 REST API
Service
對(duì) Service的 操作只包括 Get,即獲取用戶所有的 Buckets 列表。Request headers 除了通用的,沒(méi)有其他的內(nèi)容。比如
GET / HTTP/1.1
Host: s3.amazonaws.com
Date: date
Authorization: signatureValue
返回的 XML 中包括 Owner 和各個(gè) Buckets,比如:
<?xml version="1.0" encoding="UTF-8"?>
<ListAllMyBucketsResult xmlns="http://doc.s3.amazonaws.com/2006-03-01"><Owner><ID>bcaf1ffd86f461ca5fb16fd081034f</ID><DisplayName>webfile</DisplayName></Owner><Buckets><Bucket><Name>quotes</Name><CreationDate>2006-02-03T16:45:09.000Z</CreationDate></Bucket><Bucket><Name>samples</Name><CreationDate>2006-02-03T16:41:58.000Z</CreationDate></Bucket></Buckets>
</ListAllMyBucketsResult>
Buckets
由于項(xiàng)目中只用到了 Buckets 的 PUT、GET、DELETE,關(guān)于 acl、lifecycle、policy 等;
PUT Bucket
需要說(shuō)明的是,在 request headers 可以加入 bucket 的權(quán)限控制,即指定 x-amz-acl,合法的值包括:private,public-read、public-read-write、authenticated-read、bucket-owner-read、bucket-owner-full-control,從名字就可以看出具體的含義。
- 在 request body 中可以包括位置信息,即用戶期望 Bucket 放置在 Amazon 的哪個(gè)數(shù)據(jù)中心。
- 默認(rèn)為 US Standard,其他數(shù)據(jù)中心包括 US West (Oregon) Region、US West (Northern California) Region、EU (Ireland) Region、Asia Pacific (Singapore) Region、Asia Pacific (Tokyo) Region、South America (Sao Paulo) Region。
- 對(duì)于我們中國(guó)用戶來(lái)說(shuō),離得最近的是東京的數(shù)據(jù)中心。不過(guò)在 body 中內(nèi)容中,這七個(gè)數(shù)據(jù)中心寫成:‘EU’、 ‘eu-west-1’、‘us-west-1’、 ‘us-west-2’、‘a(chǎn)p-southeast-1’、‘a(chǎn)p-northeast-1’ 和 ‘sa-east-1’。
比如請(qǐng)求如下:
PUT / HTTP/1.1
Host: BucketName.s3.amazonaws.com
Content-Length: length
Date: date
Authorization: signatureValue<CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <LocationConstraint>BucketRegion</LocationConstraint>
</CreateBucketConfiguration>
GET Bucket
- Get Bucket 主要是列出這個(gè) Bucket 下所有的 objects。值得提的是四個(gè)參數(shù) Prefix、Marker、MaxKeys 和 Delimiter,利用這四個(gè)參數(shù),可以達(dá)到多種效果。
- 首先是 Prefix,它表示這個(gè) Bucket 中返回的 Object 以這個(gè)值為開頭。Marker 表示,返回這個(gè)值以后的 Objects,比如說(shuō)第一次調(diào)用沒(méi)有返回全部結(jié)果,則把第一次調(diào)用返回的 Objects 的最后一個(gè)作為 Maker 調(diào)用,以返回其以后的
Objects。MaxKeys 返回單次請(qǐng)求返回的最大 Objects 數(shù),默認(rèn)為 1000。Delimiter 表示分隔符,是在設(shè)置了
Prefix 之后,能夠返回共同的 Prefix(在結(jié)果中為 CommonPrefix)。- 因此,通過(guò)設(shè)置 MaxKeys和Marker可以達(dá)到翻頁(yè)效果,每次返回的最后一個(gè) Object 作為下一次請(qǐng)求的 Marker,在返回值中,如果 IsTruncated 為 true,那么表示還有下一頁(yè)。此外,通過(guò)設(shè)置 Prefix 和將
Delimiter 設(shè)為”/“,可以達(dá)到返回某個(gè)文件夾下所有內(nèi)容的效果,其中 CommonPrefix 下的 Prefix
表示文件夾路徑,而每個(gè) Contents 中是 Object 的信息。
GET ?prefix=N&marker=Ned&max-keys=40 HTTP/1.1
Host: quotes.s3.amazonaws.com
Date: Wed, 01 Mar 2009 12:00:00 GMT
Authorization: AWS AKIAIOSFODNN7EXAMPLE:xQE0diMbLRepdf3YB+FIEXAMPLE=
返回結(jié)果為:
HTTP/1.1 200 OK
x-amz-id-2: gyB+3jRPnrkN98ZajxHXr3u7EFM67bNgSAxexeEHndCX/7GRnfTXxReKUQF28IfP
x-amz-request-id: 3B3C7C725673C630
Date: Wed, 01 Mar 2009 12:00:00 GMT
Content-Type: application/xml
Content-Length: 302
Connection: close
Server: AmazonS3<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>bucket</Name><Prefix/><Marker/><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>my-image.jpg</Key><LastModified>2009-10-12T17:50:30.000Z</LastModified><ETag>"fba9dede5f27731c9771645a39863328"</ETag><Size>434234</Size><StorageClass>STANDARD</StorageClass><Owner><ID>75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a</ID><DisplayName>mtd@amazon.com</DisplayName></Owner></Contents><Contents><Key>my-third-image.jpg</Key><LastModified>2009-10-12T17:50:30.000Z</LastModified><ETag>"1b2cf535f27731c974343645a3985328"</ETag><Size>64994</Size><StorageClass>STANDARD</StorageClass><Owner><ID>75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a</ID><DisplayName>mtd@amazon.com</DisplayName>
Objects
PUT Object
PUT Object 基本操作類似,在 Http body 中添加 Object 的內(nèi)容,這里就需要計(jì)算 Content-Type 等值。與
PUT Bucket 類似,可以在 Http headers 中加入 x-amz-acl,以控制 Object 的權(quán)限。
GET Object 在 GET Object 時(shí),Response headers 中會(huì)包括這個(gè) Object 的相關(guān)信息,除了
Content-Length 和 Content-Type 等,Etag 其實(shí)就是內(nèi)容的 MD5 后的16進(jìn)制的字符串。而 Response
body 中就是文件的內(nèi)容。