Java-Anwendungen mit IAM-Authentifizierung mit AlloyDB for PostgreSQL verbinden

1. Hinweis

Java und AlloyDB: Einfache, sichere Verbindung

AlloyDB for PostgreSQL ist der vollständig verwaltete, PostgreSQL-kompatible Datenbankdienst von Google Cloud für anspruchsvolle Unternehmensarbeitslasten. Eine sichere und effiziente Verbindung einer Java-Anwendung mit AlloyDB wird über den AlloyDB-Java-Connector (alloydb-jdbc-connector) hergestellt, eine Clientbibliothek, die über einen Standard-JDBC-Treiber hinausgeht.

Die Magie des AlloyDB-Java-Connectors

Der alloydb-jdbc-connector fungiert als intelligenter SocketFactory für den standardmäßigen PostgreSQL-JDBC-Treiber (org.postgresql:postgresql). Er abstrahiert die Einrichtung einer sicheren Datenbankverbindung, sodass Sie sich auf die Anwendungslogik statt auf die Netzwerksicherheit oder die Rotation von Anmeldedaten konzentrieren können:

  • mTLS 1.3-Verschlüsselung: Es wird automatisch eine gegenseitig authentifizierte TLS 1.3-Verbindung zwischen Ihrer JVM und der AlloyDB-Instanz hergestellt, ohne dass Sie SSL/TLS-Clientzertifikate manuell verwalten müssen.
  • IAM-basierte Autorisierung: Anstatt sich auf statische Datenbankpasswörter zu verlassen, nutzt der Connector Google Cloud IAM und Standardanmeldedaten für Anwendungen, um automatisch kurzlebige OAuth2-Zugriffstokens abzurufen.
  • Dynamische IP-Auflösung: Fragt die AlloyDB Admin API ab, um die aktuelle IP-Adresse (PRIVATE, PUBLIC oder Private Service Connect PSC) Ihrer Datenbankinstanz dynamisch aufzulösen. Sie müssen keine Hostnamen oder IP-Adressen hartcodieren, sodass Failover und Wartung transparent sind.

So funktioniert der AlloyDB-Java-Connector im Hintergrund

Vorbereitung

  • Kenntnisse über Java, Maven und grundlegende SQL-/JDBC-Konzepte.
  • Grundlegende Kenntnisse der Google Cloud CLI (gcloud) und von IAM-Rollen.

Aufgaben

  • Konfigurieren Sie eine AlloyDB-Instanz und ein Dienstkonto für die passwortlose IAM-Datenbankauthentifizierung.
  • Gewähren Sie einem IAM-Hauptkonto PostgreSQL-Schema- und Tabellenberechtigungen nach dem Prinzip der geringsten Berechtigung.
  • Konfigurieren Sie eine produktionsreife DataSource mit Plain JDBC und HikariCP mithilfe des AlloyDB-SocketFactory.
  • Integrieren Sie den AlloyDB-Java-Connector in Spring Boot-, Quarkus- und Micronaut-Anwendungen.
  • Registrieren Sie den AlloyDB-SocketFactory für die GraalVM Native Image-Kompilierung und beheben Sie häufige IAM-Authentifizierungsprobleme.

Voraussetzungen

  • Ein Google Cloud-Projekt mit aktivierter Abrechnung und einem aktiven AlloyDB-Cluster und einer primären Instanz (siehe Anleitung zum Erstellen eines AlloyDB-Clusters oder Erstellen eines AlloyDB Express-Clusters in weniger als zwei Sekunden).
  • Die IAM-Rollen roles/alloydb.admin und roles/resourcemanager.projectIamAdmin in Ihrem Projekt.
  • Java 17 oder höher (Java 17 oder 21 LTS empfohlen) und Apache Maven installiert.
  • gcloud-CLI und psql-Client installiert (oder Zugriff auf Google Cloud Shell).

2. IAM-Datenbankauthentifizierung in AlloyDB einrichten

Bevor Sie Java-Code schreiben, müssen Sie Ihre AlloyDB-Instanz so konfigurieren, dass sie IAM-Tokens akzeptiert. Außerdem müssen Sie die IAM-Identität erstellen, die Ihre Anwendung auf drei Ebenen verwendet: Google Cloud IAM, die AlloyDB-Steuerungsebene und die PostgreSQL-Engine.

