Łączenie aplikacji w Javie z AlloyDB for PostgreSQL za pomocą uwierzytelniania uprawnień

1. Zanim zaczniesz

Java i AlloyDB: proste, bezpieczne połączenia

AlloyDB for PostgreSQL to w pełni zarządzana i zgodna z PostgreSQL usługa bazy danych Google Cloud stworzona z myślą o wymagających zbiorach zadań w przedsiębiorstwach. Bezpieczne i wydajne połączenie aplikacji w Javie z AlloyDB jest możliwe dzięki oprogramowaniu sprzęgającemu AlloyDB w Javie (alloydb-jdbc-connector), czyli bibliotece klienta, która wykracza poza standardowy sterownik JDBC.

Magia oprogramowania sprzęgającego AlloyDB w Javie

alloydb-jdbc-connector działa jako inteligentny SocketFactory dla standardowego sterownika PostgreSQL JDBC (org.postgresql:postgresql). Abstrahuje on ustanawianie bezpiecznego połączenia z bazą danych, dzięki czemu możesz skupić się na logice aplikacji, a nie na bezpieczeństwie sieci czy rotacji danych logowania:

  • Szyfrowanie mTLS 1.3: automatycznie ustanawia wzajemnie uwierzytelnione połączenie TLS 1.3 między maszyną JVM a instancją AlloyDB bez konieczności ręcznego zarządzania certyfikatami klienta SSL/TLS.
  • Autoryzacja oparta na Cloud IAM: zamiast polegać na statycznych hasłach bazy danych, oprogramowanie sprzęgające wykorzystuje Cloud IAM Google Cloud i domyślne uwierzytelnianie aplikacji (ADC) do automatycznego uzyskiwania krótkotrwałych tokenów dostępu OAuth2.
  • Dynamiczne rozpoznawanie adresów IP: wysyła zapytania do interfejsu AlloyDB Admin API, aby dynamicznie rozpoznawać bieżący adres IP (PRIVATE, PUBLIC lub Private Service Connect PSC) instancji bazy danych. Nie musisz kodować na stałe nazw hostów ani adresów IP, dzięki czemu przełączanie awaryjne i konserwacja są przejrzyste.

Jak działa oprogramowanie sprzęgające AlloyDB w Javie

Wymagania wstępne

  • znajomość języka Java, narzędzia Maven oraz podstawowych pojęć związanych z SQL/JDBC;
  • Podstawowa znajomość interfejsu Google Cloud CLI (gcloud) i ról uprawnień.

Jakie zadania wykonasz

  • Skonfiguruj instancję AlloyDB i konto usługi na potrzeby uwierzytelniania bazy danych uprawnień bez hasła.
  • Przyznaj podmiotowi zabezpieczeń uprawnienia do schematu i tabeli PostgreSQL zgodnie z zasadą jak najmniejszych uprawnień.
  • Skonfiguruj środowisko produkcyjne DataSource z Plain JDBC i HikariCP przy użyciu SocketFactory AlloyDB.
  • Zintegruj oprogramowanie sprzęgające AlloyDB w Javie z aplikacjami Spring Boot, Quarkus i Micronaut.
  • Zarejestruj SocketFactory AlloyDB na potrzeby kompilacji GraalVM Native Image i rozwiąż typowe problemy z uwierzytelnianiem uprawnień.

Czego potrzebujesz

  • Projekt Google Cloud z włączonymi płatnościami oraz aktywny klaster i instancja podstawowa AlloyDB (zobacz przewodnik po tworzeniu klastra AlloyDB lub utwórz klaster AlloyDB Express w mniej niż 2 sekundy).
  • Role uprawnień roles/alloydb.admin i roles/resourcemanager.projectIamAdmin w projekcie.
  • Zainstalowana Java 17 lub nowsza (zalecana Java 17 lub 21 LTS) oraz Apache Maven.
  • Zainstalowany interfejs wiersza poleceń gcloud i klient psql (lub dostęp do Google Cloud Shell).

2. Konfigurowanie uwierzytelniania bazy danych uprawnień w AlloyDB

Zanim napiszesz kod w języku Java, musisz skonfigurować instancję AlloyDB tak, aby akceptowała tokeny uprawnień, i utworzyć tożsamość uprawnień, której aplikacja będzie używać na 3 poziomach: Google Cloud IAM, AlloyDB Control Plane i PostgreSQL Engine.

Trójwarstwowa konfiguracja uwierzytelniania bazy danych uprawnień AlloyDB

Ustawianie zmiennych środowiskowych

