1. ก่อนเริ่มต้น

AlloyDB for PostgreSQL เป็นบริการฐานข้อมูลที่มีการจัดการครบวงจรและเข้ากันได้กับ PostgreSQL ของ Google Cloud สำหรับภาระงานขององค์กรที่มีความต้องการสูง การเชื่อมต่อแอปพลิเคชัน Java กับ AlloyDB อย่างปลอดภัยและมีประสิทธิภาพทำได้ผ่าน AlloyDB Java Connector (alloydb-jdbc-connector) ซึ่งเป็นไลบรารีของไคลเอ็นต์ที่เหนือกว่าไดรเวอร์ JDBC มาตรฐาน
ความมหัศจรรย์ของ AlloyDB Java Connector
alloydb-jdbc-connector ทำหน้าที่เป็นSocketFactoryอัจฉริยะสำหรับไดรเวอร์ JDBC มาตรฐานของ PostgreSQL (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 ConnectPSC) ของอินสแตนซ์ฐานข้อมูลแบบไดนามิก คุณไม่จำเป็นต้องฮาร์ดโค้ดชื่อโฮสต์หรือที่อยู่ IP ซึ่งจะทำให้การเฟลโอเวอร์และการบำรุงรักษาเป็นไปอย่างโปร่งใส

ข้อกำหนดเบื้องต้น
- ความคุ้นเคยกับ Java, Maven และแนวคิด SQL/JDBC พื้นฐาน
- มีความคุ้นเคยเบื้องต้นกับ Google Cloud CLI (
gcloud) และบทบาท IAM
สิ่งที่คุณจะทำ
- กำหนดค่าอินสแตนซ์ AlloyDB และบัญชีบริการสำหรับการตรวจสอบสิทธิ์ฐานข้อมูล IAM แบบไม่ใช้รหัสผ่าน
- ให้สิทธิ์สคีมาและตาราง PostgreSQL ที่มีสิทธิ์ขั้นต่ำที่สุดแก่ผู้ใช้หลักของ IAM
- กำหนดค่า
DataSourceระดับเวอร์ชันที่ใช้งานจริงด้วย Plain JDBC และ HikariCP โดยใช้SocketFactoryของ AlloyDB - ผสานรวม AlloyDB Java Connector ในแอปพลิเคชัน Spring Boot, Quarkus และ Micronaut
- ลงทะเบียน AlloyDB
SocketFactoryสำหรับการคอมไพล์ GraalVM Native Image และแก้ปัญหาข้อผิดพลาดที่พบบ่อยเกี่ยวกับการตรวจสอบสิทธิ์ IAM
สิ่งที่คุณต้องมี
- โปรเจ็กต์ที่อยู่ในระบบคลาวด์ของ Google ที่เปิดใช้การเรียกเก็บเงินและคลัสเตอร์ AlloyDB และอินสแตนซ์หลักที่ใช้งานอยู่ (ดูคู่มือการสร้างคลัสเตอร์ AlloyDB หรือสร้างคลัสเตอร์ AlloyDB Express ในเวลาไม่ถึง 2 วินาที)
- บทบาท IAM
roles/alloydb.adminและroles/resourcemanager.projectIamAdminในโปรเจ็กต์ของคุณ - ติดตั้ง Java 17 ขึ้นไป (แนะนำ Java 17 หรือ 21 LTS) และ Apache Maven
- ติดตั้ง
gcloudCLI และไคลเอ็นต์psqlแล้ว (หรือเข้าถึง Google Cloud Shell)
2. ตั้งค่าการตรวจสอบสิทธิ์ฐานข้อมูล IAM ใน AlloyDB
ก่อนเขียนโค้ด Java คุณต้องกำหนดค่าอินสแตนซ์ AlloyDB ให้ยอมรับโทเค็น IAM และสร้างข้อมูลประจำตัว IAM ที่แอปพลิเคชันจะใช้ใน 3 เลเยอร์ ได้แก่ Google Cloud IAM, AlloyDB Control Plane และเครื่องมือ PostgreSQL

