flink数据分析(具体业务逻辑)

Handler 接口类

**
 * 定义处理接口
 */
public interface Handler {

    /**
     * 有抽象类的子类进行实现
     * @param posInfo
     * @param ruleParam
     * @param ctx
     * @param vehicleState
     * @param alarmState
     * @param out
     * @throws Exception
     */
    void handle(VehiclePosInfo posInfo, RuleParam ruleParam, KeyedBroadcastProcessFunction.ReadOnlyContext ctx, ValueState<VehicleState> vehicleState, MapState<String, AlarmEvent> alarmState, Collector<AlarmEvent> out, Map<Long, LimitSpeedData> limitSpeedDataMap) throws Exception;
}

基础处理器抽象类 StreamHandler.java

/**
 * 基础处理器抽象类
 */
@Slf4j
public abstract class StreamHandler implements Handler {
	  /**
     * 处理器名称
     */
    protected String handlerName;

    protected StreamHandler(String handlerName) {
        this.handlerName = handlerName;
    }

    public String getHandlerName() {
        return handlerName;
    }
    /**
     * 获取报警附加信息抽象方法,由子类去实现,非报警业务无需实现该方法
     *
     * @param extend
     * @param englishName
     * @param beginEvent  开始报警
     * @return
     */
    protected abstract String getAlarmAttachInfo(Map<String, Object> extend, RuleParam ruleParam, String englishName, boolean beginEvent);

 /**
     * 获取报警附加信息抽象方法,由子类去实现,非报警业务无需实现该方法
     *
     * @param extend
     * @param englishName
     * @param beginEvent  开始报警
     * @return
     */
    protected abstract String getPathName(Map<String, Object> extend, RuleParam ruleParam, String englishName, boolean beginEvent);

/**
     * 模板方法,做一些统一处理工作,过滤补传数据,设置行停状态等
     *
     * @param posInfo
     * @param ctx
     * @param lastVehicleState
     * @param alarmState
     * @param out
     */
    public void handleStream(VehiclePosInfo posInfo, RuleParam ruleParam, KeyedBroadcastProcessFunction.ReadOnlyContext ctx, ValueState<VehicleState> lastVehicleState, MapState<String, AlarmEvent> alarmState, Collector<AlarmEvent> out, Map<Long, LimitSpeedData> limitSpeedDataMap) throws Exception {

        handle(posInfo, ruleParam, ctx, lastVehicleState, alarmState, out,limitSpeedDataMap);

    }
     /**
     * 判断停车
     *
     * @return
     */
    protected boolean isStop(VehiclePosInfo posInfo) {

        return posInfo.getSpeed() == 0 || posInfo.getSpeed() < 5;
    }
     /**
     * 判断运行
     *
     * @return
     */
    protected boolean isRun(VehiclePosInfo posInfo) {
        return posInfo.getSpeed() > 5;
    }
    /**
     * @param englishAlarmName
     * @param posInfo
     * @param ruleParam
     * @param ctx
     * @param lastVehicleState
     * @param alarmState
     * @param out
     */
    protected void endAlarm(String englishAlarmName, VehiclePosInfo posInfo, RuleParam ruleParam, KeyedBroadcastProcessFunction.ReadOnlyContext ctx, ValueState<VehicleState> lastVehicleState, MapState<String, AlarmEvent> alarmState, Collector<AlarmEvent> out) throws Exception {
        this.alarmHandle(englishAlarmName, posInfo, ruleParam, ctx, lastVehicleState, alarmState, out, false, true);
    }
	
	/**
     * @param englishAlarmName
     * @param posInfo
     * @param ruleParam
     * @param ctx
     * @param lastVehicleState
     * @param alarmState
     * @param out
     */
    protected void beginAlarm(String englishAlarmName, VehiclePosInfo posInfo, RuleParam ruleParam, KeyedBroadcastProcessFunction.ReadOnlyContext ctx, ValueState<VehicleState> lastVehicleState, MapState<String, AlarmEvent> alarmState, Collector<AlarmEvent> out) throws Exception {
        this.alarmHandle(englishAlarmName, posInfo, ruleParam, ctx, lastVehicleState, alarmState, out, true, false);
    }
	
