有了 serverless,前端也能夠快速開發一個 Puppeteer 網頁截圖服務

更多雲原生技術資訊可關注阿里巴巴雲原生技術圈html

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 能作什麼呢?node

  • 生成網頁截圖或者 PDF
  • 抓取 SPA(Single-Page Application) 進行服務器渲染(SSR)
  • 高級爬蟲,能夠爬取大量異步渲染內容的網頁
  • 模擬鍵盤輸入、表單自動提交、登陸網頁等,實現 UI 自動化測試
  • 捕獲站點的時間線,以便追蹤你的網站,幫助分析網站性能問題

本文選擇截圖場景做爲演示。linux

廢話很少說了,咱們直接給你們介紹下如何用函數計算產品來快速部署一個 Puppeteer Web 應用。git

如何快速部署一個分佈式 Puppeteer Web 應用?

爲了快速部署分佈式 Puppeteer Web 應用,本文以函數計算服務爲例來作展現。github

函數計算(Function Compute): 函數計算是一個事件驅動的服務,經過函數計算,用戶無需管理服務器等運行狀況,只需編寫代碼並上傳。函數計算準備計算資源,並以彈性伸縮的方式運行用戶代碼,而用戶只需根據實際代碼運行所消耗的資源進行付費。函數計算更多信息 參考

有了函數計算服務,咱們這裏目標是搭建一個分佈式應用,但作的事情其實很簡單,那就是寫好業務代碼,部署到函數計算,僅此而已。web

使用函數計算後,咱們的系統架構圖以下:chrome

1.png

效果演示

能夠直接經過如下連接查看效果:
https://1911504709953557.cn-hangzhou.fc.aliyuncs.com/2016-08-15/proxy/puppeteer-test/html2png/?url=https://www.aliyun.com/product/fc
PS:第一次請求可能會有幾秒的冷啓動時間,經過使用預留模式能夠徹底去除冷啓動,這題超綱,下次再講。docker

搭建步驟步驟:

總體流程以下圖所示:npm

2.png

其中,須要咱們操做的只有 Fun Init、Fun Install 以及 Fun Deploy 命令,每一個的步驟內容都會由這三個命令自動完成。json

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 的本地運行、調試方法與這裏介紹的徹底一致,咱們就再也不重複介紹。咱們這裏只演示下運行效果:

4.gif

5. 一鍵部署應用

基本上全部的 FaaS 平臺爲了減少應用的冷啓動,都會設置代碼包的限制,函數計算也不例外。而 puppeteer 自身已經達到了 350M 左右,連同其系統依賴已經達到了 450M。如何將 450M 體積的函數部署到 FaaS 平臺是一個比較頭痛並且繁瑣的問題。

函數計算的命令行工具 Fun 如今原生支持了這種大依賴部署(3.1.1 版本僅支持 node runtime)。不須要任何額外操做,僅僅執行 fun deploy:

$ fun deploy

fun 會自動完成依賴的部署。而當檢測到打包的依賴超過了平臺的限制時,會進入到配置嚮導,幫助用戶自動化地配置。

咱們這裏推薦的路徑是當提示是否由 Fun 自動幫助 NAS 管理是,輸入 yes,而後提示提示是否使用 NasConfig: Auto 自動處理 NAS 時,也選擇是,以後就不須要作其餘的事情,等待函數部署成功便可。

5.png

若是有其餘的需求,好比想使用本身已經存在的 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
  3. 若是已經配置,則提示用戶選擇已經配置的 NAS 存儲函數依賴
  4. 若是沒有配置,則提示用戶是否使用NasConfig: Auto自動建立 NAS 配置
  5. 若是選擇了是,則幫助用戶自動配置 nas、vpc 資源。
  6. 若是選擇了否,則列出用戶當前 NAS 控制檯上已經有的 NAS 資源,讓用戶選擇
  7. 不管上面使用哪一種方式,最終都會在 template.yml 生成 NAS 以及 VPC 相關的配置
  8. 根據語言檢測,好比 node runtime,會將 node_modules 以及 .fun/root 目錄映射到 nas 目錄(經過 .nas.yml 實現)
  9. 自動執行 fun nas sync 幫用戶把本地的依賴上傳到 NAS 服務
  10. 自動執行 fun deploy,幫用戶把代碼上傳到函數計算
  11. 提示幫助信息,對於 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 服務的方法。利用該方法,能夠作到不須要關心如何安裝依賴、也不須要關係如何上傳依賴,順滑地完成部署。

部署完成後,便可享受函數計算帶來的優點,即:

  • 無需採購和管理服務器等基礎設施,只需專一業務邏輯的開發,能夠大幅縮短項目交付時間和人力成本
  • 提供日誌查詢、性能監控、報警等功能快速排查故障
  • 免運維,毫秒級別彈性伸縮,快速實現底層擴容以應對峯值壓力,性能優異
  • 成本極具競爭力
阿里巴巴雲原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,作最懂雲原生開發者的技術圈。」
相關文章
相關標籤/搜索