使用函数计算解析视频地址

最近工作上的事情比较忙,于是不得不花些时间追剧分散一下注意力。因为之前听过一期高晓松与亲王马伯庸《晓说》,因此追的是很多人已经看完的根据马伯庸小说改编的《长安十二时辰》。

然而,独播该剧的优酷动辄120秒的广告,实在是太影响观影体验。于是花了点时间搞了今天这个小创造:视频地址解析。严格来讲,这个小工具其实不算是什么创造,因为类似的工具其实有很多。只是正好之前一直关注serverless,因此这个工具其实是使用阿里云的函数计算来完成。方案如下:

使用函数计算来做这个功能其实并不是“锤子思维”,而是因为在github找的一些视频地址解析工具命令行方式提供,而我为了在几分钟以为快速解决自己问题,不想花时间使用代码来调用工具中的执行函数。因此每个函数计算其实是开了一个进程去执行视频地址解析命令,然后向前端返回结果。函数计算因为是按照调用计费,非常适合这种场景。一来不用对进程未正常退出进行容错处理;二来频繁创建和销毁进程是非常昂贵的,不适合放在我的小vps上处理这种任务;第三,阿里云函数计算提供每个月100W次的免费调用额度(都是贫穷惹的祸呀😅)

为了快速完成这个小工具,我选择 Python 作为自己函数计算的开发语言。阿里云的函数计算也支持 Java, Node.js, C#, PHP 等其他语言,挑选一个自己趁手的就行。整体上,函数计算这个产品非常简单,基本跟着引导就能做完。其中有几个点比较常见也很重要,在这里简单记录一下。

1. 函数的调试

函数计算有 Web IDE, 你可以直接在上面编写和调试代码。但是,如果你习惯使用 VS Code在本地调试的话,推荐你使用函数计算的VSCode 插件

2. 添加外部依赖

函数计算的 Python 环境默认配置了标准库以及几个常用的的包依赖。如果需要添加其他依赖,你需要使用 fun 这个工具来管理和添加语言依赖

对于 Python, 只需要使用如下命令安装包依赖即可:

fun install –runtime python3 –package-type pip flask

该命令会将依赖包安装在项目目录的 .fun 目录下:

3. 使用 flask 封装 web server

函数计算有好几种触发方式,最常规的肯定是通过 HTTP API 调用方式触发。这个场景,当时是 fask 与 Python 最搭:

有时候,我们折腾事情可能会因为过程而忘记了初心。对于追剧这件小事这种情况是肯定不允许发生的。愉快的追剧去吧

Enjoy!

低延迟与用户体验杂谈

最近在做系统设计梳理的时候,明显感觉到「低延迟」已经成为被提及越来越频繁、考量权重越来越大的因素。 并且,越是靠用户近的系统,对延迟越敏感,对用户体验影响越大,对低延迟要求越高。

HTTP/2如今(2018.02)已经逐渐普及,其设计的第一目标就是降低延迟。主要采用了两个手段来解决:

  1. TCP连接复用。连接复用减少了TCP每次握手带来的延迟,同时避免了每次新建TCP连接的窗口慢启动带来的数据吞吐开启延迟。
  2. 使用数据分帧解决队头阻塞问题。当然,这个问题HTTP/2解决得不彻底,具体可以参见《当我们在谈论HTTP队头阻塞时,我们在谈论什么?》了解细节。

HTTP/2毕竟只能解决应用层的低延迟问题。如果要继续降级延迟,就需要下潜到传输层。因此,Google的QUIC和TLS 1.3应运而生。QUIC目前主要是Google主导,除去其自家的服务,如Google搜索首页,G+等,支持的网站还非常少。TLS 1.3则由标准化组织加持,目前在最新的OpenSSL、nginx已经支持。TLS 1.3能够做到新连接3RTT,恢复连接2RTT(TLS 1.2分别是4RTT, 3RTT;而2RTT已经与http的RTT持平!),的确非常吸引人。

回顾WEB技术过去十几年的发展,很多的特性引入和改进都是基于降低延迟。有些是技术层面的,比如上面提到的HTTP/2的低延迟设计、DNS查询缓存、HTTP1.1并发多个TCP连接请求资源、雪碧图等;有些是用户体验层面的,比如异步加载/预加载js资源、优先加载影响首屏渲染的CSS资源、避免使用大表布局、图片渐变加载、过渡动画等。

