ربط تطبيقات Java بخدمة AlloyDB for PostgreSQL باستخدام مصادقة "إدارة الهوية وإمكانية الوصول"

1. قبل البدء

‫Java وAlloyDB: اتصال بسيط وآمن

‫AlloyDB for PostgreSQL هي خدمة قواعد بيانات مُدارة بالكامل من Google Cloud ومتوافقة مع PostgreSQL ومخصّصة لأعباء العمل الصعبة في المؤسسات. يتم ربط تطبيق Java بخدمة AlloyDB بشكل آمن وفعّال من خلال AlloyDB Java Connector‏ (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 يدويًا.
  • Cloud IAM-Based Authorization: بدلاً من الاعتماد على كلمات مرور ثابتة لقاعدة البيانات، يستفيد الموصِّل من Cloud IAM في Google Cloud وبيانات الاعتماد التلقائية للتطبيق (ADC) للحصول على رموز الدخول OAuth2 القصيرة الأجل تلقائيًا.
  • حلّ عنوان IP الديناميكي: يرسل طلبات إلى AlloyDB Admin API لحلّ عنوان IP الحالي (PRIVATE أو PUBLIC أو Private Service Connect PSC) لمثيل قاعدة البيانات ديناميكيًا. لا تحتاج إلى ترميز أسماء المضيفين أو عناوين IP بشكل ثابت، ما يجعل عمليات تجاوز الفشل والصيانة شفافة.

آلية عمل AlloyDB Java Connector

المتطلبات الأساسية

  • الإلمام بلغة Java وMaven ومفاهيم SQL/JDBC الأساسية
  • معرفة أساسية بواجهة سطر الأوامر في Google Cloud ‏(gcloud) وأدوار "إدارة الهوية وإمكانية الوصول" (IAM)

الإجراءات التي ستنفذّها

  • اضبط مثيل AlloyDB وحساب الخدمة لاستخدام ميزة مصادقة قاعدة بيانات IAM بدون كلمة مرور.
  • منح أذونات مخطط وجدول PostgreSQL ذات الحد الأدنى من الامتيازات لمستخدم أساسي في "إدارة الهوية وإمكانية الوصول"
  • يمكنك إعداد DataSource على مستوى الإنتاج باستخدام Plain JDBC وHikariCP من خلال AlloyDB SocketFactory.
  • دمج AlloyDB Java Connector في تطبيقات Spring Boot وQuarkus وMicronaut
  • تسجيل AlloyDB SocketFactory لتجميع GraalVM Native Image وتحديد المشاكل الشائعة في مصادقة IAM وحلّها

المتطلبات

  • مشروع على Google Cloud تم تفعيل الفوترة فيه ومجموعة AlloyDB ومثيل أساسي نشطَين (راجِع دليل إنشاء مجموعة AlloyDB أو أنشئ مجموعة AlloyDB Express في أقل من ثانيتين).
  • دورا "إدارة الهوية وإمكانية الوصول" roles/alloydb.admin وroles/resourcemanager.projectIamAdmin في مشروعك
  • يجب تثبيت Java 17 أو إصدار أحدث (يُنصح باستخدام Java 17 أو 21 LTS) وApache Maven.
  • تثبيت واجهة سطر الأوامر (CLI) في gcloud وعميل psql (أو الوصول إلى Google Cloud Shell)

2. إعداد مصادقة قاعدة بيانات IAM على AlloyDB

قبل كتابة رمز Java، عليك ضبط مثيل AlloyDB لقبول رموز IAM المميّزة وإنشاء هوية IAM التي سيستخدمها تطبيقك على ثلاث طبقات: Google Cloud IAM وAlloyDB Control Plane ومحرك PostgreSQL.

الإعداد الثلاثي الطبقات لمصادقة قاعدة بيانات AlloyDB باستخدام "إدارة الهوية وإمكانية الوصول"

ضبط متغيرات البيئة

في الوحدة الطرفية، يمكنك تصدير المتغيّرات المقابلة لمشروعك على 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 و"إدارة الهوية وإمكانية الوصول" وService Usage في مشروعك:

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

إنشاء حساب خدمة ومنح أدوار "إدارة الهوية وإمكانية الوصول"

أنشئ حساب خدمة مخصّصًا ليكون بمثابة هوية تطبيق Java:

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

امنح حساب الخدمة الدورَين المطلوبَين في "إدارة الهوية وإمكانية الوصول" (IAM) لموصِّل AlloyDB Java:

  1. ‫roles/alloydb.client: مطلوب لاسترجاع البيانات الوصفية للمثيل وطلب شهادات mTLS المؤقتة من AlloyDB Admin API.
  2. ‫roles/serviceusage.serviceUsageConsumer: مطلوب لمصادقة قاعدة بيانات "إدارة الهوية وإمكانية الوصول".
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 الذين تم إنشاؤهم حديثًا أي امتيازات في الجداول تلقائيًا. اتصِل بمثيل AlloyDB كمستخدم مشرف في postgres (عبر psql أو AlloyDB Studio في Cloud Console) وامنح إذن الوصول إلى قاعدة البيانات والجداول المستهدَفة (مثل قاعدة بيانات عيّنة 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 والتحقّق من نماذج الصفوف:

منح أذونات &quot;إدارة الهوية وإمكانية الوصول&quot; وفحص public.film في AlloyDB Studio

ضبط "بيانات الاعتماد التلقائية للتطبيق" (ADC) المحلية

عند تشغيل الخدمة على Cloud Run أو Google Kubernetes Engine (GKE) أو Compute Engine، يجب إرفاق حساب خدمة java-alloydb-connector مباشرةً بعبء العمل. عند التشغيل محليًا على محطة العمل، انتحِل هوية حساب الخدمة لكي تنشئ "بيانات الاعتماد التلقائية للتطبيق" رموزًا مميزة لتلك الهوية:

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

3- الربط باستخدام 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();
        }
    }
}

