Verwenden von go-mssqldb mit Azure SQL-Datenbank

Der Treiber go-mssqldb unterstützt die Verbindung mit Azure SQL-Datenbank, Azure SQL Managed Instance und SQL Database in Microsoft Fabric. Dieser Artikel behandelt Azure-spezifische Konfigurationen, Authentifizierung, Verbindungsgrenzen und Fehlerbehebung, die sich vom lokalen SQL Server unterscheiden.

Herstellen einer Verbindung mit Azure SQL-Datenbank

Azure SQL-Datenbank benötigt standardmäßig verschlüsselte Verbindungen. Spezifiziere encrypt=true und TrustServerCertificate=false explizit so, dass die Verbindung TLS verwendet und das Serverzertifikat validiert:

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

Hinweis

Wenn du weglässtencrypt, fügt der Treiber nicht automatisch Azure-spezifische TLS-Einstellungen hinzu. encrypt=true&TrustServerCertificate=false in Azure SQL-Verbindungszeichenfolgen beibehalten.

Die Microsoft Entra ID-Authentifizierung entfernt Passwörter aus Ihren Verbindungszeichenketten. ActiveDirectoryDefault Wählt automatisch die beste verfügbare Zugangsberechtigung für die Umgebung aus, was die Entwicklung erleichtert:

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()
}

Von Bedeutung

ActiveDirectoryDefault ist praktisch für die Entwicklung, aber es kann die Verbindungslatenz erhöhen, da es mehrere Zugangsquellen prüft. Für Produktionsdienste bevorzugen Sie eine explizite Methode wie ActiveDirectoryManagedIdentity oder ActiveDirectoryServicePrincipal.

Wie ActiveDirectoryDefault Zugangsdaten auflöst

ActiveDirectoryDefault Versucht die folgenden Zugangsquellen der Reihe nach und verwendet die erste, die erfolgreich ist:

Bestellung Referenzquelle Typische Umgebung
1 Umweltvariablen (AZURE_CLIENT_ID, AZURE_TENANT_ID, ) AZURE_CLIENT_SECRET CI/CD-Pipelines, Docker-Container
2 Workload-Identität Kubernetes-Pods mit Azure Workload Identity
3 Verwaltete Identität Azure VMs, App Service, Container Apps, Azure Functions
4 Azure CLI (az login) Lokale Entwicklung
5 Azure Developer CLI (azd auth login) Lokale Entwicklung

Diese Anmeldeinformationskette macht die Verwendung von ActiveDirectoryDefault während der Entwicklung einfach, aber die sequenzielle Überprüfung führt bei jeder neuen Verbindung zu zusätzlicher Latenz. Für die Produktion geben Sie die genaue Authentifizierungsmethode (wie ActiveDirectoryManagedIdentity) an, damit der Treiber unnötige Überprüfungen überspringt.

Anwendungen, die in Azure gehostet werden (App Service, Container Apps, Azure Functions oder Azure VMs), sollten eine verwaltete Identität mit einem expliziten fedauth Wert verwenden. Dieser Ansatz vermeidet den Credential-Chain-Overhead und eliminiert jegliche Abhängigkeit von Umgebungsvariablen oder CLI-Zuständen.

Vom System zugewiesene verwaltete Identität:

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

Benutzerzugewiesene verwaltete Identität (geben Sie die Client-ID an):

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

Gewähren Sie den Identitätszugriff in der Datenbank

Nachdem Sie die verwaltete Identität auf der Azure-Ressource konfiguriert haben, erstellen Sie einen integrierten Datenbankbenutzer:

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];

Für systemzugewiesene Identitäten verwenden Sie den Azure-Ressourcennamen. Für benutzerdefinierte Identitäten verwenden Sie den Identitätsnamen.

Serviceprinzip für Automatisierung

Für CI/CD-Pipelines oder Service-to-Service-Authentifizierung:

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

Für alle Zugangsdaten siehe Microsoft Entra ID Authentifizierung.

Konfigurieren der Azure-Firewall

Azure SQL-Datenbank verwendet eine Server-Level-Firewall. Sie müssen die öffentliche IP-Adresse Ihres Kunden zulassen oder einen privaten Endpunkt verwenden.

Fehler: Server kann nicht geöffnet werden

Diese Fehlermeldung zeigt an, dass die Azure-Firewall Ihre Client-IP-Adresse blockiert:

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

Lösungen :

  1. Füge eine Firewall-Regel im Azure-Portal hinzu: SQL Server>Networking>Füge eine Firewall-Regel hinzu.
  2. Aktivieren Sie den Zugriff auf Azure-Dienste und -Ressourcen auf diesen Server, wenn Ihre Anwendung in Azure läuft.
  3. Für die private Verbindung konfigurieren Sie einen privaten Endpunkt.