而这些年技术层面的发展其实都是受物理定律限制的。祭出程序员延迟心经Latency Numbers Every Programmer Should Know:

软件工程师无论是做什么职位和方向,心里都应该对此有B树。

有了这些当前人类所认识的物理极限,才能做到在「在边界内做事情」(这句话不是我说的,第一次看到这句话是吴军老师的《硅谷来信》)。

举个例子,当前人类认知范围内最快的速度是光速,这是一个上限,而广泛使用的光纤通信速度大概是光速的2/3。那么,要想优化上海到加州的网络延迟,无论你如何优化线缆布设以及质量,RTT都不可能低于127ms. 因此,如你所见,这些年虽然新架设了不少新的跨太平洋光缆,但是最优网络延迟没有什么太大变化,反倒是这些光缆带来的扩容让网络拥塞得到了缓解,让我们感觉出口网络「好像」更快了。

那么在光速这个物理边界的限制下,我们要如何降低延迟呢?显然,固定的两点之间的网络延迟是无法突破该边界的(这里不讨论空间扭曲力场🤦‍♀️)。但是,很多时候,我们要解决的问题是「让用户感觉延迟低」就可以了。

在这个思想下,CDN应运而生。将内容分发到距离用户近的网络节点来降低用户访问延迟。这个idea非常简单,甚至简陋,但是非常有效,并且廉价。

顺着这个思路下去,如果把算力分发到距离用户近的节点,那是不是也可以让用户觉得计算任务也变快了呢?在一定程度上,这是可以做到的。比如,我们使用了数十年运行于浏览器的javascript,以及我们的多IDC、多主架构方案,都有这方面的考量。近来流行的serverless、边缘计算其实也可以是认为是将算力部署到离用户尽可能近的物理位置或业务流程中。

有时候,技术参数指标的提升在短期内是难以低成本解决的。这个时候,尽量避免死磕参数,投入100%的精力去换取1%的性能提升。可以尝试从设计交互上给用户形成反应很快的体验,降低体感延迟。比如,1)耗时的任务后台化并给出进度条;2)区块处理的逻辑任务尝试修改成流处理,加速部分处理结果的输出,典型应用如以视频直播服务为代表的流媒体服务全力优化首屏播放延迟;批处理任务每处理完一个子任务就反馈结果等。

不仅软件系统的延迟影响着用户体验,硬件更是如此。现在人们普遍认为iPhone的用户体验是优于安卓的。因素有很多,那些复杂的系统参数普通用户未必搞得懂,但是很多用户却承认在滑动屏幕的时候iPhone比安卓更加「跟手指」,打开应用也「感觉更快」。「跟手指」这个体验跟苹果的软件+硬件的技术优化有关,目前安卓阵营也没有赶上。打开app快则是典型的交互优化:苹果打开app未必真的比安卓快,但是从点击app图标到显示story board的确非常快。无论苹果是否鸡贼,至少从这个层面看,它的确是非常了解延迟与用户体验之间的奥义的。至于苹果每次升级系统「故意」让老设备变卡……咳,咳,同学,你怎么有又抬杠呢😅

喜欢汽车并且喜欢驾驶的朋友一定知道甚至深入研究过这几款车:马自达3/6/BRZ/86-宝马M2/M4-保时捷718/911。排名分先后,每一辆都是不同级别的驾驶者之车,也是很多玩车朋友的玩车升级路线。这些车都是「运动取向」,这是一个非常抽象的概念,普通消费者未必明白,但是你会发现他们的消费者大多会用「操控好」「响应快」来评价这些车。如果你是参数党,你会发现其实这些车在同级别中都不是最好的,但却是给人愉悦感最强的。

由物及人,当上司交给你一个任务的时候,有反馈好过无反馈,快反馈好过慢反馈。

总结

在节奏日益变快的今天,低延迟很多时候意味着良好的用户体验。而做到低延迟可以通过技术优化,也可以通过一些产品的交互方式和有选择的强调某些方面来让用户感觉很快。内容比较分散,但是都是顺着这根主线,希望你也有所思考和收获。

参考文献

Introducing Zero Round Trip Time Resumption (0-RTT)