文件上传至公有云Nos及对接CDN

本文介绍了如何将图片文件上传到网易公有云的对象存储服务NOS,并结合CDN进行内容加速。关键步骤包括前端直传文件、注意上传请求地址和鉴权信息的准确性。此外,文章还详细讨论了CDN的工作原理,如网页和视频加速,以及如何配置和使用网易CDN服务,包括刷新和预热接口的调用,强调了签名认证的重要性和格式要求。
摘要由CSDN通过智能技术生成
项目开发中,需要将图片文件上传至网易公有云的Nos,并且结合CDN做加速服务,记录一下开发过程。

流程图:
在这里插入图片描述

1. 文件上传到公有云Nos

网易对象存储服务(Netease Object Storage,简称NOS)是网易数帆提供的高可用、高可靠、高性能的云端存储服务。

本次项目由于是和外部企业合作,上传文件是上传到公有云Nos,但和部门之前上传到私有云Nos的方式一样。都是采用计算token的方式,前端直传。(私有云和公有云签名计算方式一样)

需要注意的点有:

而公有云的上传请求地址是:https://nosup-eastchina1.126.net,与私有云上传地址不同。如果请求地址不对的话,则会一直返回"AccessDenied"。

配置桶名及ak_sk的时候,一定要仔细检查,是否有错误,例如多个空格啥的。这种也会返回错误信息"AccessDenied"。

2. 认识CDN

内容分发网络(Content Delivery Network,简称CDN)是建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成的分布式网络。一般应用场景在于:网页、小文件加速;大文件下载加速;视频点播加速等。

在这里插入图片描述

可以这样理解,cdn的作用就是将源站内容发布到不同区域的边缘节点,这样在不同地方的用户请求都能被分配最适合他的节点,就近获取节点上缓存的资源。

一方面防止每个用户请求都访问源站,避免造成网络拥塞、缓解源站压力。

另一方面,使用户可以以最快的速度取得他所需的内容,解决网络带宽小、用户访问量大、网点分布不均等问题,提高用户访问的响应速度。

3. 接入CDN

关于对接网易cdn,基本参考官方文档:https://sf.163.com/help/documents/68827624361873408。
首先是在控制台配置好加速域名,回源地址等信息;
其次由于此次项目中不仅是想完成回源访问,更想着主动预热到cdn各节点,所以需要在代码里,调用CDN提供的接口。

CDN接口功能介绍:

  • 刷新:把CDN所有节点上对应的缓存资源标记为失效,当用户再次请求时,CDN会直接回源站获取对应的资源并返回给用户,同时将资源重新缓存到CDN节点。刷新功能会降低缓存命中率。
  • 预热:源站主动将对应的资源缓存到CDN节点,当您首次请求资源时,即可直接从CDN节点获取到最新的资源,无需再回源站获取。预热功能会提高缓存命中率。调用接口肯定需要鉴权,

这次开发中,在签名认证上花了较多时间,官方文档上没有示例,所以在格式上耽误了许久,下面给出签名格式代码:

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class CdnAuthorizationServiceImpl implements CdnAuthorizationService {

    @Value("${cdn.config.accessId}")
    private String accessId;

    @Value("${cdn.config.secretKey}")
    private String secretKey;

    @Value("${cdn.config.domainName}")
    private String domainName;

    @Resource
    private CdnAuthorizationService cdnAuthorizationService;

    @Override
    public String getAuthorization(String signature) {
        return "NCDN " + accessId + ":" + signature;
    }

    @Override
    public String getSignnature(String httpVerb, String contentMd5, String contentType, String date, String canonicalizedResource) throws NoSuchAlgorithmException, InvalidKeyException {
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        String message = httpVerb + "\n" + contentMd5 + "\n" + contentType + "\n" + date + "\n" + canonicalizedResource;
        byte[] bytes = sha256_HMAC.doFinal(message.getBytes(StandardCharsets.UTF_8));
        return java.util.Base64.getEncoder().encodeToString(bytes);
    }

    @Override
    public String getRfctime() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        return simpleDateFormat.format(new Date());
    }

    @Override
    public String getPreheatAuthorization() throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
        String canonicalizedResource = "/domain/" + domainName;
        String rfctime = cdnAuthorizationService.getRfctime();
        String signnature = cdnAuthorizationService.getSignnature("PUT", "", "application/json", rfctime, canonicalizedResource);
        return cdnAuthorizationService.getAuthorization(signnature);
    }

    @Override
    public String getPreheatResultAuthorization(String orderType, Integer pageNum, Integer pageSize, String status) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
        String canonicalizedResource = "/domain/" + domainName + "?orderType=" + orderType + "&pageNum=" + pageNum + "&pageSize=" + pageSize + "&status=" + status;
        String rfctime = cdnAuthorizationService.getRfctime();
        String signnature = cdnAuthorizationService.getSignnature("GET", "", "application/json", rfctime, canonicalizedResource);
        return cdnAuthorizationService.getAuthorization(signnature);
    }
}

注意点:

  1. 每个接口调用时,所需要的Authorization中内容是不同的,要看文档去分别改动签名计算内容。
  2. 获取预热结果列表接口,Authorization里的参数需要和调用接口时的参数保持一致,否则会返回签名不匹配的报错信息。
  3. 头信息除了Authorization之外,还需要Content-Type以及Date。注意Content-Type也要与签名里的Signnature保持一致。Date也要保持格式的统一。

鉴权通过后,就可以调用接口了,这里给出调用成功后的返回信息。

预热接口调用成功后会返回prehot-id:
在这里插入图片描述
预热结果列表调用成功后会返回全部预热个数以及每个预热url的结果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值