ตั้งค่าตัวแปรสภาพแวดล้อม
ในเทอร์มินัล ให้ส่งออกตัวแปรที่สอดคล้องกับโปรเจ็กต์ที่อยู่ในระบบคลาวด์ของ Google และอินสแตนซ์ AlloyDB (แทนที่ตัวยึดตำแหน่ง ด้วยค่าของคุณ)
export PROJECT_ID="<PROJECT_ID>"
export REGION="europe-west1"
export CLUSTER_ID="<CLUSTER_ID>"
export INSTANCE_ID="<INSTANCE_ID>"
export DB_NAME="dvdrental"
เปิดใช้ API ที่จำเป็น
เปิดใช้ AlloyDB, Compute Engine, Cloud Resource Manager, IAM และ Service Usage API ในโปรเจ็กต์โดยทำดังนี้
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 2 บทบาทที่ AlloyDB Java Connector กำหนดให้แก่บัญชีบริการ ดังนี้
roles/alloydb.client: จำเป็นสำหรับการดึงข้อมูลเมตาของอินสแตนซ์และขอใบรับรอง mTLS ชั่วคราวจาก AlloyDB Admin APIroles/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
ลงทะเบียนบัญชีบริการเป็นผู้ใช้ฐานข้อมูล 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) และให้สิทธิ์เข้าถึงฐานข้อมูลและตารางเป้าหมาย (เช่น ฐานข้อมูลตัวอย่าง 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 และยืนยันแถวตัวอย่างได้ ดังนี้

กำหนดค่าข้อมูลรับรองเริ่มต้นของแอปพลิเคชัน (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"
3. เชื่อมต่อด้วย Plain JDBC และ HikariCP
สำหรับแอปพลิเคชัน Java ระดับการใช้งานจริง พูลการเชื่อมต่อเป็นสิ่งจำเป็น และ HikariCP เป็นมาตรฐานอุตสาหกรรม ในขั้นตอนนี้ คุณจะสร้างแอปพลิเคชัน JDBC + HikariCP แบบธรรมดาที่มอบสิทธิ์การสร้างซ็อกเก็ตให้กับ com.google.cloud.alloydb.SocketFactory
สร้างโปรเจ็กต์ Maven (pom.xml)
สร้างไดเรกทอรีใหม่ jdbc-app ด้วยไฟล์ pom.xml ที่มีไดรเวอร์ JDBC สำหรับ PostgreSQL (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();
}
}
}

เรียกใช้แอปพลิเคชัน 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)

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 มาตรฐานเหล่านี้ที่รันไทม์ได้
ตัวแปรสภาพแวดล้อม | ค่า |
|
|
|
|
สร้าง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!

5. เชื่อมต่อกับ Quarkus, Micronaut และ GraalVM Native Image
เนื่องจาก AlloyDB Java Connector ทำงานที่ระดับไดรเวอร์ JDBC การสลับระหว่างเฟรมเวิร์ก Java ที่ดำเนินการบนระบบคลาวด์จึงไม่เปลี่ยนวิธีรักษาความปลอดภัยการรับส่งข้อมูลฐานข้อมูลหรือจัดการข้อมูลประจำตัว ทั้ง Quarkus และ Micronaut จะรวมไดรเวอร์ JDBC ที่สำคัญและมอบสิทธิ์การเข้ารหัส mTLS, การแปลง IP แบบไดนามิก และการตรวจสอบสิทธิ์ IAM ให้กับเครื่องมือเชื่อมต่อผ่าน ADC

การกำหนดค่า Quarkus (application.properties ด้วย Agroal)
ในแอปพลิเคชัน Quarkus (quarkus-agroal และ quarkus-jdbc-postgresql) ให้เพิ่ม com.google.cloud:alloydb-jdbc-connector:1.4.0 ลงในทรัพยากร Dependency และส่งพารามิเตอร์เครื่องมือเชื่อมต่อผ่าน 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
ไดรเวอร์ JDBC สำหรับ PostgreSQL จะสร้างอินสแตนซ์ 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. แก้ปัญหาที่พบได้ทั่วไปเกี่ยวกับ IAM และการเชื่อมต่อ
หากพบข้อผิดพลาด FATAL: password authentication failed for user หรือ AlloyDB IAM authentication failed ให้ตรวจสอบ 4 ส่วนต่อไปนี้

