Использование go-mssqldb с База данных SQL Azure

Драйвер go-mssqldb поддерживает подключение к База данных SQL Azure, Управляемый экземпляр SQL Azure и SQL Database в Microsoft Fabric. В этой статье рассматриваются специфические для Azure конфигурации, аутентификации, ограничений соединения и устранения неполадок, отличающихся от локального SQL Server.

Подключение к База данных SQL Azure

База данных SQL Azure по умолчанию требует зашифрованных соединений. Явно укажите encrypt=true и TrustServerCertificate=false, чтобы соединение использовало TLS и проверяло сертификат сервера:

db, err := sql.Open("sqlserver",
    "sqlserver://<user>:<password>@<server>.database.windows.net?database=<database>&encrypt=true&TrustServerCertificate=false")
if err != nil {
    panic(err)
}

Note

Если опустить encrypt, драйвер не будет автоматически добавлять специальные параметры TLS для Azure. Сохраните encrypt=true&TrustServerCertificate=false в строках подключения Azure SQL.

Аутентификация Microsoft Entra ID удаляет пароли из ваших строк подключения. ActiveDirectoryDefault Автоматически выбирает наилучший доступный учётный код для среды, что делает её удобной для разработки:

import (
    "database/sql"
    "log"

    _ "github.com/microsoft/go-mssqldb/azuread"
)

func main() {
    db, err := sql.Open("azuresql",
        "sqlserver://<server>.database.windows.net?database=<database>&fedauth=ActiveDirectoryDefault&encrypt=true&TrustServerCertificate=false")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()
}

Important

ActiveDirectoryDefault удобна для разработки, но может добавить задержку соединения, поскольку проверяет несколько источников учетных данных. Для производственных услуг предпочитайте явный метод, например ActiveDirectoryManagedIdentity или ActiveDirectoryServicePrincipal.

Как ActiveDirectoryDefault определяет учетные данные

ActiveDirectoryDefault Пробует следующие источники учетных данных по порядку и использует первый, который успешно срабатывает:

Order Источник удостоверения Типичная среда
1 Переменные среды (AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET) CI/CD конвейеры, контейнеры Docker
2 Идентификация рабочей нагрузки Модули Kubernetes с Azure Workload Identity
3 Манажируемая идентичность Azure VMs, App Service, Container Apps, Функции Azure
4 Azure CLI (az login) Местное развитие
5 Azure Developer CLI (azd auth login) Местное развитие

Эта цепочка учетных данных ActiveDirectoryDefault удобна при разработке, но последовательная проверка увеличивает задержку при каждом новом подключении. Для продакшна укажите точный метод аутентификации (например ActiveDirectoryManagedIdentity, ), чтобы драйвер пропускал ненужные проверки.

Приложения, размещённые в Azure (App Service, Container Apps, Функции Azure или Azure VMs), должны использовать управляемую идентичность с явным fedauth значением. Такой подход избегает накладных расходов на цепочку учетных данных и устраняет зависимость от переменных среды или состояния CLI.

Системное управляемое удостоверение:

sqlserver://<server>.database.windows.net?database=<database>&fedauth=ActiveDirectoryManagedIdentity&encrypt=true&TrustServerCertificate=false

Управляемая идентификация, назначенная пользователем (укажите идентификатор клиента):

sqlserver://<server>.database.windows.net?database=<database>&fedauth=ActiveDirectoryManagedIdentity&user id=<client-id>&encrypt=true&TrustServerCertificate=false

Предоставить доступ к идентичности в базе данных

После настройки управляемой идентичности ресурса Azure создайте автономного пользователя базы данных:

CREATE USER [my-app-identity] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [my-app-identity];
ALTER ROLE db_datawriter ADD MEMBER [my-app-identity];

Для идентификаторов, присваиваемых системой, используйте имя ресурса Azure. Для идентификаторов, назначенных пользователем, используйте имя идентичности.

Сервисный принцип для автоматизации

Для конвейеров CI/CD или аутентификации между сервисами:

sqlserver://<server>.database.windows.net?database=<database>&fedauth=ActiveDirectoryServicePrincipal&user id=<client-id>&password=<client-secret>&encrypt=true&TrustServerCertificate=false

Для всех типов учетных данных см. аутентификация Microsoft Entra ID.

Настройка брандмауэра Azure

База данных SQL Azure использует серверный межсетевой экран. Вы должны разрешить публичный IP-адрес клиента или использовать приватную конечную точку.

Ошибка: Не удаётся открыть сервер

Это сообщение об ошибке указывает на то, что файрвол Azure блокирует ваш IP-адрес клиента:

mssql: login error: Cannot open server '<server>' requested by the login.
Client with IP address '<client-ip>' is not allowed to access the server.

