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 是什么?

image.png

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 能做什么呢?其实有很多地方都可以受用 Puppeteer,比如:

  • 生成网页截图或者 PDF
  • 抓取 SPA(Single-Page Application) 进行服务器渲染(SSR)
  • 高级爬虫,可以爬取大量异步渲染内容的网页
  • 模拟键盘输入、表单自动提交、登录网页等,实现 UI 自动化测试
  • 捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题

本文选择截图场景作为演示。

如何快速部署一个分布式 Puppeteer Web 应用?

为了快速部署分布式 Puppeteer Web 应用,这里我们选择函数计算服务

函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息参考

有了函数计算服务,我们这里目标是搭建一个分布式应用,但做的事情其实很简单,那就是写好业务代码,部署到函数计算,仅此而已。

使用函数计算后,我们的系统架构图如下:

搭建步骤步骤:

整体流程如下图所示:

其中,需要我们操作的只有 Fun Init、Fun Install 以及 Fun Deploy 命令,每个的步骤内容都会由这三个命令自动完成。

1. 工具安装

安装 Fun 工具:
建议直接从这里下载二进制可执行程序,解压后即可直接使用。下载地址

安装 Docker:
可以按照这里介绍的方法进行安装。

2. 初始化项目:

通过 Fun 工具,使用下面的命令可以快速初始化一个 Puppeteer Web 应用的脚手架:

fun init -n puppeteer-test http-trigger-node-puppeteer

其中 -n puppeteer-test 表示初始化项目的目录名称, http-trigger-node-puppeteer 表示要使用的模板名称,可以省略该名称,省略后,可以从终端提示的列表中自行选择需要的模板。

执行完毕后,可以看到如下的目录结构:

.
├── index.js
├── package.json
└── template.yml

相比较于传统的 puppeteer 应用,这里仅仅多了一个 template.yml 文件,用于描述函数计算的资源。

而 index.js 就是我们的业务代码了,可以按照 Puppeteer 官方帮助文档的要求书写自己的业务代码,这里不再重复阐述,核心代码如下:

const browser = await puppeteer.launch({
  headless: true,
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
  ]
});

const page = await browser.newPage();
await page.emulateTimezone('Asia/Shanghai');
await page.goto('https://www.baidu.com', {
  'waitUntil': 'networkidle2'
});

await page.screenshot({ path: '/tmp/example', fullPage: true, type: 'png' });

await browser.close();

package.json 内容如下:

{
  ... ...
  "dependencies": {
    "puppeteer": "^2.0.0"
  },
  ... ...
}

可以看到,在 package.json 中声明了 puppeteer 的依赖。这个也是我们使用 node 开发时的标准做法,并无特别之处。

3. 一键安装依赖

puppeteer 的安装,即使是在传统的 linux 机器上,也不是那么的轻松。因为 puppeteer 本身依赖了非常多的系统库,要安装哪些系统库、如何安装这些系统库成了一个比较头痛的问题。

好在函数计算命令行工具 Fun 已经集成了 Puppeteer 的解决方案,只要 package.json 中包含了 puppeteer 依赖,然后使用 fun install -d 即可一键安装所有系统依赖。

fun install -d

4. 本地运行、调试函数

Puppeteer 的本地运行、调试方法与这里介绍的完全一致,我们就不再重复介绍。我们这里只演示下运行效果:

5. 一键部署应用

基本上所有的 FaaS 平台为了减小应用的冷启动,都会设置代码包的限制,函数计算也不例外。而 puppeteer 自身已经达到了 350M 左右,连同其系统依赖已经达到了 450M。如何将 450M 体积的函数部署到 FaaS 平台是一个比较头痛而且繁琐的问题。

函数计算的命令行工具 Fun 现在原生支持了这种大依赖部署(3.1.1 版本仅支持 node runtime)。不需要任何额外操作,仅仅执行 fun deploy:

$ fun deploy

fun 会自动完成依赖的部署。而当检测到打包的依赖超过了平台的限制时,会进入到配置向导,帮助用户自动化地配置。

我们这里推荐的路径是当提示是否由 Fun 自动帮助 NAS 管理是,输入 yes,然后提示提示是否使用 NasConfig: Auto 自动处理 NAS 时,也选择是,之后就不需要做其他的事情,等待函数部署成功即可。

如果有其他的需求,比如想使用自己已经存在的 NAS 服务,可以在提示使用 NasConfig: Auto 时,输入 no,这样就会进入到相应的流程。更详细的说明,请参考下面的 FAQ。

FAQ

在安装 puppeteer 时,Fun 都做了哪些事情?

puppeteer 本身是一个 npm 包,它的安装是非常简单的,通过 npm install 即可。这里的问题在于,puppeteer 依赖了 chromium,而 chromium 又依赖一些系统库。所以 npm install 后,还会触发下载 chromium 的操作。这里用户经常遇到的问题,主要是:

  1. 由于 chromium 的体积比较大,所以经常遇到网络问题导致下载失败。
  2. npm 仅仅只下载 chromium,chromium 依赖的系统库并不会自动安装。用户还需要自行查找缺失的依赖进行安装。

