基于MRS-Flink组件开发问题:JdbcSink操作GaussDB(DWS)数据库报错No Route to Host

业务需用华为云平台FusionInsight Manager的Flink组件,实现源端数据向DWS数据库实时同步。在MRS工程加业务代码后启动程序报错,经测试排除数据库连接和业务逻辑问题,最终定位是数据库Url的IP问题,将其改为云端IP后程序正常运行。

       业务需求:应用华为云平台FusionInsight Manager中的Flink组件配合业务程序实现源端数据向DWS数据库的实时同步。

        在MRS二次开发样例工程的基础上加入自己的业务代码:

public class ReadFromKafka {

    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);
        ParameterTool paraTool = ParameterTool.fromArgs(args);
        Properties properties = paraTool.getProperties();

        DataStream<String> messageStream =
                env.addSource(
                        new FlinkKafkaConsumer<>(
                                paraTool.get("topic"), new SimpleStringSchema(), properties));

        SingleOutputStreamOperator<String> operator = messageStream.
                rebalance()
                .map(
                        new MapFunction<String, String>() {
                            @Override
                            public String map(String s) throws Exception {
                                return "Flink says => " + s + System.getProperty("line.separator");
                            }
                        });

        operator.addSink(JdbcSink.
                sink("insert into test.test_fff(fff)  values (?)",
                        (preparedStatement, s) -> {
                            preparedStatement.setString(1, s);
                        },
                        JdbcExecutionOptions.builder()
                                .withBatchSize(10)
                                .withBatchIntervalMs(1000)
                                .withMaxRetries(3)
                                .build(),
                        new JdbcConnectionOptions.JdbcConnectionOptionsBuilder()
                                .withDriverName("org.postgresql.Driver") 
                                .withUrl("jdbc:postgresql://xx.xxx.xxx.xxx:xxxx/GS_DW")// 数据库Url地址
                                .withUsername("username")
                                .withPassword("password")
                                .build()
                ));

        env.execute();
    }
}

        加入需求业务后启动程序,消息发送程序实时发送编辑好的Json字符串,启动ReakFromKafka接收并消费消息。此时发生报错“java.net.NoRouteToHostException: No route to host (Host unreachable)”,程序终止。报错信息:Caused by: java.net.NoRouteToHostException: No route to host (Host unreachable)

        数据库连接经过验证没有问题。(将数据库写入代码从addSink方法中取出,直接在main方法中执行入库正常,测试代码及数据库结果如下)

        

public class ReadFromKafka3 {

    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);
        ParameterTool paraTool = ParameterTool.fromArgs(args);
        Properties properties = paraTool.getProperties();

        DataStream<String> messageStream =
                env.addSource(
                        new FlinkKafkaConsumer<>(
                                paraTool.get("topic"), new SimpleStringSchema(), properties));


        tryInsert(new Worker(1, "jjj", "123@123.com", 22, new BigDecimal("553.212")));

        SingleOutputStreamOperator<String> operator = messageStream.
                rebalance()
                .map(
                        new MapFunction<String, String>() {
                            @Override
                            public String map(String s) throws Exception {
                                return "Flink says => " + s + System.getProperty("line.separator");
                            }
                        });

        env.execute();
    }


    public static void tryInsert(Worker worker) {
        String sql = "insert into test.worker(id, name, email, age, salary) values (? ,? ,? ,? ,? )";

        Connection conn = null;
        PreparedStatement ps = null;

        try {
            conn =DriverManager.getConnection("jdbc:postgresql://xx.xxx.xxx.xxx:xxxx/GS_DW",
                    "username", "password");
            ps = conn.prepareStatement(sql);

            ps.setInt(1, worker.getInteger("id"));
            ps.setString(2, worker.getString("name"));
            ps.setString(3, worker.getString("email"));
            ps.setInt(4, worker.getInteger("age"));
            ps.setBigDecimal(5, worker.getBigDecimal("salary"));

            ps.executeUpdate();
            System.out.println(" insert finished! ");

        } catch (Exception e) {
            System.out.println(" insert error : " + e.toString() + " , " + e.getCause());
            System.out.println("e.getMessage() = " + e.getMessage() + e.getLocalizedMessage());
            e.printStackTrace();
        } finally {
            DruidUtil.closePsConn(ps, conn);
        }
    }
}

操作结果:

 故问题定位就是只要将数据库操作代码放入addSink方法中就会报如上错误。PS:flink算子入库方法改为使用JdbcSinkFunction(继承 RichSinkFunction类)后报错还是一样,说明不是业务逻辑的问题。

 经过各种测试及查找资料,最终定位问题是数据库Url的IP问题。由于Flink程序是在云平台上运行,故此时需要将"jdbc:postgresql://xx.xxx.xxx.xxx:xxxx/GS_DW"中的IP改为云端IP,找云平台运维人员拿到云端IP并修改后程序即可正常运行。

Flink 是一个开源的流处理框架,`flink-connector-jdbc` 是 Flink 提供的用于连接 JDBC 数据源的连接器。以下是关于 `flink-connector-jdbc` 的 jar 包的一些信息: ### Maven 依赖 若使用 Maven 构建项目,可在 `pom.xml` 里添加如下依赖: ```xml <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-jdbc_2.12</artifactId> <version>1.13.2</version> </dependency> ``` 这里的版本号 `1.13.2` 可依据自身 Flink 版本进行调整。 ### Gradle 依赖 若使用 Gradle 构建项目,可在 `build.gradle` 中添加如下依赖: ```groovy implementation 'org.apache.flink:flink-connector-jdbc_2.12:1.13.2' ``` 同样,版本号需根据实际的 Flink 版本修改。 ### 手动下载 也能从 Maven 中央仓库手动下载 `flink-connector-jdbc` 的 jar 包。访问 [Maven 中央仓库](https://search.maven.org/),搜索 `flink-connector-jdbc`,选择合适的版本并下载对应的 jar 包。 ### 功能与用途 `flink-connector-jdbc` 这个 jar 包可让 Flink 与各类支持 JDBC 的数据库(像 MySQL、PostgreSQL、Oracle 等)进行交互,能够从数据库读取数据,也能将处理后的数据写数据库。 ### 使用示例 以下是使用 `flink-connector-jdbc` 从 MySQL 数据库读取数据的简单示例: ```java import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.connector.jdbc.JdbcSource; import org.apache.flink.connector.jdbc.JdbcConnectionOptions; import org.apache.flink.connector.jdbc.JdbcInputFormat; import org.apache.flink.connector.jdbc.JdbcStatementBuilder; import java.sql.PreparedStatement; import java.sql.SQLException; public class FlinkJdbcExample { public static void main(String[] args) throws Exception { StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); DataStream<Tuple2<Integer, String>> stream = env.createInput( JdbcSource.<Tuple2<Integer, String>>jdbcSource( "jdbc:mysql://localhost:3306/test", "SELECT id, name FROM users", new JdbcStatementBuilder<Tuple2<Integer, String>>() { @Override public void accept(PreparedStatement preparedStatement, Tuple2<Integer, String> integerStringTuple2) throws SQLException { // 这里不需要设置参数,因为是查询语句 } }, (resultSet, row) -> new Tuple2<>(resultSet.getInt(1), resultSet.getString(2)), new JdbcConnectionOptions.JdbcConnectionOptionsBuilder() .withDriverName("com.mysql.cj.jdbc.Driver") .withUsername("root") .withPassword("password") .build() ) ); stream.print(); env.execute("Flink JDBC Example"); } } ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值