Google家开源的puppeteer使用bug修复

使用及故障

在干啥

  • 在开发mermaid插件(没错我还在持之以恒的死磕)过程中确认到mermaid渲染必须在有浏览器的情况下才能正确渲染,考虑了以下两种headless browser
    • phantom,node插件为phantom,先考虑这个是因为用过PhantomJS,本机和服务器上也都有装。然而据说已经没人维护了(两年没出新版本?),跑起来也有很多迷之bug(API都找不全),遂放弃
    • puppeteer,mermaid的开发者有提供官方的cli工具行就是基于此开发的,至少可以确认可运行

天坑故障系列集合

缺包

首先项目里正常安装

1
$ npm i puppeteer --save

安装过程没报错,运行demo的时候就开始爆炸了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Promise {
<pending>,
domain:
Domain {
domain: null,
_events: { error: [Function: debugDomainError] },
_eventsCount: 1,
_maxListeners: undefined,
members: [] } }
> (node:65773) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): Error: Failed to launch chrome!
/home/garen/Desktop/testProject/node_modules/puppeteer/.local-chromium/linux-536395/chrome-linux/chrome: error while loading shared libraries: libXss.so.1: cannot open shared object file: No such file or directory
TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md

进入安装目录查看:

1
$ cd node_modules/puppeteer/.local-chromium/linux-536395/chrome-linux/

检查bug的时候有小伙伴说可能是内核的原因,不过个人感觉更新内核还是要谨慎,顺便检查了下内核版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ cat /etc/*-release
CentOS Linux release 7.2.1511 (Core)
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
CentOS Linux release 7.2.1511 (Core)
CentOS Linux release 7.2.1511 (Core)

应该不需要……继续检查

1
2
3
$ ldd chrome | grep not
./chrome: /lib64/libnss3.so: version `NSS_3.22' not found (required by ./chrome)
libXss.so.1 => not found

可以发现有两个not found,一个个解决。重新运行了下上面的命令,定位一下

1
2
3
4
5
6
7
8
$ ldd chrome
...
linux-vdso.so.1 => (0x00007ffcbbf62000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f94b90a8000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f94b8ea4000)
librt.so.1 => /lib64/librt.so.1 (0x00007f94b8c9b000)
libX11.so.6 => /lib64/libX11.so.6 (0x00007f94b895d000)
...

发现能够正常找到的so文件基本都在/usr/lib目录下,然后查找缺失的so文件:

1
2
3
4
5
$ locate libXss.so.1
/usr/lib/vmware-tools/lib32/libXss.so.1
/usr/lib/vmware-tools/lib32/libXss.so.1/libXss.so.1
/usr/lib/vmware-tools/lib64/libXss.so.1
/usr/lib/vmware-tools/lib64/libXss.so.1/libXss.so.1

……所以其实文件是有的,只是不在对的目录?试着把vmware-tools目录下的libXss.so.1移到/usr/lib目录下,并没有用。重新搜索,以下方案在我的虚拟机上成功:

1
# yum install libXScrnSaver-1.2.2-6.1.el7.x86_64

装完后再执行相同的命令,报错变成了:

1
2
$ ldd chrome | grep not
./chrome: /lib64/libnss3.so: version `NSS_3.22' not found (required by ./chrome)

少了一个,继续试试……按照上面的troubleshooting文件,一口气先确保安装了所有CentOS需要的依赖

1
yum install pango.x86_64 libXcomposite.x86_64 libXcursor.x86_64 libXdamage.x86_64 libXext.x86_64 libXi.x86_64 libXtst.x86_64 cups-libs.x86_64 libXScrnSaver.x86_64 libXrandr.x86_64 GConf2.x86_64 alsa-lib.x86_64 atk.x86_64 gtk3.x86_64 ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc

安装完还是老样子并没有回复╮(╯▽╰)╭,果然不会这么简单就解决的。看起来问题出在安装的chromium(从目录上看序号大概是***536395***?)上,试着换个puppeteer看看安装的版本会不会变化。查看package.json确认当前版本为1.1.1最新版,试着降到1.1.01.0.0版本

1.1.0版本安装过程部分如下:

1
2
3
> node install.js
Downloading Chromium r536395 - 96.2 Mb [====================] 100% 0.0s

从序号上可以发现还是同一款的chromium,降到1.0.0发现序号开始不同了:

1
2
3
> node install.js
Downloading Chromium r526987 - 97.1 Mb [====================] 100% 0.0s

安装好后再试一试,当然还是没什么卵用啦【微笑渐渐消失.jpg

继续艰苦的Google搜索,最后发现了看起来可靠的操作(跪谢这位大佬,好人一生平安)

enter image description here

于是尝试了这个方法,这里国内的小伙伴们注意下,这个操作似乎需要挂代理(但是直接ping mirror.webtatic.com显示又正常,不太明白这里),不然会超时阻塞,报类似的错如下:

1
2
Could not retrieve mirrorlist https://mirror.webtatic.com/yum/el7/x86_64/mirrorlist error was
12: Timeout on https://mirror.webtatic.com/yum/el7/x86_64/mirrorlist: (28, 'Operation timed out after 30000 milliseconds with 0 out of 0 bytes received')

我这里挂了proxychains4设置好的代理执行操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# proxychains4 yum provides */libnss3.so
......
nss-3.28.4-12.el7_4.x86_64 : Network Security Services
Repo : updates
Matched from:
Filename : /usr/lib64/libnss3.so
nss-3.28.4-15.el7_4.i686 : Network Security Services
Repo : updates
Matched from:
Filename : /usr/lib/libnss3.so
nss-3.28.4-15.el7_4.x86_64 : Network Security Services
Repo : updates
Matched from:
Filename : /usr/lib64/libnss3.so
nss-3.28.4-15.el7_4.x86_64 : Network Security Services
Repo : @updates
Matched from:
Filename : /usr/lib64/libnss3.so
......

选择了最新的一个match目录/usr/lib64/libnss3.so的版本,yum安装

1
# yum install nss-3.28.4-15.el7_4.x86_64

安装完后再执行操作检查,没有缺包了!哦也!(o)/

1
2
$ ldd chrome | grep not
$

沙盒环境存在问题

上面解决完后新的bug立刻就来:

1
2
(node:72791) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Failed to launch chrome!
[0310/051527.838287:FATAL:zygote_host_impl_linux.cc(126)] No usable sandbox! Update your kernel or see https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.md for more information on developing with the SUID sandbox. If you want to live dangerously and need an immediate workaround, you can try using --no-sandbox.

这个解决方案很清晰了,直接修改launch的参数

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

后记

  • 都是一把辛酸泪啊……开源皆天坑果然是真理○| ̄|_
  • 要……有……耐……心
  • 有时候是ZhenJiang不知道为这种乱七八糟的坑花费时间到底值不值啊Orz

Written with StackEdit.