Fehler: Verbindung ist ausgelaufen

Wenn die Verbindung ohne klaren Fehler abläuft, blockiert die Firewall die Verbindung wahrscheinlich stillschweigend. Überprüfe zuerst die Firewall-Regeln.

Verbindungsgrenzen nach Dienststufe

Azure SQL-Datenbank erzwingt Verbindungslimits pro Datenbank basierend auf der Service-Schicht. Das Überschreiten des Limits führt zu Authentifizierungsfehlern bei neuen Verbindungen. Die vollständigen Grenzwerttabellen finden Sie unter DTU-Ressourcengrenzwerte für einzelne Datenbanken und vCore-Ressourcengrenzwerte für einzelne Datenbanken.

Setze MaxOpenConns so ein, dass sie zu deiner Stufe passen

Setze MaxOpenConns immer einen Wert unterhalb des Verbindungslimits für dein Azure SQL-Tier:

// 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

Wenn mehrere Anwendungen dieselbe Datenbank teilen, teilen Sie das Verbindungslimit auf alle Anwendungen auf. Wenn zum Beispiel drei Dienste eine S2-Datenbank teilen (maximal 60 Arbeitskräfte), werden 15–20 Verbindungen pro Dienst zugewiesen.

Azure SQL-Drosselung behandeln

Die Azure SQL-Datenbank kann Verbindungen und Abfragen drosseln, wenn die Datenbank Ressourcengrenzen (CPU, IO, Speicher oder Sitzungsanzahl) erreicht. Drosselung äußert sich in bestimmten Fehlernummern.

Häufige Drosselungsfehler

Fehlernummer Nachrichtenmuster Ursache
10928 Resource ID: %d. The %s limit for the database is %d and has been reached. Sitzungs- oder Mitarbeiterlimit erreicht.
10929 Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d. Ressourcenkontrolle Drosselung.
40501 The service is currently busy. Allgemeine Drosselung. Wiederholen.
40544 The database has reached its size quota. Datenbankgrößengrenze erreicht. Erhöhe die Kapazität oder den freien Platz, bevor du es erneut versuchst.
40549 Session is terminated because you have a long-running transaction. Die Transaktion hat das Zeitlimit überschritten.
40550 Session is terminated because of too many locks. Übermäßiges Lösen von Schlossen.
40551 Session is terminated because of excessive tempdb usage. Übermäßige Nutzung von tempdb.
40552 Session is terminated because of excessive transaction log usage. Der Transaktionsprotokollplatz wurde überschritten.
40553 Session is terminated because of excessive memory usage. Übermäßiger Speicherverbrauch.
40613 Database '%.*ls' on server '%.*ls' is not currently available. Datenbank wird verschoben oder neu konfiguriert.
49918 Cannot process request. Not enough resources to process request. Ressourcenauslastung.
49919 Cannot process create or update request. Zu viele gleichzeitige Erstellungs-/Aktualisierungsoperationen.
49920 Cannot process request. Too many operations in progress. Limit für gleichzeitige Vorgänge erreicht.

Erneute Drosselungsanfragen

Die meisten Azure SQL-Throttling- und Verfügbarkeitsfehler in der vorangegangenen Tabelle sind vorübergehend und sollten mit exponentiellem Backoff erneut versucht werden. Der Fehler 40544 ist nicht vorübergehend. Das bedeutet, dass die Datenbank ihre Größenquote erreicht hat, sodass die Operation erst erfolgreich ist, wenn man die Datenbank hochskaliert oder Daten löscht.

Für eine vollständige Retry-Implementierung siehe Fehlerbehandlung und Retry-Patterns.

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
}

Verbindungsresilienz

Azure SQL-Datenbank konfiguriert gelegentlich Server für Updates, Failovers und Lastverteilung neu. Diese Ereignisse lassen bestehende Verbindungen fallen, die als driver: bad connection Fehler sichtbar werden. Konfigurieren Sie Ihren Pool so, dass er sich automatisch wiederherstellt:

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.

Hinweis

Das Azure SQL-Gateway schließt Verbindungen, die etwa 30 Minuten lang im Leerlauf sind. Setzen Sie ConnMaxIdleTime deutlich unter diesen Schwellenwert, um driver: bad connection Fehler bei der ersten Abfrage nach einer Phase der Inaktivität zu vermeiden. Bei nicht transaktionalen Aufrufen versucht database/sql automatisch eine Wiederholung über eine neue Verbindung. Bei transaktionalen Aufrufen muss Ihr Code den Fehler erkennen und die gesamte Transaktion erneut versuchen.

