有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务
更多云原生技术资讯可关注阿里巴巴云原生技术圈。
Puppeteer 是什么?
puppeteer 官网的介绍如下:
Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol. Puppeteer runs headless by default, but can be configured to run full (non-headless) Chrome or Chromium.
通俗描述就是:Puppeteer 可以将 Chrome 或者 Chromium 以无界面的方式运行(当然也可以运行在有界面的服务器上),然后可以通过代码控制浏览器的行为,即使是非界面的模式运行,Chrome 或 Chromium 也可以在内存中正确渲染网页的内容。
那么 Puppeteer 能做什么呢?
- 生成网页截图或者 PDF
- 抓取 SPA(Single-Page Application) 进行服务器渲染(SSR)
- 高级爬虫,可以爬取大量异步渲染内容的网页
- 模拟键盘输入、表单自动提交、登录网页等,实现 UI 自动化测试
- 捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题
本文选择截图场景作为演示。
废话不多说了,我们直接给大家介绍下如何用函数计算产品来快速部署一个 Puppeteer Web 应用。
如何快速部署一个分布式 Puppeteer Web 应用?
为了快速部署分布式 Puppeteer Web 应用,本文以函数计算服务为例来做展示。
函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息参考。
有了函数计算服务,我们这里目标是搭建一个分布式应用,但做的事情其实很简单,那就是写好业务代码,部署到函数计算,仅此而已。
使用函数计算后,我们的系统架构图如下:
效果演示
可以直接通过以下链接查看效果:
https://1911504709953557.cn-hangzhou.fc.aliyuncs.com/2016-08-15/proxy/puppeteer-test/html2png/?url=https://www.aliyun.com/product/fc
PS:第一次请求可能会有几秒的冷启动时间,通过使用[预留模式](https://statistics.functioncompute.com/?title=有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务&src=article&author=小默&url=https://help.aliyun.com/document_detail/138103.html?spm=a2c4g.11174283.6.687.882d5212Y0AECh)可以完全去除冷启动,这题超纲,下次再讲。
搭建步骤步骤:
整体流程如下图所示:
其中,需要我们操作的只有 Fun Init、Fun Install 以及 Fun Deploy 命令,每个的步骤内容都会由这三个命令自动完成。
1. 工具安装
安装 Fun 工具:
建议直接从这里下载二进制可执行程序,解压后即可直接使用。[下载地址](https://statistics.functioncompute.com/?title=有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务&src=article&author=小默&url=https://github.com/alibaba/funcraft/blob/master/docs/usage/installation-zh.md)。
安装 Docker:
可以按照[这里介绍的方法](https://statistics.functioncompute.com/?title=有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务&src=article&author=小默&url=https://github.com/alibaba/funcraft/blob/master/docs/usage/installation-zh.md?spm=a2c4e.10696291.0.0.6bb619a4UjYXqN#docker)进行安装。
2. 初始化项目:
通过 Fun 工具,使用下面的命令可以快速初始化一个 Puppeteer Web 应用的脚手架:
fun init -n puppeteer-test http-trigger-node-puppeteer其中 -n puppeteer-test 表示初始化项目的目录名称, http-trigger-node-puppeteer 表示要使用的模板名称,可以省略该名称,省略后,可以从终端提示的列表中自行选择需要的模板。
执行完毕后,可以看到如下的目录结构:
相比较于传统的 puppeteer 应用,这里仅仅多了一个 [template.yml](https://statistics.functioncompute.com/?title=有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务&src=article&author=小默&url=https://github.com/alibaba/funcraft/blob/master/docs/specs/2018-04-03-zh-cn.md?spm=a2c4e.10696291.0.0.717019a45X1W0g&file=2018-04-03-zh-cn.md) 文件,用于描述函数计算的资源。
而 index.js 就是我们的业务代码了,可以按照 Puppeteer 官方帮助文档的要求书写自己的业务代码,这里不再重复阐述,核心代码如下:
package.json 内容如下:
{... ..."dependencies": {"puppeteer": "^2.0.0"},... ... }可以看到,在 package.json 中声明了 puppeteer 的依赖。这个也是我们使用 node 开发时的标准做法,并无特别之处。
3. 一键安装依赖
puppeteer 的安装,即使是在传统的 linux 机器上,也不是那么的轻松。因为 puppeteer 本身依赖了非常多的系统库,要安装哪些系统库、如何安装这些系统库成了一个比较头痛的问题。
好在函数计算命令行工具 [Fun](https://statistics.functioncompute.com/?title=有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务&src=article&author=小默&url=https://github.com/alibaba/funcraft) 已经集成了 Puppeteer 的解决方案,只要 package.json 中包含了 puppeteer 依赖,然后使用 fun install -d 即可一键安装所有系统依赖。
fun install -d4. 本地运行、调试函数
Puppeteer 的本地运行、调试方法与[这里](https://statistics.functioncompute.com/?title=有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务&src=article&author=小默&url=https://yq.aliyun.com/articles/683683)介绍的完全一致,我们就不再重复介绍。我们这里只演示下运行效果:
5. 一键部署应用
基本上所有的 FaaS 平台为了减小应用的冷启动,都会设置代码包的限制,函数计算也不例外。而 puppeteer 自身已经达到了 350M 左右,连同其系统依赖已经达到了 450M。如何将 450M 体积的函数部署到 FaaS 平台是一个比较头痛而且繁琐的问题。
函数计算的命令行工具 Fun 现在原生支持了这种大依赖部署(3.1.1 版本仅支持 node runtime)。不需要任何额外操作,仅仅执行 fun deploy:
$ fun deployfun 会自动完成依赖的部署。而当检测到打包的依赖超过了平台的限制时,会进入到配置向导,帮助用户自动化地配置。
我们这里推荐的路径是当提示是否由 Fun 自动帮助 NAS 管理是,输入 yes,然后提示提示是否使用 NasConfig: Auto 自动处理 NAS 时,也选择是,之后就不需要做其他的事情,等待函数部署成功即可。
如果有其他的需求,比如想使用自己已经存在的 NAS 服务,可以在提示使用 [NasConfig: Auto](https://statistics.functioncompute.com/?title=有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务&src=article&author=小默&url=https://yq.aliyun.com/articles/712693) 时,输入 no,这样就会进入到相应的流程。更详细的说明,请参考下面的 FAQ。
FAQ
在安装 puppeteer 时,Fun 都做了哪些事情?
puppeteer 本身是一个 npm 包,它的安装是非常简单的,通过 npm install 即可。这里的问题在于,puppeteer 依赖了 chromium,而 chromium 又依赖一些系统库。所以 npm install 后,还会触发下载 chromium 的操作。这里用户经常遇到的问题,主要是:
Fun 做的优化主要是:
Fun 是如何把大依赖部署到函数计算的?不是有代码包大小的限制吗?
基本上所有的 FaaS 为了优化函数冷启动,都会加入函数代码包大小的限制。函数计算也不例外。但是,Fun 通过内置 NAS(阿里云文件存储) 解决方案,可以一键帮用户创建、配置 NAS,并上传依赖到 NAS 上。而函数计算在运行时,可以自动从 NAS 读取到函数依赖。
为了帮助用户自动化地完成这些操作,Fun 内置了一个向导(3.1.1 版本仅支持 node,后续会支持更多,欢迎 [github issue ](https://statistics.functioncompute.com/?title=有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务&src=article&author=小默&url=https://yq.aliyun.com/go/articleRenderRedirect?url=https://github.com/alibaba/funcraft/issues)提需求),在检测到代码体积大小超过平台限制时,会提示是否由 Fun 将其改造成 NAS 的方案,整个向导的逻辑如下:
是否可以指定 puppeteer 的版本?
可以的,只需要修改 package.json 中的 puppeteer 的版本,重新安装即可。
函数计算实例中的时区采用的 UTC,是否有办法改为北京时间?
某些网页的显示效果是和时区挂钩的,时区不同,可能会导致显示的内容有差异。使用本文介绍的方法,可以非常容易的使用 puppeteer 的最新版本,而在 puppeteer 的最新版本 2.0 提供了一个新的 API [page.emulateTimezone(timezoneId)](https://statistics.functioncompute.com/?title=有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务&src=article&author=小默&url=https://github.com/puppeteer/puppeteer/blob/v2.0.0/docs/api.md?spm=a2c4e.10696291.0.0.6b9c19a4BsT3qZ#pageemulatetimezonetimezoneid) , 可以非常容易的修改时区。
如果 Puppeteer 后续版本更新后,依赖更多的系统依赖,本文介绍的方法还适用吗?
Fun 内置了 .so 缺失检测机制,当在本地调试运行时,会智能地根据报错识别出缺失的依赖库,然后精准地给出安装命令,可以做到一键安装。
如果添加了新的依赖,如何更新?
如果添加了新的依赖,比如 node_modules 目录添加了新的依赖库,只需要重新执行 fun nas sync 进行同步即可。
如果修改了代码,只需要使用 fun deploy 重新部署即可。由于大依赖和代码通过 NAS 进行了分离,依赖通常不需要频繁变化,所以调用的频率比较低,而 fun deploy 的由于没有了大依赖
除了本文介绍的方法还有哪些方法可以一键安装 puppeteer?
Fun 提供了非常多的依赖安装方式,除了本文介绍的将依赖直接声明在 package.json 中,然后通过 fun install -d 的方式安装外,还有很多其他方法,他们均有各自适用的场景:
总结
本文介绍了一种比较简单易行地从零开始搭建分布式 Puppeteer Web 服务的方法。利用该方法,可以做到不需要关心如何安装依赖、也不需要关系如何上传依赖,顺滑地完成部署。
部署完成后,即可享受函数计算带来的优势,即:
- 无需采购和管理服务器等基础设施,只需专注业务逻辑的开发,可以大幅缩短项目交付时间和人力成本
- 提供日志查询、性能监控、报警等功能快速排查故障
- 免运维,毫秒级别弹性伸缩,快速实现底层扩容以应对峰值压力,性能优异
- 成本极具竞争力
“阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”
总结
以上是生活随笔为你收集整理的有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 快速搭建 Serverless 在线图片
- 下一篇: 2020 有哪些不容错过的前端技术趋势?