使用Google Dataflow向CloudSQL PostgreSQL写入数据时遇连接失败问题
尝试搭建基于Google Dataflow的ETL管道,将BigQuery数据写入CloudSQL PostgreSQL数据库时,连接CloudSQL实例失败。
代码实现
String jdbcConURL = "jdbc:postgresql://google/<db-name>?cloudSqlInstance=<project-id>:<region>:<instance-name>&socketFactory=com.google.cloud.sql.postgres.SocketFactory"; pipeline .apply( BigQueryIO.read() .fromQuery("select * from <big-query-table>") .usingStandardSql() .withoutValidation() ) .apply(JdbcIO.<TableRow>write() .withDataSourceConfiguration( JdbcIO.DataSourceConfiguration .create("org.postgresql.Driver", jdbcConURL) .withUsername("<username>") .withPassword("<password>") ) .withStatement("insert into <sql-table-name> values(?,?,?)")
错误信息
java.sql.SQLException: Cannot create PoolableConnectionFactory (The connection attempt failed.
java.net.UnknownHostException: google at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:220) at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403) at java.net.Socket.connect(Socket.java:609) at org.postgresql.core.PGStream.(PGStream.java:61) at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:121) ... 45 more
补全必要依赖
项目必须添加Cloud SQL PostgreSQL Socket Factory依赖,Maven配置示例:<dependency> <groupId>com.google.cloud.sql</groupId> <artifactId>postgres-socket-factory</artifactId> <version>1.15.0</version> <!-- 使用最新稳定版 --> </dependency>Gradle配置示例:
implementation 'com.google.cloud.sql:postgres-socket-factory:1.15.0'修正JDBC连接URL
原URL中的google主机名无法被解析,正确格式应省略具体主机名,改为:String jdbcConURL = "jdbc:postgresql:///<db-name>?cloudSqlInstance=<project-id>:<region>:<instance-name>&socketFactory=com.google.cloud.sql.postgres.SocketFactory";Socket Factory会自动处理Cloud SQL实例的连接逻辑,无需指定实际主机地址。
配置服务账号权限
运行Dataflow的服务账号必须拥有Cloud SQL Client角色(roles/cloudsql.client),确保其能通过Socket Factory连接Cloud SQL实例。检查实例状态与网络配置
确认Cloud SQL实例处于运行状态,若使用自定义VPC,需保证Dataflow作业的网络配置与Cloud SQL实例的VPC兼容。验证数据库用户权限
确保使用的数据库用户名拥有目标表的INSERT权限,且该用户允许通过Socket Factory连接(默认Socket Factory连接属于内部授权连接)。
内容的提问来源于stack exchange,提问作者Rakesh