1. นำ .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 ที่เป็นบุคคลธรรมดา ให้ใช้อีเมลแบบเต็มโดยไม่มีการแก้ไข (เช่น
)
2. ยืนยันวิธีสร้างผู้ใช้ฐานข้อมูล
คุณได้ลงทะเบียนผู้ใช้ผ่าน gcloud alloydb users create --type=IAM_BASED (หรือ Console/Terraform) หรือไม่ การสร้างผู้ใช้ด้วย SQL ดิบ CREATE USER จะใช้ไม่ได้กับการตรวจสอบสิทธิ์ IAM เนื่องจาก AlloyDB จำกัด GRANT alloydbiamuser ไว้ที่ระนาบควบคุม
3. ยืนยันข้อมูลประจำตัว ADC ที่ใช้งานอยู่
ตรวจสอบว่าสภาพแวดล้อมที่กระบวนการ Java ทำงานอยู่ได้รับการตรวจสอบสิทธิ์เป็น IAM Principal เป้าหมายจริง โดยทำดังนี้
- เวิร์กสเตชันภายใน (เชื่อมต่อเป็นบัญชีบริการ): เรียกใช้
gcloud auth application-default login --impersonate-service-account=java-alloydb-connector@เพื่อให้ ADC สร้างโทเค็นสำหรับบัญชีบริการแทนอีเมลส่วนตัวของคุณ.iam.gserviceaccount.com - Cloud Run / GKE: ยืนยันว่าบัญชีบริการเชื่อมโยงกับภาระงานและมีทั้ง
roles/alloydb.clientและroles/serviceusage.serviceUsageConsumer
4. พิจารณาการเผยแพร่ IAM และการกำหนดเส้นทางเครือข่าย
- ความล่าช้าในการเผยแพร่ IAM: การเชื่อมโยงนโยบาย IAM อาจใช้เวลา 60-120 วินาทีในการเผยแพร่ หากเพิ่งสร้างบัญชีบริการหรือการเชื่อมโยงบทบาท ให้รอสักครู่แล้วลองอีกครั้ง
- การเข้าถึงเครือข่าย VPC: โดยค่าเริ่มต้น ตัวเชื่อมต่อ AlloyDB Java จะเชื่อมต่อกับ IP
PRIVATEของอินสแตนซ์ หากแอปพลิเคชันทำงานบน Cloud Run ให้กำหนดค่าข้อมูลขาออก VPC โดยตรง (แนะนำสำหรับเวลาในการตอบสนองและค่าใช้จ่ายที่ต่ำกว่าเมื่อเทียบกับเครื่องมือเชื่อมต่อการเข้าถึง VPC แบบ Serverless เดิม) หรือเชื่อมต่อผ่าน Private Service Connect (PSC) หากเชื่อมต่อจากเครื่องภายในที่อยู่นอก VPC ให้เปิดใช้ IP สาธารณะในอินสแตนซ์และส่งalloydbIpType=PUBLIC
7. ล้างข้อมูล
โปรดล้างทรัพยากรด้านล่างเพื่อหลีกเลี่ยงการเรียกเก็บเงินที่ไม่จำเป็นในบัญชี Google Cloud และนำข้อมูลประจำตัว IAM ที่สร้างขึ้นระหว่าง Codelab นี้ออก
1. นำผู้ใช้ฐานข้อมูล IAM และบัญชีบริการของ 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. ขอแสดงความยินดี
คุณได้ทำ Codelab เสร็จแล้ว และสร้างการเชื่อมต่อที่ปลอดภัยและไม่ต้องใช้รหัสผ่านจาก Java ไปยัง AlloyDB สำหรับ PostgreSQL
สิ่งที่คุณทำสำเร็จ
- กำหนดค่าการตรวจสอบสิทธิ์ฐานข้อมูล IAM: สร้างบัญชีบริการที่มีสิทธิ์ขั้นต่ำที่สุด เปิดใช้
alloydb.iam_authentication=onลงทะเบียนผู้ใช้ IAM ในคลัสเตอร์ AlloyDB และให้สิทธิ์ตาราง PostgreSQL - เชื่อมต่อด้วย Plain JDBC และ HikariCP: กำหนดค่า
HikariConfigด้วยcom.google.cloud.alloydb.SocketFactoryสำหรับการเข้ารหัส mTLS 1.3 อัตโนมัติ, การรีเฟรชโทเค็น IAM และการแปลง IP แบบไดนามิก - เฟรมเวิร์กที่ดำเนินการบนระบบคลาวด์แบบผสานรวม: กำหนดค่า Spring Boot, Quarkus (Agroal) และ Micronaut (HikariCP) โดยไม่มี Boilerplate ของพูลการเชื่อมต่อที่กำหนดเอง พร้อมคำแนะนำการสะท้อนสำหรับ GraalVM Native Image
- เชี่ยวชาญการแก้ปัญหา IAM: ได้เรียนรู้วิธีวินิจฉัยปัญหาการจัดรูปแบบชื่อผู้ใช้ การแอบอ้างเป็น ADC และการกำหนดเส้นทาง VPC