本文由百度智能云-视频云-内容分发加速技术架构师——高岩 在百度开发者沙龙线上分享的演讲内容整理而成。内容从CDN应用Serverless的意义出发,详细介绍EdgeJS Serverless服务。

文/ 高岩
整理/ 百度开发者中心
视频回放:https://developer.baidu.com/live.html?id=11

本次分享的主题是:CDN边缘JavaScript敏捷交付实践,内容主要分为以下三个方面:

  • CDN应用Serverless的意义
  • EdgeJS Severless服务
  • 沉浸式CDN编程体验

01 CDN应用Serverless的意义

CDN基本介绍

CDN含义:
是指一组分布在不同地理位置的服务器,协同工作以提供互联网内容的快速交付。

CDN服务已得到不断普及。如今,大多数web流量都通过CDN提供服务,几乎所有的门户网站、常用的视频 APP(例如,爱奇艺、抖音)都会用 CDN 架构实现更加快速的内容分发,让用户更快地看到视频内容,带来更好的用户体验。

这是因为 CDN 允许快速传输、加载互联网内容所需要的资源。以门户网站为例,我们需要加载 HTML 页面、JavaScript、文件 css 等资源;而视频网站则需要加载缩略图、视频文件。

CDN 还可帮助保护网站免受某些常见的恶意攻击,例如分布式拒绝服务(DDOS)攻击。

使用CDN优势:

  1. 缩短网站加载时间
    通过将内容分发到访问者附近的CDN服务器(以及其他优化措施),访问者体验到更快的页面加载时间。由于访问者更倾向于离开加载缓慢的网站,CDN 可以降低跳出率并增加人们在该网站上停留的时间。换句话说,网站速度越快,用户停留的时间越长。

  2. 减少带宽成本
    网站托管的带宽消耗成本是网站的主要费用。通过缓存和其他优化,CDN 能够减少源服务器必须提供的数据量,从而降低网站所有者的托管成本。

  3. 增加内容可用性和冗余
    大流量或硬件故障可能会扰乱正常的网站功能。由于CDN具有分布式特性,因此与许多源服务器相比,CDN 可以处理更多流量并更好地承受硬件故障。

  4. 改善网站安全性
    CDN 可以通过提供鉴权、安全证书的改进以及其他优化措施来提高安全性。

vCDN的发展

早在2009年,伯克利曾针对当时兴起的云计算做过评论,并提出了以下6个潜在的优点:

  1. (理论上)无限可用的计算资源,可在资源池中实现任意的伸缩。
  2. 用户再也不需要承担服务器运维的工作和责任。
  3. 服务的按需付费成为可能。
  4. 超大型数据中心的使用成本显著降低。
  5. 通过可视化资源管理,运维操作的难度大大降低。
  6. 分时复用,物理硬件的利用率大大提高。

基于云计算的理念,可以实现一个虚拟化CDN(vCDN), 即可在专有、裸金属、虚拟化或基于容器的基础设施上运行CDN。vCDN作为云上的一个应用,是CDN和云紧密结合的产品。其主要功能特性包括:
硬件虚拟化:虚拟化基础架构使软件和硬件功能得以分解,服务器运维大大简化。
低延迟:在共享基础设施上运行CDN功能,可以更快的调起其他应用,比如可以实时进行图片处理。
弹性伸缩:可以按需使用CDN,在流量高峰和低峰,进行自动的弹性扩容和缩容。

但是云计算技术发展到今天,虚拟化并不能解决所有的问题,
在对性能有特别高要求的场景下,面临的主要难点如下:

  • 虚拟机/容器,构建业务应用运维成本较高。
  • 不能做到按需付费,仍然需要独占虚拟机。
  • 开发复杂,需要很多其它的依赖,在开发业务的过程中,需要数据库、对象存储等框架。需要自己掌控运维和使用情况,开发难度较高。

Serverless介绍与特点

为了解决上述问题,亚马逊的 AWS 在 2015 年推出了 lambda 服务,提出了Cloud Function的概念,引起了业界对于 Serverless 的关注广泛。

Serverless 主要包含 Faas、Baas 两种形态。其中,Faas 将 Function 作为服务,Baas 将后端服务作为服务。

在应用了 vCDN 后,也可以用 Baas 的方式运行服务。Serverless 旨在让开发人员不需要再关注服务器,云会帮自动实现服务器的运维和伸缩。

