在 Azure Functions 中排查 Python 错误

本文提供的信息可帮助你排查 Azure Functions 中 Python 函数的错误。 本文支持 v1 和 v2 编程模型。 请从文章顶部的选择器中选择要使用的模型。

注意

Python v2 编程模型仅在 4.x 函数运行时中受支持。 有关详细信息,请参阅 Azure Functions 运行时版本概述

下面是 Python 函数常见问题的故障排除部分:

ModuleNotFoundError 错误排查

本部分可帮助你排查 Python 函数应用中与模块相关的错误。 这些错误通常会导致以下 Azure Functions 错误消息:

“异常: ModuleNotFoundError: 不存在名为 'module_name' 的模块。”

当 Python 函数应用加载 Python 模块失败时,会发生此错误。 此错误的根本原因是以下问题之一:

查看项目文件

为了确定问题的真正原因,你需要获取在函数应用上运行的 Python 项目文件。 如果本地计算机上没有这些项目文件,可以通过以下方式之一获取它们:

  • 如果函数应用具有 WEBSITE_RUN_FROM_PACKAGE 应用设置,并且其值是一个 URL,请通过将该 URL 复制并粘贴到浏览器来下载文件。
  • 如果函数应用具有 WEBSITE_RUN_FROM_PACKAGE 并且它设置为 1,请转到 https://<app-name>.scm.chinacloudsites.cn/api/vfs/data/SitePackages,并从最新的 href URL 下载文件。
  • 如果函数应用没有上述任一应用设置,请转到 https://<app-name>.scm.chinacloudsites.cn/api/settings 并在 SCM_RUN_FROM_PACKAGE 下找到 URL。 通过将 URL 复制并粘贴到浏览器来下载文件。
  • 如果建议解决了此问题,请转到 https://<app-name>.scm.chinacloudsites.cn/DebugConsole 并查看 /home/site/wwwroot 下的内容。

本文的其余部分通过检查函数应用的内容、确定根本原因并解决特定问题,来帮助你排查此错误的潜在原因。

诊断 ModuleNotFoundError

本部分详细介绍与模块相关的错误的潜在根本原因。 找出可能的根本原因后,可以转到相关的缓解措施。

找不到该包

转到 .python_packages/lib/python3.6/site-packages/<package-name>.python_packages/lib/site-packages/<package-name>。 如果文件路径不存在,这个缺失的路径可能就是根本原因。

在部署过程中使用第三方或过时的工具可能会导致此问题。

若要缓解此问题,请参阅启用远程生成生成本机依赖项

未使用正确的 Linux wheel 解析该包

转到 .python_packages/lib/python3.6/site-packages/<package-name>-<version>-dist-info.python_packages/lib/site-packages/<package-name>-<version>-dist-info。 使用你喜欢的文本编辑器打开 wheel 文件并检查 Tag: 部分。 问题可能在于标记值不包含 linux。

Python 函数只能在 Azure 中的 Linux 上运行。 Functions 运行时 v2.x 在 Debian Stretch 上运行,v3.x 运行时在 Debian Buster 上运行。 该项目应包含正确的 Linux 二进制文件。 在 Core Tools、第三方或过时的工具中使用 --build local 标志可能会导致使用较旧的二进制文件。

若要缓解问题,请参阅启用远程生成生成本机依赖项

该包与 Python 解释器版本不兼容

转到 .python_packages/lib/python3.6/site-packages/<package-name>-<version>-dist-info.python_packages/lib/site-packages/<package-name>-<version>-dist-info。 在文本编辑器中,打开 METADATA 文件并检查 Classifiers: 节。 如果该节不包含 Python :: 3Python :: 3.6Python :: 3.7Python :: 3.8Python :: 3.9,则表示包版本太旧,或者已经停止维护(这种情况更有可能)。

可以从 Azure 门户检查函数应用的 Python 版本。 导航到函数应用的“概述”资源页以查找运行时版本。 该运行时版本支持 Azure Functions 运行时版本概述中所述的 Python 版本。

若要缓解问题,请参阅将包更新到最新版本将包替换为等效的包

该包与其他包冲突

如果已验证使用适当的 Linux wheel 正确解析了该包,则可能是该包与其他包冲突。 在某些包中,PyPi 文档可能会阐明不兼容的模块。 例如,在 azure 4.0.0 中,可以看到以下陈述:

“此包与 azure-storage 不兼容。 如果你已安装 azure-storage,或者已安装 azure 1.x/2.x 且未卸载 azure-storage,则必须先卸载 azure-storage。”

可以在 https://pypi.org/project/<package-name>/<package-version> 中找到包版本的相应文档。

若要缓解问题,请参阅将包更新到最新版本将包替换为等效的包

该包仅支持 Windows 和 macOS 平台

使用文本编辑器打开 requirements.txt,并在 https://pypi.org/project/<package-name> 中检查该包。 某些包只能在 Windows 和 macOS 平台上运行。 例如,pywin32 只能在 Windows 上运行。