Dreistufige Einrichtung für die AlloyDB-IAM-Datenbankauthentifizierung

Umgebungsvariablen festlegen

Exportieren Sie in Ihrem Terminal die Variablen, die Ihrem Google Cloud-Projekt und Ihrer AlloyDB-Instanz entsprechen. Ersetzen Sie dabei die Platzhalter durch Ihre Werte:

export PROJECT_ID="<PROJECT_ID>"
export REGION="europe-west1"
export CLUSTER_ID="<CLUSTER_ID>"
export INSTANCE_ID="<INSTANCE_ID>"
export DB_NAME="dvdrental"

Erforderliche APIs aktivieren

Aktivieren Sie die AlloyDB, Compute Engine, Cloud Resource Manager, IAM und Service Usage APIs in Ihrem Projekt:

gcloud services enable \
    alloydb.googleapis.com \
    compute.googleapis.com \
    cloudresourcemanager.googleapis.com \
    iam.googleapis.com \
    serviceusage.googleapis.com \
    --project="${PROJECT_ID}"

Dienstkonto erstellen und IAM-Rollen zuweisen

Erstellen Sie ein dediziertes Dienstkonto, das als Identität Ihrer Java-Anwendung dient:

gcloud iam service-accounts create java-alloydb-connector \
    --project="${PROJECT_ID}" \
    --display-name="Java Application DB Connector"

Weisen Sie dem Dienstkonto die beiden IAM-Rollen zu, die für den AlloyDB-Java-Connector erforderlich sind:

  1. roles/alloydb.client: Erforderlich, um Instanzmetadaten abzurufen und sitzungsspezifische mTLS-Zertifikate von der AlloyDB Admin API anzufordern.
  2. roles/serviceusage.serviceUsageConsumer: Erforderlich für die IAM-Datenbankauthentifizierung.
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/alloydb.client"

gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/serviceusage.serviceUsageConsumer"

IAM-Authentifizierung für die AlloyDB-Instanz aktivieren

Aktualisieren Sie die AlloyDB-Instanz-Flags, um alloydb.iam_authentication=on festzulegen. Dies ist ein dynamisches Flag, das sofort wirksam wird, ohne dass die Instanz neu gestartet werden muss:

gcloud alloydb instances update "${INSTANCE_ID}" \
    --cluster="${CLUSTER_ID}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --database-flags=alloydb.iam_authentication=on

IAM-Datenbanknutzer registrieren

Registrieren Sie das Dienstkonto mit gcloud als IAM_BASED-Datenbanknutzer in Ihrem AlloyDB-Cluster:

gcloud alloydb users create "java-alloydb-connector@${PROJECT_ID}.iam" \
    --cluster="${CLUSTER_ID}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --type=IAM_BASED

PostgreSQL-Schema- und Tabellenberechtigungen gewähren

Neu erstellte IAM-Datenbanknutzer haben standardmäßig keine Tabellenberechtigungen. Stellen Sie als postgres-Administrator (über psql oder AlloyDB Studio in der Cloud Console) eine Verbindung zu Ihrer AlloyDB-Instanz her und gewähren Sie Zugriff auf Ihre Zieldatenbank und -tabellen (z. B. die DVD Rental-Beispieldatenbank):

-- Connect to your target database first
\c dvdrental

-- (Optional) Create a sample film table if your database is empty
CREATE TABLE IF NOT EXISTS public.film (
    film_id SERIAL PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    release_year INTEGER DEFAULT 2006,
    rating VARCHAR(10) DEFAULT 'PG',
    rental_rate NUMERIC(4,2) DEFAULT 2.99
);

INSERT INTO public.film (film_id, title, release_year, rating, rental_rate) VALUES
    (1, 'Academy Dinosaur', 2006, 'PG', 0.99),
    (2, 'Ace Goldfinger', 2006, 'G', 4.99),
    (3, 'Adaptation Holes', 2006, 'NC-17', 2.99),
    (4, 'Affair Prejudice', 2006, 'G', 2.99),
    (5, 'African Egg', 2006, 'G', 2.99)
ON CONFLICT (film_id) DO NOTHING;

-- Grant permissions to the IAM user (double quotes are required because of '@' and '.')
GRANT CONNECT ON DATABASE "dvdrental" TO "java-alloydb-connector@<PROJECT_ID>.iam";
GRANT USAGE ON SCHEMA public TO "java-alloydb-connector@<PROJECT_ID>.iam";
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO "java-alloydb-connector@<PROJECT_ID>.iam";