Решения:

  1. Добавьте правило межсетевого экрана в портале Azure: SQL server>Networking>Добавьте правило межсетевого экрана.
  2. Включите Разрешить сервисам и ресурсам Azure доступ к этому серверу, если ваше приложение работает в Azure.
  3. Для приватного подключения настройте приватную конечную точку.

Ошибка: Время соединения окончено

Если соединение выходит из тайм-аут без явной ошибки, файрвол, скорее всего, бесшумно блокирует соединение. Сначала проверьте правила межсетевого экрана.

Ограничения соединения по уровню обслуживания

База данных SQL Azure устанавливает ограничения соединения для каждой базы данных в зависимости от уровня сервиса. Превышение лимита приводит к сбоям аутентификации для новых соединений. Для полных таблиц лимитов см. лимиты ресурсов одиночной базы данных DTU и лимиты ресурсов одиночных баз данных vCore.

Настройте MaxOpenConns под ваш уровень

Всегда устанавливайте MaxOpenConns значение ниже лимита соединения для вашего уровня Azure SQL:

// Example for S2 tier (60 max workers).
// Leave headroom for Azure management connections and other clients.
db.SetMaxOpenConns(20)
db.SetMaxIdleConns(10)
db.SetConnMaxLifetime(5 * time.Minute)

Tip

Если несколько приложений используют одну и ту же базу данных, разделите лимит соединения между всеми приложениями. Например, если три сервиса используют одну базу данных S2 (максимум 60 работников), выделяйте 15-20 соединений на один сервис.

Обработка ограничения пропускной способности Azure SQL

База данных SQL Azure может ограничивать соединения и запросы, когда база данных приближается к лимиту ресурсов (CPU, IO, память или количество сессий). Троттлинг проявляется в виде конкретных ошибок.

Распространённые ошибки при троттлинге

Номер ошибки Шаблон сообщения Причина
10928 Resource ID: %d. The %s limit for the database is %d and has been reached. Достигнут лимит сессий или рабочих процессов.
10929 Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d. Ограничение регулятором ресурсов
40501 The service is currently busy. Общее ограничение скорости. Повторите попытку.
40544 The database has reached its size quota. Достигнут лимит размера базы данных. Увеличьте вместимость или свободное пространство перед повторной попыткой.
40549 Session is terminated because you have a long-running transaction. Транзакция превысила срок.
40550 Session is terminated because of too many locks. Чрезмерное получение блокировок.
40551 Session is terminated because of excessive tempdb usage. Чрезмерное использование tempdb.
40552 Session is terminated because of excessive transaction log usage. Пространство журнала транзакций превышено.
40553 Session is terminated because of excessive memory usage. Чрезмерное потребление памяти.
40613 Database '%.*ls' on server '%.*ls' is not currently available. База данных перемещается или перестраивается.
49918 Cannot process request. Not enough resources to process request. Исчерпание ресурсов.
49919 Cannot process create or update request. Слишком много одновременных операций по созданию и обновлению.
49920 Cannot process request. Too many operations in progress. Достигнут лимит параллельной эксплуатации.

Повторите запросы, отклонённые из-за ограничения скорости

Большинство ошибок ограничения и доступности Azure SQL в предыдущей таблице являются временными, поэтому операцию следует повторить с экспоненциальной задержкой между попытками. Ошибка 40544 не является временной. Это значит, что база данных достигла квоты размера, и операция не будет успешной, пока вы не увеличите масштаб базы данных или не удаляете данные.

Для полной реализации повторной попытки см. раздел «Обработка ошибок и паттерны повторных попыток».

import (
    "errors"

    mssql "github.com/microsoft/go-mssqldb"
)

func isAzureThrottling(err error) bool {
    var mssqlErr mssql.Error
    if !errors.As(err, &mssqlErr) {
        return false
    }
    switch mssqlErr.Number {
    case 10928, 10929, 40501, 40549, 40550, 40551, 40552, 40553,
        40613, 49918, 49919, 49920:
        return true
    }
    return false
}

Устойчивость подключения

База данных SQL Azure иногда перенастраивает серверы для обновлений, отказов и балансировки нагрузки. Эти события разрывают существующие соединения, что проявляется в виде ошибок driver: bad connection. Настройте пул на автоматическое восстановление:

db.SetConnMaxLifetime(5 * time.Minute)  // Rotate connections so stale ones are replaced.
db.SetConnMaxIdleTime(2 * time.Minute)  // Recycle before Azure gateway drops idle connections (30 min).
db.SetMaxIdleConns(10)                  // Keep warm connections for quick recovery.

Note

