背景
函数计算 FC 提供了基于 Debian9 和 Debian10 并包含各种语言支持的运行时。但是在使用某些复杂依赖时,这些运行时默认是不满足需求的。可能是因为某些依赖所需要的 apt 依赖并没有在函数计算的运行时里。这种情况下如何使用函数计算呢?
解决方案
方案1(强烈推荐): 函数计算支持用“容器镜像”创建函数,所以您可以通过 Dockerfile 来完全定义自己的运行环境。
方案2: 在函数计算提供的运行时中,手动安装确实的 apt 依赖等。
方案2
方案1中您可以通过 Docker 自己安装任何依赖。本文主要介绍方案 2。
步骤1
创建函数时选择“自定义运行时(Web 函数)” 中的 Debian10。因为目前内置运行时中都是基于 Debian9 的,有一些依赖比较旧了。例如目前最新的 Chromium 已经不能在 Debian9 中方便的运行了。因此,我们可以选择最新的 Debian10 的运行时。
步骤2
创建 Chromium 的层。去 https://vikyd.github.io/download-chromium-history-version/#/ 下载 Linux 64 的依赖。目前最新版本为 1191875 https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Linux_x64/1191875/。您需要下载 chrome-linux.zip 和 chromedriver_linux64.zip 两个文件。然后您可以使用这两个文件创建两个层(注意:兼容运行时选择 Debian10),并配置给函数。
步骤3
“测试”函数,并登陆到实例,测试 chrome 和 chromedriver 所缺少的依赖。目标是可以让 chrome 和 chromedriver 可以执行。我们可以在“登陆实例“中输入下方命令,检查缺少的依赖,并通过 apt-get 安装缺失的依赖。
/opt/chrome-linux/chrome --disable-dev-shm-usage--no-sandbox--headless--disable-gpu--no-zygote--disable-setuid-sandbox--no-first-run
步骤4
最后发现缺少的依赖如下。安装完如下依赖后,chrome 可以启动成功。我们可以通过在线构建层的功能把这些依赖和 Python 依赖安装到层里。并把层配置给函数。
apt 依赖
libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon-x11-0 libxcomposite-dev libxdamage1 libxrandr2 libgbm-dev libasound2
pip 依赖
selenium==4.12.0
undetected_chromedriver==3.5.3
步骤5
更新代码,进行测试。并验证截图成功!
fromflaskimportFlaskfromflaskimportrequestimportundetected_chromedriverasucREQUEST_ID_HEADER='x-fc-request-id'app=Flask(__name__) route("/invoke", methods= ["POST"]) .defhello_world(): rid=request.headers.get(REQUEST_ID_HEADER) print("FC Invoke Start RequestId: "+rid) data=request.stream.read() print(str(data)) print("FC Invoke End RequestId: "+rid) print("=============") options=uc.ChromeOptions() options.binary_location="/opt/chrome-linux/chrome"options.add_argument("--disable-dev-shm-usage") options.add_argument("--no-sandbox") options.add_argument("--headless") options.add_argument("--disable-gpu") options.add_argument("--no-zygote") options.add_argument("--disable-setuid-sandbox") options.add_argument("--no-first-run") driver=uc.Chrome(driver_executable_path='/opt/chromedriver_linux64/chromedriver', options=options) driver.get('https://www.baidu.com') driver.save_screenshot('/tmp/baidu.png') driver.quit() return"Hello, World!"if__name__=='__main__': app.run(host='0.0.0.0',port=9000)