Wenn Sie diese Anweisungen in AlloyDB Studio (oder psql) ausführen, können Sie das Schema public.film prüfen und die Beispielzeilen verifizieren:

IAM-Berechtigungen gewähren und „public.film“ in AlloyDB Studio prüfen

Lokale Standardanmeldedaten für Anwendungen (Application Default Credentials, ADC) konfigurieren

Wenn Sie Cloud Run, Google Kubernetes Engine (GKE) oder Compute Engine verwenden, hängen Sie das java-alloydb-connector-Dienstkonto direkt an die Arbeitslast an. Wenn Sie die Anwendung lokal auf Ihrer Workstation ausführen, übernehmen Sie die Identität des Dienstkontos, damit ADC Tokens für diese Identität erstellt:

gcloud auth application-default login \
    --impersonate-service-account="java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com"

3. Verbindung mit Plain JDBC und HikariCP herstellen

Für jede produktionsreife Java-Anwendung ist ein Verbindungspool unerlässlich. HikariCP ist der Branchenstandard. In diesem Schritt erstellen Sie eine einfache JDBC- und HikariCP-Anwendung, die die Socket-Erstellung an com.google.cloud.alloydb.SocketFactory delegiert.

Maven-Projekt erstellen (pom.xml)

Erstellen Sie ein neues Verzeichnis jdbc-app mit einer pom.xml-Datei, die den PostgreSQL-JDBC-Treiber (42.7.14), den AlloyDB-Java-Connector (1.4.0) und HikariCP (7.1.0) enthält:

mkdir -p jdbc-app/src/main/java
cd jdbc-app

pom.xml erstellen:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example.alloydb</groupId>
    <artifactId>alloydb-jdbc-sample</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <exec.mainClass>AlloyDBConnectivity</exec.mainClass>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.7.14</version>
        </dependency>

        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>alloydb-jdbc-connector</artifactId>
            <version>1.4.0</version>
        </dependency>

        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>7.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>2.0.16</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.5.0</version>
                <configuration>
                    <cleanupDaemonThreads>false</cleanupDaemonThreads>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

AlloyDBConnectivity.java erstellen