Fun 做的优化主要是:

  1. 通过检测网络环境,对于国内用户,会帮助配置淘宝 NPM 镜像实现加速下载的效果。
  2. 自动为用户安装 chromium 所缺失的依赖库。

Fun 是如何把大依赖部署到函数计算的?不是有代码包大小的限制吗?

基本上所有的 FaaS 为了优化函数冷启动,都会加入函数代码包大小的限制。函数计算也不例外。但是,Fun 通过内置 NAS(阿里云文件存储) 解决方案,可以一键帮用户创建、配置 NAS,并上传依赖到 NAS 上。而函数计算在运行时,可以自动从 NAS 读取到函数依赖。

为了帮助用户自动化地完成这些操作,Fun 内置了一个向导(3.1.1 版本仅支持 node,后续会支持更多,欢迎 github issue 提需求),在检测到代码体积大小超过平台限制时,会提示是否由 Fun 将其改造成 NAS 的方案,整个向导的逻辑如下:

  1. 询问是否使用 Fun 来自动化的配置 NAS 管理依赖?(如果回答是,则进入向导,回答否,则继续发布流程)
  2. 检测用户的 yml 中是否已经配置了 NAS
    1. 如果已经配置,则提示用户选择已经配置的 NAS 存储函数依赖
    2. 如果没有配置,则提示用户是否使用 NasConfig: Auto 自动创建 NAS 配置
      1. 如果选择了是,则帮助用户自动配置 nas、vpc 资源。
      2. 如果选择了否,则列出用户当前 NAS 控制台上已经有的 NAS 资源,让用户选择
    3. 无论上面使用哪种方式,最终都会在 template.yml 生成 NAS 以及 VPC 相关的配置
    4. 根据语言检测,比如 node runtime,会将 node_modules 以及 .fun/root 目录映射到 nas 目录(通过 .nas.yml 实现)
    5. 自动执行 fun nas sync 帮用户把本地的依赖上传到 NAS 服务
    6. 自动执行 fun deploy,帮用户把代码上传到函数计算
    7. 提示帮助信息,对于 HTTP Trigger 的,提示函数的 Endpoint,直接打开浏览器访问即可看到效果

是否可以指定 puppeteer 的版本?

可以的,只需要修改 package.json 中的 puppeteer 的版本,重新安装即可。

函数计算实例中的时区采用的 UTC,是否有办法改为北京时间?

某些网页的显示效果是和时区挂钩的,时区不同,可能会导致显示的内容有差异。使用本文介绍的方法,可以非常容易的使用 puppeteer 的最新版本,而在 puppeteer 的最新版本 2.0 提供了一个新的 API page.emulateTimezone(timezoneId) , 可以非常容易的修改时区。

如果 Puppeteer 后续版本更新后,依赖更多的系统依赖,本文介绍的方法还适用吗?

Fun 内置了 .so 缺失检测机制,当在本地调试运行时,会智能地根据报错识别出缺失的依赖库,然后精准地给出安装命令,可以做到一键安装。

如果添加了新的依赖,如何更新?

如果添加了新的依赖,比如 node_modules 目录添加了新的依赖库,只需要重新执行 fun nas sync 进行同步即可。
如果修改了代码,只需要使用 fun deploy 重新部署即可。由于大依赖和代码通过 NAS 进行了分离,依赖通常不需要频繁变化,所以调用的频率比较低,而 fun deploy 的由于没有了大依赖,部署速度也会非常的快。

除了本文介绍的方法还有哪些方法可以一键安装 puppeteer?

Fun 提供了非常多的依赖安装方式,除了本文介绍的将依赖直接声明在 package.json 中,然后通过 fun install -d 的方式安装外,还有很多其他方法,他们均有各自适用的场景:

  1. 命令式安装。比如 fun install -f functionName -p npm puppeteer。这种安装方式的好处是即使对 fun 不了解的用户也可以傻瓜式的使用。
  2. 声明式安装。这种安装方式的好处是提供了类 Dockerfile 的体验,Dockerfile 的大部分指令在这里都是可以直接使用的。通过这种方式声明的依赖,可以通过直接提交到版本仓库。他人拉取代码后,也可以一键安装所有依赖。
  3. 交互环境安装。这种安装方式的好处是提供了类似传统物理机的安装体验。在交互环境中,大部分 linux 命令都是可以使用的,而且可以不断试错。

总结

本文介绍了一种比较简单易行地从零开始搭建分布式 Puppeteer Web 服务的方法。利用该方法,可以做到不需要关心如何安装依赖、也不需要关系如何上传依赖,顺滑地完成部署。

部署完成后,即可享受函数计算带来的优势,即:

  • 无需采购和管理服务器等基础设施,只需专注业务逻辑的开发,可以大幅缩短项目交付时间和人力成本
  • 提供日志查询、性能监控、报警等功能快速排查故障
  • 免运维,毫秒级别弹性伸缩,快速实现底层扩容以应对峰值压力,性能优异
  • 成本极具竞争力
