简讯:Puppeteer+RabbitMQ:Node.js 批量加工pdf服务架构设计与落地 - 行业资讯 -

当前位置:首页  >  行业资讯  > 正文

简讯:Puppeteer+RabbitMQ:Node.js 批量加工pdf服务架构设计与落地

简讯:Puppeteer+RabbitMQ:Node.js 批量加工pdf服务架构设计与落地
2023-04-20 11:54:45 来源:博客园

智慧作业最近上线「个性化手册」(简称个册)功能,一份完整的个性化手册分为三部分

学情分析:根据学生阶段性的学习和考试情况进行学情分析、归纳、总结,汇总学情数据;精准推荐:推荐算法基于学情数据结合知识图谱进行精准练习题推荐;错题回顾:错题的阶段性回顾复习。第一部分学情分析的PDF由Node.js加工,与Java后端通过消息队列RabbitMQ进行数据交互,本文简单记录一下Node.js批量加工PDF服务的架构模式,以及基于现阶段发现的问题,梳理未来的迭代规划和演进方向。业务特征

个册三个部分的PDF数据来源不同,生产逻辑独立由不同的服务生产,最终将三份PDF合并为一份,还要支持班级所有学生批量生产和压缩打包,所以这个功能在技术角度最主要的特征就是环节多耗时长

环节多意味着在各个服务之间存在较多的网络通信和数据交互,核心挑战在于如何设计低耦合、高可用的服务架构;耗时长一方面体现在多个环节的总耗时,另一方面体现在三个PDF生产服务各自的加工耗时。基于以上业务特征,PDF加工服务架构设计的一个大方向就是将长耗时任务异步处理,各服务之间逻辑解耦,通过消息队列进行数据交互。技术选型

服务端生成PDF通常有两种方案:


【资料图】

第一种是使用 pdfkit 之类的工具通过代码绘制,这种方案最大的问题是可渲染的内容类型有限,定制化不足;第二种是创建 headless browser用html渲染后截取pdf,这种方案的架构相对复杂,但是可以支持所有web端的内容类型。个册第一部分学情分析的某一页长这个样子:

仅这一页就涵盖文本、表格、图表以及各种自定义图案,内容类型多样并且后续迭代可能增加更多定制化内容,第一种方案的局限性很难满足需求,所以最终选定 headless browser 方案。

具体到 headless browser 的技术选型就非常有限了,可选的无非就是 Selenium/PhantomJS 这类老招牌,或者 Puppeteer/Playwright 这类新玩家。

严格来说Selenium只是一种类似按键精灵的工具,可通过代码在浏览器中模拟人的操作,本身并不是浏览器,所以需要搭配第三方浏览器使用,比如PhantomJS。Selenium/PhantomJS 的最大的优点就是生态健全,支持多种编程语言,有相对繁荣的技术社区;缺点就是稳定性和性能较差,Selenium的稳定性出了名的糟糕,PhantomJS五年前就停止维护了。这哥俩通常用在对稳定性要求不是很高的场景,比如爬虫。

与之形成鲜明对比的,Puppeteer/Playwright 最大的优点就是稳定性高,性能更优;缺点就是对编程语言的支持有限,生态和技术社区相对没那么健全。

个册的业务特征一是对稳定性和性能要求很高;二是不要求跨浏览器(Playwright支持浏览器类型更丰富)。最终综合考虑API易用性、稳定性、性能、社区、风险等因素,在 Puppeteer 和 Playwright 之间选择了 Puppeteer。既然选定了 Puppeteer,配套的自然就是 Node.js了。

Puppeteer 和 Playwright 的对比可以参考这篇文章:Playwright vs Puppeteer: Core Differences。这个需求是我第一次使用Puppeteer,还没完全摸透,下文涉及到Puppeteer相关的方案如果有问题,欢迎讨论指点

实现方案

智慧教育的分层架构如下:

