解决N+1问题的另一种方法 - 关联的多结果集ResultSet

文章介绍了MyBatis从3.2.3版本开始支持的解决N+1查询问题的新方法——关联的多结果集(ResultSet)。通过存储过程返回多个结果集,可以在不使用连接的情况下,仅访问数据库一次获取相关数据。文中提供了一个创建存储过程的例子,并展示了如何在映射语句中配置resultSets属性以及resultMap,以填充关联的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果我的博客对你有帮助,欢迎进行评论✏️✏️、点赞👍👍、收藏⭐️⭐️,满足一下我的虚荣心💖🙏🙏🙏 。

从版本 3.2.3 开始,MyBatis 提供了另一种解决 N+1 查询问题的方法--关联的多结果集(ResultSet)
某些数据库允许存储过程返回多个结果集,或一次性执行多个语句,每个语句返回一个结果集。 我们可以利用这个特性,在不使用连接的情况下,只访问数据库一次就能获得相关数据。

先介绍下它的属性:

column:当使用多个结果集时,该属性指定结果集中用于与 foreignColumn 匹配的列(多个列名以逗号隔开),以识别关系中的父类型与子类型。
foreignColumn:指定外键对应的列名,指定的列将与父类型中 column 的给出的列进行匹配。
resultSet:指定用于加载复杂类型的结果集名字。

首先新建一个简单的存储过程,存储过程执行两个查询语句返回两个结果集。第一个结果集会返回User的结果,第二个则返回Wife的结果,如下:

DELIMITER $$
CREATE PROCEDURE `uwife`(IN `userId` INT)
BEGIN
	SELECT * FROM mybatis_user WHERE id = userId;
	SELECT * FROM mybatis_wife WHERE user_id = userId;
END $$

在映射语句中,必须通过 resultSets 属性为每个结果集指定一个名字,多个名字使用逗号隔开。

