conn.State和conn.errors.count的选择

作者上班时遇到网站提示数据库链接失败,原判断连接是否成功的代码存在失误。后通过查阅ado的chm手册,找到conn的state属性,利用其值判断连接状态,将判断句修改后,测试所有错误成功状态,拦截工作恢复正常。

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

早上上班坐下,开机,打开熟悉的工作网站界面,突然发现网站提示数据库链接失败,但是系统作的错误拦截居然没有生效果(数据库链接的原因是数据库服务器没开,这个不是本文重点)。
检查了一下判断连接是否成功的代码发现是这样写的
if conn.errors.count<>0 and conn.errors.count<>2 then
显示链链失败提示
end if
想起,原来是用conn.errors.count<>0来判断是否连接成功,但是老是判断失误,跟踪了一下原因,发现当数据库连接时有时会产生conn.errors.count等于2的结果,但是链接是成功的,所以加上了一个conn.errors.count<>2,但是,这个conn.errors.count=2却包含了所有连接不成功的原因,所以发生了上面说的那一幕。

想了半天没想出个办法,上个洗手间,晕倒,居然在洗手时想到conn有一个检查连接状态的属性(为什么会在去洗手间时想到的呢?),回来查了一下ado的chm手册,找到了state属性,下面是这个属性的一些值
AdStateClosed  默认,指示对象是关闭的。
AdStateOpen   指示对象是打开的。
AdStateConnecting 指示 Recordset 对象正在连接。
AdStateExecuting 指示 Recordset 对象正在执行命令。
AdStateFetching  指示 Recordset 对象的行正在被读取。

查了一下adovbs.ini,这几个状态的真实值是:
Const adStateClosed = &H00000000
Const adStateOpen = &H00000001
Const adStateConnecting = &H00000002
Const adStateExecuting = &H00000004
Const adStateFetching = &H00000008

state还是一个组合值,如当状态是AdStateExecuting Recordset 对象正在执行命令时,真正值应该是AdStateOpen和AdStateExecuting的组合。具体什么样的组合格式,有心人可以试试。我现在的重点是第一个参数adStateClosed,很明显adStateClosed的十进制值是0
那也就是说当conn.State<>0就是链接成功。那判断句就可以改成
if conn.State=0 then
显示链链失败提示
end if
测试所有错误成功状态,拦截工作一切正常。耶~(这个是被MM感染了,喜欢说耶,要吐的吐啊吐的就习惯了的。-_-||b)

