服务器使用的CentOS系统,使用docker
安装Puppeteer
容器
使用Express
框架搭建服务端,调用Puppeteer
库来访问某链接
调用接口比较频繁,存在并发的情况
发现运行一段时间后内存占用很高,重启后会降下来
网上说的创建固定的Browser
实例数量以及修改初始化配置方案都无效
可能是Browser
和Page
关闭后没有完全释放内存,导致内存可用率降低
定时重启
使用linux的crontab
定时重启Express
服务,这种方案会造成短时间的连接中断及服务不可用
定时创建和摧毁Browser
实例
在代码层实现Browser
实例的定时创建和销毁,具体逻辑参考代码
const puppeteer = require("puppeteer"); // Browser实例 let browserList = []; // 不用的浏览器 let unusedBrowser = []; // 创建浏览器实例 const createBrowser = async () => { const browser = await puppeteer.launch({ headless: true, args: [ "--disable-gpu", "--disable-dev-shm-usage", "--disable-setuid-sandbox", "--no-first-run", "--no-sandbox", "--no-zygote", "--single-process", ], }); // 记录该浏览器实例打开的页面数 let pageCount = 0; // 监听到打开了一个新窗口 browser.on("targetcreated", () => { pageCount++; }); // 监听到窗口关闭 browser.on("targetdestroyed", () => { pageCount--; if (pageCount === 0 && unusedBrowser.includes(browser)) { console.log("命中unusedBrowser"); delBrowser(browser); } }); browserList.push(browser); }; // 从browserList和unusedBrowser中删除 const delBrowser = (browser) => { browserList = browserList.filter((item) => item !== browser); unusedBrowser = unusedBrowser.filter((item) => item !== browser); browser.close().then(() => { browser = null; console.log("删除浏览器", browserList.length, unusedBrowser.length); }); }; // 始终返回最后一个浏览器实例 const getBrowser = () => { return browserList[browserList.length - 1]; }; // 定时任务 const scheduledTask = () => { // 每隔20秒去创建一个新的Browser实例,并销毁第一个实例 setInterval(() => { createBrowser().then(() => { // 把第一个浏览器置为不可用 const firstBrower = browserList[0]; firstBrower.pages().then((pages) => { console.log(`第一个浏览器实例打开的页面数为${pages.length}`); // 如果当前没有打开的页面,创建Browser实例时会默认初始化一个页面,所以这里判断的是<=1 if (pages.length <= 1) { delBrowser(firstBrower); } else { unusedBrowser.push(browserList[0]); } }); }); }, 20 * 1000); };