W terminalu wyeksportuj zmienne odpowiadające projektowi Google Cloud i instancji AlloyDB (zastąp obiekty zastępcze swoimi wartościami):

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

Włącz wymagane interfejsy API

Włącz w projekcie interfejsy AlloyDB API, Compute Engine API, Cloud Resource Manager API, IAM API i Service Usage API:

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

Tworzenie konta usługi i przyznawanie ról uprawnień

Utwórz dedykowane konto usługi, które będzie służyć jako tożsamość aplikacji w Javie:

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

Przypisz do konta usługi 2 role uprawnień wymagane przez oprogramowanie sprzęgające AlloyDB w Javie:

  1. roles/alloydb.client: wymagana do pobierania metadanych instancji i żądania tymczasowych certyfikatów mTLS z interfejsu AlloyDB Admin API.
  2. roles/serviceusage.serviceUsageConsumer: wymagane do uwierzytelniania bazy danych uprawnień.
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"

Włączanie uwierzytelniania uprawnień w instancji AlloyDB

Zaktualizuj flagi instancji AlloyDB, aby ustawić alloydb.iam_authentication=on. Jest to flaga dynamiczna, która zaczyna obowiązywać natychmiast bez ponownego uruchamiania instancji:

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

Rejestrowanie użytkownika bazy danych uprawnień

Zarejestruj konto usługi jako użytkownika bazy danych IAM_BASED w klastrze AlloyDB za pomocą gcloud:

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

Przyznawanie uprawnień do schematu i tabeli PostgreSQL

Nowo utworzeni użytkownicy bazy danych uprawnień nie mają domyślnie uprawnień do tabeli. Połącz się z instancją AlloyDB jako administrator postgres (za pomocą psql lub AlloyDB Studio w konsoli Cloud) i przyznaj dostęp do docelowej bazy danych i tabel (takich jak przykładowa baza danych DVD Rental):

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

Po uruchomieniu tych instrukcji w AlloyDB Studio (lub psql) możesz sprawdzić schemat public.film i zweryfikować przykładowe wiersze:

Przyznawanie uprawnień i sprawdzanie tabeli public.film w AlloyDB Studio

Konfigurowanie lokalnego domyślnego uwierzytelniania aplikacji (ADC)

Jeśli korzystasz z Cloud Run, Google Kubernetes Engine (GKE) lub Compute Engine, podłącz konto usługi java-alloydb-connector bezpośrednio do zadania. Podczas uruchamiania lokalnie na stacji roboczej podszywaj się pod konto usługi, aby ADC generowało tokeny dla tej tożsamości:

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

3. Łączenie za pomocą zwykłego JDBC i HikariCP

W przypadku każdej aplikacji Java klasy produkcyjnej niezbędna jest pula połączeń, a HikariCP jest standardem branżowym. W tym kroku utworzysz prostą aplikację JDBC + HikariCP, która deleguje tworzenie gniazd do com.google.cloud.alloydb.SocketFactory.

Tworzenie projektu Maven (pom.xml)

Utwórz nowy katalog jdbc-app z plikiem pom.xml zawierającym sterownik JDBC PostgreSQL (42.7.14), oprogramowanie sprzęgające AlloyDB w Javie (1.4.0) i HikariCP (7.1.0):

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

Utwórz pom.xml:

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

Utwórz ocenę AlloyDBConnectivity.java

Utwórz src/main/java/AlloyDBConnectivity.java (wyświetl we fragmencie kodu w GitHubie):

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

Anatomia adresu URL JDBC AlloyDB i konfiguracja HikariCP

Uruchamianie aplikacji Plain JDBC

Wyeksportuj zmienne środowiskowe instancji AlloyDB (ustaw ALLOYDB_IP_TYPE="PUBLIC", jeśli łączysz się spoza sieci VPC przez publiczny adres IP, lub "PRIVATE" / "PSC", jeśli łączysz się z sieci VPC) i uruchom aplikację:

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

Dane wyjściowe powinny być podobne do tych:

[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)

Dane wyjściowe terminala dla przykładu Plain JDBC i HikariCP

4. Łączenie ze Spring Boot

Spring Boot upraszcza połączenie z bazą danych, automatycznie konfigurując pulę połączeń HikariCP na podstawie właściwości aplikacji. Integracja oprogramowania sprzęgającego AlloyDB w Javie nie wymaga żadnego niestandardowego kodu komponentu DataSource.

Tworzenie projektu Spring Boot (pom.xml)

Utwórz nowy katalog 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

Utwórz pom.xml za pomocą spring-boot-starter-jdbc (który zawiera HikariCP), org.postgresql:postgresql i 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>

