动静分离-静态资源缓存控制
一、靜態(tài)資源服務(wù)與動態(tài)資源服務(wù)的區(qū)別
首先動靜分離非前后端分離,關(guān)于兩者的介紹如下:
- 動靜分離:動態(tài)資源(jsp、ftl)與靜態(tài)資源(js、img、css)分開
- 前后端分離:接口與視圖分開獨(dú)立開發(fā)部署
二、為什么靜態(tài)資源需要實(shí)現(xiàn)CDN內(nèi)容加速
在一個(gè)網(wǎng)站中,請求是比較占寬帶資源的。
其主要加載內(nèi)容為靜態(tài)資源,如: css、js、img
我們知道,一個(gè)1兆帶寬服務(wù)器 = 128kb/s,如果存在一個(gè) 512/kb 的靜態(tài)資源需要請求 4s 左右,而動態(tài)資源(json)占帶寬很小(幾十B),幾乎可以忽略不計(jì)。
既然帶寬影響網(wǎng)站訪問速度,那就加帶寬好了?
但是!帶寬價(jià)格不是貴的一點(diǎn)點(diǎn)…
所以市場上出現(xiàn)了一些靜態(tài)資源服務(wù)器平臺(對象文件存儲) 。
比如七牛云、阿里云(oss)、騰訊云(內(nèi)置CDN內(nèi)容分發(fā))。
什么是CDN內(nèi)容分發(fā)?
CDN內(nèi)容分發(fā),就是將靜態(tài)資源服務(wù)器會部署全國各個(gè)服務(wù)器節(jié)點(diǎn),用戶訪問的時(shí)候,遵循就近原則。比如你的所在地在濟(jì)南,那么你在訪問資源文件時(shí),會分配給你距離濟(jì)南最近的CDN網(wǎng)點(diǎn)。
三、七牛云創(chuàng)建靜態(tài)資源存儲空間
官方地址:https://developer.qiniu.com/
注冊之后就可以去創(chuàng)建對象存儲空間了,詳細(xì)步驟建議看官方文檔。
創(chuàng)建好空間后需要綁定一個(gè)自己的域名,如果不綁定則使用默認(rèn)提供的域名,提供的域名有默認(rèn)的使用時(shí)長:
如下是我的存儲空間域名綁定截圖:
如下是我之前涂涂影院存放的一些靜態(tài)資源:
四、動靜分離架構(gòu)系統(tǒng)缺點(diǎn)
使用CDN內(nèi)容分發(fā)確實(shí)提高了網(wǎng)站的訪問速度,但是動靜分離架構(gòu)模式有什么缺點(diǎn)呢?
跨域問題
比如域名訪問的是:www.sscai.club
而靜態(tài)資源訪問的則是:cdn.sscai.club
如何解決跨域問題?
nginx轉(zhuǎn)發(fā)
將 www.sscai.club 轉(zhuǎn)發(fā)到 cdn.sscai.club
五、代碼中實(shí)現(xiàn)七牛云文件上傳
引入pom依賴
<!--?七牛云SDK?--><dependency>
????<groupId>com.qiniu</groupId>
????<artifactId>qiniu-java-sdk</artifactId>
????<version>[7.2.0,?7.2.99]</version>
</dependency>
主要代碼:
public?Result<Object>?upload(
?????MultipartFile?file,
?????String?base64,
????HttpServletRequest?request)?{
????//?判斷上傳類型?*/
????if(StrUtil.isNotBlank(base64)){
????????//?base64上傳?*/
????????file?=?Base64DecodeMultipartFile.base64Convert(base64);
????}
????String?result?=?"";
????String?fKey?=?renamePic(file.getOriginalFilename());
????File?f?=?new?File();
????try?{
????????//?獲取文件流
????????InputStream?inputStream?=?file.getInputStream();
????????/*?上傳至第三方云服務(wù)——七牛云?*/
????????result?=?qiniuInputStreamUpload(inputStream,?fKey);
????????f.setLocation(CommonConstant.OSS_QINIU);
????????/*?保存數(shù)據(jù)信息至數(shù)據(jù)庫?*/
????????f.setName(file.getOriginalFilename());
????????f.setSize(file.getSize());
????????f.setType(file.getContentType());
????????f.setFKey(fKey);
????????f.setUrl(result);
????????fileService.save(f);
????}?catch?(Exception?e)?{
????????log.error(e.toString());
????????return?new?ResultUtil<Object>().setErrorMsg(e.toString());
????}
????if(used.equals(SettingConstant.LOCAL_OSS)){
????????OssSetting?os?=?fileUtil.getOssSetting();
????????result?=?os.getHttp()?+?os.getEndpoint()?+?"/"?+?f.getId();
????}
????return?new?ResultUtil<Object>().setData(result);
}
public?static?String?renamePic(String?fileName)?{
????String?extName?=?fileName.substring(fileName.lastIndexOf("."));
????return?UUID.randomUUID().toString().replace("-",?"")?+?extName;
}
/**
?*?文件流上傳
?*?@param?inputStream
?*?@param?key??文件名
?*?@return
?*/
public?String?qiniuInputStreamUpload(InputStream?inputStream,?String?key)?{
????OssSetting?os?=?getOssSetting();
????Auth?auth?=?Auth.create(os.getAccessKey(),?os.getSecretKey());
????String?upToken?=?auth.uploadToken(os.getBucket());
????try?{
????????Response?response?=?getUploadManager(getConfiguration(os.getZone())).put(inputStream,?key,?upToken,?null,?null);
????????/*?解析上傳成功的結(jié)果?*/
????????DefaultPutRet?putRet?=?new?Gson().fromJson(response.bodyString(),?DefaultPutRet.class);
????????return?os.getHttp()?+?os.getEndpoint()?+?"/"?+?putRet.key;
????}?catch?(QiniuException?ex)?{
????????Response?r?=?ex.response;
????????throw?new?XbootException("上傳文件出錯(cuò),請檢查七牛云配置,"?+?r.toString());
????}
}
public?class?OssSetting?implements?Serializable{
????
????private?String?serviceName;
????
????private?String?accessKey;
????
????private?String?secretKey;
????
????private?String?endpoint;
????
????private?String?bucket;
????
????private?String?http;
????
????private?Integer?zone;
????
????private?String?bucketRegion;
????
????private?String?filePath;
????
????private?Boolean?changed;
}
Base64轉(zhuǎn)為MultipartFile工具類:
/**?*?base64轉(zhuǎn)為multipartFile工具類
?*?@author?nikou
?*/
public?class?Base64DecodeMultipartFile?implements?MultipartFile?{
????private?final?byte[]?imgContent;
????private?final?String?header;
????public?Base64DecodeMultipartFile(byte[]?imgContent,?String?header)?{
????????this.imgContent?=?imgContent;
????????this.header?=?header.split(";")[0];?
????}
????
????public?String?getName()?{
????????return?System.currentTimeMillis()?+?Math.random()?+?"."?+?header.split("/")[1];
????}
????
????public?String?getOriginalFilename()?{
????????return?System.currentTimeMillis()?+?(int)Math.random()?*?10000?+?"."?+?header.split("/")[1];
????}
????
????public?String?getContentType()?{
????????return?header.split(":")[1];
????}
????
????public?boolean?isEmpty()?{
????????return?imgContent?==?null?||?imgContent.length?==?0;
????}
????
????public?long?getSize()?{
????????return?imgContent.length;
????}
????
????public?byte[]?getBytes()?throws?IOException?{
????????return?imgContent;
????}
????
????public?InputStream?getInputStream()?throws?IOException?{
????????return?new?ByteArrayInputStream(imgContent);
????}
????
????public?void?transferTo(File?dest)?throws?IOException,?IllegalStateException?{
????????new?FileOutputStream(dest).write(imgContent);
????}
????public?static?MultipartFile?base64Convert(String?base64)?{
????????String[]?baseStrs?=?base64.split(",");
????????BASE64Decoder?decoder?=?new?BASE64Decoder();
????????byte[]?b?=?new?byte[0];
????????try?{
????????????b?=?decoder.decodeBuffer(baseStrs[1]);
????????}?catch?(IOException?e)?{
????????????e.printStackTrace();
????????}
????????for?(int?i?=?0;?i?<?b.length;?++i)?{
????????????if?(b[i]?<?0)?{
????????????????b[i]?+=?256;
????????????}
????????}
????????return?new?Base64DecodeMultipartFile(b,?baseStrs[0]);
????}
}
我創(chuàng)建了一個(gè)java相關(guān)的公眾號,用來記錄自己的學(xué)習(xí)之路,感興趣的小伙伴可以關(guān)注一下微信公眾號哈:niceyoo
總結(jié)
以上是生活随笔為你收集整理的动静分离-静态资源缓存控制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 绑定报表
- 下一篇: ffmpeg将webm格式转换成mp4