بنية عنوان URL لـ AlloyDB JDBC وإعداد HikariCP

تشغيل تطبيق Plain JDBC

صدِّر متغيّرات البيئة لمثيل AlloyDB (اضبط ALLOYDB_IP_TYPE="PUBLIC" في حال الاتصال من خارج شبكة VPC عبر عنوان IP علني، أو "PRIVATE" / "PSC" في حال الاتصال من داخل شبكة VPC) وشغِّل التطبيق:

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)

Terminal Output of the Plain JDBC and HikariCP Sample

4. الربط باستخدام Spring Boot

يسهّل Spring Boot الاتصال بقاعدة البيانات من خلال ضبط مجموعة اتصالات HikariCP تلقائيًا من خصائص تطبيقك. لا يتطلّب دمج AlloyDB Java Connector أي رمز برمجي مخصّص لـ DataSource bean.

إنشاء مشروع 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 أو متغيرات البيئة

يمكنك ضبط عنوان URL الخاص بالاتصال في 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 ومخرجات التنفيذ المباشر

5- الربط مع Quarkus وMicronaut وGraalVM Native Image

بما أنّ AlloyDB Java Connector يعمل على مستوى برنامج تشغيل JDBC، فإنّ التبديل بين أُطر عمل Java المستندة إلى السحابة الإلكترونية لا يغيّر طريقة تأمين حركة بيانات قاعدة البيانات أو إدارة الهويات. يغلّف كل من Quarkus وMicronaut برنامج تشغيل JDBC الأساسي ويفوّضان تشفير mTLS وتحليل عنوان IP الديناميكي ومصادقة "إدارة الهوية وإمكانية الوصول" إلى الموصّل من خلال "بيانات الاعتماد التلقائية للتطبيق".

أُطر عمل Java المستندة إلى السحابة الإلكترونية وصورة GraalVM الأصلية مع 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)، هناك تفصيل واحد مهم: الانعكاس.

ينشئ برنامج تشغيل 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 { ... }
    

6. تحديد المشاكل الشائعة في "إدارة الهوية وإمكانية الوصول" والاتصال وحلّها

إذا واجهت خطأ FATAL: password authentication failed for user أو AlloyDB IAM authentication failed، تحقَّق من الجوانب الأربعة التالية:

ملخّص حول تحديد المشاكل وحلّها في ما يتعلّق بإدارة الهوية وإمكانية الوصول والاتصال في AlloyDB

1. إزالة .gserviceaccount.com من أسماء مستخدمي قاعدة بيانات حساب الخدمة

إنّ السبب الأكثر شيوعًا لحالات تعذُّر المصادقة في "إدارة الهوية وإمكانية الوصول" هو إدخال عنوان البريد الإلكتروني الكامل لحساب الخدمة كاسم مستخدم لقاعدة البيانات. يُنسِّق AlloyDB أسماء مستخدمي قاعدة بيانات "إدارة الهوية وإمكانية الوصول" بشكل مختلف استنادًا إلى نوع المدير:

  • بالنسبة إلى حسابات خدمة "إدارة الهوية وإمكانية الوصول" (إزالة .gserviceaccount.com): إذا كان عنوان البريد الإلكتروني لحساب خدمة Google Cloud هو java-alloydb-connector@.iam.gserviceaccount.com، يجب إزالة اللاحقة .gserviceaccount.com وضبط اسم مستخدم قاعدة بيانات JDBC/AlloyDB على java-alloydb-connector@.iam.
  • بالنسبة إلى حسابات أو مجموعات مستخدمي "إدارة الهوية وإمكانية الوصول" (يُرجى الاحتفاظ بعنوان البريد الإلكتروني الكامل): إذا كنت تجري المصادقة كمستخدم بشري في Google Workspace أو Cloud Identity، استخدِم عنوان بريدك الإلكتروني الكامل بدون تعديل (مثلاً، ).

