متصل کردن برنامه‌های Java به AlloyDB برای PostgreSQL با «اصالت‌سنجی IAM»

۱. قبل‌از شروع

Java و AlloyDB: اتصال‌پذیری ساده و امن

AlloyDB برای PostgreSQL سرویس پایگاه داده کاملاً مدیریت‌شده و سازگار با PostgreSQL در Google Cloud برای بارهای کاری سازمانی پرتقاضا است. متصل کردن برنامه Java به AlloyDB به‌صورت ایمن و کارآمد ازطریق رابط Java برای AlloyDB (alloydb-jdbc-connector) انجام می‌شود که کتابخانه کارخواهی است که فراتر از درایور JDBC استاندارد عمل می‌کند.

جادوی AlloyDB Java Connector

alloydb-jdbc-connector به‌عنوان یک SocketFactory هوشمند برای درایور استاندارد PostgreSQL JDBC (‏org.postgresql:postgresql) عمل می‌کند. این ابزار برقراری اتصال امن به پایگاه داده را انتزاعی می‌کند تا بتوانید به‌جای امنیت شبکه یا چرخش اعتبارنامه‌ها، بر منطق برنامه تمرکز کنید:

  • رمزگذاری mTLS 1.3: به‌طور خودکار اتصال TLS 1.3 با اصالت‌سنجی متقابل بین JVM شما و نمونه AlloyDB برقرار می‌کند، بدون اینکه لازم باشد گواهینامه‌های کارخواه SSL/TLS را به‌صورت دستی مدیریت کنید.
  • مجوز مبتنی بر IAM: به‌جای تکیه بر گذرواژه‌های پایگاه داده ایستا، این متصل‌کننده از Google Cloud IAM و اعتبارنامه‌های پیش‌فرض برنامه (ADC) برای دریافت خودکار کد دسترسی OAuth2 کوتاه‌مدت استفاده می‌کند.
  • وضوح IP پویا: از AlloyDB Admin API برای حل نشانی IP فعلی (PRIVATE، PUBLIC، یا Private Service Connect PSC) نمونه پایگاه داده شما به‌صورت پویا پرس‌وجو می‌کند. نیازی به کدگذاری سخت نام‌های میزبان یا نشانی‌های IP ندارید، که این امر باعث می‌شود انتقال به سرور پشتیبان و نگهداری شفاف باشد.

نحوه عملکرد «اتصال‌دهنده جاوا AlloyDB» در پشت صحنه

پیش‌نیازها

  • آشنایی با مفاهیم Java،‏ Maven، و SQL/JDBC پایه.
  • آشنایی اولیه با Google Cloud CLI (gcloud) و نقش‌های IAM.

آنچه انجام خواهید داد

  • پیکربندی کردن نمونه AlloyDB و «حساب خدمات» برای اصالت‌سنجی پایگاه داده IAM بدون گذرواژه.
  • اجازه‌های جدول و طرح‌واره PostgreSQL با کمترین امتیاز را به یک اصلی IAM اعطا کنید.
  • پیکربندی DataSource در سطح تولید با Plain JDBC و HikariCP بااستفاده از AlloyDB SocketFactory.
  • ادغام کردن «رابط AlloyDB Java» در برنامه‌های Spring Boot،‏ Quarkus، و Micronaut.
  • ثبت کردن AlloyDB SocketFactory برای کامپایل GraalVM Native Image و عیب‌یابی کردن مشکلات رایج در احراز هویت IAM.

آنچه نیاز خواهید داشت

  • یک پروژه Google Cloud با صورت‌حساب فعال و یک خوشه AlloyDB و نمونه اصلی فعال (به راهنمای ایجاد خوشه AlloyDB مراجعه کنید یا یک خوشه AlloyDB Express را در کمتر از دو ثانیه راه‌اندازی کنید).
  • نقش‌های IAM roles/alloydb.admin و roles/resourcemanager.projectIamAdmin در پروژه شما.
  • Java 17 یا بالاتر (Java 17 یا 21 LTS توصیه می‌شود) و Apache Maven نصب شده باشد.
  • gcloud CLI و psql کارخواه نصب‌شده (یا دسترسی به Google Cloud Shell).

