Azure Functions 发布成功但 API 返回 HTTP 500 的处理手顺
Copyright Notice: This article is an original work licensed under the CC 4.0 BY-NC-ND license.
If you wish to repost this article, please include the original source link and this copyright notice.
Source link: https://v2know.com/article/1314
——以 Azure SQL Database 连接设定缺失为例
在使用 Visual Studio 发布 Azure Functions 时,可能会遇到这样一种情况:
发布画面显示:
Publish succeeded
Azure Portal 上也能看到 Function 已经成功部署,函数列表中也显示各个 HTTP Trigger 函数处于「有効」状态。
但是实际访问 API 时,却出现:
HTTP ERROR 500
このページは現在機能していません
这类问题通常说明:
Azure Functions 本身已经收到了请求,但是函数内部执行时发生了错误。
本次问题的原因是:
本地开发环境中使用的 local.settings.json 里的数据库连接设定,并不会自动发布到 Azure Functions 的云端环境中。
因此,Azure 上的 Function App 缺少 SQL Database 的连接信息,导致 API 执行时报错。
1. 确认 Function 是否已经发布成功
首先进入 Azure Portal,打开对应的 Function App。
例如:
shori-jokyo-func-dev
确认函数列表中是否已经存在对应的 API。
例如:
DatabaseHealth
ImportJissekiDateInfoTable
ImportJissekiDateMemoTable
ImportJissekiInfoTable
TaxCategoryExtensionCountReport
如果这些函数已经显示在 Azure Portal 上,并且状态为:
有効
说明发布本身大概率是成功的。
2. 确认 API URL 是否正确
Azure Functions 的 HTTP Trigger URL 通常是这种形式:
https://xxxxx.azurewebsites.net/api/函数名
例如:
https://shori-jokyo-func-dev-xxxxx.japaneast-01.azurewebsites.net/api/database/health
如果 Function 的 Authorization Level 是 Function,还需要带上 function key:
https://xxxxx.azurewebsites.net/api/database/health?code=你的FunctionKey
如果 URL 正确、key 也正确,但仍然返回:
HTTP ERROR 500
那么问题通常不是 URL 或 key,而是函数内部执行时报错。
3. 判断 HTTP 500 的含义
HTTP 500 表示服务器内部错误。
在 Azure Functions 的场景中,它通常意味着:
请求已经进入 Function
但是 Function 执行过程中发生异常
常见原因包括:
数据库连接字符串缺失
数据库防火墙未放行
SQL 用户名或密码错误
环境变量名称不一致
依赖 DLL 或 Runtime 配置问题
本次问题中,最可疑的是数据库连接设定缺失。
4. 理解 local.settings.json 不会自动发布到 Azure
本地开发 Azure Functions 时,通常会在 local.settings.json 中保存设定。
例如:
{
"IsEncrypted": false,
"Values": {
"SqlDatabase__Server": "xxxxx.database.windows.net",
"SqlDatabase__Database": "dbname",
"SqlDatabase__User": "sqluser",
"SqlDatabase__Password": "password"
}
}
但是 local.settings.json 是本机开发用文件。
发布到 Azure 时,它通常不会自动上传到 Azure Function App。
所以即使本地执行正常,发布到 Azure 后也可能因为找不到这些设定而失败。
5. 在 Azure Portal 中追加环境变量
进入 Azure Portal 后,打开 Function App:
shori-jokyo-func-dev
然后进入:
設定
→ 環境変数
→ アプリ設定
旧版 UI 中可能显示为:
設定
→ 構成
→ アプリケーション設定
在这里可以看到当前 Function App 的环境变量。
如果只看到类似下面这些:
APPLICATIONINSIGHTS_CONNECTION_STRING
AzureWebJobsStorage
DEPLOYMENT_STORAGE_CONNECTION_STRING
说明还没有追加 SQL Database 的连接设定。
6. 追加 SQL Database 连接设定
点击:
+ 追加
依次新增下面 4 个应用程序设置。
6.1 追加 SQL Server 名称
名前:
SqlDatabase__Server
値:
你的SQLServer名.database.windows.net
例如:
SqlDatabase__Server = xxxxx.database.windows.net
6.2 追加 Database 名称
名前:
SqlDatabase__Database
値:
你的数据库名
例如:
SqlDatabase__Database = shori-jokyo-db
6.3 追加 SQL 用户名
名前:
SqlDatabase__User
値:
你的SQL登录用户
注意,这里不是 Azure Portal 的登录账号。
而是 Azure SQL Server 的 SQL 登录用户,例如 server admin login。
6.4 追加 SQL 密码
名前:
SqlDatabase__Password
値:
你的SQL密码
7. 为什么使用双下划线 __
这里的设定名中使用了双下划线:
SqlDatabase__Server
原因是,在 .NET 的 Configuration 系统中,双下划线 __ 会被解释为配置层级分隔符。
例如代码中读取:
configuration["SqlDatabase:Server"]
在 JSON 中相当于:
{
"SqlDatabase": {
"Server": "xxxxx.database.windows.net"
}
}
但在 Azure App Settings / Environment Variables 中,不适合直接使用 :。
因此使用:
SqlDatabase__Server
来表示:
SqlDatabase:Server
也就是说:
SqlDatabase__Server = SqlDatabase:Server
SqlDatabase__Database = SqlDatabase:Database
SqlDatabase__User = SqlDatabase:User
SqlDatabase__Password = SqlDatabase:Password
简单来说,双下划线是给 .NET 设定系统看的层级符号。
8. デプロイ スロットの設定 是否需要勾选
在追加应用程序设定时,会看到:
デプロイ スロットの設定
这个 checkbox 通常不需要勾选。
它的作用是:
如果以后使用 Deployment Slot,例如 staging / production,勾选后该环境变量会固定在当前 slot,不会随着 slot swap 交换。
普通 Function App 设置数据库连接时,不需要勾选。
也就是:
不要勾选
直接保存即可。
9. 保存并重启 Function App
添加完成后,点击:
適用
或者:
保存
Azure 可能会提示是否重新启动应用。
选择确认。
如果没有自动重启,可以回到 Function App 的概要页,手动点击:
再起動
环境变量变更后,建议重启 Function App,确保新设定被正确读取。
10. 确认 Azure SQL 防火墙设定
即使 Function App 已经有了连接字符串,如果 Azure SQL Server 不允许访问,也会连接失败。
进入 Azure SQL Server 的 Networking 页面:
Azure SQL Server
→ ネットワーク
确认是否允许 Azure 服务访问。
测试阶段可以先打开:
Azure サービスおよびリソースにこのサーバーへのアクセスを許可する
英文 UI 中是:
Allow Azure services and resources to access this server
设置为:
はい / Yes
然后保存。
如果这里没有放行,Function 调用数据库时也可能返回 500。
11. 重新测试 API
再次访问 health check API。
例如:
https://xxxxx.azurewebsites.net/api/database/health?code=你的FunctionKey
如果设定正确,应该返回类似:
{
"status": "OK"
}
或者返回项目中定义好的数据库健康检查结果。
如果仍然返回 500,就继续查看日志。
12. 查看 Log Stream
进入 Function App:
ログ ストリーム
然后再次刷新 API URL。
这时日志中通常会显示真正的异常原因。
常见错误包括:
The ConnectionString property has not been initialized.
表示连接字符串没有正确读取。
Login failed for user ...
表示 SQL 用户名或密码错误。
Cannot open server requested by the login.
表示 SQL Server、Database 或权限设定有问题。
A network-related or instance-specific error occurred.
表示网络、防火墙或 SQL Server 访问限制有问题。
13. 注意不要公开 Function Key
Function URL 中的:
code=xxxx
相当于 API 密钥。
如果不小心把它贴到截图、聊天记录或 Blog 中,建议之后到 Azure Portal 中重新生成 key。
路径大致是:
Function App
→ 関数
→ 对应 Function
→ 関数キー
→ 再生成
Blog 中展示 URL 时,应该写成:
https://xxxxx.azurewebsites.net/api/database/health?code=你的FunctionKey
不要贴真实 key。
总结
本次问题的核心是:
Azure Functions 发布成功
≠
Azure 上已经拥有本地 local.settings.json 的设定
本地执行正常,但发布到 Azure 后 API 返回 HTTP 500,常见原因就是 Azure Function App 缺少环境变量。
解决方式是:
1. 打开 Function App
2. 进入 環境変数 / アプリ設定
3. 新增 SqlDatabase__Server
4. 新增 SqlDatabase__Database
5. 新增 SqlDatabase__User
6. 新增 SqlDatabase__Password
7. 保存
8. 重启 Function App
9. 确认 Azure SQL 防火墙
10. 重新测试 API
这类问题不需要反复重新发布。
先确认 Azure 上的环境变量和 SQL 防火墙,通常就能定位原因。
This article was last edited at