Node.js PDF服务是本次需求新增的,为了方便分离部署和优化,PDF服务单独建立一个服务,不涉及Node.js接入层的改动。下图是个册PDF加工的完整流程:

每个环节的具体流程不细讲,Node.js PDF加工服务的细节下文详解。与Node.js PDF服务相关最关键的是与Java后端的数据交互流程。Java后端与Node.js PDF服务通过 RabbitMQ 消息队列进行数据交互,建立两个队列

队列生产者消费者说明
任务队列Java后端Node.js PDF服务Java 向队列中发送个册渲染数据,Node.js 消费
回传队列Node.js PDF服务Java后端Node.js 向队列中发送pdf加工结果数据,Java 消费

这部分没啥好讲的,Node.js与Java之间按照约定的数据规范组装数据即可,下面详细介绍一下Node.js加工pdf的具体逻辑。

这一版个册的第一部分学情分析控制在3页,早期规划的个册PDF大约25页左右,技术调研和架构设计都是基于这个预期进行的,所以现在这套模式多少有点杀鸡用牛刀的意思,不过前期打好基础给后续迭代留些空间也是好事。

单份PDF加工流程

为了更方便理解,在介绍pdf加工流程之前,有必要先简要一下Node.js PDF服务的架构,以及与PDF加工逻辑最相关的 worker角色。

Node.js PDF服务架构最核心的三个角色:

Scheduler:负责轮询调度,发起任务;Executor:负责任务前置后置相关逻辑,包括worker pool管理、worker 调度、MQ任务队列消息拉取、MQ回传队列消息发送等;Worker:负责实质执行任务,包括pdf渲染、生产、上传OSS;三者的关系如下所示:

SchedulerExecutor的具体逻辑以及三个角色之间的调度逻辑下文再详解,PDF文件的实质生产逻辑都集中在 Worker中,流程如下:

图中「发送消息至MQ回传队列」实质是由 Executor执行,此处画出方便理解完整流程。

预启动

图中虚线部分的预启动是在启动 Node.js 服务之前执行的逻辑,预启动完成之后 Node.js 服务被拉起,所以预启动的耗时是一次性的。

预启动过程执行两个动作:

读取磁盘中的html文件内容,写入内存,为后续环节「加载网页」提供数据;创建 Puppeteer browser 实例。

上图中只画出pdf加工逻辑相关的预启动工作,实际上预启动还包含一些其他逻辑,比如建立 MQ 连接信道。

冷启动(废弃)

虽然冷启动在后来开发过程中被废弃,但通过这个事情发现自己的不足,还是值得记录一下的。最初之所以设想冷启动环节,是因为尝试用 worker 模拟多线程。每个worker会创建一个browser实例和多个page实例(目前是3个),如下所示:

这样做的目的是将每个worker的负载上限固定,便于服务器资源规模预估,避免服务器某个节点负载过高,进而也可以避免k8s集群pod的纵向伸缩。

k8s纵向伸缩的取舍见仁见智,我个人不太建议使用。如果任务队列长时间为空会触发缓存清理逻辑,销毁browser和page实例以节省服务器资源,再次发起任务会触发冷****启动。冷启动执行两件事情:

