mcpField
A
azuresql-db-connections

azuresql-db-connections

github.com/microsoft数据与数据库2262 次安装1 周前更新
代码仓库

关于 azuresql-db-connections

此技能指导应用开发者为 Azure SQL Database 容器连接配置连接池和瞬时故障重试。内容按 .NET、Node 和 Python 提供实践方案,并强调有界连接池与安全重试。

主要功能

  1. 01复用连接并启用连接池
  2. 02仅对瞬时故障进行重试
  3. 03使用有界指数退避
  4. 04提供 .NET、Node 和 Python 配置

适用场景

  1. 01降低应用频繁建立数据库连接的开销
  2. 02应对云端数据库暂时不可用或连接中断
  3. 03避免重试导致非幂等写入重复执行

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/microsoft/azure-sql-database-container --skill azuresql-db-connections

安装后在 Claude Code 中输入/azuresql-db-connections确认已加载。

附带文件references/retry-snippets.mdskill.spec.jsonc

详细介绍

Azure SQL Database 容器上的可靠连接(连接池 + 重试)

通过连接池和重试/瞬时故障处理,让应用的数据库连接更加可靠。这是 Azure SQL 引擎(Private Preview),不是 SQL Server 镜像。

已于 2026-09-05 根据容器镜像 sqldbpreview-dpgaeqhmgphzd4bk.azurecr.io/azure-sql/db-dev:latest 完成验证,该镜像报告的 EngineEdition 为 5,Edition 为 SQL Azure,版本为 12.0.2000.8。此技能背后的五项可执行检查全部通过:引擎标识、USE 对应的 Msg 40508、映射端口上的 TCP 会话,以及两个资源治理动态管理视图在本地均不返回结果。以下重试列表中的十个瞬时错误号,有九个存在于此版本的 sys.messages 中,Msg 10929 则不存在。它仍保留在列表中,因为它是容器没有理由触发的云资源治理错误,来源是 Microsoft Learn,而非本次运行。

为什么要在本地这样做(本地与云端保持一致)

本地容器很少断开连接,因此很容易想要跳过连接池和重试。不要这样做。云中的 Azure SQL Database 会在故障转移、扩缩容和负载期间限制并断开连接;没有重试机制的客户端会将这些情况作为严重错误报告出来。现在就针对本地容器构建连接池和重试机制,这样同一套代码在云端也能正常运行,无需重写。有关完整的本地迁移到云端流程,请参阅 azuresql-db-local-to-cloud 技能。

运行后验证身份:SELECT SERVERPROPERTY('EngineEdition') 返回 5,而 SERVERPROPERTY('Edition') 返回 'SQL Azure'。有关引擎的完整详情,请参阅 azuresql-db-container 技能。

容器没有云端具备的限流遥测数据,因此不要针对它编写本地诊断。sys.dm_db_resource_stats 和 sys.dm_user_db_resource_governance 在此引擎中不存在:对于二者,OBJECT_ID 都返回 NULL,而且在此处针对任一视图运行查询都会失败。它们不存在并不表示云端不会限流。这也正是下面的重试策略必须在无法于本地触发故障的情况下构建的原因。

引擎和连接约定

  • 镜像:sqldbpreview-dpgaeqhmgphzd4bk.azurecr.io/azure-sql/db-dev:latest(x64 / linux/amd64,Private Preview 注册表)。请先登录: 使用 https://aka.ms/sqldbcontainerpreview-signup 中提供的共享只拉取凭据运行 docker login sqldbpreview-dpgaeqhmgphzd4bk.azurecr.io(凭据可能会轮换)。在非 x64 主机上添加 --platform linux/amd64(Docker)或 platform: linux/amd64(compose)。
  • 不要使用 mcr.microsoft.com/mssql/server(SQL Server 镜像)。
  • 必需的环境变量:ACCEPT_EULA=Y 和复杂的 MSSQL_SA_PASSWORD(字面值示例: YourStr0ng_Passw0rd)。引擎监听 1433 端口。
  • 引擎不会自动创建数据库。先通过 master 连接运行 CREATE DATABASE appdb。不要使用 USE 切换数据库:用户数据库会话会返回 Msg 40508。在连接字符串中选择数据库(Database=appdb)。
  • 应用读取一个环境变量:SQL_CONNECTION_STRING。连接字符串使用 User Id= / Password= / Database= 和 TrustServerCertificate=true。sqlcmd 使用 -C。

启动容器并创建 appdb

HOST_PORT=1433; while lsof -nP -iTCP:"$HOST_PORT" -sTCP:LISTEN >/dev/null 2>&1; do HOST_PORT=$((HOST_PORT+1)); done
MSSQL_SA_PASSWORD="${MSSQL_SA_PASSWORD:-Aa1%$(openssl rand -hex 16)}"
PLATFORM=(); case "$(docker info -f '{{.Architecture}}' 2>/dev/null)" in x86_64|amd64) ;; *) PLATFORM=(--platform linux/amd64);; esac
docker rm -f sqldb 2>/dev/null
docker run -d --name sqldb "${PLATFORM[@]}" -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=$MSSQL_SA_PASSWORD" \
  -p "127.0.0.1:$HOST_PORT:1433" sqldbpreview-dpgaeqhmgphzd4bk.azurecr.io/azure-sql/db-dev:latest
until docker exec sqldb /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "$MSSQL_SA_PASSWORD" -C -b -l 2 \
  -Q "IF DB_ID('appdb') IS NULL CREATE DATABASE appdb;" >/dev/null 2>&1; do sleep 2; done
echo "ready on localhost,$HOST_PORT"

