通过SCF实现COS更新后自动刷新CDN功能

腾讯云的COS和CDN产品是天生一对,搭配使用和大幅提高下载速度,降低成本,优化性能。但是其中也存在一个问题,当COS文件更新(重新上传或删除)CDN仍然保存缓存内容,造成与源站不一致,那能否在COS更新的时候自动刷新CDN 的缓存呢?答案是肯定的。我们可以使用腾讯云的另一个款产品SCF(无服务器云函数)来实现。

实现的方法为:

1.创建COS bucket并绑定CDN

COS控制台-创建bucket(北京)
CDN控制台-绑定CDN域名

2.创建SCF函数和COS操作触发器

我们进入SCF控制台,创建与COS同地域的函数。

SCF控制台-创建函数

↑↑↑创建一个“空白函数”,函数名和运行环境根据自己的业务需要,我们这里起名test_php 运行环境选择PHP 5.6

注:选择的运行环境和后面封装CDN使用的语言环境有关。

SCF控制台-触发方式-添加触发方式

↑↑↑创建两个COS触发器,分别是文件上传时触发,文件删除时触发,COS和SCF函数必须为同一地域。

3.实现上传事件解析和刷新CDN功能

添加函数代码:

<?php
$gl = 1;
function main_handler($event, $context) {
    $eve = json_decode(json_encode($event,JSON_FORCE_OBJECT),true);
    $usr_url=strval($eve["Records"][0]["cos"]["cosObject"]["url"]);
    
    //截取object部分
    $object=substr($usr_url,strpos($usr_url,"/",8));

    /*需要填写您的密钥,可从  https://console.cloud.tencent.com/capi 获取 SecretId 及 $secretKey*/
    $secretKey='这里替换您的secretKey';
    $secretId='这里替换您的secretId';
    $action='RefreshCdnUrl';

    $HttpUrl="cdn.api.qcloud.com";
    /*除非有特殊说明,如MultipartUploadVodFile,其它接口都支持GET及POST*/
    $HttpMethod="GET";
    /*是否https协议,大部分接口都必须为https,只有少部分接口除外(如MultipartUploadVodFile)*/
    $isHttps =true;
    $nurl="http://这里替换成您的CDN域名".$object; //   示例:$nurl="http://abc.com".$object;
    //print_r($nurl);

    /*下面这五个参数为所有接口的 公共参数;对于某些接口没有地域概念,则不用传递Region(如DescribeDeals)*/
    $COMMON_PARAMS = array(
                    'Nonce' => rand(),
                    'Timestamp' =>time(NULL),
                    'Action' =>$action,
                    'SecretId' => $secretId,
                    'SignatureMethod' => 'HmacSHA256',
                    'urls.0' => $nurl
                    );
    $PRIVATE_PARAMS = array();
    //**********执行CDN刷新URL操作**********/
    CreateRequest($HttpUrl,$HttpMethod,$COMMON_PARAMS,$secretKey, $PRIVATE_PARAMS, $isHttps);
   return "RefreshCdnUrl OK";
}
/***************CDN API调用方法***************/
function CreateRequest($HttpUrl,$HttpMethod,$COMMON_PARAMS,$secretKey, $PRIVATE_PARAMS, $isHttps)
{
        $FullHttpUrl = $HttpUrl."/v2/index.php";

        /***************对请求参数 按参数名 做字典序升序排列,注意此排序区分大小写*************/
        $ReqParaArray = array_merge($COMMON_PARAMS, $PRIVATE_PARAMS);
        ksort($ReqParaArray);

        /**********************************生成签名原文**********************************
         * 将 请求方法, URI地址,及排序好的请求参数  按照下面格式  拼接在一起, 生成签名原文,此请求中的原文为 
         * GETcvm.api.qcloud.com/v2/index.php?Action=DescribeInstances&Nonce=345122&Region=gz
         * &SecretId=AKIDz8krbsJ5yKBZQ    ·1pn74WFkmLPx3gnPhESA&Timestamp=1408704141
         * &instanceIds.0=qcvm12345&instanceIds.1=qcvm56789
         * ****************************************************************************/
        $SigTxt = $HttpMethod.$FullHttpUrl."?";
        $isFirst = true;
        foreach ($ReqParaArray as $key => $value)
        {
                if (!$isFirst) 
                {
                        $SigTxt = $SigTxt."&";
                }
                $isFirst= false;
                /*拼接签名原文时,如果参数名称中携带_,需要替换成.*/
                if(strpos($key, '_'))
                {
                        $key = str_replace('_', '.', $key);
                }
                $SigTxt=$SigTxt.$key."=".$value;
        }
        /*********************根据签名原文字符串 $SigTxt,生成签名 Signature******************/
        $Signature = base64_encode(hash_hmac('sha256', $SigTxt, $secretKey, true));

        /***************拼接请求串,对于请求参数及签名,需要进行urlencode编码********************/
        $Req = "Signature=".urlencode($Signature);
        foreach ($ReqParaArray as $key => $value)
        {
                $Req=$Req."&".$key."=".urlencode($value);
        }

        /*********************************发送请求********************************/
        if($HttpMethod === 'GET')
        {
                if($isHttps === true)
                {
                        $Req="https://".$FullHttpUrl."?".$Req;
                }
                else
                {
                        $Req="http://".$FullHttpUrl."?".$Req;
                }
                $Rsp = file_get_contents($Req);
        }
        else
        {
                if($isHttps === true)
                {
                        $Rsp= SendPost("https://".$FullHttpUrl,$Req,$isHttps);
                }
                else
                {
                        $Rsp= SendPost("http://".$FullHttpUrl,$Req,$isHttps);
                }
        }
        var_export(json_decode($Rsp,true));
}
function SendPost($FullHttpUrl, $Req, $isHttps)
{
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $Req);
        curl_setopt($ch, CURLOPT_URL, $FullHttpUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        if ($isHttps === true) {
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,  false);
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,  false);
        }
        $result = curl_exec($ch);
        return $result;
}
?>