链接/创建browser实例创建page实例另外增加一个标识位_mounted代表冷启动是否完成,代码如下:
public async run(){  if(!this._mounted){    // 触发冷启动    this._mount();  }  // ...其他逻辑}private async _mount(){    if(!this._browser?.isConnected()){      // 链接browser      this._browser = await puppeteer.connect({        browserWSEndpoint: this._wsEndpoint      });    }    // 创建page实例    if(isEmpty(this._pages)){      for(let i =0;i

乍看起来似乎没啥问题,但实际跑一跑代码会发现,在任务调度密集的时候,run函数短时间内被调用多次(具体的调度策略下文讲解),worker会触发多次冷启动,虽然不影响业务逻辑,但会引起服务器资源暴涨,这是因为冷启动会创建新的browser和page实例,但是旧实例并没有被清理,仍然在执行任务。冷启动被调用多次的根本原因是Node.js不是多线程,如下图所示,假设冷启动耗时20ms,在此期间再次调用run函数,标识位_mounted还未被设置为true,就会又触发一次冷启动。

有没有解法?

当然有。多线程编程解决竞态最常用的就是:加锁。既然想模拟多线程那就彻底一点,把锁逻辑也加上呗。

worker本身是有“锁”的,每个worker有3个page实例,只有当存在空闲实例(busy为false)时run函数才可以执行,但是这个锁机制并不能避免多次冷启动问题,因为冷启动完成之前page实例还未被创建。

可能会有人说,那就加个限制,page实例不存在时也不让run函数执行不就得了?这么做的话run函数永远都不会被执行啊大聪明。

既然worker已有的锁不行,那就再加个冷启动锁,冷启动之前锁定,冷启动之后解锁。这么做当然是可以的,但是会增加逻辑复杂度,worker有两种锁,对后期迭代维护无疑是埋雷。

其实之所以有冷启动无非就是为了省点内存,用时间换空间,一个browser实例+3个空白page实例总共100m左右的内存,这年头内存这么便宜,为了省这点空间把逻辑搞那么复杂完全得不偿失。什么叫过度设计,这就是过度设计。

所以后来索性把冷启动过程干掉了,browser和page实例的创建放在worker初始化逻辑里。

public async init() {    /**     * 尽量禁用掉不需要的功能,提高性能     */    this._browser = await puppeteer.launch({      headless: true,      args: [        "--incognito",        "--disable-gpu",        "--disable-dev-shm-usage",        "--disable-setuid-sandbox",        "--no-first-run",        "--no-sandbox",        "--no-zygote",        "--single-process"      ]    });    this._wsEndpoint = this._browser.wsEndpoint();    // _mount函数逻辑不改动,调用_mount函数放在初始化逻辑中    await this._mount();}
加载网页

网页通过page.setContent(html)函数加载本地html文件,与通过page.goto(url)加载远程URL相比,既节省了部署网页的服务器资源,同时速度也更快

时间消耗执行时机性能瓶颈其他
远程URLDNS耗时下载耗时解析html耗时运行时网络IO异步下载html引用的静态资源会增加额外耗时
本地html读磁盘耗时解析html耗时预启动阶段文件IO+常驻内存

上文提到过,本地html文件在预启动阶段提前从磁盘读取存放于内存,运行时无需实时读取。所以文件IO的耗时不算在pdf加工逻辑总耗时中,而加载远程URL只能在运行时执行,会增长pdf加工的总时长。

另外,加载的本地html文件中不能存在静态资源引用,比如js和css必须全部以行内

标签:

(责任编辑:news01)
守护年轻人心理健康的运动处方 世界热资讯

守护年轻人心理健康的运动处方 世界热资讯

4月16日,一位家长跑者推着孩子参加北京半程马拉松。视觉中国供图近年来,我国年轻人心理健康问题备受关...
04-18 22:13:40
今日报丨《盟约》举行首映式 杰米·李·柯蒂斯亲吻吉伦哈尔

今日报丨《盟约》举行首映式 杰米·李·柯蒂斯亲吻吉伦哈尔

《盟约》举行首映式杰米·李·柯蒂斯亲吻吉伦哈尔
04-18 21:59:44
当日快讯:长城军工:应收账款 计提信用减值损失增加等,2022年年归母净利润同比下滑41.4%

当日快讯:长城军工:应收账款 计提信用减值损失增加等,2022年年归母净利润同比下滑41.4%

长城军工4月18日发布2022年年度报告,2022年实现营业收入114亿元,同比增长07%;归属于上市公司股东的净...
04-18 21:29:19
明晚起,郑州东三马路等三路段停水36小时-每日速讯

明晚起,郑州东三马路等三路段停水36小时-每日速讯

为配合郑州市南关菜场街(德济路—民乐北里)老旧管网改造提升工程,郑州自来水投资控股有限公司拟对东...
04-18 21:26:38
大宗交易:中国黄金成交9348.05万元,折价9.47%(04-18)

大宗交易:中国黄金成交9348.05万元,折价9.47%(04-18)

2023年4月18日,中国黄金发生1笔大宗交易,总成交815万股,成交金额9348 05万元,成交价11 47元,折价9 47%。
04-18 20:43:22
杂技演员高空坠亡,为何全程无保护?

杂技演员高空坠亡,为何全程无保护?

4月15日晚,安徽宿州埇桥区蒿沟镇发生一起杂技演员坠亡事件。据官方通报,表演高空杂技的女演员孙某某经...
04-18 19:33:00
成都高新区投融资项目洽谈会欧洲站在法国巴黎举行

成都高新区投融资项目洽谈会欧洲站在法国巴黎举行

洽谈会上,成都高新区代表和法国科知信思公司、富巴公司、ODDOBHF银行等欧方机构、企业代表进行了交流沟...
04-18 19:08:08
2023郑许市域铁路完整站点名单 每日速读

2023郑许市域铁路完整站点名单 每日速读

2023郑许市域铁路完整站点名单长安路北站、港区北站、文体中心站、枣园站、翱翔路站、长安路南站、新郑...
04-18 18:52:44
焦点信息:禁止驶入!珠江口部分海域内将进行军事演习

焦点信息:禁止驶入!珠江口部分海域内将进行军事演习

据中国海事局网站4月18日消息,广东海事局发布航行警告,4月20日9时30分至15时,珠江口部分海域内将进行...
04-18 18:21:28
国家统计局:3月份社会消费品零售总额增长10.6%

国家统计局:3月份社会消费品零售总额增长10.6%

人民网北京4月18日电(记者王震)国家统计局今日发布数据显示,3月份,社会消费品零售总额37855亿元,同...
04-18 17:55:17
广德:万物复“苏”乡村“觉”醒 今日播报

广德:万物复“苏”乡村“觉”醒 今日播报

建菜园、清垃圾、修路沿……走进安徽广德市桐汭街道苏觉社区,随处可见人居环境整治的火热场面。近日,...
04-18 17:18:51
“杭州2岁女童被保姆遗留电梯坠亡案”择期宣判,记者重回现场:出事的窗台至今未加装任何防护设施

“杭州2岁女童被保姆遗留电梯坠亡案”择期宣判,记者重回现场:出事的窗台至今未加装任何防护设施

据钱江晚报消息,4月18日,“女童被保姆遗留电梯坠亡案”公开开庭审理,保姆吴某某以过失致人死亡罪被提...
04-18 16:48:34
嘉兴人,嘉兴市区新建一所学校!规划48个班!|世界最资讯

嘉兴人,嘉兴市区新建一所学校!规划48个班!|世界最资讯

嘉兴人,嘉兴市区新建一所学校!规划48个班!
04-18 16:41:31
环球动态:村民被当成野兔遭枪击溺亡 4人被拘是什么情况

环球动态:村民被当成野兔遭枪击溺亡 4人被拘是什么情况

村民被当成野兔遭枪击溺亡4人被拘今天的热度非常高,现在也是在热搜榜上了,那么具体的村民被当成野兔遭...
04-18 16:19:56
这是秦始皇摔过最狠的一跤 潍坊国际风筝节现场风筝千奇百怪 世界快消息

这是秦始皇摔过最狠的一跤 潍坊国际风筝节现场风筝千奇百怪 世界快消息

4月18日消息,最近一年一度的潍坊国际风筝节开幕,现场涌现了各种各样千奇百怪的风筝。在一众形态各异的...
04-18 16:11:58
全球微资讯!英国央行副行长:可能需要限制用稳定币支付 避免威胁金融稳定

全球微资讯!英国央行副行长:可能需要限制用稳定币支付 避免威胁金融稳定

【英国央行副行长:可能需要限制用稳定币支付避免威胁金融稳定】《华尔街日报》4月17日消息,英国央行副...
04-18 15:26:53
年产50亿只蚊子阻止登革热,巴西拟建全球最大转基因蚊子工厂|今日热闻

年产50亿只蚊子阻止登革热,巴西拟建全球最大转基因蚊子工厂|今日热闻

据英国《自然》网站日前报道,非营利组织世界蚊子计划(WMP)宣布,将与巴西公共科学机构奥斯瓦尔多·克...
04-18 15:24:43
朝阳区重庆街道开展退役军人志愿服务月活动

朝阳区重庆街道开展退役军人志愿服务月活动

近日,长春市朝阳区重庆街道组织“吉行军”退役军人志愿服务分队队员走进社区,开展了为期一个月的志愿...
04-18 15:03:48
天津部分区域禁停共享单车 违者限制骑行

天津部分区域禁停共享单车 违者限制骑行

》》》最新消息:为充分发挥信用手段在社会治理中的作用,引导市民文明出行,建设文明幸福的现代化天津...
04-18 14:05:55
杜鹃花,开展啦~

杜鹃花,开展啦~

杜鹃花,开展啦~
04-18 13:15:29
最新消息:竞争激烈门槛低,水果行业里要出头怎么办?

最新消息:竞争激烈门槛低,水果行业里要出头怎么办?

我国是世界上最大的水果出产国,种植面积和水果产量稳定居全球第一,同时,中国也是水果消费大国。根据...
04-18 12:11:13
欧司朗

欧司朗

1、欧司朗(OSRAM)集团总部位于德国慕尼黑,是一家拥有超过110年品牌历史的高科技公司。2、众多世界著...
04-18 11:19:58
基金增减仓丨铭普光磁:冯明远的信澳新能源股票减仓

基金增减仓丨铭普光磁:冯明远的信澳新能源股票减仓

2023-03-31数据显示,上市公司铭普光磁前十大流通股东名单中,冯明远的信澳新能源股票现身其中,比上期减少18120
04-18 10:53:49
徐州泉山:“红色梧桐暖心团”架起群众连心桥

徐州泉山:“红色梧桐暖心团”架起群众连心桥

在徐州泉山区王陵街道,常年活跃着这样一支队伍,他们是政策的宣传员,把最新政策传达至居民心中;他们...
04-18 09:51:35
参松养心胶囊的作用与用处_参松养心胶囊的作用和副作用

参松养心胶囊的作用与用处_参松养心胶囊的作用和副作用

1、沈宋养心胶囊具有益气养阴、活血通络、清心安神的功效。主要用于治疗气阴两虚、心络瘀阻的冠心病、室...
04-18 09:17:11
焦点速读:3月郑州CPI同比上涨0.4%

焦点速读:3月郑州CPI同比上涨0.4%

3月郑州CPI同比上涨0 4%
04-18 08:15:50
无线话筒没有接收器怎么办_无线话筒接收器使用

无线话筒没有接收器怎么办_无线话筒接收器使用

1、插入扩音器话筒输入就可以了。2、可通过蓝牙连接,,,手机上也要有相关软件支持有个发射器,与话筒...
04-18 06:47:15
关注:花椒及其制品中花椒麻素的测定高效液相色谱法

关注:花椒及其制品中花椒麻素的测定高效液相色谱法

1、《花椒及其制品中花椒麻素的测定高效液相色谱法》是2020年07月20日实施的一项行业标准。2、。以上就...
04-18 04:54:31
当前关注:中国诗词大会的意义和影响_中国诗词大会的意义

当前关注:中国诗词大会的意义和影响_中国诗词大会的意义

1、对青少年培养文学爱好大有脾益!培养青少年对古诗词的兴趣,传承国学文化精髓,延续中华文明优良传统...
04-18 00:42:04

为您推荐

精彩推送