使用 Windows 或 macOS 进行本地开发时,可能不会发生 Module Not Found 错误。 但是,在 Azure Functions 上无法导入该包,因为 Azure Functions 在运行时使用 Linux。 此问题可能是由于在项目初始化期间使用 pip freeze 从 Windows 或 macOS 计算机将虚拟环境导出到 requirements.txt 而引起的。

若要缓解问题,请参阅将包替换为等效的包手动创建 requirements.txt

缓解 ModuleNotFoundError

下面是与模块相关的问题的潜在缓解措施。 使用前面所述的诊断来确定要尝试其中的哪种缓解措施。

启用远程生成

确保启用了远程生成。 启用方式取决于你的部署方法。

确保已安装适用于 Visual Studio Code 的 Azure Functions 扩展的最新版本。 验证 .vscode/settings.json 文件是否存在并且包含设置 "azureFunctions.scmDoBuildDuringDeployment": true。 如果不包含,请创建启用 azureFunctions.scmDoBuildDuringDeployment 设置的文件,然后重新部署项目。

生成本机依赖项

确保已安装 Docker 和 Azure Functions Core Tools 的最新版本。 转到本地函数项目文件夹,并使用 func azure functionapp publish <app-name> --build-native-deps 进行部署。

将包更新到最新版本

https://pypi.org/project/<package-name> 的最新包版本中,检查 Classifiers: 节。 包应为 OS Independent 或与操作系统中的 POSIXPOSIX :: Linux 兼容。 另外,编程语言应包含 Python :: 3Python :: 3.6Python :: 3.7Python :: 3.8Python :: 3.9

如果这些包项都正确,则你可以通过更改 requirements.txt 中的行 <package-name>~=<latest-version>,将包更新为最新版本。

手动创建 requirements.txt

一些开发人员使用 pip freeze > requirements.txt 为其开发环境生成 Python 包列表。 尽管这种便捷做法在大多数情况下都是可行的,但在跨平台部署方案中可能会出现问题,例如在 Windows 或 macOS 本地开发函数,但发布到在 Linux 上运行的函数应用。 在此方案中,pip freeze 可能会引入特定于操作系统的意外依赖项或本地开发环境的依赖项。 在 Linux 上运行时,这些依赖项可能会中断 Python 函数应用。

最佳做法是在项目源代码中检查每个 .py 文件的导入语句,并且仅在 requirements.txt 文件中签入这些模块。 这种做法可确保在不同的操作系统上正确处理包的解析。

用等效的包代替

首先,在 https://pypi.org/project/<package-name> 中查看包的最新版本。 此包通常具有自身的 GitHub 页面。 在 GitHub 上转到“问题”部分,并通过搜索来查看问题是否已修复。 如果已修复,请将包更新到最新版本。

有时,该包可能已集成到 Python 标准库(例如 pathlib)中。 如果是这样,应在 requirements.txt 文件中删除该包,因为我们在 Azure Functions 中提供了特定的 Python 发行版(Python 3.6、Python 3.7、Python 3.8 和 Python 3.9)。

但是,如果你发现问题尚未修复,但又临近项目截止日期,我们建议你做些研究,为项目找到一个类似的包。 通常,Python 社区将提供各种类似的库供你使用。

禁用依赖项隔离标志

将应用程序设置 PYTHON_ISOLATE_WORKER_DEPENDENCIES 设置为值 0


错误排查无法导入“cygrpc”

本部分可帮助你排查 Python 函数应用中与“cygrpc”相关的错误。 这些错误通常会导致以下 Azure Functions 错误消息:

“无法从 'grpc._cython' 导入名称 'cygrpc'”

如果 Python 函数应用无法在相应的 Python 解释器上启动,会发生此错误。 此错误的根本原因是以下问题之一:

诊断“cygrpc”引用错误

Python 解释器与操作系统体系结构不匹配

这种不匹配问题的原因很可能是在 64 位操作系统上安装了 32 位的 Python 解释器。

如果你运行的是 x64 操作系统,请确保你的 Python 版本 3.6、3.7、3.8 或 3.9 解释器也是 64 位版本。

可运行以下命令检查 Python 解释器位数:

在 Windows 上的 PowerShell 中,运行 py -c 'import platform; print(platform.architecture()[0])'

在类似于 Unix 的 shell 上,运行 python3 -c 'import platform; print(platform.architecture()[0])'

如果 Python 解释器位数和操作系统体系结构不匹配,请从 Python Software Foundation 下载适当的 Python 解释器。

Azure Functions Python 辅助角色不支持 Python 解释器

Azure Functions Python 工作进程仅支持 Python 版本 3.6、3.7、3.8 和 3.9。

请在 Windows 中使用 py --version 或者在类似于 Unix 的系统中使用 python3 --version,来检查你的 Python 解释器是否与预期的版本匹配。 确保返回的结果为 Python 3.6.xPython 3.7.xPython 3.8.xPython 3.9.x