相关实践学习
【玩转ComfyUI】基于函数计算一键部署AI生图平台ComfyUI
本次实验将带大家通过使用阿里云产品函数计算FC,快速使用ComfyUI实现更高质量的图像生成。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
目录
相关文章
|
5月前
|
人工智能 运维 安全
加速智能体开发:从 Serverless 运行时到 Serverless AI 运行时
在云计算与人工智能深度融合的背景下,Serverless 技术作为云原生架构的集大成者,正加速向 AI 原生架构演进。阿里云函数计算(FC)率先提出并实践“Serverless AI 运行时”概念,通过技术创新与生态联动,为智能体(Agent)开发提供高效、安全、低成本的基础设施支持。本文从技术演进路径、核心能力及未来展望三方面解析 Serverless AI 的突破性价值。
|
消息中间件 人工智能 监控
文生图架构设计原来如此简单之分布式服务
想象一下,当成千上万的用户同时要求AI画图,如何公平高效地处理这些请求?文生图/图生图大模型的架构设计看似复杂,实则遵循简单而有效的原则:合理排队、分工明确、防患未然。
457 14
文生图架构设计原来如此简单之分布式服务
|
Cloud Native 安全 Serverless
云原生应用实战:基于阿里云Serverless的API服务开发与部署
随着云计算的发展,Serverless架构日益流行。阿里云函数计算(Function Compute)作为Serverless服务,让开发者无需管理服务器即可运行代码,按需付费,简化开发运维流程。本文从零开始,介绍如何使用阿里云函数计算开发简单的API服务,并探讨其核心优势与最佳实践。通过Python示例,演示创建、部署及优化API的过程,涵盖环境准备、代码实现、性能优化和安全管理等内容,帮助读者快速上手Serverless开发。
|
SQL 分布式计算 DataWorks
MaxCompute MaxFrame评测 | 分布式Python计算服务MaxFrame(完整操作版)
在当今数字化迅猛发展的时代,数据信息的保存与分析对企业决策至关重要。MaxCompute MaxFrame是阿里云自研的分布式计算框架,支持Python编程接口、兼容Pandas接口并自动进行分布式计算。通过MaxCompute的海量计算资源,企业可以进行大规模数据处理、可视化数据分析及科学计算等任务。本文将详细介绍如何开通MaxCompute和DataWorks服务,并使用MaxFrame进行数据操作。包括创建项目、绑定数据源、编写PyODPS 3节点代码以及执行SQL查询等内容。最后,针对使用过程中遇到的问题提出反馈建议,帮助用户更好地理解和使用MaxFrame。
|
SQL 分布式计算 数据处理
云产品评测|分布式Python计算服务MaxFrame | 在本地环境中使用MaxFrame + 基于MaxFrame实现大语言模型数据处理
本文基于官方文档,介绍了由浅入深的两个部分实操测试,包括在本地环境中使用MaxFrame & 基于MaxFrame实现大语言模型数据处理,对步骤有详细说明。体验下来对MaxCompute的感受是很不错的,值得尝试并使用!
347 1
|
分布式计算 数据处理 MaxCompute
云产品评测|分布式Python计算服务MaxFrame
云产品评测|分布式Python计算服务MaxFrame
308 2
|
人工智能 分布式计算 数据处理
有奖评测,基于分布式 Python 计算服务 MaxFrame 进行数据处理
阿里云MaxCompute MaxFrame推出分布式Python计算服务MaxFrame评测活动,助力开发者高效完成大规模数据处理、可视化探索及ML/AI开发。活动时间为2024年12月17日至2025年1月31日,参与者需体验MaxFrame并发布评测文章,有机会赢取精美礼品。
|
分布式计算 数据处理 MaxCompute
分布式Python计算服务MaxFrame使用心得
大家好,我是V哥。MaxFrame是阿里云自研的分布式计算框架,专为Python开发者设计,支持大规模数据处理和AI模型开发。MaxFrame适用于快速进行数据处理、数据科学和交互式探索,支持按量付费及包年包月两种计费方式。通过两个案例(金融数据清洗和大语言模型预处理),展示了MaxFrame在大规模数据处理中的显著性能提升。安装MaxFrame客户端只需简单几步,轻松开启高效数据处理之旅。欢迎关注威哥爱编程,一起交流技术心得!
227 0
|
7月前
|
存储 负载均衡 NoSQL
【赵渝强老师】Redis Cluster分布式集群
Redis Cluster是Redis的分布式存储解决方案,通过哈希槽(slot)实现数据分片,支持水平扩展,具备高可用性和负载均衡能力,适用于大规模数据场景。
515 2
|
7月前
|
存储 缓存 NoSQL
【📕分布式锁通关指南 12】源码剖析redisson如何利用Redis数据结构实现Semaphore和CountDownLatch
本文解析 Redisson 如何通过 Redis 实现分布式信号量(RSemaphore)与倒数闩(RCountDownLatch),利用 Lua 脚本与原子操作保障分布式环境下的同步控制,帮助开发者更好地理解其原理与应用。
461 6

相关产品

  • 函数计算