對於前期用戶量不大但是需要穩定服務的項目,S3和Cloudfront是個不錯的選擇
一,申請amazon 賬戶 申請過程不再介紹 我是在淘寶上買一張1美元的萬事達卡來申請的,成本10塊錢左右
1.1,等待申請通過後進入控制檯 在所有服務中找到存儲 ->s3 (如下圖1)如果amazon賬號申請已經通過 進入頁面就可以直接在頁面創建存儲桶,我是需要通過編程的方式上傳文件,所以這裏不再介紹在頁面創建存儲桶的過程,可以自己玩玩摸索一下
1.2,通過java編程的方式上傳文件到存儲桶,需要使用到開源包jets3t,maven引入的方式如下
<!-- https://mvnrepository.com/artifact/net.java.dev.jets3t/jets3t -->
<dependency>
<groupId>net.java.dev.jets3t</groupId>
<artifactId>jets3t</artifactId>
<version>0.9.4</version>
</dependency>
1.2.1,要通過java訪問s3存儲桶並進行操作的話,必須要有授權,這個授權需要 AWS_ACCESS_KEY和AWS_SECRET_KEY,這兩個key有多種方式獲取,最簡單粗暴的就是直接在amazon IAM頁面去生成一個,申請鏈接 獲取訪問Amazon S3的access_key及secret_key 如下圖2
1.2.2,獲取訪問授權的另一種方式(與1.2.1作用相同,都是爲了獲取對s3訪問的憑證,1.2.1和1.2.2可以自己選擇用哪種方式)
進入IAM控制檯 如下圖3 這裏相當於建立了amazon的子賬戶,可以設置這些子賬戶的訪問權限,比如你可以建一個賬戶只能對s3進行操作,你拿到這個子賬戶的授權key就只能在代碼裏訪問或者操作s3的資源內容
1.2.3 創建用戶 如圖4
1.2.4 創建成功後會給你一個祕鑰,這個祕鑰就是訪問s3的憑證
1.2.5 當然,要爲用戶添加訪問s3的權限,如圖5
1.2.6 獲取到的access_key和secret_key後即可對s3進行編程上傳文件和獲取文件訪問地址,java代碼片段如下
private static String AWS_ACCESS_KEY = "AKIAINA*******SD3QQ";
private static String AWS_SECRET_KEY = "5WTDmwn***************7JfQd2g5LSs9/t";
要進行s3訪問需要首先獲取RestS3Service對象
@Override
public S3Service getS3Service(String accKey, String sec_key) {
AWSCredentials awsCredentials = new AWSCredentials(accKey, sec_key);
return new RestS3Service(awsCredentials);
}
對s3做一些簡單的操作,如創建存儲桶,獲取存儲桶
/**
* 創建存儲桶
*
* @param bucketName
* @param location
* @return
*/
@Override
public S3Bucket createS3Bucket(String bucketName, String location) {
S3Bucket euBucket = null;
try {
euBucket = s3Service.createBucket(bucketName, location);
} catch (S3ServiceException e) {
e.printStackTrace();
}
return euBucket;
}
/**
* 獲取存儲桶
*
* @param bucketName
* @param location
* @return
*/
@Override
public S3Bucket getS3Bucket(String bucketName, String location) {
S3Bucket euBucket = null;
try {
euBucket = s3Service.getOrCreateBucket(bucketName, location);
} catch (S3ServiceException e) {
e.printStackTrace();
}
return euBucket;
}
1.2.7 上傳文件到存儲桶(注意此時上傳到存儲桶中的文件的訪問不是公開的,所以此時直接訪問可能會出現拒絕訪問)
/**
* 上傳本地文件到s3存儲桶
* @param filePath
* @param s3Service
* @param euBucket
* @return
*/
@Override
public S3Object localUpload(String filePath, S3Service s3Service, S3Bucket euBucket) {
File fileData = new File(filePath);
S3Object fileObject = null;
try {
fileObject = new S3Object(fileData);
fileObject.setKey(UUID.randomUUID().toString().replaceAll("-", ""));
fileObject = s3Service.putObject(euBucket, fileObject);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return fileObject;
}
/**
* 上傳網絡文件到s3存儲桶
*
* @param file
* @param bucketName
* @param key
* @param location
* @return
*/
@Override
public S3Object uploadFileToS3(File file, String bucketName, String key, String location) {
if (!file.exists()) {
return null;
}
S3Bucket euBucket = getS3Bucket(bucketName, location);
S3Object fileObject = null;
try {
fileObject = new S3Object(file);
fileObject.setKey(key);//如果設置了key 在創建訪問鏈接的時候要使用這個key作爲文件名
fileObject = s3Service.putObject(euBucket, fileObject);
} catch (Exception e) {
e.printStackTrace();
}
return fileObject;
}
1.2.8 獲取s3存儲桶中文件的訪問鏈接
/**
* 創建s3訪問鏈接
*
* @param euBucket
* @param fileName
* @return
*/
@Override
public String createSignedUrl(String euBucket, String fileName) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 50);
Date expiryDate = cal.getTime();
String signedUrl = s3Service.createSignedGetUrl(euBucket, fileName, expiryDate, false);
BouncyCastleProvider provider = new BouncyCastleProvider();
return signedUrl;
}
以上就基本實現了文件的上傳及訪問鏈接的生產,鏈接可以設置多長時間失效。
二,使用amazon CloudFront爲s3存儲文件創建cdn分發
2.1,進入CloudFront控制檯
2.1.1創建分配 如下圖6
2.1.2 選擇s3存儲桶作爲源域名 如下圖7
2.1.3 創建完成之後需要授予cloudfront對s3的訪問權限,如下設置源和源組
2.1.4 授予對存儲桶的讀取權限
2.1.5 此時就可以使用cloudfront分配給你的域名來訪問你的s3資源了 域名如下圖10
然後你就可以直接用這個域名訪問s3存儲桶中的文件
2.2 爲cloudfront設置ssl訪問 (我是使用自己的域名來做ssl訪問的 域名爲tokyo.imdou8.com)
2.2.1 編輯分配 設置備用域名(CNAMEs)如下圖11
2.2.2 進入自己的域名供應商設置界面 設置域名(tokyo.imdou8.com)的cname指向cloudfront分配給你的域名如(dxxxxxxxd42gq.cloudfront.net) 如下圖12
然後你就可以通過自己的域名來訪問cloudfont分發的s3資源了
2.3 以上步驟完成後,你可以通過自己的域名來訪問cloudfront在全球邊緣節點分發的s3資源,速度會比直接訪問s3要快。但是此時你會發現訪問是不可信的ssl連接。以下是爲cloudfront配置ssl證書
2.3.1 進入amazon 證書管理控制檯 如下圖13
填寫域名
2.3.2 由於不知道dns怎麼驗證,所以我選擇的是郵件驗證,如果是你自己的域名,選擇郵件驗證後amazon會給你發送一封郵件
郵件截圖如下 直接點擊郵件中的鏈接進行驗證
點擊i approve 然後可以看到驗證成功
2.3.3 回到cloudfront控制檯 進入編輯分配頁面 選擇剛纔分配的證書 並保存設置 如下圖18
由此,及完成了ssl證書的設置 再訪問cloudfront鏈接就是已授信鏈接了
2.4 通過編程生成授信cloudfront鏈接
2.4.1 在amazon網站右上角用戶名下拉列表中找到"我的安全憑證" 點擊進入
2.4.2 創建cloudfront祕鑰對 獲取一個pk-APKAJXXXXXXXPREKE3PFA.pem
2.4.3 通過pem文件生成.der文件 獲取cdnPK.der
openssl pkcs8 -topk8 -nocrypt -in pk-APKAJCHZMNRPREKE3PFA.pem -inform PEM -out cdnPK.der -outform DER
2.4.5 編程獲取ssl鏈接
/**
* 獲取cloudfont訪問鏈接
*
* @param domain
* @param privateKeyPath
* @param keyPairId
* @param s3ObjectKey
* @return
*/
@Override
public String privateS3Url(String domain, String privateKeyPath, String keyPairId, String s3ObjectKey) {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 50);
String signedUrl = null;
try {
String policyResourcePath = "https://" + domain + "/" + s3ObjectKey;
byte[] derPrivateKey = ServiceUtils.readInputStreamToBytes(new
FileInputStream(privateKeyPath));
//
// String signedUrlCanned = CloudFrontService.signUrlCanned(
// policyResourcePath,
// keyPairId,
// derPrivateKey,
// ServiceUtils.parseIso8601Date(sdf.format(cal.getTime())) // DateLessThan
// );
//
String policy = CloudFrontService.buildPolicyForSignedUrl(
policyResourcePath,
ServiceUtils.parseIso8601Date(sdf.format(cal.getTime())),
"0.0.0.0/0",
ServiceUtils.parseIso8601Date(sdf.format(new Date().getTime()))
);
signedUrl = CloudFrontService.signUrl(
policyResourcePath,
keyPairId,
derPrivateKey,
policy
);
} catch (Exception e) {
e.printStackTrace();
}
return signedUrl;
}
以上可以獲取一個授信的https鏈接 如下
https://tokyo.imdou8.com/vid/20190104/1f1652c9953744b2bc7435a98b472692.mp4?Policy=eyJTdGF0ZW1lbnQiOiBbeyJSZXNvdXJjZSI6Imh0dHBzOi8vdG9reW8uaW1kb3U4LmNvbS92aWQvMjAxOTAxMDQvMWYxNjUyYzk5NTM3NDRiMmJjNzQzNWE5OGI0NzI2OTIubXA0IiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNTUwOTEzMzk5fSwiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI6IjAuMC4wLjAvMCJ9LCJEYXRlR3JlYXRlclRoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTU0NjU5MzM5OX19fV19&Signature=3CEaJ3JFf4YwIwvl17nJO-9Eopp3QW~~6wwx7sOyJ~d4jwyTg1dko5UEy6rRPQ89s9mtzrv114UhkLcgvrX~BV1AwsucBkGusvPOMdyf1P5SibMorVJdMvN0GuZx8wWqUWEebxgDnJP0JhBmwNj8v9zsN5uz9BYZaTavkwkeVT9XPfE~hbDIhNOjBz9ciqWyM8x4wQUDWWJUWV-~BAiYuKA-yyPajnluXsDzia7pVonI8TLSuUGFnPLBzCeqhEkt7LWLhlzQzOCUMB0-~DKTMbj0giVkM3O728lBewJvDyhs77nOPdQOjFoleyFNVvP1iq~879~7H1~y6xRrspz4pA__&Key-Pair-Id=APKAJCHZMNRPREKE3PFA
ok this all