如果你的 Python 解释器版本不符合 Azure Functions 的要求,请从 Python Software Foundation 下载 Python 版本 3.6、3.7、3.8 或 3.9 解释器。


对“Python 已退出,代码为 137”进行故障排除

发生代码 137 错误的原因通常是 Python 函数应用中存在内存不足的问题。 因此,你会收到以下 Azure Functions 错误消息:

“Microsoft.Azure.WebJobs.Script.Workers.WorkerProcessExitException: Python 已退出,代码为 137”

当一个 Python 函数应用被操作系统用 SIGKILL 信号强制终止时,会发生此错误。 此信号通常指示 Python 进程中出现内存不足错误。 Azure Functions 平台有一项服务限制,它将终止超出此限制的所有函数应用。

访问 Python 函数的内存分析中的教程部分,以分析函数应用中的内存瓶颈。


对“Python 已退出,代码为 139”进行故障排除

本部分可帮助你对 Python 函数应用中的分段错误进行故障排除。 这些错误通常会导致以下 Azure Functions 错误消息:

“Microsoft.Azure.WebJobs.Script.Workers.WorkerProcessExitException: Python 已退出,代码为 139”

当一个 Python 函数应用被操作系统用 SIGSEGV 信号强制终止时,会发生此错误。 此信号指示存在内存分段冲突,可能是因为意外地从/向受限的内存区域执行了读取或写入操作。 在以下各节中,我们将提供常见根本原因的列表。

来自第三方包的回归

在函数应用的 requirements.txt 中,每个 Azure Functions 部署中未固定的包都将升级到最新版本。 这些包的供应商可能会在其最新版本中引入回归。 若要在发生此问题后进行恢复,请尝试注释掉 import 语句、禁用包引用或将包固定到 requirements.txt 中的之前版本。

从格式错误的 .pkl 文件取消封装

如果函数应用使用 Python pickel 库从 .pkl 文件加载 Python 对象,那么该文件有可能包含格式错误的字节字符串或无效的地址引用。 若要在发生此问题后进行恢复,请尝试注释掉 pickle.load() 函数。

Pyodbc 连接冲突

如果函数应用使用的是常用 ODBC 数据库驱动程序 pyodbc,则可能会在一个函数应用中打开多个连接。 若要避免此问题,请使用单一实例模式,并确保在函数应用中只使用一个 pyodbc 连接。


同步触发器失败

错误 Sync triggers failed 可能由多个问题造成。 一个潜在原因是,当函数在应用服务计划中运行时,客户定义的依赖项和 Python 内置模块之间存在冲突。 有关详细信息,请参阅包管理


对“无法加载文件或程序集”进行故障排除

如果收到此错误,原因可能是使用了 v2 编程模型。 此错误是由一个已知问题造成的,该问题在即将发布的版本中会得到解决。

此特定错误可能会显示:

“DurableTask.Netherite.AzureFunctions: 无法加载文件或程序集 'Microsoft.Azure.WebJobs.Extensions.DurableTask,版本=2.0.0.0,区域性=neutral,PublicKeyToken=014045d636e89289'。
系统找不到指定的文件。”

此错误的可能原因是扩展捆绑包的缓存方式有问题。 若要排查此问题,可以结合 --verbose 运行以下命令来查看更多详细信息:

func host start --verbose

运行该命令后,如果你发现每个扩展的 Loading startup extension <> 未后接 Loaded extension <>,则可能存在缓存问题。

若要解决此问题,请执行下列操作:

  1. 运行以下命令找到 .azure-functions-core-tools 路径:

    func GetExtensionBundlePath
    
  2. 删除 .azure-functions-core-tools 目录。

    rm -r <insert path>/.azure-functions-core-tools
    

对“无法解析 Azure 存储连接”进行故障排除

你可能会在本地输出中看到显示以下消息的错误:

“Microsoft.Azure.WebJobs.Extensions.DurableTask: 无法解析名为 'Storage' 的 Azure 存储连接。
值不能为空。 (参数 'provider')”

此错误的原因与在本地从捆绑包加载扩展的方式有关。 若要解决此错误,请执行以下操作之一:

  • 使用 Azurite 之类的存储仿真器。 如果你不打算在函数应用程序中使用存储帐户,这是一个不错的选择。

  • 创建存储帐户,并将连接字符串添加到 localsettings.json 文件中的 AzureWebJobsStorage 环境变量。 将存储帐户触发器或绑定用于应用程序,或者有现有的存储帐户时,请使用此选项。 若要开始使用,请参阅创建存储帐户

部署问题

Azure 门户中选择“设置”>“配置”,并确保 AzureWebJobsFeatureFlags 应用程序设置的值为 EnableWorkerIndexing。 如果找不到此设置,请将此设置添加到函数应用。

后续步骤

如果无法解决问题,请联系 Azure Functions 团队: