CDN边缘JavaScript敏捷交付实践
本文由百度智能云-视频云-内容分发加速技术架构师——高岩 在百度开发者沙龙线上分享的演讲内容整理而成。内容从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优势:
缩短网站加载时间
通过将内容分发到访问者附近的CDN服务器(以及其他优化措施),访问者体验到更快的页面加载时间。由于访问者更倾向于离开加载缓慢的网站,CDN 可以降低跳出率并增加人们在该网站上停留的时间。换句话说,网站速度越快,用户停留的时间越长。减少带宽成本
网站托管的带宽消耗成本是网站的主要费用。通过缓存和其他优化,CDN 能够减少源服务器必须提供的数据量,从而降低网站所有者的托管成本。增加内容可用性和冗余
大流量或硬件故障可能会扰乱正常的网站功能。由于CDN具有分布式特性,因此与许多源服务器相比,CDN 可以处理更多流量并更好地承受硬件故障。改善网站安全性
CDN 可以通过提供鉴权、安全证书的改进以及其他优化措施来提高安全性。
vCDN的发展
早在2009年,伯克利曾针对当时兴起的云计算做过评论,并提出了以下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 具有以下特点:
- 计算的无状态化,服务的储存和计算完全分开部署的,开发者只需要关心计算的实现,可以通过其它云上的独立服务进行储存,容易进行迁移和扩缩容。
- 资源透明化的,无需要再关心服务器、虚拟机、容器需要多少资源、带宽、磁盘空间,可以通过调用函数在平台内实现资源的自动管理。
- 按需计费,根据调用时长、调用次数进行计费。目前,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 具有以下特性:
- 动态编码。
- 即时编译。即用户代码在边缘区编译之后,可以被缓存,无需进行重复编译,理论上大大提升了执行的效率。
- 风险隔离。即严格隔离不同用户的代码,为用户可以使用的资源设置最高上限。
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敏捷交付实践相关推荐
- CDN边缘节点容器调度实践(下)
5月27日,OSC 源创会在上海成功举办.又拍云系统开发高级工程师黄励博在大会分享了<CDN 边缘节点容器调度的实践>.主要介绍又拍云自主开发的边缘节点容器调度方案,从 0 到 1 ,实现 ...
- 网易互客敏捷交付实践
作者 | 九歌 网易智企服务端开发 敏捷开发的一个重要目标是建立持续价值交付的能力.这种能力最终必须服务于业务的创新,促进业务的成功. 面临的问题 在互联网行业,业务的发展通常日新月异,并且伴随着不断 ...
- 基于CDN边缘网络智能优化图片和视频
本文由Akamai高级技术顾问--何明聪在LiveVideoStack线上分享演讲内容整理而成.在分享中,何明聪老师结合Akamai图片和视频优化方案及具体实践经验,详细解析了如何在无需修改源站代码的 ...
- 如何在CDN边缘节点执行你的JavaScript?
Serverless和边缘计算都是目前云计算领域备受瞩目的研究和应用方向.做为拥有超过130Tbps带宽分发能力的阿里云CDN,巨大的边缘网络有超过2800个节点遍布全球,如何将中心源站的计算能力下沉 ...
- 《规范敏捷交付:企业级敏捷软件交付的方法与实践》——3.11 观点总结
3.11 观点总结 本章描述了规范敏捷交付过程框架所基于的核心敏捷方法的根基.它们之间有很多相似之处,但每个方法又都有一些不同.肯·施瓦伯,Scrum的创始人之一,曾经将敏捷方法比作象棋比赛.这里面只 ...
- EdgeRoutine技术专家教你把JS代码跑到CDN边缘
4月27日CDN云课堂中,阿里云智能技术专家洪晓龙在线分享<阿里云CDN轻量编程环境>,对EdgeRoutine的背景.功能.案例实践介绍并在线进行上手操作演示,希望更多用户能够使用CDN ...
- POLYV敏捷项目管理实践
本文主要介绍POLYV半年来的敏捷项目管理实践经验,融合了以往十多年研发过程管理经验,采取了双班车制度,有效推进客户高商业价值的需求落地:同时也介绍了PM工具箱,确保研发过程的风险控制,让客户价值得到 ...
- 阿里云高级技术专家周哲:阿里云边缘云原生应用实践
简介: 为什么需要边缘云原生?边缘云原生的技术特性和优势是什么?它可以为行业提供哪些关键能力?又有哪些场景适合边缘云原生呢?在MEC全球应用开发者大会的"MEC开放论坛"上,阿里云 ...
- [敏捷开发实践](2) 用于开发和维持复杂产品的敏捷开发框架Scrum
[敏捷开发实践](2) 用于开发和维持复杂产品的敏捷开发框架Scrum 1,Scrum概述 上篇中提到敏捷开发有两种主流的方法,一个是XP,另一个是Scrum,本篇简要介绍Scrum方法.Scrum是 ...
最新文章
- 用户与订单之间的关系_wms与oms、tms的上下游关系
- 第十二届蓝桥杯大赛软件赛省赛第二场 C/C++ 大学B组
- 通过libusb操作usb设备扫描二维码
- BeetleX网关自定义请求日志插件
- 装配图位置偏转怎么调整_物理微课|匀变速直线运动、电容器动态分析及磁偏转技巧、方法、模型...
- keil编译运行错误,缺少error:#5:#includecore_cm3.h_过路老熊_新浪博客
- AJPFX浅谈关于Java程序员缺乏面向对象的基本功的问题
- VS 15 预览 5 中 VB 15 新增的功能
- AngularJS从构建项目开始
- 洛谷 3951 小凯的疑惑
- 微信小程序双层图片swiper滑动(底部图片模糊处理)实现
- 数字图像处理(dip)
- 如何从零开始系统运营微信公众号?
- 计算机日历教案,计算机基础教学日历.doc
- Windows 10无法打开设置
- 可获取公网IP的网址
- Linux DNS之正向解析(邮件记录、别名解析、泛域名解析)
- 计算机绘图入门,[2018年最新整理]AutoCAD计算机绘图入门.ppt
- js 将字符串转化为number的简单方式
- 【JAVA】8.5.1内部购物券
热门文章
- 404. 左叶子之和
- html入门学习(二)
- linux fedora35禁用或启用仓库
- harbor的镜像复制功能使用教程
- Apache Subversion command line tools下载地址 svn命令行客户端
- docker-compose HBase + Phoenix 开发环境单机快速部署
- k8s pod应用升级回滚(set image/rollout)和弹性伸缩(scale)示例
- Fiddler 4设置代理后无法上网的问题解决办法(亲测有效)
- Python爬虫开发:正则表达式re的使用
- 优惠券卡包应用数据库字段设计/系统架构设计/缓存层设计方案