Шлюз Azure SQL закрывает соединения, находящиеся в простое около 30 минут. Установите ConnMaxIdleTime значительно ниже этого порога, чтобы избежать driver: bad connection ошибок при первом запросе после периода простоя. Для нетранзакционных вызовов database/sql автоматически выполняет повторную попытку при новом соединении. Для транзакционных вызовов ваш код должен обнаружить ошибку и повторить всю транзакцию.

Повторное подключение после отказа

Вне транзакций database/sql может прозрачно повторить вызов, который начинается при использовании неисправного соединения, если драйвер помечает это соединение как непригодное для использования. Это поведение не является полноценной политикой повторных попыток для обработки временных сбоев, таких как ограничение пропускной способности, аварийное переключение или другие SQL-ошибки, допускающие повторную попытку. Оберните обращения к базе данных в функцию повторных попыток, чтобы обработать такие ситуации:

var count int
err := RetryFunc(ctx, DefaultRetryConfig, func(ctx context.Context) error {
    return db.QueryRowContext(ctx, "SELECT COUNT(*) FROM HumanResources.Employee").Scan(&count)
})

См. раздел «Обработка ошибок и шаблоны повторных попыток» для реализации RetryFunc.

Управляемый экземпляр Azure SQL

Управляемый экземпляр SQL Azure поддерживает те же функции драйверов, что и локальный SQL Server, с некоторыми отличиями:

Функция База данных SQL Azure Управляемый экземпляр Azure SQL
Агент SQL Server Недоступно Available
Межбазовые запросы Недоступно Available
Связанные серверы Недоступно Available
Именованные каналы Недоступно Недоступно (только TCP)
Общая память Недоступно Недоступно (только TCP)
Проверка подлинности Windows (SSPI) Недоступно Доступно в управляемом VNet

Подключитесь к Управляемый экземпляр:

sqlserver://<user>:<password>@<instance>.database.windows.net?database=<database>&encrypt=true&TrustServerCertificate=false

База данных SQL в Microsoft Fabric

Important

База данных SQL в Fabric требует проверки подлинности с помощью Microsoft Entra ID. Аутентификация SQL Server не поддерживается.

Для производственных нагрузок предпочтителен явный режим fedauth вместо ActiveDirectoryDefault, чтобы избежать накладных расходов на проверку цепочки учетных данных при установлении новых соединений.

SQL база данных в Fabric поддерживает драйвер go-mssqldb с аутентификацией Microsoft Entra ID:

db, err := sql.Open("azuresql",
    "sqlserver://<server>.database.fabric.microsoft.com?database=<database>&fedauth=ActiveDirectoryDefault&encrypt=true&TrustServerCertificate=false")
if err != nil {
    panic(err)
}

Рекомендации по повышению производительности Azure SQL

Tip Сведения
Использование пула соединений Azure SQL засчитывает каждое открытое соединение в лимит уровня обслуживания. Поддерживайте MaxOpenConns в заданных пределах.
Включите encrypt=strict Для самой высокой безопасности используйте шифрование TDS 8.0: encrypt=strict. База данных SQL Azure поддерживает строгий режим.
Используйте ApplicationIntent=ReadOnly Направляйте запросы с преобладанием операций чтения на реплики для чтения: ApplicationIntent=ReadOnly. Доступен на уровнях Premium, Business Critical и Hyperscale.
Мониторинг использования DTU/vCore Высокая загрузка CPU, I/O или рабочих процессов указывает на то, что ваш тарифный план может быть недостаточным. Используйте Azure Monitor для отслеживания использования ресурсов.
Держите транзакции короткими Azure SQL завершает сессии с транзакциями, превышающими пороги ресурсов (ошибка 40549).
Использование региональных конечных точек Разместите приложение в том же регионе Azure, что и база данных, чтобы минимизировать задержки.

Контрольный список по устранению неполадок Azure SQL

Симптом Вероятно, причина Solution
Cannot open server Отсутствует правило межсетевого экрана Добавьте свой IP или включите доступ к сервисам Azure.
Login failed Неправильные учетные данные или отсутствующий пользователь базы данных Проверьте, что логин существует и имеет доступ к базе данных.
Тайм-аут соединений происходит периодически Перенастройка сервера или резервное подключение Реализуйте логику повторных попыток и ротацию соединений.
Resource limit reached Слишком много одновременных соединений Быстро снижайте MaxOpenConns и закрывайте соединения.
The service is currently busy Azure SQL throttling Повторите попытку с экспоненциальной задержкой. Подумайте о масштабировании.
Медленные запросы после того, как до этого работали нормально Исчерпание ресурсов DTU/vCore Проверьте метрики Azure Monitor. Масштабируйте или оптимизируйте запросы.