2. التحقّق من كيفية إنشاء مستخدم قاعدة البيانات

هل سجّلت المستخدم من خلال gcloud alloydb users create --type=IAM_BASED (أو Console/Terraform)؟ لن يعمل إنشاء مستخدم باستخدام لغة الاستعلامات البنيوية (SQL) الأولية CREATE USER لمصادقة "إدارة الهوية وإمكانية الوصول" لأنّ AlloyDB يقيّد GRANT alloydbiamuser على مستوى التحكّم.

3- إثبات هويتك النشطة في ADC

تأكَّد من أنّ البيئة التي يتم فيها تشغيل عملية Java تمت مصادقتها فعليًا كمستخدم IAM الرئيسي المستهدَف:

  • محطة العمل المحلية (الاتصال كحساب خدمة): شغِّل gcloud auth application-default login --impersonate-service-account=java-alloydb-connector@.iam.gserviceaccount.com لكي تنشئ "بيانات الاعتماد التلقائية للتطبيق" رموزًا مميّزة لحساب الخدمة بدلاً من بريدك الإلكتروني الشخصي.
  • ‫Cloud Run / GKE: تأكَّد من أنّ حساب الخدمة مرتبط بعبء العمل ويحتوي على كل من roles/alloydb.client وroles/serviceusage.serviceUsageConsumer.

4. مراعاة انتشار "إدارة الهوية وإمكانية الوصول" وتوجيه الشبكة

  • تأخير نشر "إدارة الهوية وإمكانية الوصول": قد يستغرق نشر عمليات ربط سياسات "إدارة الهوية وإمكانية الوصول" من 60 إلى 120 ثانية. إذا أنشأت حساب الخدمة أو ربط الدور للتو، يُرجى الانتظار دقيقة ثم إعادة المحاولة.
  • الوصول إلى شبكة VPC: يتصل AlloyDB Java Connector تلقائيًا بعنوان IP الخاص بـ PRIVATE في المثيل. إذا كان تطبيقك يعمل على Cloud Run، اضبط الخروج المباشر من سحابة VPC (يُنصح به لتقليل وقت الاستجابة والتكلفة مقارنةً بموصّلات "إمكانية الوصول إلى VPC بدون خادم" القديمة) أو اتصِل من خلال Private Service Connect (PSC). في حال الاتصال من جهاز محلي خارج سحابة VPC، فعِّل عنوان IP العلني على المثيل وأدخِل alloydbIpType=PUBLIC.

7. تَنظيم

لتجنُّب تحمُّل رسوم غير ضرورية في حسابك على Google Cloud ولإزالة هويات "إدارة الهوية وإمكانية الوصول" التي تم إنشاؤها خلال هذا الدرس التطبيقي حول الترميز، عليك إزالة الموارد أدناه.

1. إزالة مستخدم قاعدة بيانات AlloyDB 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

2. إعادة ضبط "بيانات الاعتماد التلقائية للتطبيق" المحلية

إذا ضبطت انتحال هوية ADC محليًا، أعِد ضبط بيانات الاعتماد المحلية على هوية المستخدم التلقائية:

gcloud auth application-default login

3- (اختياري) حذف مجموعة AlloyDB

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

8. تهانينا

لقد أكملت الدرس التطبيقي حول الترميز وأنشأت اتصالاً آمنًا بدون كلمة مرور من Java إلى AlloyDB for PostgreSQL.

إنجازاتك

  1. ضبط مصادقة قاعدة بيانات "إدارة الهوية وإمكانية الوصول" (IAM): تم إنشاء حساب خدمة بأقل امتيازات، وتفعيل alloydb.iam_authentication=on، وتسجيل مستخدم "إدارة الهوية وإمكانية الوصول" (IAM) في مجموعة AlloyDB، ومنح امتيازات جدول PostgreSQL.
  2. الاتصال باستخدام Plain JDBC وHikariCP: تم ضبط HikariConfig باستخدام com.google.cloud.alloydb.SocketFactory لتشفير mTLS 1.3 التلقائي وإعادة تحميل الرمز المميّز لـ "إدارة الهوية وإمكانية الوصول" وحلّ عنوان IP الديناميكي.
  3. أُطر عمل مدمجة مستندة إلى السحابة الإلكترونية: تم إعداد Spring Boot وQuarkus (Agroal) وMicronaut (HikariCP) بدون استخدام أيّ نموذج مخصّص لمجموعة الاتصالات، بالإضافة إلى تلميحات الانعكاس لـ GraalVM Native Image.
  4. إتقان تحديد مشاكل "إدارة الهوية وإمكانية الوصول" وحلّها: تعلّمت كيفية تشخيص مشاكل تنسيق اسم المستخدم وانتحال هوية "بيانات الاعتماد التلقائية للتطبيق" وتوجيه شبكة VPC.

مزيد من المعلومات