۲. راه‌اندازی «اصالت‌سنجی پایگاه داده IAM» در AlloyDB

قبل‌از نوشتن کد جاوا، باید نمونه AlloyDB خود را پیکربندی کنید تا توکن‌های IAM را بپذیرد و هویت IAM را ایجاد کند که برنامه شما در سه لایه استفاده خواهد کرد: Google Cloud IAM،‏ AlloyDB Control Plane، و PostgreSQL Engine.

راه‌اندازی سه‌لایه برای اصالت‌سنجی پایگاه داده AlloyDB IAM

تنظیم متغیرهای محیط

در پایانه، متغیرهای مربوط به پروژه Google Cloud و نمونه AlloyDB خود را صادر کنید (جای‌بان‌های را با مقادیر خود جایگزین کنید):

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

فعال کردن میاناهای برنامه‌سازی کاربردی لازم

میاناهای برنامه‌سازی کاربردی AlloyDB،‏ Compute Engine،‏ Cloud Resource Manager،‏ IAM، و Service Usage را در پروژه‌تان فعال کنید:

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

ایجاد حساب سرویس و اعطای نقش‌های IAM

یک «حساب سرویس» اختصاصی ایجاد کنید که به‌عنوان هویت برنامه Java شما عمل کند:

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

دو نقش IAM موردنیاز AlloyDB Java Connector را به «حساب سرویس» اعطا کنید:

  1. roles/alloydb.client: برای واکشی فراداده نمونه و درخواست گواهی‌های mTLS زودگذر از AlloyDB Admin API لازم است.
  2. roles/serviceusage.serviceUsageConsumer: برای اصالت‌سنجی پایگاه داده IAM لازم است.
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» در «نمونه AlloyDB»

پرچم‌های نمونه AlloyDB را برای تنظیم alloydb.iam_authentication=on به‌روز کنید. این پرچم پویا است و بلافاصله بدون بازراه‌اندازی نمونه اعمال می‌شود:

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

ثبت «کاربر پایگاه داده مدیریت هویت و دسترسی»

«حساب خدمات» را به‌عنوان کاربر پایگاه داده IAM_BASED در خوشه AlloyDB خود بااستفاده از gcloud ثبت کنید:

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

اعطای اجازه‌های جدول و طرح‌واره PostgreSQL