	/**
     * 通用报警处理方法
     *
     * @param englishAlarmName
     * @param posInfo
     * @param ruleParam
     * @param ctx
     * @param lastVehicleState
     * @param alarmState
     * @param out
     * @param existAlarm
     * @param lastExistAlarm
     * @throws Exception
     */
    protected void alarmHandle(String englishAlarmName, VehiclePosInfo posInfo, RuleParam ruleParam, KeyedBroadcastProcessFunction.ReadOnlyContext ctx, ValueState<VehicleState> lastVehicleState, MapState<String, AlarmEvent> alarmState, Collector<AlarmEvent> out, Boolean existAlarm, Boolean lastExistAlarm) throws Exception {
		//情况1 当前报警
        if (existAlarm) {
        	//1.1当前报警,上次不报警 ,产生开始报警事件(如果离线,也表示上次不报警)
            if (!lastExistAlarm) {
                // 获取是否高速上的标志
                //1.1.1产生开始报警事件
                AlarmEvent beginAlarmEvent = beginAlarmEvent(posInfo, lastVehicleState.value(), ruleParam, englishAlarmName, ctx);
                //1.1.2中间状态记录该报警事件
                alarmState.put(englishAlarmName, beginAlarmEvent);
                //1.1.3发送报警

                log.info("开始报警:{}", JSON.toJSONString(beginAlarmEvent));

                out.collect(beginAlarmEvent);
                //线上模式
                if (!Main.localMode) {
                    RedisDataUtil.updateAlarm(beginAlarmEvent,ctx);
                }

            }
          //1.2当前报警,上次报警  ,产生持续报警事件
            if (lastExistAlarm) {  
            	//1.2.1获取开始报警事件
                AlarmEvent beginAlarmEvent = alarmState.get(englishAlarmName);
                //持续报警次数加 1
                beginAlarmEvent.setAlarmNum(beginAlarmEvent.getAlarmNum() + 1);
                beginAlarmEvent.setSpeed(posInfo.getSpeed());
                //更新中间数据状态
                alarmState.put(englishAlarmName, beginAlarmEvent);
            }
        }
        // 情况2 当前不报警
        if (!existAlarm) { 
        	//2.1当前不报警,上次报警,产生结束报警事件,清除报警
            if (lastExistAlarm) {
            	//2.1.1获取开始报警事件
                AlarmEvent beginAlarmEvent = alarmState.get(englishAlarmName);
//                //2.1.2 产生结束报警事件
                AlarmEvent endAlarmEvent = endAlarmEvent(posInfo, lastVehicleState.value().getLastPosInfo(), englishAlarmName, ruleParam, beginAlarmEvent);
                //2.1.3 发送结束报警事件
                if (endAlarmEvent !=null){
                    out.collect(endAlarmEvent);
                    //2.1.4 中间状态清除该报警事件
                    log.info("删除报警车牌:{}",posInfo.getPlate());
                    alarmState.remove(englishAlarmName);
                    //线上模式
                   if (!Main.localMode) {
                       RedisDataUtil.updateAlarm(endAlarmEvent,ctx);
                    log.info("结束报警:{}", JSON.toJSONString(endAlarmEvent));
                   }

                }
            }
            //2.2当前不报警,上次不报警 (不做任何处理)
            if (!lastExistAlarm) {

            }
        }
        
	}
 /**
     * 构建开始报警事件
     *
     * @param posInfo
     * @param englishAlarmName
     * @return
     */
     protected AlarmEvent beginAlarmEvent(VehiclePosInfo posInfo, VehicleState state, RuleParam ruleParam, String englishAlarmName, KeyedBroadcastProcessFunction.ReadOnlyContext ctx) {
     	AlarmDefine alarmDefine = AlarmTypeCache.getAlarmDefine(englishAlarmName);
        if(alarmDefine==null){
            log.info("alarmDefine信息为空:{}",englishAlarmName);
            return null;
        }
		AlarmEvent event = new AlarmEvent();
        //设置基础属性
        setBaseProp(posInfo, event,alarmDefine);
        //结束status为1
        event.setStatus((byte) 1);
        event.setAlarmId(IdGenUtil.nextId());
        event.setAlarmNum(1);
        event.setAlarmClass(alarmDefine.getAlarmClass());
        event.setAlarmType(alarmDefine.getAlarmType());
        event.setChineseName(alarmDefine.getChineseName());
        event.setEnglishName(alarmDefine.getEnglishName());
        return event;
  
     }
**
     * 设置基础属性
     *
     * @param posInfo
     * @param event
     */
    protected void setBaseProp(VehiclePosInfo posInfo, AlarmEvent event,AlarmDefine alarmDefine) {
    		event.setVehicleId(posInfo.getVehicleId());
        event.setGroupId(posInfo.getGroupId());
        event.setPlate(posInfo.getPlate());
        event.setPlateColorByte(posInfo.getPlateColor());
        event.setEventTime(posInfo.getDevTime() != null ? posInfo.getDevTime().getTime() : 0);
        event.setCompanyGroupId(GroupCache.getCompanyId(Long.valueOf(event.getGroupId())));
        event.setLat(posInfo.getLat());
        event.setDirect(posInfo.getDirect() != null ? new Double(posInfo.getDirect()).intValue() : 0);
        event.setLon(posInfo.getLon());
        event.setType((byte) 2);
        event.setSpeed(posInfo.getSpeed());
        event.setVehicleShape(posInfo.getVehicleShape());
    }
/**
     * 构建结束报警事件
     *
     * @param posInfo
     * @param englishAlarmName
     * @param beginAlarmEvent
     * @return
     */
    protected AlarmEvent endAlarmEvent(VehiclePosInfo posInfo, VehiclePosInfo last, String englishAlarmName, RuleParam ruleParam, AlarmEvent beginAlarmEvent) {
    	.....具体逻辑	
    }
/**
     * 判断设备时间是否在时间范围内  精确到分钟  例:22:00_05:00、22:00:00_05:00:00 21:00_23:00
     *
     * @param rule
     * @param date
     * @return
     */
      protected static boolean isInTimeFrame(String rule, Date date){
	  	LocalDateTime currTime = LocalDateTimeUtil.of(date.getTime(), ZoneId.systemDefault());
        String currTimeStr = LocalDateTimeUtil.format(currTime, "HH:mm:ss");
        String[] times = null;
        if (rule.contains("_")){
            times = rule.split("_");
        }else if (rule.contains("-")){
            times = rule.split("-");
        }
        String startTime = null;
        String endTime = null;
        if (times[0].split(":").length==2){
            startTime = times[0]+":00";
            endTime = times[1]+":00";
        } else {
            startTime = times[0];
            endTime = times[1];
        }
        if(startTime.compareTo(endTime)>0){
            if(currTimeStr.compareTo(startTime)>=0||currTimeStr.compareTo(endTime)<=0){
                return true;
            }
        }else if(startTime.compareTo(endTime)<0){
            if(currTimeStr.compareTo(startTime)>=0&&currTimeStr.compareTo(endTime)<=0){
                return true;
            }
        }
        return false;
	  }
	/**
     * 判断两次定位数据是否夸天
     *
     * @return
     */
    protected boolean isCrossDay(Date currentDevTime, Date lastDevTime) {
        if (currentDevTime != null && lastDevTime != null) {
            return currentDevTime.getDay() != lastDevTime.getDay();
        }

        return false;
    }
 /**
     * @Title: timeDifference
     * @Description: 两个时间相差多少天多少小时多少分
     * @param @param t1
     * @param @param t2
     * @param @return 参数
     * @return String 返回类型
     * @throws
     */
	public static String timeDifference(long diff) {
		StringBuffer buf = new StringBuffer();
        // 时间差
//        long diff = Math.abs(t1 - t2);
        // 一天的毫秒数
        long nd = 1000 * 24 * 60 * 60;
        // 一小时的毫秒数
        long nh = 1000 * 60 * 60;
        // 一分钟的毫秒数
        long nm = 1000 * 60;
        // 一秒钟的毫秒数
        long ns = 1000;
        // 多少天
        long day = diff / nd;
        // 多少小时
        long hour = diff % nd / nh;
        // 多少分
        long min = diff % nd % nh / nm;
        // 多少秒
        long sec = diff % nd % nh % nm / ns;
        // x天 或者 ""
        buf.append(day > 0 ? day + "天" : "");
   
        // x时 或者 x时x分
        buf.append(hour > 0 ? hour + "小时" : (min > 0 ? (day > 0 ? hour + "小时" : "") + min + "分钟" : ""));
        // x分 或者 ""
        buf.append((hour > 0 && min > 0) ? min + "分钟" : "");
        // x秒 或者 ""
        buf.append((sec > 0) ? sec + "秒" : "");
        // 结果
        return buf.toString();
	}
}

