动静分离-静态资源缓存控制

一、静态资源服务与动态资源服务的区别

首先动静分离非前后端分离,关于两者的介绍如下:

  • 动静分离:动态资源(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, nullnull);
        /* 解析上传成功的结果 */
        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());
    }
}


@Data
public 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/414246.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式session共享

一、前言 为什么会出现session共享问题&#xff1f; 客户端与服务器交互时会产生唯一的sessionid用于标记用户&#xff0c;但是在分布式架构中&#xff0c;如果还是采用 session 的方式&#xff0c;用户发起请求&#xff0c;通过 nginx 做请求转发时&#xff0c;并不知道是转发…

InnoDB锁问题

InnoDB锁问题 InnoDB与MyISAM的最大不同有两点&#xff1a;一是支持事务&#xff08;TRANSACTION&#xff09;&#xff1b;二是采用了行级锁。行级锁与表级锁本来就有许多不同之处&#xff0c;另外&#xff0c;事务的引入也带来了一些新问题。下面我们先介绍一点背景知识&#…

phpsduty环境下,使用composer安装报错

1.首先要下载composer进行安装 点击下载 &#xff0c;最新的composer要求的php版本都比较高&#xff0c;安装之后&#xff0c;将composer的安装路径加入环境变量&#xff0c;我的参考路径&#xff1a;D:\composer&#xff1b; 2.我的环境使用的php版本是php7.0.12-nts&#xf…

SPU、SKU、ARPU

在涂涂商城开发之前&#xff0c;发现一篇关于电商中 SPU、SKU、ARPU 的介绍&#xff0c;转至博客&#xff0c;原文地址&#xff1a;http://www.ikent.me/blog/3017 什么是SPU、SKU、ARPU 首先&#xff0c;搞清楚商品与单品的区别。例如&#xff0c;iphone 是一个单品&#xff0…

NOIP2011提高组day2

NOIP 2011 提高组 Day 2 T1 &#xff1a; 题意&#xff1a; 这道题题意很显然&#xff0c;方法就是利用数学中的二项式定理 &#xff1a; ( x y ) ^ n C ( i , n ) * x ^ i * y ^ ( n - i )&#xff0c;i ∈ [ 0 , n ]&#xff0c;所以求x ^ n * y ^ m的系数&#xff0c;就是…

react+redux+node报错Tapable.plugin is deprecated. Use new API on `.h ooks` instead

npm run hot运行 报错(node:5372) DeprecationWarning: Tapable.plugin is deprecated. Use new API on .h ooks instead 原因是内网的IP变了&#xff0c;所以启动报错&#xff0c;修改webpack.dev.js里的host&#xff0c;解决。

什么是单点登录

前言&#xff1a; 是时候了解一下SSO相关的知识了&#xff0c;本篇主要是概念篇&#xff0c;发现网上两篇不错的文章&#xff0c;简单整合了一下&#xff0c;原文链接&#xff1a;https://www.cnblogs.com/Java3y/p/10877465.htmlhttps://www.cnblogs.com/EzrealLiu/p/5559255.…

支付宝H5支付,ISV权限不足

报错如下&#xff1a; 登录支付宝商户平台&#xff0c;发现签约产品已失效&#xff1a; 重新申请&#xff0c;修改网址之后就成功了&#xff1a;

我们为何需要单点登录系统

SSO&#xff0c;Single Sign On&#xff0c;也就是单点登录&#xff0c;保证一个账户在多个系统上实现单一用户的登录 现在随着网站的壮大&#xff0c;很多服务会进行拆分&#xff0c;会做SOA服务&#xff0c;会使用dubbo做微服务&#xff0c;或者简单的小型分布式&#xff0c…

微信JSAPI支付,报错当前页面的URL未注册

调用微信统一支付的接口&#xff0c;支付时报错&#xff1a; 解决方案&#xff1a; 打开微信商户平台&#xff0c;将当前页面的URL配置到JSAPI域名。

借助xxl-sso实现SSO

前言 市场上一下主流的SSO技术搭配方案&#xff1a; SpringSecurity OAuth2 SpringSecurity CAS 功能较弱&#xff0c;对前后端分离的项目支持不是很好Shiro CAS JWT 可以自定义需求&#xff0c;灵活扩展鉴权方式 本篇主要是单点登录&#xff0c;不涉及鉴权&#xff0c;后面…

C语言数组初始化的问题

转载于:https://www.cnblogs.com/chulin/p/8880184.html

blocked by CORS policy,是否跨域?

经排查不是跨域的问题&#xff0c;代码报错&#xff0c;改好就解决了 2021.10.20 项目上线又报错&#xff0c;测试环境一直没问题&#xff0c;上线了就报这个错&#xff0c;如果是前端代码的问题&#xff0c;那么使用测试接口的时候肯定也会报这个错&#xff0c;所以排除前端代…

那些一眼就被看出包装过的简历

本文作者&#xff1a;Coody原文链接&#xff1a;https://my.oschina.net/hooker/blog/3014656 前言 在互联网极速膨胀的社会背景下&#xff0c;各行各业涌入互联网的IT民工日益增大。 早在2016年&#xff0c;我司发布了Java、Ios工程师的招聘信息&#xff0c;就Java工程师单个岗…

sql 查询优化小计

好久没更博了&#xff0c;偷偷的抽时间写一下。 早上开始working的时候&#xff0c;发现一个页面加载很慢&#xff0c;经排查是昨天写的一条联合查询的sql导致的。于是着手优化&#xff01; 首先想到的是在join的时候&#xff0c;减少表体积之后再进行关联&#xff0c;于是有了…

微信支付宝扫一扫进入小程序的相关配置

需求: 微信小程序和支付宝小程序,用微信和支付宝扫同一个普通二维码,支付宝扫码进入支付宝小程序指定页面,微信扫码进入微信小程序的指定页面。解决办法: 微信公众平台和支付宝开放平台都有自己的二维码配置规则。配置相同的规则,然后用配置的二维码地址加上参数,用草料…