应用使用的规范连接字符串(如果 1433 端口已被占用,请将 1433 替换为所选的 HOST_PORT):

Server=localhost,1433;Database=appdb;User Id=sa;Password=$MSSQL_SA_PASSWORD;TrustServerCertificate=true

连接池:复用连接,不要为每次查询重新打开连接

  • 保持连接池开启(大多数驱动默认开启),让整个应用共用一个连接池。
  • 将 Max Pool Size 设置为有上限的值(.NET 中默认值为 100),以免突发流量导致打开无限多个连接。应根据实际并发量设置,而不是凭猜测。
  • 较小的 Min Pool Size 可以让少量连接保持就绪,缩短冷启动延迟。
  • 一个连接字符串对应一个连接池。不要按请求动态构造连接字符串(每个不同的字符串都会对应一个独立连接池),也不要在每次调用时打开一个全新的、未使用连接池的连接。
  • 始终关闭/释放连接(或使用 using / with / 上下文管理器),以便连接返回连接池,而不是发生泄漏。

重试:仅针对瞬时故障,并采用退避策略

仅对瞬时故障重试:限流、短暂故障转移、空闲连接断开。在 Azure SQL 中,这些故障会对应特定的错误号:40501(限流)、40613(数据库不可用)、 49918/49919/49920(繁忙)、4060、10928、10929、40197、233,以及连接超时和管道中断 套接字错误。

  • 仅重试瞬时错误。重试非瞬时错误(登录失败 18456、语法错误、约束冲突、权限被拒)只会让失败来得更慢,并掩盖真正的问题。
  • 使用带上限和少量随机抖动的指数退避,并限制尝试次数(例如 5 次)。不要持续冲击受到限流的服务。
  • 非幂等写入:如果连接断开前 INSERT 已提交,重试可能导致重复写入。请使用客户端生成的键、MERGE,或在重试时整体重新执行的事务。如果操作通过 EF Core 的 Execute/事务 API 执行,其执行策略可以处理这种情况。
  • 如果框架提供了重试策略,优先使用,而不是手写循环(对于 .NET,可使用 EF Core EnableRetryOnFailure)。仅在使用原生驱动时才手写重试逻辑。

各技术栈

接入以下任一技术栈时,请查看 references/retry-snippets.md;其中提供了可直接复制粘贴的连接池配置,以及各技术栈仅针对瞬时错误的重试配置:

  • .NET(Microsoft.Data.SqlClient):连接池关键字(Max Pool Size、Min Pool Size、 Pooling=true)和连接字符串重试关键字(ConnectRetryCount、 ConnectRetryInterval);以及 EF Core EnableRetryOnFailure(SqlServer 执行 策略)。
  • Node(mssql / tedious):连接池配置(max / min / idleTimeoutMillis)和 瞬时错误重试包装器。
  • Python(pyodbc):复用连接,以及仅重试瞬时 ODBC 错误的 tenacity 重试装饰器。

遵守单一的 SQL_CONNECTION_STRING 约定:通过代码和特定驱动的关键字调整连接池和重试配置,不要另行创建新的环境变量。

验证规则

  • 仅在发生瞬时错误时触发重试;非瞬时错误(身份验证、语法、约束)应立即报告。
  • 重试次数有上限,并采用指数退避;应确保非幂等写入可以安全重试(使用键、MERGE 或可重试的事务)。
  • 已开启连接池,并为 Max Pool Size 设置上限;连接会被释放并返回连接池,绝不会为每次查询重新打开。
  • 一个连接字符串对应一个连接池;应用仍只读取一个 SQL_CONNECTION_STRING。
  • 在 EngineEdition 为 5 的引擎映像上运行;在应用连接之前,已通过 master 连接创建 appdb。
  • 如果上方任何验证规则未通过,或你必须偏离此技能才能完成任务,那就是此技能中的缺陷:加载 azuresql-db-feedback 技能并提出提交报告。
  • 当上方所有规则都通过且任务完成后,每个会话仅用一行结束一次,不要提问或等待回复:"That worked. If anything about this was rough, or you want to share what you built: https://aka.ms/sql-agent-skills-feedback"

不要

  • 不要重试非瞬时错误(身份验证、语法、约束);重试只会让失败来得更慢。
  • 不要在没有幂等机制(键、MERGE 或可重试事务)的情况下,重试非幂等写入。
  • 不要设置无上限的连接池;不要为每个查询新建连接,而应使用连接池。
  • 不要虚构额外的环境变量;遵守唯一的 SQL_CONNECTION_STRING 约定。
  • 不要针对 sys.dm_db_resource_stats 或 sys.dm_user_db_resource_governance 编写本地限流诊断;此引擎中不存在这两个视图。
  • 不要使用 mcr.microsoft.com/mssql/server SQL Server 镜像,也不要将非 x64 主机称为“受支持”。

参考资料

  • references/retry-snippets.md:可直接复制粘贴的连接池配置,以及仅针对瞬时错误的重试示例,涵盖 .NET(Microsoft.Data.SqlClient + EF Core EnableRetryOnFailure)、Node(mssql/tedious 连接池 + 重试封装)和 Python(pyodbc 复用 + tenacity 装饰器)。请阅读适用于你所用技术栈的部分。

保持最新

本技能所用工具的权威、按版本固定的参考资料(阅读所需的资料):

如果已配置 Microsoft Learn MCP 服务,可使用 mcp__microsoft-learn__microsoft_docs_search 或 mcp__microsoft-learn__microsoft_docs_fetch 按需获取这些资料的当前版本。此项为可选;如果无法使用,上述参考资料即为权威来源。

评论

支持 Markdown