Springboot接口提交flink程序到集群当中

一、问题描述

由于我们编写的flink程序无法实现动态的管理,并且无法和前端进行交互,所以在数据中台的环境下,可以通过springboot的接口程序提交flink程序到集群当中去,或者是直接springboot集成flink的程序,接下来演示springboot提交程序到flink集群当中,整体架构如下所示

二、实现 

controller层

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springboot.flink.FlinkBean;
import springboot.service.FlinkService;

@RestController
@RequestMapping("/flink")
public class FlinkController {

    @Autowired
    private FlinkService flinkService;


    @GetMapping("/test2")
    public String test2(String arg1,String arg2,String arg3)
    {
        String args[]={arg1,arg2,arg3};
        String resultCommond = flinkService.buildCommond(args);
        String result = flinkService.exeCmd(resultCommond);
        return result;
    }
}

service层

package springboot.service;


import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStreamReader;

@Service
public class FlinkService {
    public String exeCmd(String commandStr) {

        String result = null;
        try {
            String[] cmd = new String[]{"/bin/sh", "-c",commandStr};
            Process ps = Runtime.getRuntime().exec(cmd);

            BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
            StringBuffer sb = new StringBuffer();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line).append("\n");
            }
            result = sb.toString();


        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;

    }
    public String buildCommond(String... args)
    {
        StringBuffer commond=new StringBuffer();
        commond.append("/opt/modul/flink/bin/flink run -d -c com.studyflink.paramerTest.FlinkParamerTest /opt/software/flink/flink-study-book-1.0-SNAPSHOT-jar-with-dependencies.jar");
        for(int i=0;i<args.length;i++)
        {
            commond.append(" "+args[i]);
        }
        return commond.toString();
    }
}

测试的flink代码

import com.studyflink.bean.Event;
import com.studyflink.commentUtils.ClickSource;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import com.studyflink.bean.Event;
import org.apache.flink.streaming.api.functions.source.SourceFunction;

import java.util.Calendar;
import java.util.Random;
public class FlinkParamerTest {
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(Integer.valueOf(args[0]));
        DataStreamSource<Event> dataStreamSource = env.addSource(new ClickSource());

        SingleOutputStreamOperator<String> mapStream = dataStreamSource.map(value -> {
            return value.getUser()+" 测试参数的flink程序";
        }).setParallelism(Integer.valueOf(args[1]));

        mapStream.print().setParallelism(Integer.valueOf(args[2]));
        env.execute();
    }
}



/**
 * @author :family
 * @date :2022/11/1 18:09
 */
class ClickSource implements SourceFunction<Event> {
    // 声明一个布尔变量,作为控制数据生成的标识位
    private Boolean running = true;
    @Override
    public void run(SourceContext<Event> ctx) throws Exception {
        Random random = new Random();    // 在指定的数据集中随机选取数据
        String[] users = {"Mary", "Alice", "Bob", "Cary"};
        String[] urls = {"./home", "./cart", "./fav", "./prod?id=1", "./prod?id=2"};

        while (running) {
            ctx.collect(new Event(
                    users[random.nextInt(users.length)],
                    urls[random.nextInt(urls.length)],
                    Calendar.getInstance().getTimeInMillis()
            ));
            // 隔1秒生成一个点击事件,方便观测
            Thread.sleep(1000);
        }
    }
    @Override
    public void cancel() {
        running = false;
    }
}

三、执行过程以及结果

前端调用接口,并且返回如下所示信息之后表示成功通过接口提交了flink程序到集群当中

 

四、总结 

通过前端api接口的形势来调用flink程序,可以随时修改flink的固定参数,例如,设置并行度,设置source端的数据源,设置sink的数据源,甚至设置transform端的转换规则都可以进行相应的设置

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将Spring BootFlink结合使用,可以按照以下步骤进行: 1. 在Spring Boot应用程序中添加Flink的依赖。可以在`pom.xml`文件中添加Flink的相关依赖,例如: ```xml <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-java</artifactId> <version>${flink.version}</version> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-streaming-java_2.11</artifactId> <version>${flink.version}</version> </dependency> ``` 2. 创建Flink的流处理程序。可以使用FlinkJava API编写数据处理代码,并在Spring Boot应用程序中调用该代码。例如: ```java StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); DataStream<String> stream = env.socketTextStream("localhost", 9999); DataStream<Tuple2<String, Integer>> counts = stream.flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() { @Override public void flatMap(String value, Collector<Tuple2<String, Integer>> out) { for (String word : value.split("\\s")) { out.collect(new Tuple2<>(word, 1)); } } }).keyBy(0).sum(1); counts.print(); env.execute("Word Count"); ``` 在上面的代码中,我们使用FlinkJava API创建了一个简单的单词计数程序,可以从本地的9999端口接收输入数据,并输出单词计数结果。然后,我们使用`env.execute()`方法来启动该程序。 3. 在Spring Boot应用程序中添加REST API,以便管理和监视Flink流处理程序。可以使用Spring Boot的`@RestController`注解来创建REST API,例如: ```java @RestController @RequestMapping("/flink") public class FlinkController { @Autowired private StreamExecutionEnvironment env; @RequestMapping("/start") public String start() throws Exception { DataStream<String> stream = env.socketTextStream("localhost", 9999); DataStream<Tuple2<String, Integer>> counts = stream.flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() { @Override public void flatMap(String value, Collector<Tuple2<String, Integer>> out) { for (String word : value.split("\\s")) { out.collect(new Tuple2<>(word, 1)); } } }).keyBy(0).sum(1); counts.print(); env.execute("Word Count"); return "Flink job started."; } } ``` 在上面的代码中,我们创建了一个`FlinkController`类,并在其中添加了一个`start()`方法,该方法可以启动我们之前创建的Flink流处理程序。然后,我们使用Spring Boot的`@RestController`和`@RequestMapping`注解将该方法暴露为REST API,可以通过`/flink/start`路径来访问该API。 4. 在Spring Boot应用程序中添加Web界面,以便监视和管理Flink流处理程序。可以使用Spring Boot的Thymeleaf模板引擎来创建Web界面,例如: ```html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Spring Boot + Flink</title> </head> <body> <h1>Spring Boot + Flink</h1> <form method="POST" action="/flink/start"> <button type="submit">Start Flink Job</button> </form> </body> </html> ``` 在上面的代码中,我们创建了一个简单的HTML页面,其中包含一个“Start Flink Job”按钮,可以用于启动我们之前创建的Flink流处理程序。我们使用Thymeleaf的模板语法来生成HTML页面。 通过以上步骤,我们就可以将Spring BootFlink结合使用,创建一个实时数据处理应用程序,并在Spring Boot应用程序中添加Web界面和REST API,以便监视和管理Flink流处理程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值