Konfigurowanie application.properties lub zmiennych środowiskowych

Adres URL połączenia możesz skonfigurować w src/main/resources/application.properties:

# 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

Aby w plikach źródłowych nie było identyfikatorów projektów ani nazw instancji, możesz pozostawić pole application.properties puste i podać te standardowe zmienne środowiskowe Spring Boot w czasie działania:

Zmienna środowiskowa

Wartość

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

Utwórz ocenę AlloyDbTestApplication.java

Utwórz src/main/java/com/example/alloydb/AlloyDbTestApplication.java (wyświetl we fragmencie kodu w GitHubie):

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

Uruchamianie aplikacji Spring Boot

Wyeksportuj zmienne środowiskowe i uruchom aplikację za pomocą mvn spring-boot:run:

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

Zobaczysz, że:

>>> ALLOYDB STATUS: Connection Successful!

Automatyczna konfiguracja Spring Boot i dane wyjściowe wykonywania na żywo

5. Łączenie z Quarkus, Micronaut i GraalVM Native Image

Ponieważ oprogramowanie sprzęgające AlloyDB w Javie działa na poziomie sterownika JDBC, przełączanie się między chmurowymi platformami Java nie zmienia sposobu zabezpieczania ruchu w bazie danych ani zarządzania tożsamościami. Zarówno Quarkus, jak i Micronaut opakowują bazowy sterownik JDBC i przekazują szyfrowanie mTLS, dynamiczne rozpoznawanie adresów IP i uwierzytelnianie uprawnień do oprogramowania sprzęgającego za pomocą ADC.

Chmurowe platformy Java i obraz natywny GraalVM z AlloyDB

Konfiguracja Quarkus (application.properties z Agroal)

W aplikacji Quarkus (quarkus-agroal i quarkus-jdbc-postgresql) dodaj com.google.cloud:alloydb-jdbc-connector:1.4.0 do zależności i przekaż parametry oprogramowania sprzęgającego za pomocą quarkus.datasource.jdbc.additional-jdbc-properties w 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

Konfiguracja Micronaut (application.yml z HikariCP)

W aplikacji Micronaut (micronaut-jdbc-hikari) dodaj com.google.cloud:alloydb-jdbc-connector:1.4.0 i skonfiguruj 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

Rejestrowanie oprogramowania sprzęgającego dla obrazu natywnego GraalVM

Podczas kompilowania aplikacji do obrazu natywnego GraalVM (ze Spring Boot 3+, Quarkus lub Micronaut) należy pamiętać o jednym ważnym szczególe: refleksji.

Sterownik PostgreSQL JDBC tworzy instancję com.google.cloud.alloydb.SocketFactory dynamicznie według nazwy klasy przy użyciu refleksji. Aby zapobiec usunięciu klasy przez analizę statyczną GraalVM podczas kompilacji natywnej, zarejestruj ją jawnie:

  • Spring Boot 3+: dodaj @RegisterReflectionForBinding(com.google.cloud.alloydb.SocketFactory.class) do głównej aplikacji lub klasy @Configuration:
    @SpringBootApplication
    @RegisterReflectionForBinding(com.google.cloud.alloydb.SocketFactory.class)
    public class AlloyDbTestApplication { ... }
    
  • Quarkus: dodaj @RegisterForReflection(targets = com.google.cloud.alloydb.SocketFactory.class) do klasy głównej lub komponentu CDI:
    @QuarkusMain
    @RegisterForReflection(targets = com.google.cloud.alloydb.SocketFactory.class)
    public class QuarkusAlloyDbApp implements QuarkusApplication { ... }
    

6. Rozwiązywanie typowych problemów z uprawnieniami i połączeniami

Jeśli wystąpi błąd FATAL: password authentication failed for user lub AlloyDB IAM authentication failed, sprawdź te 4 obszary:

Ściągawka dotycząca rozwiązywania problemów z uprawnieniami i połączeniami AlloyDB

1. Usuń .gserviceaccount.com z nazw użytkowników bazy danych konta usługi

Najczęstszą przyczyną niepowodzeń uwierzytelniania uprawnień jest przekazywanie pełnego adresu e-mail konta usługi jako nazwy użytkownika bazy danych. AlloyDB formatuje nazwy użytkowników bazy danych uprawnień w różny sposób w zależności od typu podmiotu zabezpieczeń:

  • Konta usługi uprawnień (usuń .gserviceaccount.com): jeśli adres e-mail konta usługi Google Cloud to java-alloydb-connector@.iam.gserviceaccount.com, musisz usunąć sufiks .gserviceaccount.com i ustawić nazwę użytkownika bazy danych JDBC/AlloyDB na java-alloydb-connector@.iam.
  • W przypadku kont użytkowników lub grup uprawnień (zachowaj pełny adres e-mail): jeśli uwierzytelniasz się jako użytkownik Google Workspace lub Cloud Identity, użyj pełnego adresu e-mail bez zmian (np. ).