<select id="selectByResultSet" resultSets="uresult,wresult" 
    resultMap="userResultByResultSet" statementType="CALLABLE">
        {call uwife(#{userId,jdbcType=INTEGER,mode=IN})}
    </select>

现在我们可以指定使用 “wresult” 结果集的数据来填充 “wife” 关联:

<resultMap id="userResultByResultSet" type="User">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="sex" column="sex"/>
        <result property="age" column="age"/>
        <result property="province" column="province"/>
        <result property="city" column="city"/>
        <result property="createdTime" column="created_time"/>
        <result property="createdBy" column="created_by"/>
        <result property="updatedTime" column="updated_time"/>
        <result property="updatedBy" column="updated_by"/>
        <association property="wife" javaType="Wife" resultSet="wresult" column="id" foreignColumn="user_id">
            <id property="wifeId" column="wife_id"/>
            <result property="userId" column="user_id"/>
            <result property="wifeName" column="wife_name"/>
        </association>
    </resultMap>

完成!

补充一下:

上面xml文件中有一个statementType,它是用来标记在mapper文件中使用什么的对象操作SQL语句。 
要实现动态传入表名、列名,需要做如下修改 ,添加属性statementType=”STATEMENT” ,同时sql里的属有变量取值都改成${xxxx},而不是#{xxx}
取值说明: 
1、STATEMENT:直接操作sql,不进行预编译,获取数据:$—Statement 
2、PREPARED:预处理,参数,进行预编译,获取数据:#—–PreparedStatement:默认 
3、CALLABLE:执行存储过程————CallableStatement 

具体的使用网上自行查阅。

如果我的博客对你有帮助,欢迎进行评论✏️✏️、点赞👍👍、收藏⭐️⭐️,满足一下我的虚荣心💖🙏🙏🙏 。

package com.tongchuang.realtime.mds; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.tongchuang.realtime.bean.ULEParamConfig; import com.tongchuang.realtime.util.KafkaUtils; import org.apache.flink.api.common.eventtime.WatermarkStrategy; import org.apache.flink.api.common.state.; import org.apache.flink.api.common.time.Time; import org.apache.flink.api.common.typeinfo.BasicTypeInfo; import org.apache.flink.api.common.typeinfo.TypeInformation; import org.apache.flink.configuration.Configuration; import org.apache.flink.connector.kafka.source.KafkaSource; import org.apache.flink.connector.kafka.source.enumerator.initializer.OffsetsInitializer; import org.apache.flink.streaming.api.datastream.; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.api.functions.co.KeyedBroadcastProcessFunction; import org.apache.flink.streaming.api.functions.source.RichSourceFunction; import org.apache.flink.util.Collector; import org.apache.flink.util.OutputTag; import java.io.Serializable; import java.sql.; import java.text.SimpleDateFormat; import java.util.; import java.util.Date; import java.util.concurrent.TimeUnit; public class ULEDataanomalyanalysis { public static void main(String[] args) throws Exception { final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.setParallelism(1); // 创建Kafka消费者 KafkaSource kafkaConsumer = KafkaUtils.getKafkaConsumer( “realdata_minute”, “minutedata_uledataanomalyanalysis”, OffsetsInitializer.latest() ); DataStreamSource kafkaDS = env.fromSource( kafkaConsumer, WatermarkStrategy.noWatermarks(), “realdata_uledataanomalyanalysis” ); kafkaDS.print(“分钟数据流”); // 解析JSON并拆分每个tag的数据 SingleOutputStreamOperator splitStream = kafkaDS .map(JSON::parseObject) .flatMap((JSONObject value, Collector out) -> { JSONObject data = value.getJSONObject(“datas”); String time = value.getString(“times”); for (String tag : data.keySet()) { JSONObject tagData = data.getJSONObject(tag); JSONObject newObj = new JSONObject(); newObj.put(“time”, time); newObj.put(“tag”, tag); newObj.put(“ontime”, tagData.getDouble(“ontime”)); newObj.put(“avg”, tagData.getDouble(“avg”)); out.collect(newObj); } }) .returns(TypeInformation.of(JSONObject.class)) .name(“Split-By-Tag”); // 每5分钟加载参数配置 DataStream configDataStream = env .addSource(new MysqlConfigSource()) .setParallelism(1) .filter(Objects::nonNull) .name(“Config-Source”); // 将配置流转换为广播流 BroadcastStream configBroadcastStream = configDataStream .broadcast(Descriptors.configStateDescriptor); // 按tag分组并连接广播流 KeyedStream<JSONObject, String> keyedStream = splitStream .keyBy(json -> json.getString(“tag”)); BroadcastConnectedStream<JSONObject, ConfigCollection> connectedStream = keyedStream.connect(configBroadcastStream); // 异常检测处理 SingleOutputStreamOperator anomalyStream = connectedStream .process(new OptimizedAnomalyDetectionFunction()) .name(“Anomaly-Detection”); anomalyStream.print(“异常检测结果”); // anomalyStream.map(JSON::toString).addSink(KafkaUtils.getKafkaSink(“minutedata_uleanomaly”)); env.execute(“uledataanomalyanalysis”); } // 配置集合类 - 添加检查点时间 public static class ConfigCollection implements Serializable { private static final long serialVersionUID = 1L; public final Map<String, List> tagToConfigs; public final Map<String, ULEParamConfig> encodeToConfig; public final Set allTags; public final long checkpointTime; // 配置加载的时间戳 public ConfigCollection(Map<String, List> tagToConfigs, Map<String, ULEParamConfig> encodeToConfig) { this.tagToConfigs = new HashMap<>(tagToConfigs); this.encodeToConfig = new HashMap<>(encodeToConfig); this.allTags = new HashSet<>(tagToConfigs.keySet()); this.checkpointTime = System.currentTimeMillis(); // 记录配置加载时间 } } // MySQL配置源 public static class MysqlConfigSource extends RichSourceFunction { private volatile boolean isRunning = true; private final long interval = TimeUnit.MINUTES.toMillis(5); @Override public void run(SourceContext ctx) throws Exception { while (isRunning) { ConfigCollection newConfig = loadParams(); if (newConfig != null) { ctx.collect(newConfig); System.out.println("配置加载完成,检查点时间: " + new Date(newConfig.checkpointTime)); } else { System.out.println(“配置加载失败”); } Thread.sleep(interval); } } private ConfigCollection loadParams() { Map<String, List> tagToConfigs = new HashMap<>(5000); Map<String, ULEParamConfig> encodeToConfig = new HashMap<>(5000); String url = “jdbc:mysql://10.51.37.73:3306/eps?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8”; String user = “root”; String password = “6CKIm5jDVsLrahSw”; String query = "SELECT F_tag AS tag, F_enCode AS encode, F_dataTypes AS datatype, " + "F_isConstantValue AS constantvalue, F_isOnline AS isonline, " + "F_isSync AS issync, F_syncParaEnCode AS syncparaencode, " + "F_isZero AS iszero, F_isHigh AS ishigh, F_highThreshold AS highthreshold, " + "F_isLow AS islow, F_lowThreshold AS lowthreshold, F_duration AS duration " + "FROM t_equipmentparameter " + "WHERE F_enabledmark = ‘1’ AND (F_isConstantValue =‘1’ OR F_isZero= ‘1’ " + “OR F_isHigh = ‘1’ OR F_isLow = ‘1’ OR F_isOnline = ‘1’ OR F_isSync = ‘1’)”; try (Connection conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(query)) { while (rs.next()) { ULEParamConfig config = new ULEParamConfig(); config.tag = rs.getString(“tag”); config.encode = rs.getString(“encode”); config.datatype = rs.getString(“datatype”); config.constantvalue = rs.getInt(“constantvalue”); config.iszero = rs.getInt(“iszero”); config.ishigh = rs.getInt(“ishigh”); config.highthreshold = rs.getDouble(“highthreshold”); config.islow = rs.getInt(“islow”); config.lowthreshold = rs.getDouble(“lowthreshold”); config.duration = rs.getLong(“duration”); config.isonline = rs.getInt(“isonline”); config.issync = rs.getInt(“issync”); config.syncparaencode = rs.getString(“syncparaencode”); // 跳过无效配置 if (config.encode == null || config.encode.isEmpty()) { System.err.println(“忽略无效配置: 空encode”); continue; } String tag = config.tag; tagToConfigs.computeIfAbsent(tag, k -> new ArrayList<>(10)).add(config); encodeToConfig.put(config.encode, config); } System.out.println(“加载配置: " + encodeToConfig.size() + " 个参数”); return new ConfigCollection(tagToConfigs, encodeToConfig); } catch (SQLException e) { System.err.println(“加载参数配置错误:”); e.printStackTrace(); return null; } } @Override public void cancel() { isRunning = false; } } // 状态描述符 public static class Descriptors { public static final MapStateDescriptor<Void, ConfigCollection> configStateDescriptor = new MapStateDescriptor<>( “configState”, TypeInformation.of(Void.class), TypeInformation.of(ConfigCollection.class) ); } // 优化后的异常检测函数(无定时器实现) public static class OptimizedAnomalyDetectionFunction extends KeyedBroadcastProcessFunction<String, JSONObject, ConfigCollection, JSONObject> { // 状态管理 private transient MapState<String, AnomalyState> stateMap; // key=encode private transient MapState<String, Double> lastValuesMap; // key=tag private transient MapState<String, Long> lastDataTimeMap; // key=tag private transient ValueState lastCheckpointState; // 记录该tag上次处理的检查点时间 private transient SimpleDateFormat timeFormat; // 日志频率控制 private transient long lastSyncLogTime = 0; // 侧输出标签用于离线检测 private static final OutputTag OFFLINE_CHECK_TAG = new OutputTag(“offline-check”){}; @Override public void open(Configuration parameters) { // 状态TTL配置(30天自动清理) StateTtlConfig ttlConfig = StateTtlConfig.newBuilder(Time.days(300)) .setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite) .setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired) .cleanupFullSnapshot() .build(); // 初始化异常状态存储(启用TTL) MapStateDescriptor<String, AnomalyState> stateDesc = new MapStateDescriptor<>( “anomalyState”, BasicTypeInfo.STRING_TYPE_INFO, TypeInformation.of(AnomalyState.class) ); stateDesc.enableTimeToLive(ttlConfig); stateMap = getRuntimeContext().getMapState(stateDesc); // 初始化最新值存储(启用TTL) MapStateDescriptor<String, Double> valuesDesc = new MapStateDescriptor<>( “lastValuesState”, BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.DOUBLE_TYPE_INFO ); valuesDesc.enableTimeToLive(ttlConfig); lastValuesMap = getRuntimeContext().getMapState(valuesDesc); // 初始化最后数据时间存储(启用TTL) MapStateDescriptor<String, Long> timeDesc = new MapStateDescriptor<>( “lastDataTimeState”, BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.LONG_TYPE_INFO ); timeDesc.enableTimeToLive(ttlConfig); lastDataTimeMap = getRuntimeContext().getMapState(timeDesc); // 初始化检查点状态(记录上次处理的配置时间) ValueStateDescriptor checkpointDesc = new ValueStateDescriptor<>( “lastCheckpointState”, BasicTypeInfo.LONG_TYPE_INFO ); checkpointDesc.enableTimeToLive(ttlConfig); lastCheckpointState = getRuntimeContext().getState(checkpointDesc); timeFormat = new SimpleDateFormat(“yyyy-MM-dd HH:mm”); } @Override public void processElement(JSONObject data, ReadOnlyContext ctx, Collector out) throws Exception { String tag = ctx.getCurrentKey(); String timeStr = data.getString(“time”); long eventTime = timeFormat.parse(timeStr).getTime(); // 更新最后数据时间 lastDataTimeMap.put(tag, eventTime); // 获取广播配置 ConfigCollection configCollection = getBroadcastConfig(ctx); if (configCollection == null) { return; } List configs = configCollection.tagToConfigs.get(tag); if (configs == null || configs.isEmpty()) { return; } // 跟踪已恢复的tag Set recoveredTags = new HashSet<>(); // ========== 清理无效状态 ========== // 修复:使用临时列表避免ConcurrentModificationException List keysToRemove = new ArrayList<>(); for (String encode : stateMap.keys()) { boolean found = false; for (ULEParamConfig cfg : configs) { if (cfg.encode.equals(encode)) { found = true; break; } } if (!found) { System.out.println("清理过期状态: " + encode); keysToRemove.add(encode); } } for (String encode : keysToRemove) { stateMap.remove(encode); } // ========== 检查离线状态(基于配置检查点) ========== Long lastCP = lastCheckpointState.value(); if (lastCP == null || configCollection.checkpointTime > lastCP) { // 新配置到达,检查离线状态 for (ULEParamConfig config : configs) { if (config.isonline == 1) { // 获取该tag的最后数据时间 Long lastEventTime = lastDataTimeMap.get(tag); if (lastEventTime == null) { // 从未收到数据,触发离线报警 AnomalyState state = getOrCreateState(config.encode); AnomalyStatus status = state.getStatus(5); if (!status.reported) { // 使用超时时间点作为触发时间 long timeoutPoint = configCollection.checkpointTime; String triggerTime = timeFormat.format(new Date(timeoutPoint)); reportAnomaly(5, 1, 0.0, triggerTime, config, out); status.reported = true; stateMap.put(config.encode, state); } } else { // 计算超时时间点:检查点时间 - duration long timeoutPoint = configCollection.checkpointTime - config.duration * 60 * 1000; if (lastEventTime < timeoutPoint) { // 触发离线报警 AnomalyState state = getOrCreateState(config.encode); AnomalyStatus status = state.getStatus(5); if (!status.reported) { // 使用超时时间点作为触发时间 String triggerTime = timeFormat.format(new Date(timeoutPoint)); reportAnomaly(5, 1, 0.0, triggerTime, config, out); status.reported = true; stateMap.put(config.encode, state); } } } } } // 更新检查点状态 lastCheckpointState.update(configCollection.checkpointTime); } double value = 0; boolean valueSet = false; // 遍历配置项进行异常检测 for (ULEParamConfig config : configs) { if (!valueSet) { value = “436887485805570949”.equals(config.datatype) ? data.getDouble(“ontime”) : data.getDouble(“avg”); lastValuesMap.put(tag, value); valueSet = true; } // 获取或初始化状态 AnomalyState state = getOrCreateState(config.encode); // ========== 离线恢复检测 ========== if (config.isonline == 1) { AnomalyStatus status = state.getStatus(5); if (status.reported) { // 设备重新上线,发送恢复事件 if (!recoveredTags.contains(tag)) { // 使用当前系统时间作为恢复时间 String recoveryTime = timeFormat.format(new Date()); reportAnomaly(5, 0, 0.0, recoveryTime, config, out); status.reset(); recoveredTags.add(tag); // 标记该tag已恢复 System.out.println(“设备 " + tag + " 恢复在线”); } } } // 处理异常类型 checkConstantValueAnomaly(config, value, timeStr, state, out); checkZeroValueAnomaly(config, value, timeStr, state, out); checkThresholdAnomaly(config, value, timeStr, state, out); checkSyncAnomaly(config, value, timeStr, state, configCollection, out); // 保存状态 stateMap.put(config.encode, state); } } // 恒值检测 private void checkConstantValueAnomaly(ULEParamConfig config, double currentValue, String timeStr, AnomalyState state, Collector out) { if (config.constantvalue != 1) return; try { AnomalyStatus status = state.getStatus(1); long durationThreshold = config.duration * 60 * 1000; Date timestamp = timeFormat.parse(timeStr); if (status.lastValue == null) { status.lastValue = currentValue; status.lastChangeTime = timestamp; return; } if (Math.abs(currentValue - status.lastValue) > 0.001) { status.lastValue = currentValue; status.lastChangeTime = timestamp; if (status.reported) { reportAnomaly(1, 0, currentValue, timeStr, config, out); } status.reset(); return; } long elapsed = timestamp.getTime() - status.lastChangeTime.getTime(); if (elapsed > durationThreshold) { if (!status.reported) { reportAnomaly(1, 1, currentValue, timeStr, config, out); status.reported = true; } } } catch (Exception e) { System.err.println("恒值检测错误: " + config.encode + " - " + e.getMessage()); } } // 零值检测 private void checkZeroValueAnomaly(ULEParamConfig config, double currentValue, String timeStr, AnomalyState state, Collector out) { if (config.iszero != 1) return; try { AnomalyStatus status = state.getStatus(2); Date timestamp = timeFormat.parse(timeStr); boolean isZero = Math.abs(currentValue) < 0.001; if (isZero) { if (status.startTime == null) { status.startTime = timestamp; } else if (!status.reported) { long elapsed = timestamp.getTime() - status.startTime.getTime(); if (elapsed >= config.duration * 60 * 1000) { reportAnomaly(2, 1, currentValue, timeStr, config, out); status.reported = true; } } } else { if (status.reported) { reportAnomaly(2, 0, currentValue, timeStr, config, out); status.reset(); } else if (status.startTime != null) { status.startTime = null; } } } catch (Exception e) { System.err.println("零值检测错误: " + config.encode + " - "+e.getMessage()); } } // 阈值检测 private void checkThresholdAnomaly(ULEParamConfig config, double currentValue, String timeStr, AnomalyState state, Collector out) { try { if (config.ishigh == 1) { AnomalyStatus highStatus = state.getStatus(3); processThresholdAnomaly(highStatus, currentValue, timeStr, currentValue > config.highthreshold, config, 3, out); } if (config.islow == 1) { AnomalyStatus lowStatus = state.getStatus(4); processThresholdAnomaly(lowStatus, currentValue, timeStr, currentValue < config.lowthreshold, config, 4, out); } } catch (Exception e) { System.err.println("阈值检测错误: " + config.encode + " - " + e.getMessage()); } } private void processThresholdAnomaly(AnomalyStatus status, double currentValue, String timeStr, boolean isAnomaly, ULEParamConfig config, int anomalyType, Collector out) { try { Date timestamp = timeFormat.parse(timeStr); if (isAnomaly) { if (status.startTime == null) { status.startTime = timestamp; } else if (!status.reported) { long elapsed = timestamp.getTime() - status.startTime.getTime(); if (elapsed >= config.duration * 60 * 1000) { reportAnomaly(anomalyType, 1, currentValue, timeStr, config, out); status.reported = true; } } } else { if (status.reported) { reportAnomaly(anomalyType, 0, currentValue, timeStr, config, out); status.reset(); } else if (status.startTime != null) { status.startTime = null; } } } catch (Exception e) { System.err.println("阈值处理错误: " + config.encode + " - " + e.getMessage()); } } // 同步检测 - 优化实现 private void checkSyncAnomaly(ULEParamConfig config, double currentValue, String timeStr, AnomalyState state, ConfigCollection configCollection, Collector out) { if (config.issync != 1 || config.syncparaencode == null) return; try { // 日志频率控制:每分钟最多打印一次 long now = System.currentTimeMillis(); if (now - lastSyncLogTime > 60000) { System.out.println("同步检测 - 当前配置: " + config); lastSyncLogTime = now; } AnomalyStatus status = state.getStatus(6); Date timestamp = timeFormat.parse(timeStr); // 直接获取关联配置 ULEParamConfig relatedConfig = configCollection.encodeToConfig.get(config.syncparaencode); if (relatedConfig == null) { System.out.println(“同步检测: 未找到关联配置, encode=” + config.syncparaencode); return; } // 查找关联tag String relatedTag = null; for (Map.Entry<String, List> entry : configCollection.tagToConfigs.entrySet()) { for (ULEParamConfig cfg : entry.getValue()) { if (cfg.encode.equals(relatedConfig.encode)) { relatedTag = entry.getKey(); break; } } if (relatedTag != null) break; } if (relatedTag == null) { System.out.println(“同步检测: 未找到关联Tag,关联encode=” + relatedConfig.encode); return; } // 安全获取关联值 Double relatedValue = null; if (lastValuesMap.contains(relatedTag)) { relatedValue = lastValuesMap.get(relatedTag); } if (relatedValue == null) { System.out.println(“同步检测: 关联值不可用, tag=” + relatedTag); return; } // 优化比较逻辑:使用更精确的阈值 boolean isAnomaly = (currentValue >= 0.99) && (Math.abs(relatedValue) < 0.01); // 调试信息 System.out.printf(“同步检测: %s (%.4f) vs %s (%.4f) -> %b%n”, config.tag, currentValue, relatedTag, relatedValue, isAnomaly); if (isAnomaly) { if (status.startTime == null) { status.startTime = timestamp; } else if (!status.reported) { long elapsed = timestamp.getTime() - status.startTime.getTime(); if (elapsed >= config.duration * 60 * 1000) { reportAnomaly(6, 1, currentValue, timeStr, config, out); status.reported = true; } } } else { if (status.reported) { reportAnomaly(6, 0, currentValue, timeStr, config, out); status.reset(); } else if (status.startTime != null) { status.startTime = null; } } } catch (Exception e) { System.err.println("同步检测错误: " + config.encode + " - " + e.getMessage()); } } // 报告异常 private void reportAnomaly(int anomalyType, int statusFlag, double value, String time, ULEParamConfig config, Collector out) { JSONObject event = new JSONObject(); event.put(“tag”, config.tag); event.put(“paracode”, config.encode); event.put(“abnormaltype”, anomalyType); event.put(“statusflag”, statusFlag); event.put(“datavalue”, value); event.put(“triggertime”, time); out.collect(event); } @Override public void processBroadcastElement(ConfigCollection newConfig, Context ctx, Collector out) { BroadcastState<Void, ConfigCollection> state = ctx.getBroadcastState(Descriptors.configStateDescriptor); try { // 获取旧配置 ConfigCollection oldConfig = state.get(null); // 处理配置变更:清理不再启用的报警 if (oldConfig != null) { for (Map.Entry<String, ULEParamConfig> entry : oldConfig.encodeToConfig.entrySet()) { String encode = entry.getKey(); ULEParamConfig oldCfg = entry.getValue(); // 检查配置是否被删除或禁用 ULEParamConfig newCfg = newConfig.encodeToConfig.get(encode); if (newCfg == null || !isAlarmEnabled(newCfg, oldCfg)) { // 发送恢复事件 sendRecoveryEvents(encode, oldCfg, ctx, out); } } } // 更新广播状态 state.put(null, newConfig); System.out.println("广播配置更新完成, 配置项: " + newConfig.encodeToConfig.size()); System.out.println("配置摘要: " + newConfig.encodeToConfig.keySet()); // 触发离线检测 for (String tag : newConfig.allTags) { ctx.output(OFFLINE_CHECK_TAG, tag); } } catch (Exception e) { e.printStackTrace(); } } // 检查报警是否启用 private boolean isAlarmEnabled(ULEParamConfig newCfg, ULEParamConfig oldCfg) { // 检查所有报警类型是否被禁用 return (oldCfg.constantvalue == 1 && newCfg.constantvalue == 1) || (oldCfg.iszero == 1 && newCfg.iszero == 1) || (oldCfg.ishigh == 1 && newCfg.ishigh == 1) || (oldCfg.islow == 1 && newCfg.islow == 1) || (oldCfg.isonline == 1 && newCfg.isonline == 1) || (oldCfg.issync == 1 && newCfg.issync == 1); } // 发送恢复事件 private void sendRecoveryEvents(String encode, ULEParamConfig config, Context ctx, Collector out) { try { AnomalyState state = stateMap.get(encode); if (state == null) return; // 遍历所有可能的报警类型 for (int type = 1; type <= 6; type++) { AnomalyStatus status = state.getStatus(type); if (status.reported) { JSONObject recoveryEvent = new JSONObject(); recoveryEvent.put(“tag”, config.tag); recoveryEvent.put(“paracode”, config.encode); recoveryEvent.put(“abnormaltype”, type); recoveryEvent.put(“statusflag”, 0); // 恢复事件 recoveryEvent.put(“datavalue”, 0.0); recoveryEvent.put(“triggertime”, timeFormat.format(new Date())); out.collect(recoveryEvent); status.reset(); } } // 更新状态 stateMap.put(encode, state); } catch (Exception e) { System.err.println(“发送恢复事件失败: " + e.getMessage()); } } // ========== 辅助方法 ========== private ConfigCollection getBroadcastConfig(ReadOnlyContext ctx) throws Exception { return ctx.getBroadcastState(Descriptors.configStateDescriptor).get(null); } private AnomalyState getOrCreateState(String encode) throws Exception { AnomalyState state = stateMap.get(encode); if (state == null) { state = new AnomalyState(); } return state; } } // 异常状态类 public static class AnomalyState implements Serializable { private static final long serialVersionUID = 1L; private final Map<Integer, AnomalyStatus> statusMap = new HashMap<>(); public AnomalyStatus getStatus(int type) { return statusMap.computeIfAbsent(type, k -> new AnomalyStatus()); } } // 异常状态详情 public static class AnomalyStatus implements Serializable { private static final long serialVersionUID = 1L; public Date startTime; // 异常开始时间 public Double lastValue; // 用于恒值检测 public Date lastChangeTime; // 值最后变化时间 public boolean reported; // 是否已报告 public void reset() { startTime = null; lastValue = null; lastChangeTime = null; reported = false; } } } 运行日志为"C:\Program Files (x86)\Java\jdk1.8.0_102\bin\java.exe” -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:12725,suspend=y,server=n -javaagent:C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2021.2\captureAgent\debugger-agent.jar=file:/C:/Users/Administrator/AppData/Local/Temp/capture.props -Dfile.encoding=UTF-8 -classpath C:\Users\Administrator\AppData\Local\Temp\classpath679239090.jar com.tongchuang.realtime.mds.ULEDataanomalyanalysis 已连接到目标 VM, 地址: ‘‘127.0.0.1:12725’,传输: ‘套接字’’ SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/F:/flink/flinkmaven/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.10.0/log4j-slf4j-impl-2.10.0.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/F:/flink/flinkmaven/repository/org/slf4j/slf4j-log4j12/1.7.25/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory] 加载配置: 30 个参数 配置加载完成,检查点时间: Mon Aug 04 10:51:26 CST 2025 广播配置更新完成, 配置项: 30 配置摘要: [EP000015, EP000014, EP000013, EP000012, EP000011, EP000010, EP100013, EP100014, EP000019, EP000018, EP100010, EP000017, EP100011, EP000016, EP100012, EP000004, EP000003, EP000002, EP000001, EP000022, EP000021, EP100007, EP000020, EP100008, EP100009, EP000009, EP000008, EP000007, EP000006, EP000005] 分钟数据流> {“times”:“2025-08-04 10:51”,“datas”:{“DA-LT-5BT0001”:{“ontime”:3093.452,“avg”:3128.6265,“min”:3083.741,“max”:3185.4487},“DA-LT-6BT008”:{“ontime”:174.2086,“avg”:172.546,“min”:171.8335,“max”:174.2086},“DA-LT-5BT0005”:{“ontime”:408.24,“avg”:407.208,“min”:404.94,“max”:409.2},“DA-LT-6BT004”:{“ontime”:1219.4089,“avg”:1219.8833,“min”:1219.3755,“max”:1220.4434},“DA-LT-5BT0004”:{“ontime”:1200.4,“avg”:1200.045,“min”:1199.5,“max”:1200.5},“DA-LT-6BT005”:{“ontime”:389.8511,“avg”:390.6297,“min”:389.8511,“max”:391.9514},“DA-LT-5BT0008”:{“ontime”:193.6,“avg”:190.7653,“min”:186.94,“max”:193.82},“DA-NY-LG1ZL-2-001”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA-LT-4BT0008”:{“ontime”:124.2625,“avg”:124.46,“min”:123.1875,“max”:125.7875},“DA-LT-4BT0007”:{“ontime”:169.4,“avg”:169.715,“min”:168.9,“max”:170.3},“DB5701P250A00_101”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0004”:{“ontime”:1211.0,“avg”:1211.0,“min”:1211.0,“max”:1211.0},“DA-LT-6BT001”:{“ontime”:174443.58,“avg”:173604.8032,“min”:172657.02,“max”:174912.67},“DA-LT-4BT0005”:{“ontime”:293.0625,“avg”:293.5583,“min”:292.1875,“max”:294.6875},“DA-NY-LG2ZL-2-003”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA_DB195_RH_R_0281”:{“ontime”:283.58,“avg”:310.297,“min”:283.58,“max”:384.99},“DA-DB195-RH-B-0200”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-DB195-RH-B-0201”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0001”:{“ontime”:120682.57,“avg”:120638.2251,“min”:119844.39,“max”:121553.055}}} 同步检测 - 当前配置: ULEParamConfig(tag=DA-DB195-RH-B-0201, encode=EP000001, datatype=436887485805570949, constantvalue=1, iszero=1, isonline=1, issync=1, syncparaencode=EP000022, ishigh=1, highthreshold=1000000.0, islow=1, lowthreshold=10.0, duration=1) 同步检测: 关联值不可用, tag=DA-NY-LG1ZL-2-001 分钟数据流> {“times”:“2025-08-04 10:52”,“datas”:{“DA-LT-5BT0001”:{“ontime”:3105.4685,“avg”:3127.2034,“min”:3085.331,“max”:3208.071},“DA-LT-6BT008”:{“ontime”:172.8935,“avg”:173.5736,“min”:172.8935,“max”:174.0123},“DA-LT-5BT0005”:{“ontime”:404.88,“avg”:405.671,“min”:404.76,“max”:407.34},“DA-LT-5BT0004”:{“ontime”:1199.4,“avg”:1198.915,“min”:1198.2001,“max”:1199.6},“DA-LT-6BT004”:{“ontime”:1220.4434,“avg”:1220.8577,“min”:1220.3433,“max”:1221.2441},“DA-LT-6BT005”:{“ontime”:391.971,“avg”:392.889,“min”:391.971,“max”:393.3843},“DA-LT-5BT0008”:{“ontime”:186.88,“avg”:188.0343,“min”:186.8,“max”:189.34},“DA-NY-LG1ZL-2-001”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA-LT-4BT0008”:{“ontime”:124.6625,“avg”:124.4888,“min”:123.825,“max”:125.3625},“DA-LT-4BT0007”:{“ontime”:170.0,“avg”:170.085,“min”:169.3,“max”:170.4},“DB5701P250A00_101”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0004”:{“ontime”:1211.0,“avg”:1210.3333,“min”:1210.0,“max”:1211.0},“DA-LT-6BT001”:{“ontime”:173081.9,“avg”:173387.4525,“min”:172657.1,“max”:174215.6},“DA-LT-4BT0005”:{“ontime”:294.0625,“avg”:293.925,“min”:292.625,“max”:294.5},“DA-NY-LG2ZL-2-003”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA_DB195_RH_R_0281”:{“ontime”:311.85,“avg”:298.3053,“min”:226.51,“max”:340.17},“DA-DB195-RH-B-0200”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-DB195-RH-B-0201”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0001”:{“ontime”:120709.81,“avg”:121436.6195,“min”:120241.945,“max”:123212.08}}} 异常检测结果> {“abnormaltype”:2,“paracode”:“EP000022”,“datavalue”:0.0,“tag”:“DA-NY-LG1ZL-2-001”,“triggertime”:“2025-08-04 10:52”,“statusflag”:1} 异常检测结果> {“abnormaltype”:4,“paracode”:“EP000022”,“datavalue”:0.0,“tag”:“DA-NY-LG1ZL-2-001”,“triggertime”:“2025-08-04 10:52”,“statusflag”:1} 异常检测结果> {“abnormaltype”:4,“paracode”:“EP000001”,“datavalue”:1.0,“tag”:“DA-DB195-RH-B-0201”,“triggertime”:“2025-08-04 10:52”,“statusflag”:1} 同步检测 - 当前配置: ULEParamConfig(tag=DA-DB195-RH-B-0201, encode=EP000001, datatype=436887485805570949, constantvalue=1, iszero=1, isonline=1, issync=1, syncparaencode=EP000022, ishigh=1, highthreshold=1000000.0, islow=1, lowthreshold=10.0, duration=1) 同步检测: 关联值不可用, tag=DA-NY-LG1ZL-2-001 分钟数据流> {“times”:“2025-08-04 10:53”,“datas”:{“DA-LT-5BT0001”:{“ontime”:3088.489,“avg”:3114.5305,“min”:3066.6252,“max”:3183.479},“DA-LT-6BT008”:{“ontime”:173.9338,“avg”:174.8619,“min”:173.9141,“max”:176.7015},“DA-LT-5BT0005”:{“ontime”:407.34,“avg”:408.787,“min”:407.34,“max”:409.62},“DA-LT-5BT0004”:{“ontime”:1198.2001,“avg”:1197.635,“min”:1197.0,“max”:1198.3},“DA-LT-6BT004”:{“ontime”:1221.1775,“avg”:1221.4828,“min”:1221.144,“max”:1221.7448},“DA-LT-6BT005”:{“ontime”:393.345,“avg”:393.5502,“min”:393.031,“max”:394.1498},“DA-LT-5BT0008”:{“ontime”:189.26,“avg”:190.819,“min”:189.26,“max”:192.74},“DA-NY-LG1ZL-2-001”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA-LT-4BT0008”:{“ontime”:124.2125,“avg”:124.3077,“min”:123.5125,“max”:125.1125},“DA-LT-4BT0007”:{“ontime”:169.4,“avg”:169.0767,“min”:167.7,“max”:169.8},“DB5701P250A00_101”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0004”:{“ontime”:1210.0,“avg”:1209.3167,“min”:1209.0,“max”:1210.0},“DA-LT-6BT001”:{“ontime”:173364.6,“avg”:173578.1482,“min”:172720.47,“max”:174390.27},“DA-LT-4BT0005”:{“ontime”:292.8125,“avg”:292.6771,“min”:291.1875,“max”:293.6875},“DA-NY-LG2ZL-2-003”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA_DB195_RH_R_0281”:{“ontime”:295.82,“avg”:294.4385,“min”:273.98,“max”:322.66},“DA-DB195-RH-B-0200”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-DB195-RH-B-0201”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0001”:{“ontime”:122562.12,“avg”:122467.8892,“min”:120901.414,“max”:124176.8}}} 异常检测结果> {“abnormaltype”:1,“paracode”:“EP000022”,“datavalue”:0.0,“tag”:“DA-NY-LG1ZL-2-001”,“triggertime”:“2025-08-04 10:53”,“statusflag”:1} 异常检测结果> {“abnormaltype”:1,“paracode”:“EP000001”,“datavalue”:1.0,“tag”:“DA-DB195-RH-B-0201”,“triggertime”:“2025-08-04 10:53”,“statusflag”:1} 同步检测: 关联值不可用, tag=DA-NY-LG1ZL-2-001 分钟数据流> {“times”:“2025-08-04 10:54”,“datas”:{“DA-LT-5BT0001”:{“ontime”:3078.615,“avg”:3082.1354,“min”:3039.7373,“max”:3216.3108},“DA-LT-6BT008”:{“ontime”:175.5434,“avg”:173.7907,“min”:172.8149,“max”:175.5434},“DA-LT-5BT0005”:{“ontime”:409.38,“avg”:408.7688,“min”:407.94,“max”:409.68},“DA-LT-5BT0004”:{“ontime”:1196.9,“avg”:1196.2543,“min”:1195.3,“max”:1197.1},“DA-LT-6BT004”:{“ontime”:1221.7448,“avg”:1221.7742,“min”:1221.6447,“max”:1221.8448},“DA-LT-6BT005”:{“ontime”:393.1291,“avg”:392.4774,“min”:392.1673,“max”:393.1291},“DA-LT-5BT0008”:{“ontime”:191.14,“avg”:191.1912,“min”:190.66,“max”:191.74},“DA-NY-LG1ZL-2-001”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA-LT-4BT0008”:{“ontime”:123.825,“avg”:123.6761,“min”:122.225,“max”:124.7875},“DA-LT-4BT0007”:{“ontime”:167.5,“avg”:167.35,“min”:167.1,“max”:167.5},“DB5701P250A00_101”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0004”:{“ontime”:1209.0,“avg”:1209.0,“min”:1209.0,“max”:1209.0},“DA-LT-6BT001”:{“ontime”:173662.19,“avg”:173854.9536,“min”:172842.14,“max”:175016.47},“DA-LT-4BT0005”:{“ontime”:290.625,“avg”:291.1727,“min”:290.25,“max”:291.9375},“DA-NY-LG2ZL-2-003”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA_DB195_RH_R_0281”:{“ontime”:316.75,“avg”:294.1453,“min”:263.4,“max”:318.26},“DA-DB195-RH-B-0200”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0001”:{“ontime”:123655.62,“avg”:122644.2382,“min”:121316.24,“max”:123656.664},“DA-DB195-RH-B-0201”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0}}} 同步检测 - 当前配置: ULEParamConfig(tag=DA-DB195-RH-B-0201, encode=EP000001, datatype=436887485805570949, constantvalue=1, iszero=1, isonline=1, issync=1, syncparaencode=EP000022, ishigh=1, highthreshold=1000000.0, islow=1, lowthreshold=10.0, duration=1) 同步检测: 关联值不可用, tag=DA-NY-LG1ZL-2-001 分钟数据流> {“times”:“2025-08-04 10:55”,“datas”:{“DA-LT-5BT0001”:{“ontime”:3218.5786,“avg”:3046.705,“min”:2944.5356,“max”:3218.5786},“DA-LT-6BT008”:{“ontime”:174.4442,“avg”:173.5075,“min”:171.5587,“max”:174.719},“DA-LT-5BT0005”:{“ontime”:407.76,“avg”:410.281,“min”:406.38,“max”:412.92},“DA-LT-5BT0004”:{“ontime”:1195.5,“avg”:1194.82,“min”:1194.4,“max”:1195.5},“DA-LT-6BT004”:{“ontime”:1221.8115,“avg”:1221.7748,“min”:1221.678,“max”:1221.8448},“DA-LT-6BT005”:{“ontime”:392.2654,“avg”:391.9164,“min”:391.4803,“max”:392.344},“DA-LT-5BT0008”:{“ontime”:191.16,“avg”:193.6457,“min”:190.1,“max”:195.76},“DA-NY-LG1ZL-2-001”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA-LT-4BT0008”:{“ontime”:122.225,“avg”:123.2477,“min”:121.95,“max”:125.275},“DB5701P250A00_101”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0004”:{“ontime”:1209.0,“avg”:1209.1833,“min”:1209.0,“max”:1210.0},“DA-LT-6BT001”:{“ontime”:173967.0,“avg”:173799.209,“min”:172448.05,“max”:174773.38},“DA-LT-4BT0005”:{“ontime”:290.625,“avg”:292.1531,“min”:290.625,“max”:294.1875},“DA-NY-LG2ZL-2-003”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA_DB195_RH_R_0281”:{“ontime”:295.73,“avg”:299.1413,“min”:258.3,“max”:335.65},“DA-DB195-RH-B-0200”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0001”:{“ontime”:123094.66,“avg”:121517.155,“min”:120457.766,“max”:123094.66},“DA-DB195-RH-B-0201”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0}}} 同步检测: 关联值不可用, tag=DA-NY-LG1ZL-2-001 加载配置: 30 个参数 配置加载完成,检查点时间: Mon Aug 04 10:56:27 CST 2025 广播配置更新完成, 配置项: 30 配置摘要: [EP000015, EP000014, EP000013, EP000012, EP000011, EP000010, EP100013, EP100014, EP000019, EP000018, EP100010, EP000017, EP100011, EP000016, EP100012, EP000004, EP000003, EP000002, EP000001, EP000022, EP000021, EP100007, EP000020, EP100008, EP100009, EP000009, EP000008, EP000007, EP000006, EP000005] 分钟数据流> {“times”:“2025-08-04 10:56”,“datas”:{“DA-LT-5BT0001”:{“ontime”:3057.6804,“avg”:3012.5768,“min”:2949.3123,“max”:3078.372},“DA-LT-6BT008”:{“ontime”:171.8335,“avg”:172.1848,“min”:171.8335,“max”:172.5597},“DA-LT-5BT0005”:{“ontime”:412.74,“avg”:413.215,“min”:412.02,“max”:415.14},“DA-LT-6BT004”:{“ontime”:1221.678,“avg”:1221.6897,“min”:1221.6113,“max”:1221.7448},“DA-LT-5BT0004”:{“ontime”:1194.8,“avg”:1196.8434,“min”:1194.8,“max”:1199.3},“DA-LT-6BT005”:{“ontime”:391.5392,“avg”:390.6559,“min”:389.8314,“max”:391.5392},“DA-LT-5BT0008”:{“ontime”:195.66,“avg”:195.8223,“min”:195.08,“max”:197.42},“DA-NY-LG1ZL-2-001”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA-LT-4BT0008”:{“ontime”:125.275,“avg”:124.2504,“min”:123.45,“max”:126.2625},“DB5701P250A00_101”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0004”:{“ontime”:1210.0,“avg”:1210.0,“min”:1210.0,“max”:1210.0},“DA-LT-6BT001”:{“ontime”:173206.77,“avg”:174326.7505,“min”:173206.77,“max”:175154.61},“DA-LT-4BT0005”:{“ontime”:293.875,“avg”:293.4646,“min”:292.5625,“max”:295.0625},“DA-NY-LG2ZL-2-003”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA_DB195_RH_R_0281”:{“ontime”:288.86,“avg”:301.8983,“min”:268.97,“max”:349.89},“DA-DB195-RH-B-0200”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0001”:{“ontime”:120710.516,“avg”:120748.8062,“min”:119682.57,“max”:122023.83},“DA-DB195-RH-B-0201”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0}}} 同步检测 - 当前配置: ULEParamConfig(tag=DA-DB195-RH-B-0201, encode=EP000001, datatype=436887485805570949, constantvalue=1, iszero=1, isonline=1, issync=1, syncparaencode=EP000022, ishigh=1, highthreshold=1000000.0, islow=1, lowthreshold=10.0, duration=1) 同步检测: 关联值不可用, tag=DA-NY-LG1ZL-2-001 分钟数据流> {“times”:“2025-08-04 10:57”,“datas”:{“DA-LT-5BT0001”:{“ontime”:3005.6284,“avg”:3004.7748,“min”:2962.2488,“max”:3059.464},“DA-LT-6BT008”:{“ontime”:171.9316,“avg”:171.3516,“min”:170.5968,“max”:172.0494},“DA-LT-5BT0005”:{“ontime”:415.14,“avg”:416.542,“min”:415.14,“max”:417.24},“DA-LT-5BT0004”:{“ontime”:1199.3,“avg”:1200.7184,“min”:1199.3,“max”:1201.3},“DA-LT-6BT004”:{“ontime”:1221.7114,“avg”:1221.5724,“min”:1221.411,“max”:1221.7448},“DA-LT-6BT005”:{“ontime”:389.8118,“avg”:389.4774,“min”:389.1444,“max”:389.8118},“DA-LT-5BT0008”:{“ontime”:197.42,“avg”:198.3487,“min”:197.42,“max”:198.68},“DA-NY-LG1ZL-2-001”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA-LT-4BT0008”:{“ontime”:124.2,“avg”:123.2256,“min”:121.8625,“max”:126.1},“DB5701P250A00_101”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0004”:{“ontime”:1210.0,“avg”:1210.0,“min”:1210.0,“max”:1210.0},“DA-LT-6BT001”:{“ontime”:174333.06,“avg”:173710.917,“min”:172544.47,“max”:174776.31},“DA-NY-LG2ZL-2-003”:{“ontime”:0.0,“avg”:0.0,“min”:0.0,“max”:0.0},“DA-LT-4BT0005”:{“ontime”:294.0,“avg”:293.3229,“min”:291.5625,“max”:296.0},“DA_DB195_RH_R_0281”:{“ontime”:289.38,“avg”:297.7735,“min”:273.12,“max”:343.61},“DA-DB195-RH-B-0200”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0},“DA-LT-4BT0001”:{“ontime”:121024.04,“avg”:120971.4221,“min”:120043.63,“max”:122208.27},“DA-DB195-RH-B-0201”:{“ontime”:1.0,“avg”:1.0,“min”:1.0,“max”:1.0}}} 同步检测 - 当前配置: ULEParamConfig(tag=DA-DB195-RH-B-0201, encode=EP000001, datatype=436887485805570949, constantvalue=1, iszero=1, isonline=1, issync=1, syncparaencode=EP000022, ishigh=1, highthreshold=1000000.0, islow=1, lowthreshold=10.0, duration=1) 同步检测: 关联值不可用, tag=DA-NY-LG1ZL-2-001。其中1、同步分析功能为实现。2、DA-LT-4BT0007的初始离线和流数据出现数据又离线均未报出离线异常。请生成完整优化后代码
最新发布
08-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值