کاربران پایگاه داده IAM که به‌تازگی ایجاد شده‌اند به‌طور پیش‌فرض هیچ امتیاز جدولی ندارند. به‌عنوان کاربر سرپرست postgres به نمونه AlloyDB خود متصل شوید (ازطریق psql یا AlloyDB Studio در «کنسول Cloud») و به پایگاه داده و جدول‌های هدف خود (مانند پایگاه داده نمونه 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";

هنگام اجرای این دستورات در AlloyDB Studio (یا psql)، می‌توانید طرح‌واره public.film را بررسی کنید و ردیف‌های نمونه را تأیید کنید:

اعطای اجازه‌های IAM و بازرسی public.film در «استودیوِ AlloyDB»

پیکربندی «اعتبارنامه‌های پیش‌فرض برنامه محلی» (ADC)

هنگام اجرا در Cloud Run،‏ Google Kubernetes Engine‏ (GKE)، یا Compute Engine،‏ java-alloydb-connector «حساب سرویس» را مستقیماً به حجم کاری پیوست کنید. هنگام اجرا به‌صورت محلی در ایستگاه کاری‌تان، خود را به‌جای «حساب سرویس» جا بزنید تا ADC برای آن هویت، توکن صادر کند:

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

۳. اتصال با Plain JDBC و HikariCP

برای هر برنامه Java در سطح تولید، استخر اتصال ضروری است و HikariCP استاندارد صنعت است. در این مرحله، برنامه JDBC + HikariCP ساده‌ای خواهید ساخت که ایجاد سوکت را به com.google.cloud.alloydb.SocketFactory واگذار می‌کند.

ساختن پروژه Maven‏ (pom.xml)

دایرکتوری جدید jdbc-app را با فایل pom.xml حاوی درایور PostgreSQL JDBC‏ (42.7.14)،‏ AlloyDB Java Connector‏ (1.4.0)، و HikariCP‏ (7.1.0) ایجاد کنید:

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

ایجاد کردن 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>

ساختن AlloyDBConnectivity.java

ایجاد src/main/java/AlloyDBConnectivity.java (مشاهده در GitHub Gist):

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

آناتومی نشانی وب AlloyDB JDBC و پیکربندی HikariCP

اجرای برنامه JDBC ساده

متغیرهای محیطی را برای نمونه AlloyDB خود صادر کنید (اگر از خارج از VPC خود ازطریق IP عمومی متصل می‌شوید، ALLOYDB_IP_TYPE="PUBLIC" را تنظیم کنید، یا اگر داخل VPC هستید، "PRIVATE" / "PSC" را تنظیم کنید) و برنامه را اجرا کنید:

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

باید بروندادی مشابه زیر ببینید:

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

خروجی پایانه نمونه Plain JDBC و HikariCP

۴. اتصال با Spring Boot

‫Spring Boot اتصال پایگاه داده را با پیکربندی خودکار استخر اتصال HikariCP از ویژگی‌های برنامه شما ساده می‌کند. ادغام کردن AlloyDB Java Connector به هیچ کد bean DataSource سفارشی نیاز ندارد.

ایجاد پروژه Spring Boot‏ (pom.xml)

ایجاد دایرکتوری جدید 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

pom.xml را با spring-boot-starter-jdbc (که شامل HikariCP است)، org.postgresql:postgresql، و 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 یا متغیرهای محیطی

می‌توانید نشانی وب اتصال را در 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

برای اینکه فایل‌های منبع شما کاملاً عاری از شناسه پروژه یا نام نمونه باشد، می‌توانید application.properties را خالی بگذارید و این متغیرهای محیطی استاندارد Spring Boot را در زمان اجرا ارائه دهید:

متغیر محیط

مقدار

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

ایجاد src/main/java/com/example/alloydb/AlloyDbTestApplication.java (مشاهده در GitHub Gist):

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

متغیرهای محیط را صادر کنید و برنامه را با 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

باید موارد زیر را ببینید:

>>> ALLOYDB STATUS: Connection Successful!

پیکربندی خودکار Spring Boot و خروجی اجرای زنده

۵. اتصال با Quarkus،‏ Micronaut، و GraalVM Native Image

ازآنجایی‌که AlloyDB Java Connector در سطح درایور JDBC عمل می‌کند، جابه‌جایی بین چارچوب‌های Java بومی ابری نحوه ایمن‌سازی ترافیک پایگاه داده یا مدیریت هویت‌ها را تغییر نمی‌دهد. ‫Quarkus و Micronaut هر دو درایور JDBC زیربنایی را بسته‌بندی می‌کنند و رمزگذاری mTLS، وضوح IP پویا، و اصالت‌سنجی IAM را ازطریق ADC به رابط واگذار می‌کنند.

چارچوب‌های جاوای بومی ابری و GraalVM Native Image با AlloyDB

پیکربندی Quarkus (application.properties با Agroal)

در برنامه Quarkus (quarkus-agroal و quarkus-jdbc-postgresql)، com.google.cloud:alloydb-jdbc-connector:1.4.0 را به وابستگی‌هایتان اضافه کنید و پارامترهای اتصال‌دهنده را ازطریق quarkus.datasource.jdbc.additional-jdbc-properties در 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 (application.yml با HikariCP)

در برنامه Micronaut‏ (micronaut-jdbc-hikari)، com.google.cloud:alloydb-jdbc-connector:1.4.0 را اضافه کنید و 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

درحال ثبت «رابط» برای GraalVM Native Image

هنگام کامپایل کردن برنامه در GraalVM Native Image (با Spring Boot 3+‎،‏ Quarkus، یا Micronaut)، یک جزئیات مهم وجود دارد: Reflection.

گرداننده PostgreSQL JDBC بااستفاده از بازتاب، com.google.cloud.alloydb.SocketFactory را به‌طور پویا براساس نام کلاس نمونه‌سازی می‌کند. برای جلوگیری از حذف کلاس توسط تحلیل ایستا GraalVM درطول کامپایل بومی، آن را به‌طور صریح ثبت کنید:

  • Spring Boot 3+‎: @RegisterReflectionForBinding(com.google.cloud.alloydb.SocketFactory.class) را به برنامه اصلی یا کلاس @Configuration اضافه کنید:
    @SpringBootApplication
    @RegisterReflectionForBinding(com.google.cloud.alloydb.SocketFactory.class)
    public class AlloyDbTestApplication { ... }
    
  • Quarkus: @RegisterForReflection(targets = com.google.cloud.alloydb.SocketFactory.class) را به کلاس اصلی یا یک CDI bean اضافه کنید:
    @QuarkusMain
    @RegisterForReflection(targets = com.google.cloud.alloydb.SocketFactory.class)
    public class QuarkusAlloyDbApp implements QuarkusApplication { ... }
    

‫۶. عیب‌یابی مشکلات رایج اتصال‌پذیری و IAM

اگر با خطای FATAL: password authentication failed for user یا AlloyDB IAM authentication failed مواجه شدید، چهار مورد زیر را بررسی کنید:

برگه تقلب عیب‌یابی اتصال‌پذیری و AlloyDB IAM

۱. برداشتن .gserviceaccount.com از «نام‌های کاربری پایگاه داده حساب سرویس»

رایج‌ترین دلیل انجام نشدن اصالت‌سنجی IAM ارسال نشانی ایمیل کامل «حساب خدمات» به‌عنوان نام کاربری پایگاه داده است. AlloyDB نام‌های کاربری پایگاه داده IAM را بسته به نوع اصلی به‌طور متفاوتی قالب‌بندی می‌کند:

  • برای «حساب‌های سرویس IAM» (حذف .gserviceaccount.com): اگر ایمیل «حساب سرویس Google Cloud» شما java-alloydb-connector@.iam.gserviceaccount.com است، باید پسوند .gserviceaccount.com را بردارید و نام کاربری پایگاه داده JDBC/AlloyDB خود را روی java-alloydb-connector@.iam تنظیم کنید.
  • برای «گروه‌ها» یا «حساب‌های کاربری IAM» (ایمیل کامل را نگه دارید): اگر به‌عنوان کاربر انسانی Google Workspace یا Cloud Identity اصالت‌سنجی می‌کنید، از نشانی ایمیل کامل خود بدون تغییر استفاده کنید (برای مثال، ).

۲. تأیید نحوه ایجاد کاربر پایگاه داده

آیا کاربر را ازطریق gcloud alloydb users create --type=IAM_BASED (یا Console/Terraform) ثبت‌نام کرده‌اید؟ ایجاد کردن کاربر با SQL خام CREATE USER برای اصالت‌سنجی IAM کار نخواهد کرد زیرا AlloyDB GRANT alloydbiamuser را به صفحه کنترل محدود می‌کند.

۳. درستی‌سنجی کردن هویت فعال ADC

مطمئن شوید محیطی که فرایند Java در آن اجرا می‌شود واقعاً به‌عنوان اصلی IAM هدف اصالت‌سنجی شده باشد:

  • ایستگاه کاری محلی (اتصال به‌عنوان «حساب سرویس»): gcloud auth application-default login --impersonate-service-account=java-alloydb-connector@.iam.gserviceaccount.com را اجرا کنید تا ADC به‌جای ایمیل شخصی شما، برای «حساب سرویس» توکن صادر کند.
  • Cloud Run / GKE: مطمئن شوید که «حساب سرویس» به حجم کاری متصل است و هم roles/alloydb.client و هم roles/serviceusage.serviceUsageConsumer را دارد.

۴. حساب برای انتشار IAM و مسیریابی شبکه

  • تأخیر انتشار IAM: انتشار اتصال‌های خط‌مشی IAM ممکن است ۶۰ تا ۱۲۰ ثانیه طول بکشد. اگر «حساب سرویس» یا اتصال نقش را تازه ایجاد کرده‌اید، یک دقیقه صبر کنید و دوباره امتحان کنید.
  • دسترسی به شبکه VPC: به‌طور پیش‌فرض، AlloyDB Java Connector به IP PRIVATE نمونه متصل می‌شود. اگر برنامه‌تان در Cloud Run اجرا می‌شود، Direct VPC Egress را پیکربندی کنید (برای تأخیر و هزینه کمتر نسبت‌به «اتصال‌دهنده‌های دسترسی VPC بدون سرور» قدیمی توصیه می‌شود) یا ازطریق Private Service Connect (PSC) متصل شوید. اگر از دستگاهی محلی خارج از VPC متصل می‌شوید، IP عمومی را در نمونه فعال کنید و alloydbIpType=PUBLIC را ارسال کنید.

‫۷. مرتب‌سازی

برای جلوگیری از تحمیل هزینه‌های غیرضروری به حساب Google Cloud خود و برداشتن هویت‌های IAM ایجادشده درطول این codelab، منابع زیر را پاک‌سازی کنید.

۱. برداشتن «حساب سرویس» و «کاربر پایگاه داده AlloyDB IAM»

کاربر پایگاه داده IAM را از خوشه AlloyDB خود حذف کنید و «حساب سرویس» را بردارید:

# 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

۲. بازنشانی کردن اعتبارنامه‌های پیش‌فرض برنامه محلی

اگر جعل هویت ADC محلی را پیکربندی کرده‌اید، اعتبارنامه‌های محلی‌تان را به هویت کاربر پیش‌فرضتان بازنشانی کنید:

gcloud auth application-default login

۳. (اختیاری) حذف کردن خوشه AlloyDB

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

‫۸. تبریک می‌گوییم

شما codelab را تکمیل کرده‌اید و اتصال امن و بدون گذرواژه از Java به AlloyDB برای PostgreSQL برقرار کرده‌اید!

آنچه انجام داده‌اید

  1. پیکربندی اصالت‌سنجی پایگاه داده IAM: «حساب خدمات» با کمترین امتیاز ایجاد شد، alloydb.iam_authentication=on فعال شد، کاربر IAM در خوشه AlloyDB ثبت شد، و امتیازات جدول PostgreSQL اعطا شد.
  2. متصل‌شده با Plain JDBC و HikariCP: HikariConfig با com.google.cloud.alloydb.SocketFactory برای رمزگذاری خودکار mTLS 1.3، بازآوری کد IAM، و وضوح IP پویا پیکربندی شده است.
  3. چارچوب‌های یکپارچه Cloud-Native: Spring Boot،‏ Quarkus (Agroal)، و Micronaut (HikariCP) را با صفر کد تکراری استخر اتصال سفارشی، به‌علاوه نکات بازتابی برای GraalVM Native Image پیکربندی کرد.
  4. تسلط بر عیب‌یابی IAM: یاد گرفتید که چگونه قالب‌بندی نام کاربری، جعل هویت ADC، و مشکلات مسیریابی VPC را تشخیص دهید.

بیشتر بدانید