2. Sprawdzanie sposobu utworzenia użytkownika bazy danych

Czy użytkownik został zarejestrowany za pomocą gcloud alloydb users create --type=IAM_BASED (lub konsoli/Terraform)? Utworzenie użytkownika za pomocą nieprzetworzonego kodu SQL CREATE USER nie zadziała w przypadku uwierzytelniania z użyciem uprawnień, ponieważ AlloyDB ogranicza GRANT alloydbiamuser do platformy sterującej.

3. Weryfikacja aktywnej tożsamości ADC

Upewnij się, że środowisko, w którym działa proces Java, jest uwierzytelnione jako docelowy podmiot zabezpieczeń uprawnień:

  • Lokalna stacja robocza (połączenie jako konto usługi): uruchom gcloud auth application-default login --impersonate-service-account=java-alloydb-connector@.iam.gserviceaccount.com, aby ADC generował tokeny dla konta usługi, a nie dla Twojego osobistego adresu e-mail.
  • Cloud Run / GKE: sprawdź, czy konto usługi jest dołączone do zadania i ma role roles/alloydb.client oraz roles/serviceusage.serviceUsageConsumer.

4. Uwzględnianie propagacji uprawnień i routingu sieciowego

  • Opóźnienie rozpowszechniania uprawnień: rozpowszechnianie powiązań zasad uprawnień może potrwać 60–120 sekund. Jeśli konto usługi lub powiązanie roli zostało utworzone niedawno, poczekaj chwilę i spróbuj ponownie.
  • Dostęp do sieci VPC: domyślnie oprogramowanie sprzęgające AlloyDB w Javie łączy się z adresem IP PRIVATE instancji. Jeśli aplikacja działa w Cloud Run, skonfiguruj bezpośredni ruch wychodzący VPC (zalecany ze względu na mniejsze opóźnienia i koszty w porównaniu ze starszymi oprogramowaniami sprzęgającymi bezserwerowego dostępu do VPC) lub połącz się przez Private Service Connect (PSC). Jeśli łączysz się z komputera lokalnego poza VPC, włącz publiczny adres IP w instancji i przekaż alloydbIpType=PUBLIC.

7. Czyszczenie danych

Aby uniknąć niepotrzebnych opłat na koncie Google Cloud i usunąć tożsamości uprawnień utworzone podczas tego ćwiczenia, wyczyść poniższe zasoby.

1. Usuwanie użytkownika bazy danych uprawnień AlloyDB i konta usługi

Usuń użytkownika bazy danych uprawnień z klastra AlloyDB i usuń konto usługi:

# 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. Resetowanie lokalnych domyślnych danych uwierzytelniających aplikacji

Jeśli skonfigurowano lokalne personifikowanie ADC, zresetuj lokalne dane uwierzytelniające do domyślnej tożsamości użytkownika:

gcloud auth application-default login

3. (Opcjonalnie) Usuwanie klastra AlloyDB

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

8. Gratulacje

Udało Ci się ukończyć ćwiczenie i nawiązać bezpieczne, bezhasłowe połączenie między Javą a AlloyDB for PostgreSQL.

osiągnięcia,

  1. Skonfigurowano uwierzytelnianie bazy danych uprawnień: utworzono konto usługi z jak najmniejszymi uprawnieniami, włączono alloydb.iam_authentication=on, zarejestrowano użytkownika uprawnień w klastrze AlloyDB i przyznano uprawnienia do tabeli PostgreSQL.
  2. Połączenie za pomocą Plain JDBC i HikariCP: skonfigurowano HikariConfig z com.google.cloud.alloydb.SocketFactory na potrzeby automatycznego szyfrowania mTLS 1.3, odświeżania tokenów uprawnień i dynamicznego rozpoznawania adresów IP.
  3. Zintegrowane platformy chmurowe: skonfigurowane platformy Spring Boot, Quarkus (Agroal) i Micronaut (HikariCP) bez niestandardowego kodu szablonowego puli połączeń oraz wskazówki dotyczące refleksji dla GraalVM Native Image.
  4. Opanowanie rozwiązywania problemów z uprawnieniami: dowiedz się, jak diagnozować problemy z formatowaniem nazwy użytkownika, personifikacją ADC i routingiem VPC.

Więcej informacji