具体而言,Serverless 具有以下特点:

  1. 计算的无状态化,服务的储存和计算完全分开部署的,开发者只需要关心计算的实现,可以通过其它云上的独立服务进行储存,容易进行迁移和扩缩容。
  2. 资源透明化的,无需要再关心服务器、虚拟机、容器需要多少资源、带宽、磁盘空间,可以通过调用函数在平台内实现资源的自动管理。
  3. 按需计费,根据调用时长、调用次数进行计费。目前,vCDN 可以为客户提供 Baas 服务。如果用户需要更通用的函数计算产品,推荐使用百度云的 CFC,可以配置 CDN 的触发器。

CDN应用Serverless的意义

早在 2018年,云管理公司 RightScale 开展的一项调查显示,Serverless 是增长最快的公共云服务。
据统计,AWS 上超过一半的用户已经在使用 Serverless 服务。Serverless 一直在高速发展,呈现出越来越大的影响力。
Serverless 将无处不在,CDN也必须拥抱Serverless理念,提供边缘可编程能力,使用户可以在控制台上通过 API 设置代码,形成编程能力,更有效地控制 CDN。

在 CDN 业务中实践 Serverless 理念可以提供敏捷交付的能力,具有以下优势:

  • 编程能力 对于刚接触CDN的客户来说,可编程能力,即便不理解CDN的具体运作流程,也能快速编写出可用的代码。
  • 敏捷交付 对于CDN研发人员,serverless节省了他们部署和运维的时间,让他们能够更加专注于解决和优化应用本身的问题。
  • 场景下沉结合编程能力,可以和其他场景更方便的结合在一起。
  • 边缘计算在CDN的边缘,可以进行更加自由的计算,节省端上处理的时间和延迟。

02 EdgeJS Serverless服务

EdgeJS Serverless服务目标

Serverless 的目标是使用户可以更容易地编写和部署代码,而无需关注底层结构。尽管目前的 CDN 业务可以实现按需付费,但是仍然不够灵活。

为此,我们推出了 EdgeJS Serverless 服务。该服务在百度智能云 CDN 上使用JavaScript 语言去提供的一种可编程的配置能力,实现高并发、低成本的敏捷交付,使 CDN 能够体现出 serverless 的思想,进行靠拢或者是计划。

该服务具有以下特点:

  • 嵌入式 JavaScript runtime,而非独立的 runtime。出于对性能的考虑,在支持 JS 标准库的同事,避免了独立runtime 带来的冷启动时间。
  • 提供请求对象 request,可以在代码中进行随意更改。
  • 提供对外访问能力。

作为一种 Serverless 服务,EdgeJS 需要实现用户隔离、具备较高的性能,能够动态编码。具体而言,EdgeJS 具有以下特性:

  1. 动态编码。
  2. 即时编译。即用户代码在边缘区编译之后,可以被缓存,无需进行重复编译,理论上大大提升了执行的效率。
  3. 风险隔离。即严格隔离不同用户的代码,为用户可以使用的资源设置最高上限。

EdgeJS Serverless服务的特性

EdgeJS致力于让CDN更易用,向serverless服务能力迈进。所以EdgeJS的定位一开始就是完全免费,在CDN按需使用的带宽费用之外,不会产生额外的费用。

在降低CDN使用门槛的初衷下,必须还得保持CDN的高可用、低延迟、就近服务的能力。

EdgeJS的设计,是完全嵌入到CDN接入层的JavaScriptruntime,无需冷启动时间,没有性能损失,并支持标准ES6语法的JavaScriptAPI,各种特性陆续补齐中。

而且相比传统交付,开发上线至少周级别的交付周期,EdgeJS真正能做到秒级交付,用户在控制台配置上代码,就可以秒级生效。当然建议在正式发布前,先使用预发布功能来灰度验证。EdgeJS,可以根据请求进行各种特征处理,这极大丰富了CDN接入的场景。

