动静分离-静态资源缓存控制
一、静态资源服务与动态资源服务的区别
首先动静分离非前后端分离,关于两者的介绍如下:
- 动静分离:动态资源(jsp、ftl)与静态资源(js、img、css)分开
- 前后端分离:接口与视图分开独立开发部署
二、为什么静态资源需要实现CDN内容加速
在一个网站中,请求是比较占宽带资源的。
其主要加载内容为静态资源,如: css、js、img
我们知道,一个1兆带宽服务器 = 128kb/s,如果存在一个 512/kb 的静态资源需要请求 4s 左右,而动态资源(json)占带宽很小(几十B),几乎可以忽略不计。
既然带宽影响网站访问速度,那就加带宽好了?
但是!带宽价格不是贵的一点点…
所以市场上出现了一些静态资源服务器平台(对象文件存储) 。
比如七牛云、阿里云(oss)、腾讯云(内置CDN内容分发)。
什么是CDN内容分发?
CDN内容分发,就是将静态资源服务器会部署全国各个服务器节点,用户访问的时候,遵循就近原则。比如你的所在地在济南,那么你在访问资源文件时,会分配给你距离济南最近的CDN网点。
三、七牛云创建静态资源存储空间
官方地址:https://developer.qiniu.com/
注册之后就可以去创建对象存储空间了,详细步骤建议看官方文档。
创建好空间后需要绑定一个自己的域名,如果不绑定则使用默认提供的域名,提供的域名有默认的使用时长:
如下是我的存储空间域名绑定截图:
如下是我之前涂涂影院存放的一些静态资源:
四、动静分离架构系统缺点
使用CDN内容分发确实提高了网站的访问速度,但是动静分离架构模式有什么缺点呢?
跨域问题
比如域名访问的是:www.sscai.club
而静态资源访问的则是:cdn.sscai.club
如何解决跨域问题?
nginx转发
将 www.sscai.club 转发到 cdn.sscai.club
五、代码中实现七牛云文件上传
引入pom依赖
<!-- 七牛云SDK --><dependency> <groupId>com.qiniu</groupId> <artifactId>qiniu-java-sdk</artifactId> <version>[7.2.0, 7.2.99]</version></dependency>
主要代码:
@RequestMapping(value = "/file", method = RequestMethod.POST)@ApiOperation(value = "文件上传")public Result<Object> upload( @RequestParam(required = false) MultipartFile file, @RequestParam(required = false) 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();
/* 上传至第三方云服务——七牛云 */ result = qiniuInputStreamUpload(inputStream, fKey); f.setLocation(CommonConstant.OSS_QINIU);
/* 保存数据信息至数据库 */ 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); /* 解析上传成功的结果 */ 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("上传文件出错,请检查七牛云配置," + r.toString()); }}
@Datapublic class OssSetting implements Serializable{
@ApiModelProperty(value = "服务商") private String serviceName;
@ApiModelProperty(value = "ak") private String accessKey;
@ApiModelProperty(value = "sk") private String secretKey;
@ApiModelProperty(value = "endpoint域名") private String endpoint;
@ApiModelProperty(value = "bucket空间") private String bucket;
@ApiModelProperty(value = "http") private String http;
@ApiModelProperty(value = "zone存储区域") private Integer zone;
@ApiModelProperty(value = "bucket存储区域") private String bucketRegion;
@ApiModelProperty(value = "本地存储路径") private String filePath;
@ApiModelProperty(value = "是否改变secrectKey") private Boolean changed;}
Base64转为MultipartFile工具类:
/** * base64转为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]; }
@Override public String getName() { return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1]; }
@Override public String getOriginalFilename() { return System.currentTimeMillis() + (int)Math.random() * 10000 + "." + header.split("/")[1]; }
@Override public String getContentType() { return header.split(":")[1]; }
@Override public boolean isEmpty() { return imgContent == null || imgContent.length == 0; }
@Override public long getSize() { return imgContent.length; }
@Override public byte[] getBytes() throws IOException { return imgContent; }
@Override public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(imgContent); }
@Override 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]); }}
我创建了一个java相关的公众号,用来记录自己的学习之路,感兴趣的小伙伴可以关注一下微信公众号哈:niceyoo
动静分离-静态资源缓存控制相关推荐
- 变态的静态资源缓存与更新
本文搬运自我在知乎上 同名问题 中的答案. 这是一个非常有趣的 非主流前端领域,这个领域要探索的是如何用工程手段解决前端开发和部署优化的综合问题,入行到现在一直在学习和实践中. 在我的印象中,face ...
- 四层负载均衡 动静分离和资源分离 Rewrite rewrite伪静态实例
文章目录 四层负载均衡 四层负载均衡特点 查看四层负载均衡语法 四层负载均衡配置 优化配置文件 四层负载均衡日志配置 nginx的TCP负载均衡---端口转发 动静分离 单台的动静分离 多台机器动静分 ...
- nginx动静分离和资源隔离的网站搭建
| 作业 nginx动静分离和资源隔离的网站搭建 一.动静分离的网站 0.准备环境 主机 IP 主机角色 条件 web01 192.168.15.7 Android页面 关闭防火墙和selinux w ...
- nginx 配置静态资源缓存。解决web静态资源访问过慢
Nginx文件结构 1.全局块:配置影响nginx全局的指令.一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等. ...
- SpringBoot cache-control 配置静态资源缓存 (以及其中的思考经历)
昨天在部署项目时遇到一个问题,因为服务要部署到外网使用,中间经过了较多的网络传输限制,而且要加载arcgis等较大的文件,所以在部署后,发现页面loading需要很长时间,而且刷新也要重新从服务器下载 ...
- Nginx 静态资源缓存配置
示例 # Media: images, icons, video, audio, HTC location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|m ...
- 前端web:浏览器静态资源缓存策略
浏览器静态资源缓存策略 浏览器其实提供了两种控制策略,分别是强制缓存和协商缓存 强制缓存 强制缓存:就是强制使用浏览器缓存下来的资源; 在指定的一段时间内用自己缓存的文件就行,不需要再次发出请求. 具 ...
- Spring boot 2.4开启静态资源缓存
Spring boot 2.4开启静态资源缓存 yml配置: spring:web:resources:cache:cachecontrol:no-store: falsemax-age: 10000 ...
- 前端静态资源缓存最优解以及max-age的陷阱
原文地址:点这里 合理的使用缓存可以极大地提高网站资源的利用率,还可以节约带宽从而降低服务器成本.但是很多站点针对缓存的策略并不合理,甚至是完全无作为,如果是这样,就完全没有发挥出缓存的优势,而不合理 ...
最新文章
- 数据结构与算法---队列
- mysql列名可以用中文吗_用了这么久的MySQL,你知道它的存储引擎吗?
- jar包打补丁 jar -uf_windows下批处理指定不同jdk版本运行jar包
- MySQL子查询操作实例详解
- ionic view 视图
- 微信小程序 - 展开收缩列表
- wxpython使窗口重新显示_wxpython刷新窗口按按钮
- 【Kafka】KafkaConsumer is not safe for multi-threaded access
- python123平台作业答案循环结构棋盘放米_python练习集100题(1-20)
- 再谈本土EDA竞争力顺便聊聊DTCO在中国落地
- xmind电脑安卓v2021.20.8免费全平台永久思维导图直装版
- APICloud 入门教程窗口篇
- 看完这一篇,智能家居的坑你至少避开80%(上)
- ios : Provision Profile 添加设备 device的 udid
- 高德地图自定义定位按钮后搜索周边
- Image Signal Processing(ISP)-第三章-BCL, WB, Gamma的原理和软件实现
- 设备描述符请求失败解决
- 微信小程序 - 引入并使用 Fly.js 请求库(超级详细的教程及运行示例)提供 Fly.js 源码源文件下载,贴心的配置示例及注释,优雅快速的发起 http 网络请求
- 树莓派做网络调试陪试机
- 华为在发布会带来了harmonyos,Mate 40发布会彩蛋!华为智选智能摄像头Pro发布
热门文章
- [html] html5点击返回键怎样不让它返回上一页
- 前端学习(2781):底部tabber配置
- 工作总结8:关于Vue中的slot-scope=“scope“
- “睡服”面试官系列第十三篇之函数的扩展(建议收藏学习)
- oracle之数据处理2
- 前端学习(771):小结
- shiro学习(4):shiro认证流程
- spring mvc学习(55):简单异常处理二
- Qt程序窗口关闭不退出而最小化到托盘的方法
- python爬虫爬汽车图片_Python快速爬取车标网图片,以后不要说这什么车你不认识了!...