具体业务的例子:超速报警分析
OverSpeedPlatform.java

**
 * @author ljy
 * 平台超速业务处理类
 */

@Slf4j
public class OverSpeedPlatform extends StreamHandler {
	public final static String OVER_SPEED = "overSpeedPlatform";
    public static String vehicleShape = null;
    public OverSpeedPlatform() {
        super("平台超速报警处理类");
    }
    @Override
    public void handle(VehiclePosInfo posInfo, RuleParam ruleParam, KeyedBroadcastProcessFunction.ReadOnlyContext ctx, ValueState<VehicleState> vehicleState, MapState<String, AlarmEvent> alarmState, Collector<AlarmEvent> out, Map<Long, LimitSpeedData> limitSpeedDataMap) throws Exception {
    	VehicleState state = vehicleState.value();
        VehiclePosInfo last = state.getLastPosInfo();
        boolean lastExistOverSpeedAlarm = alarmState.contains(OVER_SPEED);
        //离线需要结束掉报警
        if (isOffline(posInfo, last) && lastExistOverSpeedAlarm) {
            this.endAlarm(OVER_SPEED, posInfo, ruleParam, ctx, vehicleState, alarmState, out);
            lastExistOverSpeedAlarm = false;

        }
         vehicleShape = posInfo.getVehicleShape();
        if (vehicleShape == null) {
            return;
        }
        // 获取平台超速报警规则
        GeneralRule rulePlatform = ruleParam.getGeneralRuleMap().get(GeneralRuleType.OVER_SPEED_PLATFORM);
         if (posInfo.getPlate().equals(plate)){
            log.info("规则{}", JSON.toJSONString(rulePlatform));
        }
        // 规则参数
        String params;
        // 规则数组
        String [] param;
        // 车辆类型
        String vehicleShapeRule = null;
        // 限速值
        String speedlimit = null;
        // 持续时长
        String duration = null;
        // 超速比
        String overSpeedRatio = null;
        
        if (rulePlatform !=null){
        	 params = rulePlatform.getParam();
            if (params!=null){
                param = params.split(",");
                if (param.length == 4){
                    vehicleShapeRule = param[0];
                    speedlimit = param[1];
                    duration = param[2];
                    overSpeedRatio = param[3];
                }

            }
        }
        // 当规则车型为空时,判断上次是否存在报警,存在结束掉报警
            if (StringUtils.isBlank(vehicleShapeRule)) {
                if(lastExistOverSpeedAlarm){
                    this.endAlarm(OVER_SPEED, posInfo, ruleParam, ctx, vehicleState, alarmState, out);
                }
                return;
            }
            if (StringUtils.isNotBlank(vehicleShapeRule) && !vehicleShape.equals(vehicleShapeRule)){
                if (posInfo.getPlate().equals(plate)) {
                    log.info("当前车辆类型跟规则类型不一致");
                }
                if(lastExistOverSpeedAlarm){
                    this.endAlarm(OVER_SPEED, posInfo, ruleParam, ctx, vehicleState, alarmState, out);
                }
                return;
            }else {
            if(lastExistOverSpeedAlarm){
                this.endAlarm(OVER_SPEED, posInfo, ruleParam, ctx, vehicleState, alarmState, out);
            }
            return;
        }
        boolean existOverSpeedAlarm = existOverSpeedAlarm(posInfo, state, speedlimit, duration, overSpeedRatio);
        if(existOverSpeedAlarm){
            // 根据超速比推送报警等级
//            Integer alarmPushLevel = alarmPushAccordingToSpeedProportion(lastExistOverSpeedAlarm,existOverSpeedAlarm,ruleParam,OVER_SPEED,posInfo,out,alarmState,vehicleState,speedlimit);
            posInfo.getExtend().put(posInfo.getVehicleShape()+"超速比",speedlimit);
//            posInfo.getExtend().put("alarmPushLevel",alarmPushLevel);
            this.alarmHandle(OVER_SPEED, posInfo, ruleParam, ctx, vehicleState, alarmState, out, true, lastExistOverSpeedAlarm);
            // 这里做风险逻辑处理
//            DealRiskPush.dealRiskLevelData(vehicleState, alarmState, out, OVER_SPEED, lastExistOverSpeedAlarm, true, posInfo,Double.parseDouble(speedlimit),false);
        }  else if (lastExistOverSpeedAlarm) {
            // 这里做风险逻辑处理
//            DealRiskPush.dealRiskLevelData(vehicleState, alarmState, out, OVER_SPEED, true, false, posInfo,Double.parseDouble(speedlimit),false);
            this.alarmHandle(OVER_SPEED, posInfo, ruleParam, ctx, vehicleState, alarmState, out, false, true);
            //不存在报警,清空报警开始时间
            state.setStartOverSpeedTime(null);
        }  
    }
    @Override
    protected String getPathName(Map<String, Object> extend, RuleParam ruleParam, String englishName, boolean beginEvent) {
        return null;
    }
	private boolean existOverSpeedAlarm(VehiclePosInfo posInfo, VehicleState state, String speedLimit, String duration,String overSpeedRate) {	
		boolean existAlarm = false;
		if (StringUtils.isNotBlank(speedLimit)) {
			boolean sign = posInfo.getSpeed().intValue() > (Double.parseDouble(speedLimit) + (Double.parseDouble(speedLimit) * (overSpeedRate==null?0:Double.parseDouble(overSpeedRate) / 100)));
            if (sign) {
                //判断是否是第一次
                if (state.getStartOverSpeedTime() == null) {
                    state.setStartOverSpeedTime(posInfo.getDevTime());
                } else {
                    //判断是否大于规则设置的持续时间
                    if (posInfo.getDevTime().getTime() - state.getStartOverSpeedTime().getTime() > (duration == null?0:Integer.parseInt(duration))*1000) {
                        existAlarm = true;
                    }
                }
            }
		}
		 return existAlarm;
	}
@Override
    protected String getAlarmAttachInfo(Map<String, Object> extend, RuleParam ruleParam, String englishName, boolean beginEvent) {

        if(OVER_SPEED.equals(englishName)){
            if (StringUtils.isNotBlank(vehicleShape)) {
                if(extend.get(vehicleShape+"超速比")!=null){
                    return (String) extend.get(vehicleShape+"超速比");
                }
            }
        }
        return null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在这个科技高速发展的时代,经历了PC时代几乎人手一台电脑,随之衍生出站长这个概念;移动互联网时代几乎人手一部智能手机,智能手机一般都会安装很多应用,目前应用呈爆发式的增长;随着产业的不断深入发展,小程序的发展也日益壮大,应用涵盖各个领域;如今一个公司就可能有多个软件应用,对于软件开发商来说,急需一套分析系统帮助软件运营,如果单独开发一个分析系统去针对一个软件进行分析的话,成本会非常的大,这个成本包含开发成本以及以后的维护成本。为了解决了上述的问题,我们开发出了一套云产品:亿级动态数据统计分析系统,本系统可以支持所有的终端  (Web端、移动端、小程序端等 )数据统计,只要简单的使用sdk就可以接入我们的系统,软件开发商可以很轻松的对软件使用的情况进行监控,及时辅助公司对该软件的运营。该产品历经2年的实践,商业价值极高。本套案例是完全基于真实的产品进行开发和讲解的,同时对架构进行全面的升级,采用了全新的 Flink 架构+Node.js+Vue.js等,完全符合目前企业级的使用标准。对于本套课程在企业级应用的问题,可以提供全面的指导。Flink作为第四代大数据计算引擎,越来越多的企业在往Flink转换。Flink在功能性、容错性、性能方面都远远超过其他计算框架,兼顾高吞吐和低延时。Flink能够基于同一个Flink运行时,提供支持流处理和批处理两种类型应用的功能。也就是说同时支持流处理和批处理。Flink将流处理和批处理统一起来,也就是说作为流处理看待时输入数据流是无界的;批处理被作为一种特殊的流处理,只是它的输入数据流被定义为有界的。Flink技术特点1. 流处理特性支持高吞吐、低延迟、高性能的流处理支持带有事件时间的窗口(Window)操作支持有状态计算的Exactly-once语义支持高度灵活的窗口(Window)操作,支持基于time、count、session,以及data-driven的窗口操作支持具有Backpressure功能的持续流模型支持基于轻量级分布式快照(Snapshot)实现的容错一个运行时同时支持Batch on Streaming处理和Streaming处理Flink在JVM内部实现了自己的内存管理支持迭代计算支持程序自动优化:避免特定情况下Shuffle、排序等昂贵操作,间结果有必要进行缓存2. API支持对Streaming数据类应用,提供DataStream API对批处理类应用,提供DataSet API(支持Java/Scala)3. Libraries支持支持机器学习(FlinkML)支持图分析(Gelly)支持关系数据处理(Table)支持复杂事件处理(CEP)4. 整合支持支持Flink on YARN支持HDFS支持来自Kafka的输入数据支持Apache HBase支持Hadoop程序支持Tachyon支持ElasticSearch支持RabbitMQ支持Apache Storm支持S3支持XtreemFS课程所涵盖的知识点包括:Flink、 Node.js、 Vue.js、 Kafka、Flume、Spring、SpringMVC、Dubbo、HDFS、Hbase、Highcharts等等  企业一线架构师讲授,代码在老师指导下可以复用,提供企业解决方案。  版权归作者所有,盗版将进行法律维权。   
### 回答1: Flink是一个开源的大数据处理框架,可以用于实时流处理和批处理。 使用Java编写Flink代码需要几个步骤: 1. 创建Maven项目并添加Flink依赖。 在pom.xml文件加入如下依赖: ``` <dependencies> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-java</artifactId> <version>1.12.0</version> </dependency> </dependencies> ``` 2. 创建数据源。 Flink支持多种数据源,比如文件、Kafka、Socket等。你可以使用如下代码创建一个文件数据源: ``` // 创建数据源 DataStream<String> text = env.readTextFile("file:///path/to/file"); ``` 3. 定义转换操作。 Flink支持许多转换操作,比如map、filter、reduce等。你可以使用如下代码对数据流的每条记录执行map操作: ``` // 定义转换操作 DataStream<Integer> numbers = text.map(new MapFunction<String, Integer>() { @Override public Integer map(String value) throws Exception { return Integer.parseInt(value); } }); ``` 4. 定义数据分流逻辑。 Flink提供了split和select操作来实现数据分流。你可以使用如下代码对数据流进行分流: ``` // 定义数据分流逻辑 SplitStream<Integer> splitStream = numbers.split(new OutputSelector<Integer>() { @Override public Iterable<String> select(Integer value) { List<String> outputs = new ArrayList<>(); if (value % 2 == 0) { outputs.add("even"); ### 回答2: Flink 是一个开源的流处理框架,使用 Java 编写 Flink 分流代码可以帮助我们对数据进行高效的处理和分析。下面是一个简单的示例: ```java // 导入必要的包 import org.apache.flink.api.common.functions.MapFunction; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.datastream.SplitStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; public class FlinkDataStreamSplitExample { public static void main(String[] args) throws Exception { // 创建 Flink 执行环境 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 生成一个包含一系列整数的输入流 DataStream<Integer> input = env.fromElements(1, 2, 3, 4, 5); // 使用 MapFunction 将输入流分成两个流 SplitStream<Integer> splitStream = input.split(new MySplitter()); // 通过选择器选择不同的输出流并进行处理 DataStream<Integer> evenStream = splitStream.select("even"); DataStream<Integer> oddStream = splitStream.select("odd"); // 在控制台打印偶数流和奇数流 evenStream.print(); oddStream.print(); // 执行作业 env.execute("Flink Data Stream Split Example"); } // 自定义分流逻辑 public static class MySplitter implements org.apache.flink.streaming.api.collector.selector.OutputSelector<Integer> { @Override public Iterable<String> select(Integer value) { if (value % 2 == 0) { // 偶数流选择器 return Collections.singletonList("even"); } else { // 奇数流选择器 return Collections.singletonList("odd"); } } } } ``` 这段代码首先导入 Flink 相关的包,并创建了一个 Flink 执行环境。然后,它生成了一个包含一系列整数的输入流。接下来使用 `MapFunction` 对输入流进行分流操作,将其分成两个流,其一个流包含偶数,另一个流包含奇数。再通过选择器选择要处理的流,并在控制台打印。最后,使用 `execute` 方法执行 Flink 作业。 这只是一个简单的示例,实际业务场景会更加复杂。在实际应用,我们可以根据具体需求自定义分流逻辑,以便更好地处理数据。 ### 回答3: 使用Java编写flink数据分流代码可以借助DataStream API来实现。首先,我们需要创建一个ExecutionEnvironment或者StreamExecutionEnvironment对象来执行任务,并导入必要的flink依赖包。 以下是一个示例代码,演示了如何使用Java编写flink数据分流代码: ```java import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.datastream.SplitStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; public class DataStreamSplitExample { public static void main(String[] args) throws Exception { // 创建执行环境 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 创建数据流 DataStream<String> inputDataStream = env.socketTextStream("localhost", 9999); // 对数据流进行分流处理 SplitStream<Tuple2<String, Integer>> splitStream = inputDataStream .flatMap((String value, Collector<Tuple2<String, Integer>> out) -> { // 对数据进行拆分,生成一个新的数据流 String[] words = value.split(" "); for (String word : words) { out.collect(new Tuple2<>(word, 1)); } }) .split((OutputSelector<Tuple2<String, Integer>>) value -> { // 通过定义OutputSelector来对数据流进行分流 List<String> output = new ArrayList<>(); if (value.f0.contains("java")) { output.add("java"); } else if (value.f0.contains("python")) { output.add("python"); } else { output.add("other"); } return output; }); // 获取分流后的数据流 DataStream<Tuple2<String, Integer>> javaDataStream = splitStream.select("java"); DataStream<Tuple2<String, Integer>> pythonDataStream = splitStream.select("python"); DataStream<Tuple2<String, Integer>> otherDataStream = splitStream.select("other"); // 打印结果 javaDataStream.print("Java Stream"); pythonDataStream.print("Python Stream"); otherDataStream.print("Other Stream"); // 执行任务 env.execute("DataStreamSplitExample"); } } ``` 在上述代码,我们首先创建了一个执行环境,并使用socketTextStream方法创建了一个输入数据流。然后,通过对数据流进行flatMap操作,将输入数据拆分成一个新的数据流。接着,使用split方法对新的数据流进行分流,根据指定的条件将数据流分为不同的子流。最后,通过select方法获取分流后的子流,并通过print方法打印结果。最后,执行任务并指定任务名称为"DataStreamSplitExample"。 以上是一个简单的例子,可以根据实际需求和数据类型进行相应的调整和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值