zoukankan      html  css  js  c++  java
  • 动静分离-静态资源缓存控制

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

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

    • 动静分离:动态资源(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

  • 相关阅读:
    jvm基本结构和解析
    多态的意思
    java中对象的简单解读
    double类型和int类型的区别
    python 解析xml文件
    win10不能映射Ubuntu共享文件
    Qt程序打包
    Ubuntu boot分区文件误删,系统无法启动,怎么解
    ubuntu Boot空间不够问题“The volume boot has only 5.1MB disk space remaining”
    Ubuntu 分辨率更改 xrandr Failed to get size of gamma for output default
  • 原文地址:https://www.cnblogs.com/niceyoo/p/11258239.html
Copyright © 2011-2022 走看看