Wiederverbindung nach Failover

Außerhalb von Transaktionen kann database/sql einen Aufruf, der über eine fehlerhafte Verbindung gestartet wird, transparent wiederholen, wenn der Treiber die Verbindung als unbrauchbar markiert. Dieses Verhalten ist keine vollwertige Wiederholungsrichtlinie für vorübergehende Fehler bei Drosselung, Failover oder anderen SQL-Fehlern, bei denen ein erneuter Versuch möglich ist. Packen Sie Ihre Datenbankaufrufe in eine Retry-Funktion ein, um diese Szenarien zu handhaben:

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

Siehe Fehlerbehandlung und Wiederholungsmuster für die RetryFunc Implementierung.

Verwaltete Azure SQL-Instanz

Azure SQL Managed Instance unterstützt dieselben Treiberfunktionen wie der lokale SQL Server, mit einigen Unterschieden:

Funktion Azure SQL-Datenbank Verwaltete Azure SQL-Instanz
SQL Server-Agent-Dienst Nicht verfügbar Available
Datenbankübergreifende Abfragen Nicht verfügbar Available
Verknüpfte Server Nicht verfügbar Available
Named Pipes Nicht verfügbar Nicht verfügbar (nur TCP)
Gemeinsamer Speicher Nicht verfügbar Nicht verfügbar (nur TCP)
Windows Authentication (SSPI) Nicht verfügbar Verfügbar im verwalteten VNet

Verbinden Sie sich mit einer verwaltete Instanz:

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

SQL-Datenbank in Microsoft Fabric

Von Bedeutung

Die SQL-Datenbank in Fabric erfordert eine Microsoft Entra ID-Authentifizierung. SQL Server-Authentifizierung wird nicht unterstützt.

Für Produktionsworkloads sollte ein expliziter fedauth-Modus anstelle von ActiveDirectoryDefault verwendet werden, um den Overhead durch das Prüfen der Anmeldeinformationskette bei neuen Verbindungen zu vermeiden.

Die SQL-Datenbank in Fabric unterstützt den go-mssqldb Treiber mit Microsoft Entra ID-Authentifizierung:

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-Leistungstipps

Tip Details
Verbindungspooling verwenden Azure SQL zählt jede offene Verbindung zum Tier-Limit. Halten Sie MaxOpenConns begrenzt.
Aktivieren von encrypt=strict Für die stärkste Sicherheit verwenden Sie TDS 8.0-Verschlüsselung: encrypt=strict. Azure SQL-Datenbank unterstützt den strengen Modus.
ApplicationIntent=ReadOnly verwenden Leiten Sie leseintensive Abfragen an Lesereplikate weiter: ApplicationIntent=ReadOnly. Verfügbar auf Premium-, Business Critical- und Hyperscale-Stufen.
DTU/vCore-Nutzung überwachen Hoher CPU-, IO- oder Worker-Verbrauch deutet darauf hin, dass deine Stufe möglicherweise unterdimensioniert ist. Verwenden Sie Azure Monitor, um die Ressourcennutzung zu verfolgen.
Halten Sie die Transaktionen kurz Azure SQL beendet Sitzungen mit Transaktionen, die die Ressourcenschwellenwerte überschreiten (Fehler 40549).
Verwenden von regionalen Endpunkten Platziere deine Anwendung in derselben Azure-Region wie die Datenbank, um die Latenz zu minimieren.

Checkliste zur Problembehandlung für Azure SQL

Symptom Wahrscheinliche Ursache Lösung
Cannot open server Firewall-Regel fehlt Füge deine IP hinzu oder aktiviere den Zugriff auf Azure-Dienste.
Login failed Falsche Zugangsdaten oder fehlender Datenbankbenutzer Überprüfen Sie, ob der Login existiert und Datenbankzugriff bietet.
Verbindungen werden intermittierend ausgeblendet Server-Neukonfiguration oder Failover Implementiere Retry-Logik und Verbindungsrotation.
Resource limit reached Zu viele gleichzeitige Verbindungen Senken Sie MaxOpenConns und schließen Sie Verbindungen umgehend.
The service is currently busy Azure SQL-Drosselung Wiederholen Sie den Vorgang mit exponentiellem Backoff. Erwäge eine Hochskalierung.
Langsame Abfragen nach zuvor einwandfreier Funktion DTU-/vCore-Auslastung Überprüfen Sie die Azure Monitor-Metriken. Skalieren Sie Abfragen hoch oder optimieren Sie sie.