↑↑↑上面内容为解析COS触发事件并刷新CDN URL的代码,注意代码中三个替换标识,需要更换成您自己的资源配置

4.验证效果

COS控制台-文件列表-上传文件
COS控制台-文件列表-删除

↑↑↑进入COS控制台上传一个文件对象并且删除一个已存在文件对象

SCF控制台-日志记录

↑↑↑SCF会触发并生成两个执行日志。注:如需调试,可在函数中增加输出语句。

CDN控制台-缓存刷新-操作记录

↑↑↑访问CDN控制台的缓存刷新--操作记录,可以看到我们上传和删除的资源均被刷新了,验证成功。

后记:在上面的实践中,我们实现了COS上传和删除文件对象时自动刷新CDN URL的功能,当然SCF产品功能并不止于此,您也可以通过代码来实现刷新后的预热功能,甚至调用CVM等其他业务服务器的功能,灵活组合,搭配使用,更多操作,等您来用。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏落影的专栏

iOS开发笔记(八)---- 键盘、静态库、动画、Crash定位

43390
来自专栏Y大宽

查找一个基因的启动子序列

56320
来自专栏Django Scrapy

Zabbix监控调用map.get并且下载图文件

#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 17/8/28 上午9:09 # @Aut...

40970
来自专栏一个会写诗的程序员的博客

bootstrap-table 前端分页,刷新事件代码实例

参考文档: http://bootstrap-table.wenzhixin.net.cn/

1.4K10
来自专栏WindCoder

一个Angular 5教程:一步一步指导实现你的第一个Angular 5应用程序

现在我们可以app.component.html用这个替换:Angular是由Google开发的AngularJS框架的新版本。它带有一个完整的重写,以及各种改...

1.8K10
来自专栏葡萄城控件技术团队

MVC5:使用Ajax和HTML5实现文件上传功能

引言 在实际编程中,经常遇到实现文件上传并显示上传进度的功能,基于此目的,本文就为大家介绍不使用flash 或任何上传文件的插件来实现带有进度显示的文件上传功能...

732100
来自专栏Golang语言社区

神奇的go语言(网页下载)

目前,网上关于网页爬行的代码很多。但是,自从看了go语言的web下载代码之后,我才发现原来它的网页下载代码才是最简单的。不信的话,大家可以看一下, packa...

418100
来自专栏娱乐心理测试

小程序完整demo

32050
来自专栏生信宝典

CIRCOS圈图绘制 - 最简单绘图和解释

Circos是绘制圈图的神器,在http://circos.ca/images/页面有很多CIRCOS可视化的示例。 ? ? Circos可以在线使用,在线使用...

1.7K90
来自专栏LinXunFeng的专栏

RxSwift + MJRefresh 打造自动处理刷新控件状态

27430

扫码关注云+社区

领取腾讯云代金券