为了更好地配合 CDN 业务,EdgeJS 具有以下特性:

  • 使用 EdgeJS 在边缘进行计算(如一些特殊的鉴权等不能缓存的动态需求),将预计算任务部署在边缘设备上,大大减轻源站的压力
  • 做到秒级交付,使用户在控制台上配置代码,秒级生效。
  • 根据请求进行各种特征处理,极大丰富 CDN接入场景(包括不限于跨域访问、重定向、访问控制、单请求限速、自定义鉴权、m3u8改写、请求改写、A/BTest自定义错误页面等。

除此之外,EdgeJS还可以利用fetch等能力,和远端进行协同,包括不限于远程鉴权、云服务协同和请求画像打点上传。这些能力已经远超CDN的传统场景,向serverless服务能力靠拢。

在CDN庞大的算力加持下,可以减轻源站的性能压力和支出。而且,当增加了新的特征或者增加了新的计算方法,可以随时修改JavaScript代码,进行实时控制。

03 沉浸式CDN编程

url改写与复杂文件名改写

CDN 控制台本身支持一些 URL 改写的基本功能,但这些预定义的功能灵活性较低。我们可以通过 EdgeJS 根据用户的要求确定配置。EdgeJS 使用标准的 JS 语法,需要用户建立一个请求对象 request。
如上图所示,我们首先将 URL 中的大写字母转成小写,接着我们将请求的 variables 参数改成小写。variable 映射的是 UNIX 的变量,而这的规则完全一致的。

EdgeJS 支持复杂的文件名改写,这里涉及到三种情况:
(1)参数 attname 存在且不为空字符串
(2)参数 attname 存在且为空字符串
(3)参数 attname 不存在。

回源鉴权头

在一些对象存储场景下,我们可以通过 EdgeJs 构建回源鉴权头 authorization。首先生成一个随机数,获取当前时间,并生成请求 URL。接着,我们利用以上三者根据 crypto 算法生成鉴权头。
我们可以通过请求的 headersIn 特性获取请求头。有些特殊的请求头只能存在一份,如果重复则会被忽略(例如,host、connection,详见官网)。此外,重复的 Cookie 的请求头会返回所有的重复部分,并以分号分隔开来。如果我们想要获取所有的请求头,我们需要使用 rawHeadersIn 特性,如果请求头有多个,则会输出数组。

r.headersIn{}
请求头对象,可写Foo请求头可以使用r.headersIn.foo或者r.headersIn[‘Foo’]来访问
“Host”, “Connection”, “If-Modified-Since”, “If-Unmodified-Since”, “If-Match”, “If-None-Match”, “User-Agent”, “Referer”,
“Content-Length”, “Content-Range”, “Content-Type”, “Range”, “If-Range”, “Transfer-Encoding”, “TE”, “Expect”,
“Upgrade”, “Accept-Encoding”, “Via”, “Authorization”, “Keep-Alive”, “X-Real-IP”, “Accept”, “Accept-Language”, “Depth”,
“Destination”, “Overwrite”, "Date"这些请求头只能有一个,重复的会被忽略

重复的“Cookie”请求头,会返回所有的重复部分,并以分号(;)分隔,
重复的其他请求头,会返回所有的重复部分,并以逗号(,)分隔,
r.headersIn.foo =‘foo’,赋值会覆盖所有的重复部分。

r.headersIn [‘Foo’]= [‘a’, ‘b’],赋值数组,会产生两个重复的请求头:
Foo:a和Foo:b

r.rawHeadersIn{}
请求头KV Array,只读。
比如请求头Host:localhost;Foo: bar ;foo: bar2

r.rawHeadersIn输出类似于[‘Host’, ‘localhost’], [‘Foo’, ‘bar’], [‘foo’, ‘bar2’]
获取所有的请求头foor.rawHeadersIn.filter(v=>v[0].toLowerCase()
== ‘foo’).map(v=>v[1])
输出[‘bar’, ‘bar2’]

文件名改写

EdgeJS Serverless 服务通过请求的 headersOut 特性可以实现文件名改写、跨域访问、设置相同的响应头等功能。
如上图所示,我们可以使用请求参数 filename 命名下载文件,使用请求头 Origin 赋值给跨域响应头 Access-Control-A。在设置相同的响应头时,我们可以通过赋值数组,产生重复的响应头。

r.headersOut{}响应头对象,可写Foo响应头可以使用r.headersOut.foo或者r.headersOut[‘Foo’]来访问。
“Server”, “Date”, “Content-Length”, “Content-Encoding”,
“Location”, “Refresh”, “Last-Modified”,
“Content-Range”, “Accept-Ranges”,
“WWW-Authenticate”, “Expires”, “E-Tag”, “ETag”, “Content-Type”, “X-Override-Charset”,
“Cache-Control”, “Link”, “Age”,
“Retry-After”,这些响应头只能有一个,重复的会被忽略

重复的"Set-Cookie"响应头,会返回一个数组,例如,r.headersOut[‘Set-Cookie’].forEach
(element=> console.log(element));

重复的其他响应头,会返回所有的重复部分,并以逗号(,)分隔
r.headersOut.foo =‘foo’,赋值会覆盖所有的重复部分。

r.headersOut [‘Foo’]= [‘a’, ‘b’],赋值数组,会产生两个重复的响应头:
Foo:a和Foo:b

r.rawHeadersOut{}
响应头KV Array,只读
用法类似于r.rawHeadersIn{}

自定义错误页面

我们可以使用 EdgeJS 实现自定义的错误页面,当源站返回 404 时,可以重定向到一个对用户友好的页面。
如上图所示,我们通过 respHeader 回调实现上述功能。类似地,我们可以通过 respHeader 实现 A/B 测试,
如果源站返回了特殊头 a,可以命中一个升级的逻辑,重定向到一个应用升级的页面。

IP黑名单

EdgeJS 支持通过百度自有的库提供一些常用的访问控制功能:
(1)IP 黑名单,如果客户端地址在 192.168.1.1/32 或 192.168.2.1/24 等ip段内,则返回 403。
(2)Referer 白名单,如果 referer 不匹配某些通配符的形式,则返回 403。
(3)UA 黑名单,如果 UA 包含 curl 或 AppleWebKit,则返回 403。

代码示例:
r.remoteAddress
客户端地址,只读

baidu_utils库
function ipInCidr(ipv4,cidrs)
参数:
ipv4为点分十进制的ipv4地址,比如’192.168.2.100’
cidrs为CIDR地址列表,比如[‘192.168.1.1/32’,‘192.168.2.1/24’]

使用示例:
if (baidu_utils.ipInCidr (‘192.168.2.100’,[‘192.168.1.1/32’,‘192.168.2.1/24’])) {
r.return(403);
}
function matchWildcard(str,rule)

参数:
str为待匹配的字符串,比如’http://www.baidu.com/’
rule为有通配符的字符串,比如’http://.baidu.com/

使用示例:
if (baidu_utils.matchWildcard(‘http://www.baidu.com/’, ‘http://.baidu.com/’)
{
r.return(403);
}

鉴权

百度云基于 EdgeJS 提供了 B 类防盗链等鉴权功能。原始的 URL 包含协议头 HTTP、域名、文件名。在加密之后,URL 变成了协议头、域名、时间戳、MD5 编码,文件名。
在上图的第一段代码中,CDN 服务器收到请求之后,首先拆分 URL,得到时间戳、MD5 、文件名。
在第二段代码中,时间戳的格式并非 Unicode,而是可读的格式,我们需要进行时间戳格式的转换,将秘钥与时间戳、文件名拼接,并进行 MD5 加密编码的比对。

子请求

CDN本身是一个缓存体系,对于hls或者dash来说,其索引文件中包含的防盗链信息,在用户请求的时候很可能过期了,所以在用户请求的m3u8或者mpd的防盗链验证通过之后,需要将这个请求中的防盗链信息改写到索引文件内容中。

Fetch

Fetch
ngx.fetch(url, [options])
类似于JavaScript原生的Fetch,请求URL,并返回解析Response对象的Promise。参考Using_Fetch
目前仅支持http协议,重定向需要调用者处理
类似于js fetch,options支持body/ headers / method。

ssl选项如下:
ssl_name 指定sni,默认为url中的域名
ssl_verify是否开启证书校验,默认开启

Response
标准的JavaScript内置对象

我们可以通过 EdgeJS Serverless 服务实现 Fetch 功能,请求远程鉴权服务器,根据远程服务器的响应进行处理,如果得到非 2xx 状态码,则返回 403 禁止访问。Fetch 返回的是一个 Promise 对象,包含类方法,可以将异步的操作变为序列化的操作,只要需要关心业务逻辑。与 Fetch 一同上线的还有 Await、SubtleCrypto 等功能。

以上是老师的全部分享内容,有任何问题可以在讨论区提出。
点击进入获得更多技术信息~~

扫描二维码,备注:音视频开发,立即加入音视频开发技术交流群。

CDN边缘JavaScript敏捷交付实践相关推荐

  1. CDN边缘节点容器调度实践(下)

    5月27日,OSC 源创会在上海成功举办.又拍云系统开发高级工程师黄励博在大会分享了<CDN 边缘节点容器调度的实践>.主要介绍又拍云自主开发的边缘节点容器调度方案,从 0 到 1 ,实现 ...

  2. 网易互客敏捷交付实践

    作者 | 九歌 网易智企服务端开发 敏捷开发的一个重要目标是建立持续价值交付的能力.这种能力最终必须服务于业务的创新,促进业务的成功. 面临的问题 在互联网行业,业务的发展通常日新月异,并且伴随着不断 ...

  3. 基于CDN边缘网络智能优化图片和视频

    本文由Akamai高级技术顾问--何明聪在LiveVideoStack线上分享演讲内容整理而成.在分享中,何明聪老师结合Akamai图片和视频优化方案及具体实践经验,详细解析了如何在无需修改源站代码的 ...

  4. 如何在CDN边缘节点执行你的JavaScript?

    Serverless和边缘计算都是目前云计算领域备受瞩目的研究和应用方向.做为拥有超过130Tbps带宽分发能力的阿里云CDN,巨大的边缘网络有超过2800个节点遍布全球,如何将中心源站的计算能力下沉 ...

  5. 《规范敏捷交付:企业级敏捷软件交付的方法与实践》——3.11 观点总结

    3.11 观点总结 本章描述了规范敏捷交付过程框架所基于的核心敏捷方法的根基.它们之间有很多相似之处,但每个方法又都有一些不同.肯·施瓦伯,Scrum的创始人之一,曾经将敏捷方法比作象棋比赛.这里面只 ...

  6. EdgeRoutine技术专家教你把JS代码跑到CDN边缘

    4月27日CDN云课堂中,阿里云智能技术专家洪晓龙在线分享<阿里云CDN轻量编程环境>,对EdgeRoutine的背景.功能.案例实践介绍并在线进行上手操作演示,希望更多用户能够使用CDN ...

  7. POLYV敏捷项目管理实践

    本文主要介绍POLYV半年来的敏捷项目管理实践经验,融合了以往十多年研发过程管理经验,采取了双班车制度,有效推进客户高商业价值的需求落地:同时也介绍了PM工具箱,确保研发过程的风险控制,让客户价值得到 ...

  8. 阿里云高级技术专家周哲:阿里云边缘云原生应用实践

    简介: 为什么需要边缘云原生?边缘云原生的技术特性和优势是什么?它可以为行业提供哪些关键能力?又有哪些场景适合边缘云原生呢?在MEC全球应用开发者大会的"MEC开放论坛"上,阿里云 ...

  9. [敏捷开发实践](2) 用于开发和维持复杂产品的敏捷开发框架Scrum

    [敏捷开发实践](2) 用于开发和维持复杂产品的敏捷开发框架Scrum 1,Scrum概述 上篇中提到敏捷开发有两种主流的方法,一个是XP,另一个是Scrum,本篇简要介绍Scrum方法.Scrum是 ...

最新文章

  1. 用户与订单之间的关系_wms与oms、tms的上下游关系
  2. 第十二届蓝桥杯大赛软件赛省赛第二场 C/C++ 大学B组
  3. 通过libusb操作usb设备扫描二维码
  4. BeetleX网关自定义请求日志插件
  5. 装配图位置偏转怎么调整_物理微课|匀变速直线运动、电容器动态分析及磁偏转技巧、方法、模型...
  6. keil编译运行错误,缺少error:#5:#includecore_cm3.h_过路老熊_新浪博客
  7. AJPFX浅谈关于Java程序员缺乏面向对象的基本功的问题
  8. VS 15 预览 5 中 VB 15 新增的功能
  9. AngularJS从构建项目开始
  10. 洛谷 3951 小凯的疑惑
  11. 微信小程序双层图片swiper滑动(底部图片模糊处理)实现
  12. 数字图像处理(dip)
  13. 如何从零开始系统运营微信公众号?
  14. 计算机日历教案,计算机基础教学日历.doc
  15. Windows 10无法打开设置
  16. 可获取公网IP的网址
  17. Linux DNS之正向解析(邮件记录、别名解析、泛域名解析)
  18. 计算机绘图入门,[2018年最新整理]AutoCAD计算机绘图入门.ppt
  19. js 将字符串转化为number的简单方式
  20. 【JAVA】8.5.1内部购物券

热门文章

  1. 404. 左叶子之和
  2. html入门学习(二)
  3. linux fedora35禁用或启用仓库
  4. harbor的镜像复制功能使用教程
  5. Apache Subversion command line tools下载地址 svn命令行客户端
  6. docker-compose HBase + Phoenix 开发环境单机快速部署
  7. k8s pod应用升级回滚(set image/rollout)和弹性伸缩(scale)示例
  8. Fiddler 4设置代理后无法上网的问题解决办法(亲测有效)
  9. Python爬虫开发:正则表达式re的使用
  10. 优惠券卡包应用数据库字段设计/系统架构设计/缓存层设计方案