Erstellen Sie src/main/java/AlloyDBConnectivity.java (auf GitHub Gist ansehen):

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class AlloyDBConnectivity {
    // Retrieve configuration from environment variables
    private static final String ALLOYDB_INSTANCE_URI = System.getenv("ALLOYDB_INSTANCE_NAME"); // e.g., projects/<PROJECT_ID>/locations/<REGION>/clusters/<CLUSTER_ID>/instances/<INSTANCE_ID>
    private static final String ALLOYDB_DB_NAME = System.getenv("ALLOYDB_DB"); // e.g., "dvdrental"
    private static final String ALLOYDB_USER = System.getenv("ALLOYDB_USER"); // e.g., "java-alloydb-connector@<PROJECT_ID>.iam"
    private static final String ALLOYDB_PASS = System.getenv("ALLOYDB_PASS"); // Database password if not using IAM auth

    public static HikariDataSource createDataSource() {
        HikariConfig config = new HikariConfig();

        // The JDBC URL does not need a host or port. The SocketFactory will resolve the IP address.
        config.setJdbcUrl(String.format("jdbc:postgresql:///%s", ALLOYDB_DB_NAME));
        config.setUsername(ALLOYDB_USER);

        // Only set the password if you are NOT using IAM authentication.
        if (System.getenv("ALLOYDB_ENABLE_IAM_AUTH") == null || !System.getenv("ALLOYDB_ENABLE_IAM_AUTH").equalsIgnoreCase("true")) {
            config.setPassword(ALLOYDB_PASS);
        }

        // 1. Set the SocketFactory to the AlloyDB Connector's implementation.
        config.addDataSourceProperty("socketFactory", "com.google.cloud.alloydb.SocketFactory");

        // 2. Tell the connector which AlloyDB instance to connect to.
        config.addDataSourceProperty("alloydbInstanceName", ALLOYDB_INSTANCE_URI);

        // 3. (Recommended) Enable IAM database authentication.
        if (System.getenv("ALLOYDB_ENABLE_IAM_AUTH") != null && System.getenv("ALLOYDB_ENABLE_IAM_AUTH").equalsIgnoreCase("true")) {
            config.addDataSourceProperty("alloydbEnableIAMAuth", "true");
        }

        // 4. (Optional) Specify IP type (e.g., "PRIVATE", "PUBLIC", "PSC"). Defaults to PRIVATE.
        String ipType = System.getenv("ALLOYDB_IP_TYPE");
        if (ipType != null) {
            config.addDataSourceProperty("alloydbIpType", ipType);
        }

        // Baseline HikariCP settings
        config.setMaximumPoolSize(10);
        config.setMinimumIdle(2);
        config.setConnectionTimeout(30000); // 30 seconds
        config.setIdleTimeout(600000);      // 10 minutes
        config.setMaxLifetime(1800000);     // 30 minutes

        return new HikariDataSource(config);
    }

    public static void main(String[] args) {
        String sql = "SELECT title, release_year FROM public.film ORDER BY film_id LIMIT 5";

        try (HikariDataSource pool = createDataSource();
             Connection conn = pool.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql);
             ResultSet rs = stmt.executeQuery()) {
            System.out.println("Successfully connected to AlloyDB via IAM! Sample films:");
            while (rs.next()) {
                System.out.printf(" - %s (%d)%n", rs.getString("title"), rs.getInt("release_year"));
            }
        } catch (SQLException e) {
            System.err.println("Database connection failed: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Aufbau einer AlloyDB-JDBC-URL und HikariCP-Konfiguration

Einfache JDBC-Anwendung ausführen

Exportieren Sie die Umgebungsvariablen für Ihre AlloyDB-Instanz (legen Sie ALLOYDB_IP_TYPE="PUBLIC" fest, wenn Sie von außerhalb Ihrer VPC über eine öffentliche IP-Adresse eine Verbindung herstellen, oder "PRIVATE" / "PSC", wenn Sie sich innerhalb der VPC befinden) und führen Sie die Anwendung aus:

export ALLOYDB_INSTANCE_NAME="projects/${PROJECT_ID}/locations/${REGION}/clusters/${CLUSTER_ID}/instances/${INSTANCE_ID}"
export ALLOYDB_DB="${DB_NAME}"
export ALLOYDB_USER="java-alloydb-connector@${PROJECT_ID}.iam"
export ALLOYDB_ENABLE_IAM_AUTH="true"
export ALLOYDB_IP_TYPE="PRIVATE" # Set to PUBLIC if connecting over Public IP from a local laptop

mvn compile exec:java

Die Ausgabe sollte etwa so aussehen:

[AlloyDBConnectivity.main()] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
[AlloyDBConnectivity.main()] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@1998bf07
[AlloyDBConnectivity.main()] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
Successfully connected to AlloyDB via IAM! Sample films:
 - Academy Dinosaur (2006)
 - Ace Goldfinger (2006)
 - Adaptation Holes (2006)
 - Affair Prejudice (2006)
 - African Egg (2006)

Terminalausgabe des Beispiels für Plain JDBC und HikariCP

4. Mit Spring Boot verbinden

Spring Boot vereinfacht die Datenbankverbindung, indem automatisch ein HikariCP-Verbindungspool aus Ihren Anwendungseigenschaften konfiguriert wird. Für die Einbindung des AlloyDB-Java-Connectors ist kein benutzerdefinierter DataSource-Bean-Code erforderlich.

Spring Boot-Projekt erstellen (pom.xml)

Erstellen Sie ein neues Verzeichnis spring-boot-app:

cd ..
mkdir -p spring-boot-app/src/main/java/com/example/alloydb
mkdir -p spring-boot-app/src/main/resources
cd spring-boot-app

Erstellen Sie pom.xml mit spring-boot-starter-jdbc (einschließlich HikariCP), org.postgresql:postgresql und com.google.cloud:alloydb-jdbc-connector:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>4.0.5</version>
        <relativePath/>
    </parent>

    <groupId>com.example.alloydb</groupId>
    <artifactId>alloydb-spring-boot-sample</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.7.14</version>
        </dependency>

        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>alloydb-jdbc-connector</artifactId>
            <version>1.4.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

application.properties oder Umgebungsvariablen konfigurieren

Sie können die Verbindungs-URL in src/main/resources/application.properties konfigurieren:

# No host or port is needed; the SocketFactory handles it.
spring.datasource.url=jdbc:postgresql:///dvdrental?socketFactory=com.google.cloud.alloydb.SocketFactory&alloydbInstanceName=projects/<PROJECT_ID>/locations/<REGION>/clusters/<CLUSTER_ID>/instances/<INSTANCE_ID>&alloydbEnableIAMAuth=true
spring.datasource.username=java-alloydb-connector@<PROJECT_ID>.iam
# No password required when alloydbEnableIAMAuth is true

Wenn Sie Ihre Quelldateien vollständig frei von Projekt-IDs oder Instanznamen halten möchten, können Sie application.properties leer lassen und diese Standard-Spring Boot-Umgebungsvariablen zur Laufzeit angeben:

Umgebungsvariable

Wert

SPRING_DATASOURCE_URL

jdbc:postgresql:///dvdrental?socketFactory=com.google.cloud.alloydb.SocketFactory&alloydbInstanceName=projects//locations//clusters//instances/&alloydbEnableIAMAuth=true

SPRING_DATASOURCE_USERNAME

java-alloydb-connector@.iam

AlloyDbTestApplication.java erstellen

Erstellen Sie src/main/java/com/example/alloydb/AlloyDbTestApplication.java (auf GitHub Gist ansehen):

package com.example.alloydb;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;

@SpringBootApplication
public class AlloyDbTestApplication {

    public static void main(String[] args) {
        System.exit(SpringApplication.exit(SpringApplication.run(AlloyDbTestApplication.class, args)));
    }

    @Bean
    CommandLineRunner testConnection(JdbcTemplate jdbcTemplate) {
        return args -> {
            String result = jdbcTemplate.queryForObject("SELECT 'Connection Successful!'", String.class);
            System.out.println(">>> ALLOYDB STATUS: " + result);
        };
    }
}

Spring Boot-Anwendung ausführen

Exportieren Sie die Umgebungsvariablen und führen Sie die Anwendung mit mvn spring-boot:run aus:

export SPRING_DATASOURCE_URL="jdbc:postgresql:///${DB_NAME}?socketFactory=com.google.cloud.alloydb.SocketFactory&alloydbInstanceName=projects/${PROJECT_ID}/locations/${REGION}/clusters/${CLUSTER_ID}/instances/${INSTANCE_ID}&alloydbEnableIAMAuth=true"
export SPRING_DATASOURCE_USERNAME="java-alloydb-connector@${PROJECT_ID}.iam"

mvn spring-boot:run

Hier sollten Sie dies sehen:

>>> ALLOYDB STATUS: Connection Successful!

Spring Boot-Autokonfiguration und Live-Ausführungsausgabe

5. Verbindung mit Quarkus, Micronaut und GraalVM Native Image herstellen

Da der AlloyDB-Java-Connector auf der JDBC-Treiberebene arbeitet, ändert sich beim Wechsel zwischen cloudnativen Java-Frameworks nichts daran, wie Sie den Datenbank-Traffic sichern oder Identitäten verwalten. Sowohl Quarkus als auch Micronaut umschließen den zugrunde liegenden JDBC-Treiber und delegieren die mTLS-Verschlüsselung, die dynamische IP-Auflösung und die IAM-Authentifizierung über ADC an den Connector.

Cloudnative Java-Frameworks und GraalVM Native Image mit AlloyDB

Quarkus-Konfiguration (application.properties mit Agroal)

Fügen Sie in einer Quarkus-Anwendung (quarkus-agroal und quarkus-jdbc-postgresql) com.google.cloud:alloydb-jdbc-connector:1.4.0 zu Ihren Abhängigkeiten hinzu und übergeben Sie die Connector-Parameter über quarkus.datasource.jdbc.additional-jdbc-properties in src/main/resources/application.properties:

quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=java-alloydb-connector@<PROJECT_ID>.iam
quarkus.datasource.jdbc.url=jdbc:postgresql:///dvdrental
quarkus.datasource.jdbc.additional-jdbc-properties.socketFactory=com.google.cloud.alloydb.SocketFactory
quarkus.datasource.jdbc.additional-jdbc-properties.alloydbInstanceName=projects/<PROJECT_ID>/locations/<REGION>/clusters/<CLUSTER_ID>/instances/<INSTANCE_ID>
quarkus.datasource.jdbc.additional-jdbc-properties.alloydbEnableIAMAuth=true

Micronaut-Konfiguration (application.yml mit HikariCP)

Fügen Sie in einer Micronaut-Anwendung (micronaut-jdbc-hikari) com.google.cloud:alloydb-jdbc-connector:1.4.0 hinzu und konfigurieren Sie src/main/resources/application.yml:

datasources:
  default:
    url: jdbc:postgresql:///dvdrental?socketFactory=com.google.cloud.alloydb.SocketFactory&alloydbInstanceName=projects/<PROJECT_ID>/locations/<REGION>/clusters/<CLUSTER_ID>/instances/<INSTANCE_ID>&alloydbEnableIAMAuth=true
    username: java-alloydb-connector@<PROJECT_ID>.iam
    driver-class-name: org.postgresql.Driver

Connector für GraalVM Native Image registrieren

Wenn Sie Ihre Anwendung in ein natives GraalVM-Image (mit Spring Boot 3+, Quarkus oder Micronaut) kompilieren, gibt es ein wichtiges Detail: Reflection.

Der PostgreSQL-JDBC-Treiber instanziiert com.google.cloud.alloydb.SocketFactory dynamisch anhand des Klassennamens mithilfe von Reflexion. Damit die statische Analyse von GraalVM die Klasse während der nativen Kompilierung nicht entfernt, registrieren Sie sie explizit:

  • Spring Boot 3 oder höher: Fügen Sie @RegisterReflectionForBinding(com.google.cloud.alloydb.SocketFactory.class) zu Ihrer Hauptanwendung oder @Configuration-Klasse hinzu:
    @SpringBootApplication
    @RegisterReflectionForBinding(com.google.cloud.alloydb.SocketFactory.class)
    public class AlloyDbTestApplication { ... }
    
  • Quarkus: Fügen Sie @RegisterForReflection(targets = com.google.cloud.alloydb.SocketFactory.class) zu Ihrer Hauptklasse oder einer CDI-Bean hinzu:
    @QuarkusMain
    @RegisterForReflection(targets = com.google.cloud.alloydb.SocketFactory.class)
    public class QuarkusAlloyDbApp implements QuarkusApplication { ... }
    

6. Häufige IAM- und Verbindungsprobleme beheben

Wenn ein FATAL: password authentication failed for user- oder AlloyDB IAM authentication failed-Fehler auftritt, prüfen Sie die folgenden vier Bereiche:

Spickzettel zur Fehlerbehebung bei AlloyDB-IAM und -Verbindungen

1. .gserviceaccount.com aus den Datenbanknutzernamen des Dienstkontos entfernen

Die häufigste Ursache für IAM-Authentifizierungsfehler ist die Übergabe der vollständigen E-Mail-Adresse des Dienstkontos als Datenbanknutzername. AlloyDB formatiert IAM-Datenbanknutzernamen je nach Hauptkontotyp unterschiedlich:

  • Für IAM-Dienstkonten (.gserviceaccount.com entfernen): Wenn die E-Mail-Adresse Ihres Google Cloud-Dienstkontos java-alloydb-connector@.iam.gserviceaccount.com lautet, müssen Sie das Suffix .gserviceaccount.com entfernen und den JDBC-/AlloyDB-Datenbanknutzernamen auf java-alloydb-connector@.iam festlegen.
  • Für IAM-Nutzerkonten oder -Gruppen (vollständige E-Mail-Adresse beibehalten): Wenn Sie sich als menschlicher Google Workspace- oder Cloud Identity-Nutzer authentifizieren, verwenden Sie Ihre vollständige E-Mail-Adresse unverändert (z. B. ).

2. Erstellung des Datenbanknutzers überprüfen

Haben Sie den Nutzer über gcloud alloydb users create --type=IAM_BASED (oder die Console/Terraform) registriert? Das Erstellen eines Nutzers mit dem Roh-SQL-Befehl CREATE USER funktioniert für die IAM-Authentifizierung nicht, da AlloyDB GRANT alloydbiamuser auf die Steuerungsebene beschränkt.

3. Aktive ADC-Identität bestätigen

Prüfen Sie, ob die Umgebung, in der der Java-Prozess ausgeführt wird, tatsächlich als das IAM-Hauptkonto des Ziels authentifiziert ist:

  • Lokale Workstation (Verbindung als Dienstkonto): Führen Sie gcloud auth application-default login --impersonate-service-account=java-alloydb-connector@.iam.gserviceaccount.com aus, damit ADC Tokens für das Dienstkonto und nicht für Ihre persönliche E-Mail-Adresse erstellt.
  • Cloud Run/GKE: Prüfen Sie, ob das Dienstkonto an die Arbeitslast angehängt ist und sowohl roles/alloydb.client als auch roles/serviceusage.serviceUsageConsumer enthält.

4. IAM-Weitergabe und Netzwerkrouting berücksichtigen

  • IAM-Weitergabeverzögerung: Es kann 60–120 Sekunden dauern, bis IAM-Richtlinienbindungen weitergegeben werden. Wenn Sie das Dienstkonto oder die Rollenbindung gerade erst erstellt haben, warten Sie eine Minute und versuchen Sie es dann noch einmal.
  • VPC-Netzwerkzugriff: Standardmäßig stellt der AlloyDB-Java-Connector eine Verbindung zur PRIVATE-IP-Adresse der Instanz her. Wenn Ihre Anwendung in Cloud Run ausgeführt wird, konfigurieren Sie Direct VPC Egress (empfohlen für geringere Latenz und Kosten im Vergleich zu älteren Connectors für serverlosen VPC-Zugriff) oder stellen Sie eine Verbindung über Private Service Connect (PSC) her. Wenn Sie eine Verbindung von einem lokalen Computer außerhalb der VPC herstellen, aktivieren Sie die öffentliche IP-Adresse auf der Instanz und übergeben Sie alloydbIpType=PUBLIC.

7. Bereinigen

Damit Ihrem Google Cloud-Konto keine unnötigen Kosten entstehen, und um die in diesem Codelab erstellten IAM-Identitäten zu entfernen, bereinigen Sie die folgenden Ressourcen.

1. AlloyDB-IAM-Datenbanknutzer und -Dienstkonto entfernen

Löschen Sie den IAM-Datenbanknutzer aus Ihrem AlloyDB-Cluster und entfernen Sie das Dienstkonto:

# Delete the IAM database user from AlloyDB
gcloud alloydb users delete "java-alloydb-connector@${PROJECT_ID}.iam" \
    --cluster="${CLUSTER_ID}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --quiet

# Remove IAM policy bindings
gcloud projects remove-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/alloydb.client"

gcloud projects remove-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/serviceusage.serviceUsageConsumer"

# Delete the Service Account
gcloud iam service-accounts delete \
    "java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --project="${PROJECT_ID}" \
    --quiet

2. Lokale Standardanmeldedaten für Anwendungen zurücksetzen

Wenn Sie die lokale ADC-Identitätsübernahme konfiguriert haben, setzen Sie Ihre lokalen Anmeldedaten auf Ihre Standardnutzeridentität zurück:

gcloud auth application-default login

3. (Optional) AlloyDB-Cluster löschen

gcloud alloydb clusters delete "${CLUSTER_ID}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --force \
    --quiet

8. Glückwunsch

Sie haben das Codelab abgeschlossen und eine sichere, passwortlose Verbindung von Java zu AlloyDB for PostgreSQL hergestellt.

Ihr Lernerfolg

  1. IAM-Datenbankauthentifizierung konfiguriert: Sie haben ein Dienstkonto mit geringsten Berechtigungen erstellt, alloydb.iam_authentication=on aktiviert, den IAM-Nutzer im AlloyDB-Cluster registriert und PostgreSQL-Tabellenberechtigungen gewährt.
  2. Verbunden mit Plain JDBC und HikariCP: HikariConfig wurde mit com.google.cloud.alloydb.SocketFactory für die automatische mTLS 1.3-Verschlüsselung, die IAM-Tokenaktualisierung und die dynamische IP-Auflösung konfiguriert.
  3. Integrierte cloudnative Frameworks: Spring Boot, Quarkus (Agroal) und Micronaut (HikariCP) wurden ohne benutzerdefinierten Boilerplate-Code für Verbindungspools konfiguriert, außerdem wurden Reflexionshinweise für GraalVM Native Image hinzugefügt.
  4. IAM-Fehlerbehebung gemeistert: Sie haben gelernt, wie Sie Probleme mit der Formatierung von Nutzernamen, der ADC-Identitätsübernahme und dem VPC-Routing diagnostizieren.

Weitere Informationen