下次请把要修改的文件的位置,名称告诉我 然后我把文件发给你,你改好了(要完整的),再还给我,这是E:\AI_System\agent里的environment_interface.py:“import os import psutil import platform import json import sqlite3 import sys import subprocess import requests import logging from datetime import datetime from pathlib import Path logger = logging.getLogger('EnvironmentInterface') class EnvironmentInterface: def __init__(self, base_dir: str): # 配置日志 self.logger = logging.getLogger('EnvironmentInterface') self.logger.setLevel(logging.INFO) console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')) self.logger.addHandler(console_handler) self.logger.propagate = False # 工作区路径设置(使用绝对路径) self.workspace_root = self._resolve_workspace_path(base_dir) # 解析路径并确保目录存在 self.models_dir = self._resolve_and_create_dir(os.path.join(self.workspace_root, "01_模型存储")) self.cache_dir = self._resolve_and_create_dir(os.path.join(self.workspace_root, "01_模型存储", "下载缓存")) self.system_dir = self._resolve_and_create_dir(os.path.join(self.workspace_root, "02_核心代码")) self.temp_dir = self._resolve_and_create_dir(os.path.join(self.workspace_root, "04_环境工具", "临时补丁")) self.python_dir = self._resolve_and_create_dir(os.path.join(self.workspace_root, "04_环境工具", "Python环境")) # 环境配置 os.environ['PATH'] = f"{self.python_dir};{self.python_dir}\\Scripts;{os.environ['PATH']}" os.environ['HF_HOME'] = self.cache_dir # 安全策略 self.authorized_actions = { "file_access": True, "web_search": True, "command_exec": True, "software_install": False, "hardware_control": False } self.action_log = [] # 初始化数据库(使用绝对路径) self.environment_db = os.path.join(self.system_dir, 'environment.db') self._init_db() self.logger.info("✅ 环境接口初始化完成") def _resolve_workspace_path(self, base_dir: str) -> str: """解析工作区路径为绝对路径""" try: # 使用Path对象确保跨平台兼容性 base_path = Path(base_dir).resolve() workspace_path = base_path / "AI_Workspace" if not workspace_path.exists(): workspace_path.mkdir(parents=True, exist_ok=True) self.logger.info(f"创建工作区目录: {workspace_path}") return str(workspace_path) except Exception as e: self.logger.error(f"工作区路径解析失败: {str(e)}") # 回退到默认路径 fallback_path = os.path.join(os.path.expanduser("~"), "AI_Workspace") os.makedirs(fallback_path, exist_ok=True) return fallback_path def _resolve_and_create_dir(self, path): """解析路径并确保目录存在""" try: # 转换为绝对路径 abs_path = os.path.abspath(path) # 创建目录(如果不存在) if not os.path.exists(abs_path): os.makedirs(abs_path, exist_ok=True) self.logger.info(f"创建目录: {abs_path}") return abs_path except Exception as e: self.logger.error(f"目录解析失败: {path} - {str(e)}") # 创建临时目录作为回退 temp_path = os.path.join(self.workspace_root, "temp") os.makedirs(temp_path, exist_ok=True) return temp_path def _init_db(self): """初始化环境数据库""" try: conn = sqlite3.connect(self.environment_db) c = conn.cursor() # 系统信息表 c.execute('''CREATE TABLE IF NOT EXISTS system_info ( id INTEGER PRIMARY KEY, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, os TEXT, cpu TEXT, memory REAL, disk_usage REAL )''') # 文件探索历史表 c.execute('''CREATE TABLE IF NOT EXISTS file_exploration ( id INTEGER PRIMARY KEY, path TEXT UNIQUE, last_visited DATETIME, visit_count INTEGER DEFAULT 0 )''') # 资源管理表 c.execute('''CREATE TABLE IF NOT EXISTS resources ( id INTEGER PRIMARY KEY, name TEXT, type TEXT CHECK(type IN ('skin', 'furniture', 'tool')), path TEXT, is_active BOOLEAN DEFAULT 0 )''') conn.commit() conn.close() self.logger.info(f"✅ 数据库初始化完成: {self.environment_db}") except Exception as e: self.logger.error(f"❌ 数据库初始化失败: {str(e)}") # 系统监控功能 def get_system_info(self): """获取并记录系统信息""" try: # 获取内存使用情况 mem = psutil.virtual_memory() mem_used = round(mem.used / (1024 ** 3), 1) mem_total = round(mem.total / (1024 ** 3), 1) # 获取磁盘使用情况 disk_usage = psutil.disk_usage('/').percent info = { "os": f"{platform.system()} {platform.release()}", "cpu": f"{platform.processor()} ({psutil.cpu_count(logical=False)} cores)", "memory": f"{mem_used}GB/{mem_total}GB", "disk_usage": f"{disk_usage}%" } # 保存到数据库 conn = sqlite3.connect(self.environment_db) c = conn.cursor() c.execute('''INSERT INTO system_info (os, cpu, memory, disk_usage) VALUES (?, ?, ?, ?)''', (info['os'], info['cpu'], mem_used, disk_usage)) conn.commit() conn.close() self.log_action("system_monitor", "采集系统信息") return info except Exception as e: self.logger.error(f"❌ 获取系统信息失败: {str(e)}") return { "os": f"Error: {str(e)}", "cpu": "0%", "memory": "0GB/0GB", "disk_usage": "0%" } # 文件探索功能 def explore_directory(self, path=None): """探索目录内容""" try: target_path = path or self.workspace_root target_path = os.path.abspath(target_path) # 安全路径检查 if not target_path.startswith(os.path.abspath(self.workspace_root)): return {"error": "访问路径超出工作区范围"} if not os.path.exists(target_path): return {"error": "路径不存在"} # 记录探索历史 self._record_exploration(target_path) contents = [] for item in os.listdir(target_path): full_path = os.path.join(target_path, item) try: is_dir = os.path.isdir(full_path) size = os.path.getsize(full_path) if not is_dir else 0 modified_time = os.path.getmtime(full_path) contents.append({ "name": item, "type": "directory" if is_dir else "file", "path": full_path, "size": f"{size / 1024:.1f}KB" if size < 1024 ** 2 else f"{size / (1024 ** 2):.1f}MB", "modified": datetime.fromtimestamp(modified_time).strftime("%Y-%m-%d %H:%M") }) except PermissionError: contents.append({ "name": item, "type": "unknown", "error": "权限不足" }) except Exception as e: contents.append({ "name": item, "type": "unknown", "error": str(e) }) self.log_action("file_explore", f"探索路径: {target_path}") return { "current_path": target_path, "contents": sorted(contents, key=lambda x: (x['type'] == 'directory', x['name']), reverse=True) } except Exception as e: self.logger.error(f"❌ 探索目录失败: {str(e)}") return {"error": str(e)} def _record_exploration(self, path): """记录探索历史到数据库""" try: conn = sqlite3.connect(self.environment_db) c = conn.cursor() c.execute("SELECT id FROM file_exploration WHERE path = ?", (path,)) if c.fetchone(): c.execute('''UPDATE file_exploration SET last_visited = CURRENT_TIMESTAMP, visit_count = visit_count + 1 WHERE path = ?''', (path,)) else: c.execute('''INSERT INTO file_exploration (path, last_visited, visit_count) VALUES (?, CURRENT_TIMESTAMP, 1)''', (path,)) conn.commit() except Exception as e: self.logger.error(f"❌ 记录探索历史失败: {str(e)}") finally: conn.close() # 资源管理功能 def get_resource(self, resource_type): """获取特定类型资源""" try: conn = sqlite3.connect(self.environment_db) c = conn.cursor() c.execute('''SELECT name, path, is_active FROM resources WHERE type = ?''', (resource_type,)) resources = [ {"name": item[0], "path": item[1], "is_active": bool(item[2])} for item in c.fetchall() ] return resources except Exception as e: self.logger.error(f"❌ 获取资源失败: {str(e)}") return [] finally: conn.close() def activate_resource(self, resource_name): """激活特定资源""" try: conn = sqlite3.connect(self.environment_db) c = conn.cursor() c.execute('''UPDATE resources SET is_active = 0 WHERE type = (SELECT type FROM resources WHERE name = ?)''', (resource_name,)) c.execute('''UPDATE resources SET is_active = 1 WHERE name = ?''', (resource_name,)) conn.commit() self.log_action("resource_activate", f"激活资源: {resource_name}") return True except Exception as e: self.logger.error(f"❌ 激活资源失败: {str(e)}") return False finally: conn.close() # 工作区管理功能 def get_workspace_info(self): """获取工作区信息""" return { "workspace": self.workspace_root, "models": self.models_dir, "system": self.system_dir, "cache": self.cache_dir, "temp": self.temp_dir, "python": self.python_dir } # 辅助功能 def _is_authorized(self, action): """检查操作授权状态""" return self.authorized_actions.get(action, False) def log_action(self, action, details): """记录环境操作日志""" log_entry = { "timestamp": datetime.now().isoformat(), "action": action, "details": details } self.action_log.append(log_entry) # 保存到文件 log_file = os.path.join(self.workspace_root, "environment_actions.log") try: with open(log_file, 'a', encoding='utf-8') as f: f.write(json.dumps(log_entry, ensure_ascii=False) + "\n") except Exception as e: self.logger.error(f"❌ 记录日志失败: {str(e)}") # 同时记录到logger self.logger.info(f"{action}: {details}") return True # 使用示例 if __name__ == "__main__": # 配置日志 logging.basicConfig(level=logging.INFO) # 创建环境接口实例 env = EnvironmentInterface(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # 获取工作区信息 print("工作区信息:", json.dumps(env.get_workspace_info(), indent=2, ensure_ascii=False)) # 获取系统信息 print("系统信息:", json.dumps(env.get_system_info(), indent=2, ensure_ascii=False)) # 探索目录 print("工作区内容:", json.dumps(env.explore_directory(), indent=2, ensure_ascii=False)) ”E:\AI_System\agent里的autonomous_agent.py:“import os import time import logging from dotenv import load_dotenv # 使用绝对导入 from core.config import system_config from core.environment import DefaultEnvironment, AIHome, ActionExecutor from .environment_interface import EnvironmentInterface # 导入修复后的环境接口 class AutonomousAgent: def __init__(self): self.logger = self._setup_logger() self.logger.info("🔁 初始化自主智能体核心模块...") try: # 加载环境变量 load_dotenv() # 初始化环境感知系统 self._initialize_environment_systems() # 初始化各子系统 self._initialize_subsystems() self.logger.info("✅ 自主智能体初始化完成") except Exception as e: self.logger.error(f"❌ 智能体初始化失败: {str(e)}") raise def _setup_logger(self): """配置日志记录器""" logger = logging.getLogger('AutonomousAgent') logger.setLevel(system_config.LOG_LEVEL) # 创建控制台处理器 console_handler = logging.StreamHandler() console_handler.setLevel(system_config.LOG_LEVEL) # 创建格式化器 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') console_handler.setFormatter(formatter) # 添加处理器 logger.addHandler(console_handler) logger.propagate = False return logger def _initialize_environment_systems(self): """初始化环境感知系统 - 修复后""" # 获取项目根目录 base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 修复:使用具体实现类 DefaultEnvironment self.environment = DefaultEnvironment(base_dir) self.logger.info("✅ 环境接口初始化完成") # 初始化智能家居环境 self.home = AIHome(base_dir) self.logger.info("✅ 智能家居环境初始化完成") # 修复:ActionExecutor 不需要参数 self.executor = ActionExecutor() self.logger.info("✅ 动作执行器初始化完成") # 新增:初始化环境接口(用于数据库资源管理) self.env_interface = EnvironmentInterface(base_dir) self.logger.info("✅ 环境接口(数据库)初始化完成") # 记录环境状态 env_status = self.environment.get_system_info() self.logger.info(f"📊 系统状态: OS={env_status['os']}, CPU={env_status['cpu']}, " f"内存={env_status['memory']}GB, 磁盘={env_status['disk_usage']}%") def _initialize_subsystems(self): """初始化所有子系统""" # 1. 初始化模型管理器 from .model_manager import ModelManager self.model_manager = ModelManager( model_dir=system_config.MODEL_DIR, device=system_config.DEVICE, default_model=system_config.DEFAULT_MODEL ) self.logger.info("✅ 模型管理器初始化完成") # 2. 初始化健康系统 from .health_system import HealthSystem self.health_system = HealthSystem(self) self.logger.info("✅ 健康系统初始化完成") # 3. 初始化记忆系统 from .memory_system import MemorySystem self.memory_system = MemorySystem(self) self.logger.info("✅ 记忆系统初始化完成") # 4. 初始化情感系统 from .affective_system import AffectiveSystem self.affective_system = AffectiveSystem(agent=self) self.logger.info("✅ 情感系统初始化完成") # 5. 初始化认知架构 from .cognitive_architecture import CognitiveArchitecture self.cognitive_architecture = CognitiveArchitecture(agent=self) self.logger.info("✅ 认知架构初始化完成") # 6. 初始化通信系统 from .communication_system import CommunicationSystem self.communication_system = CommunicationSystem( cognitive_system=self.cognitive_architecture, agent=self # 传递智能体实例 ) self.logger.info("✅ 通信系统初始化完成") def process_input(self, user_input, user_id="default"): """处理用户输入(通过通信系统)""" return self.communication_system.process_input(user_input, user_id) def run_periodic_tasks(self): """运行周期性任务""" # 更新健康状态 self.health_system.update() # 情感系统更新 self.affective_system.grow() # 记忆系统维护 self.memory_system.consolidate_memories() # 修复:环境状态监控 - 使用时间戳 current_time = time.time() if not hasattr(self, "_last_env_check"): self._last_env_check = current_time # 每5分钟检查一次 if current_time - self._last_env_check > 300: self._last_env_check = current_time self._monitor_environment() def _monitor_environment(self): """监控环境状态 - 修复后""" try: # 获取当前系统状态 env_status = self.environment.get_system_info() # 安全解析磁盘使用率 disk_str = env_status.get('disk_usage', '0%').strip() if disk_str.endswith('%'): try: disk_usage = float(disk_str[:-1]) except ValueError: disk_usage = 0.0 else: disk_usage = 0.0 if disk_usage > 90: self.logger.warning(f"⚠️ 磁盘空间不足!当前使用率: {disk_usage}%") # 安全解析内存使用 memory_str = env_status.get('memory', '0GB/0GB') try: # 支持多种格式: "3.2GB/16GB" 或 "3.2/16.0 GB" parts = memory_str.replace('GB', '').replace(' ', '').split('/') if len(parts) >= 2: memory_used = float(parts[0]) memory_total = float(parts[1]) memory_ratio = memory_used / memory_total if memory_ratio > 0.85: self.logger.warning( f"⚠️ 内存使用过高!已用: {memory_used:.1f}GB, " f"总共: {memory_total:.1f}GB, " f"使用率: {memory_ratio * 100:.1f}%" ) except (ValueError, TypeError, ZeroDivisionError) as e: self.logger.error(f"内存数据解析失败: {memory_str} - {str(e)}") # 记录到健康系统 self.health_system.record_environment_status(env_status) except Exception as e: self.logger.error(f"环境监控失败: {str(e)}", exc_info=True) def get_status(self): """获取智能体状态报告""" # 获取基础状态 status = { "health": self.health_system.get_status(), "affective": self.affective_system.get_state(), "memory_stats": self.memory_system.get_stats(), "model": self.model_manager.get_current_model_info() } # 添加环境信息 try: env_status = self.environment.get_system_info() status["environment"] = { "os": env_status.get("os", "未知"), "cpu": env_status.get("cpu", "0%"), "memory": env_status.get("memory", "0GB/0GB"), "disk": env_status.get("disk_usage", "0%") } except Exception as e: status["environment"] = {"error": str(e)} return status # 环境交互方法 def explore_environment(self, path=None): """探索环境目录""" try: return self.environment.explore_directory(path) except Exception as e: self.logger.error(f"环境探索失败: {str(e)}") return {"error": str(e)} def execute_action(self, action, parameters): """通过执行器执行动作""" try: result = self.executor.execute(action, parameters) self.logger.info(f"执行动作: {action} {parameters} → {result.get('status', '未知')}") return result except Exception as e: self.logger.error(f"动作执行失败: {action} {parameters} - {str(e)}") return {"status": "error", "message": str(e)} ”没找到你说的agent_controller.py,只看见agent_core.py:“from agent.cognitive_architecture import CognitiveArchitecture from .model_manager import ModelManager from .memory_system import MemorySystem from .knowledge_manager import KnowledgeManager from .decision_system import DecisionSystem from .affective_system import AffectiveSystem from .health_system import HealthSystem from .environment_interface import EnvironmentInterface from .communication_system import CommunicationSystem class AgentCore: def __init__(self, config): self.config = config self.model_manager = ModelManager(config) self.memory = MemorySystem(config) self.knowledge = KnowledgeManager(config, self.memory) self.cognition = CognitiveArchitecture(config, self.model_manager) self.affect = AffectiveSystem(config) self.decision = DecisionSystem(config, self.cognition, self.affect) self.environment = EnvironmentInterface(config) self.communication = CommunicationSystem(config) self.health = HealthSystem(config) self.initialized = False def initialize(self): """初始化所有核心组件""" if self.initialized: return True try: # 加载默认模型 self.model_manager.load_model(self.config.DEFAULT_MODEL) # 初始化认知架构 self.cognition.initialize() # 加载环境接口 self.environment.load_environment() # 启动健康监测 self.health.start_monitoring() self.initialized = True return True except Exception as e: print(f"❌ 智能体初始化失败: {str(e)}") return False def process_input(self, input_data): """处理输入数据""" if not self.initialized: return {"error": "Agent not initialized"} # 认知处理 processed = self.cognition.process_input(input_data) # 情感评估 affective_response = self.affect.evaluate(processed) # 决策生成 decision = self.decision.make_decision(processed, affective_response) # 执行行动 result = self.environment.execute_action(decision) # 更新记忆 self.memory.store_experience({ "input": input_data, "processed": processed, "decision": decision, "result": result }) return result”
最新发布
08-10
package com.tongchuang.realtime.mds; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.tongchuang.realtime.util.KafkaUtils; import org.apache.flink.api.common.eventtime.WatermarkStrategy; import org.apache.flink.api.common.functions.RichFlatMapFunction; import org.apache.flink.api.common.serialization.DeserializationSchema; 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.sink.PrintSinkFunction; import org.apache.flink.streaming.api.functions.sink.SinkFunction; 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; import java.util.stream.Collectors; public class ULEDataanomalyanalysis { public static void main(String[] args) throws Exception { final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.setParallelism(1); // 设置合理并行度 KafkaSource<String> kafkaConsumer = KafkaUtils.getKafkaConsumer("da-data-xl", "minuteaggregation_calculation", OffsetsInitializer.latest()); //测试 指定最新位置 DataStreamSource<String> kafkaDS = env.fromSource(kafkaConsumer, WatermarkStrategy.noWatermarks(), "realdata_minuteaggregation"); // 解析JSON并拆分每个tag的数据 SingleOutputStreamOperator<JSONObject> splitStream = kafkaDS .map(JSON::parseObject) .flatMap((JSONObject value, Collector<JSONObject> 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<ConfigCollection> configDataStream = env .addSource(new MysqlConfigSource()) .setParallelism(1) // 单并行度确保配置顺序 .filter(Objects::nonNull) .name("Config-Source"); // 将配置流转换为广播流 BroadcastStream<ConfigCollection> configBroadcastStream = configDataStream .broadcast(Descriptors.configStateDescriptor); // 按tag分组并连接广播流 KeyedStream<JSONObject, String> keyedStream = splitStream .keyBy(json -> json.getString("tag")); BroadcastConnectedStream<JSONObject, ConfigCollection> connectedStream = keyedStream.connect(configBroadcastStream); // 异常检测处理 SingleOutputStreamOperator<JSONObject> anomalyStream = connectedStream .process(new OptimizedAnomalyDetectionFunction()) .name("Anomaly-Detection"); // 获取配置更新侧输出流 DataStream<ConfigCollection> configUpdateStream = anomalyStream.getSideOutput( OptimizedAnomalyDetectionFunction.CONFIG_UPDATE_TAG ); // 处理配置更新事件(检测缺失标签) SingleOutputStreamOperator<JSONObject> missingTagAnomalies = configUpdateStream .keyBy(cfg -> "global") // 全局键确保所有事件到同一分区 .flatMap(new MissingTagDetector()) .name("Missing-Tag-Detector"); // 合并所有异常流 DataStream<JSONObject> allAnomalies = anomalyStream.union(missingTagAnomalies); // 输出结果 allAnomalies.print("异常检测结果"); // 生产环境写入Kafka // allAnomalies.map(JSON::toString) // .addSink(KafkaUtils.getKafkaSink("minutedata_uleanomaly", bootstrapServers)); // 启动执行 env.execute("ULEDataAnomalyAnalysis"); } // 配置集合类 public static class ConfigCollection implements Serializable { private static final long serialVersionUID = 1L; public final Map<String, List<ULEParamConfig>> tagToConfigs; public final Map<String, ULEParamConfig> encodeToConfig; public final Set<String> allTags; public final long checkpointTime; public ConfigCollection(Map<String, List<ULEParamConfig>> 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<ConfigCollection> { private volatile boolean isRunning = true; private final long interval = TimeUnit.MINUTES.toMillis(5); @Override public void run(SourceContext<ConfigCollection> ctx) throws Exception { while (isRunning) { try { ConfigCollection newConfig = loadParams(); if (newConfig != null) { ctx.collect(newConfig); System.out.println("[Config] 配置加载完成,检查点时间: " + new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date(newConfig.checkpointTime)) + ", 参数数量: " + newConfig.encodeToConfig.size()); } else { System.out.println("[Config] 配置加载失败"); } } catch (Exception e) { System.err.println("[Config] 配置加载错误: " + e.getMessage()); } Thread.sleep(interval); } } private ConfigCollection loadParams() throws SQLException { Map<String, List<ULEParamConfig>> tagToConfigs = new HashMap<>(5000); Map<String, ULEParamConfig> encodeToConfig = new HashMap<>(5000); // 数据库配置 - 实际使用时应从环境变量获取 String url = "jdbc:mysql://mysql-host:3306/eps?useSSL=false"; String user = "app_user"; String password = "secure_password"; 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"); String tag = config.tag; tagToConfigs.computeIfAbsent(tag, k -> new ArrayList<>(10)).add(config); encodeToConfig.put(config.encode, config); } return new ConfigCollection(tagToConfigs, encodeToConfig); } } @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; private transient MapState<String, Double> lastValuesMap; private transient MapState<String, Long> lastDataTimeMap; private transient ValueState<Long> lastCheckpointState; private transient SimpleDateFormat timeFormat; // 侧输出标签用于配置更新事件 public static final OutputTag<ConfigCollection> CONFIG_UPDATE_TAG = new OutputTag<ConfigCollection>("config-update"){}; @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(); // 初始化状态 MapStateDescriptor<String, AnomalyState> stateDesc = new MapStateDescriptor<>( "anomalyState", BasicTypeInfo.STRING_TYPE_INFO, TypeInformation.of(AnomalyState.class)); stateDesc.enableTimeToLive(ttlConfig); stateMap = getRuntimeContext().getMapState(stateDesc); MapStateDescriptor<String, Double> valuesDesc = new MapStateDescriptor<>( "lastValuesState", BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.DOUBLE_TYPE_INFO); valuesDesc.enableTimeToLive(ttlConfig); lastValuesMap = getRuntimeContext().getMapState(valuesDesc); MapStateDescriptor<String, Long> timeDesc = new MapStateDescriptor<>( "lastDataTimeState", BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.LONG_TYPE_INFO); timeDesc.enableTimeToLive(ttlConfig); lastDataTimeMap = getRuntimeContext().getMapState(timeDesc); ValueStateDescriptor<Long> 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<JSONObject> 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<ULEParamConfig> configs = configCollection.tagToConfigs.get(tag); if (configs == null || configs.isEmpty()) return; // ========== 清理无效状态 ========== cleanupInvalidStates(configs); // ========== 检查离线状态(基于配置检查点) ========== checkOfflineStatus(tag, configs, configCollection, out); 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); // ========== 离线恢复检测 ========== checkOnlineRecovery(config, tag, timeStr, state, out); // 处理异常类型 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 cleanupInvalidStates(List<ULEParamConfig> configs) throws Exception { Set<String> validEncodes = configs.stream() .map(cfg -> cfg.encode) .collect(Collectors.toSet()); Iterator<String> stateKeys = stateMap.keys().iterator(); while (stateKeys.hasNext()) { String encode = stateKeys.next(); if (!validEncodes.contains(encode)) { stateMap.remove(encode); } } } // 检查离线状态 private void checkOfflineStatus(String tag, List<ULEParamConfig> configs, ConfigCollection configCollection, Collector<JSONObject> out) throws Exception { Long lastCP = lastCheckpointState.value(); if (lastCP == null || configCollection.checkpointTime > lastCP) { for (ULEParamConfig config : configs) { if (config.isonline == 1) { Long lastEventTime = lastDataTimeMap.get(tag); if (lastEventTime == null) { AnomalyState state = getOrCreateState(config.encode); AnomalyStatus status = state.getStatus(5); if (!status.reported) { reportAnomaly(5, 1, 0.0, timeFormat.format(new Date(configCollection.checkpointTime)), config, out); status.reported = true; stateMap.put(config.encode, state); } } else { long timeoutPoint = configCollection.checkpointTime - config.duration * 60 * 1000; if (lastEventTime < timeoutPoint) { AnomalyState state = getOrCreateState(config.encode); AnomalyStatus status = state.getStatus(5); if (!status.reported) { reportAnomaly(5, 1, 0.0, timeFormat.format(new Date(configCollection.checkpointTime)), config, out); status.reported = true; stateMap.put(config.encode, state); } } } } } lastCheckpointState.update(configCollection.checkpointTime); } } // 检查在线恢复 private void checkOnlineRecovery(ULEParamConfig config, String tag, String timeStr, AnomalyState state, Collector<JSONObject> out) { if (config.isonline == 1) { AnomalyStatus status = state.getStatus(5); if (status.reported) { reportAnomaly(5, 0, 0.0, timeStr, config, out); status.reset(); } } } // 恒值检测 private void checkConstantValueAnomaly(ULEParamConfig config, double currentValue, String timeStr, AnomalyState state, Collector<JSONObject> 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<JSONObject> 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<JSONObject> 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<JSONObject> 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<JSONObject> out) { if (config.issync != 1 || config.syncparaencode == null) return; try { AnomalyStatus status = state.getStatus(6); Date timestamp = timeFormat.parse(timeStr); ULEParamConfig relatedConfig = configCollection.encodeToConfig.get(config.syncparaencode); if (relatedConfig == null) return; String relatedTag = null; for (Map.Entry<String, List<ULEParamConfig>> entry : configCollection.tagToConfigs.entrySet()) { if (entry.getValue().contains(relatedConfig)) { relatedTag = entry.getKey(); break; } } if (relatedTag == null) return; Double relatedValue = lastValuesMap.get(relatedTag); if (relatedValue == null) return; boolean isAnomaly = (Math.abs(currentValue - 1.0) < 0.001) && (Math.abs(relatedValue) < 0.001); 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<JSONObject> 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<JSONObject> out) { BroadcastState<Void, ConfigCollection> state = ctx.getBroadcastState(Descriptors.configStateDescriptor); try { ConfigCollection oldConfig = state.get(null); // 处理配置变更 if (oldConfig != null) { handleConfigChanges(oldConfig, newConfig, ctx, out); } // 输出配置更新事件(用于后续缺失标签检测) ctx.output(CONFIG_UPDATE_TAG, newConfig); // 更新广播状态 state.put(null, newConfig); System.out.println("[Broadcast] 配置更新完成, 参数数量: " + newConfig.encodeToConfig.size()); } catch (Exception e) { System.err.println("[Broadcast] 配置更新错误: " + e.getMessage()); } } // 处理配置变更 private void handleConfigChanges(ConfigCollection oldConfig, ConfigCollection newConfig, Context ctx, Collector<JSONObject> out) throws Exception { // 1. 处理被删除或禁用的配置项 for (String encode : oldConfig.encodeToConfig.keySet()) { if (!newConfig.encodeToConfig.containsKey(encode)) { ULEParamConfig oldCfg = oldConfig.encodeToConfig.get(encode); sendRecoveryEvents(encode, oldCfg, ctx, out); } } // 2. 处理被删除的tag for (String tag : oldConfig.allTags) { if (!newConfig.allTags.contains(tag)) { cleanupTagStates(tag, oldConfig, ctx, out); } } } // 清理tag相关状态 private void cleanupTagStates(String tag, ConfigCollection configCollection, Context ctx, Collector<JSONObject> out) throws Exception { List<ULEParamConfig> configs = configCollection.tagToConfigs.get(tag); if (configs != null) { for (ULEParamConfig config : configs) { sendRecoveryEvents(config.encode, config, ctx, out); stateMap.remove(config.encode); } } lastValuesMap.remove(tag); lastDataTimeMap.remove(tag); } // 发送恢复事件 private void sendRecoveryEvents(String encode, ULEParamConfig config, Context ctx, Collector<JSONObject> 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); return state != null ? state : new AnomalyState(); } } // 缺失标签检测器 public static class MissingTagDetector extends RichFlatMapFunction<ConfigCollection, JSONObject> { private transient MapState<String, Long> lastCheckTimeMap; private transient SimpleDateFormat timeFormat; @Override public void open(Configuration parameters) { // 状态TTL配置 StateTtlConfig ttlConfig = StateTtlConfig.newBuilder(Time.days(30)) .setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite) .build(); // 初始化状态 MapStateDescriptor<String, Long> lastCheckDesc = new MapStateDescriptor<>( "lastCheckTime", BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.LONG_TYPE_INFO); lastCheckDesc.enableTimeToLive(ttlConfig); lastCheckTimeMap = getRuntimeContext().getMapState(lastCheckDesc); timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); } @Override public void flatMap(ConfigCollection config, Collector<JSONObject> out) throws Exception { long currentTime = System.currentTimeMillis(); for (String tag : config.allTags) { // 检查上次检测时间(避免频繁检测) Long lastCheckTime = lastCheckTimeMap.get(tag); if (lastCheckTime == null || (currentTime - lastCheckTime) > TimeUnit.MINUTES.toMillis(5)) { processTag(tag, config, out); lastCheckTimeMap.put(tag, currentTime); } } } private void processTag(String tag, ConfigCollection config, Collector<JSONObject> out) { List<ULEParamConfig> configs = config.tagToConfigs.get(tag); if (configs == null) return; for (ULEParamConfig configItem : configs) { if (configItem.isonline == 1) { // 触发离线报警 JSONObject event = new JSONObject(); event.put("tag", configItem.tag); event.put("paracode", configItem.encode); event.put("abnormaltype", 5); // 离线类型 event.put("statusflag", 1); // 报警 event.put("datavalue", 0.0); event.put("triggertime", timeFormat.format(new Date())); out.collect(event); System.out.println("[MissingTag] 检测到缺失标签: " + tag); } } } } // 异常状态类 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; } } // 参数配置类 public static class ULEParamConfig implements Serializable { public String tag; public String encode; public String datatype; public int constantvalue; public int isonline; public int issync; public String syncparaencode; public int iszero; public int ishigh; public double highthreshold; public int islow; public double lowthreshold; public long duration; } // 简单的字符串反序列化器 public static class SimpleStringDeserializer implements DeserializationSchema<String> { @Override public String deserialize(byte[] message) { return new String(message); } @Override public boolean isEndOfStream(String nextElement) { return false; } @Override public TypeInformation<String> getProducedType() { return BasicTypeInfo.STRING_TYPE_INFO; } } } 运行提示加载配置: 30 个参数 配置加载完成,检查点时间: Fri Aug 01 08:47:18 CST 2025 java.lang.NullPointerException: No key set. This method should not be called outside of a keyed context. at org.apache.flink.util.Preconditions.checkNotNull(Preconditions.java:76) at org.apache.flink.runtime.state.heap.StateTable.checkKeyNamespacePreconditions(StateTable.java:270) at org.apache.flink.runtime.state.heap.StateTable.get(StateTable.java:260) at org.apache.flink.runtime.state.heap.StateTable.get(StateTable.java:143) at org.apache.flink.runtime.state.heap.HeapMapState.get(HeapMapState.java:86) at org.apache.flink.runtime.state.ttl.TtlMapState.lambda$getWrapped$0(TtlMapState.java:64) at org.apache.flink.runtime.state.ttl.AbstractTtlDecorator.getWrappedWithTtlCheckAndUpdate(AbstractTtlDecorator.java:97) at org.apache.flink.runtime.state.ttl.TtlMapState.getWrapped(TtlMapState.java:63) at org.apache.flink.runtime.state.ttl.TtlMapState.get(TtlMapState.java:57) at org.apache.flink.runtime.state.UserFacingMapState.get(UserFacingMapState.java:47) at com.tongchuang.realtime.mds.ULEDataanomalyanalysis$OptimizedAnomalyDetectionFunction.detectMissingTags(ULEDataanomalyanalysis.java:665) at com.tongchuang.realtime.mds.ULEDataanomalyanalysis$OptimizedAnomalyDetectionFunction.processBroadcastElement(ULEDataanomalyanalysis.java:614) at com.tongchuang.realtime.mds.ULEDataanomalyanalysis$OptimizedAnomalyDetectionFunction.processBroadcastElement(ULEDataanomalyanalysis.java:220) at org.apache.flink.streaming.api.operators.co.CoBroadcastWithKeyedOperator.processElement2(CoBroadcastWithKeyedOperator.java:133) at org.apache.flink.streaming.runtime.io.StreamTwoInputProcessorFactory.processRecord2(StreamTwoInputProcessorFactory.java:221) at org.apache.flink.streaming.runtime.io.StreamTwoInputProcessorFactory.lambda$create$1(StreamTwoInputProcessorFactory.java:190) at org.apache.flink.streaming.runtime.io.StreamTwoInputProcessorFactory$StreamTaskNetworkOutput.emitRecord(StreamTwoInputProcessorFactory.java:291) at org.apache.flink.streaming.runtime.io.AbstractStreamTaskNetworkInput.processElement(AbstractStreamTaskNetworkInput.java:134) at org.apache.flink.streaming.runtime.io.AbstractStreamTaskNetworkInput.emitNext(AbstractStreamTaskNetworkInput.java:105) at org.apache.flink.streaming.runtime.io.StreamOneInputProcessor.processInput(StreamOneInputProcessor.java:66) at org.apache.flink.streaming.runtime.io.StreamTwoInputProcessor.processInput(StreamTwoInputProcessor.java:98) at org.apache.flink.streaming.runtime.tasks.StreamTask.processInput(StreamTask.java:423) at org.apache.flink.streaming.runtime.tasks.mailbox.MailboxProcessor.runMailboxLoop(MailboxProcessor.java:204) at org.apache.flink.streaming.runtime.tasks.StreamTask.runMailboxLoop(StreamTask.java:684) at org.apache.flink.streaming.runtime.tasks.StreamTask.executeInvoke(StreamTask.java:639) at org.apache.flink.streaming.runtime.tasks.StreamTask.runWithCleanUpOnFail(StreamTask.java:650) at org.apache.flink.streaming.runtime.tasks.StreamTask.invoke(StreamTask.java:623) at org.apache.flink.runtime.taskmanager.Task.doRun(Task.java:779) at org.apache.flink.runtime.taskmanager.Task.run(Task.java:566) at java.lang.Thread.run(Thread.java:745)
08-02
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值