问题分析
是的,当前的代码设计确实会导致创建很多session,这会带来以下问题:
- 资源浪费:每次调用都会创建新的session连接,消耗系统资源
- 性能下降:频繁建立和关闭连接会增加网络开销和延迟
- 连接池耗尽:IoTDB服务器的连接数有限,过多连接可能导致连接池耗尽
- 内存泄漏风险:如果session没有正确关闭,可能导致内存泄漏
修复建议
方案一:使用上下文管理器(推荐)
from contextlib import contextmanager
@contextmanager
def get_session():
session = Session(
host=settings.iotDB_host,
port=settings.iotDB_port,
user=settings.iotDB_username,
password=settings.iotDB_password,
zone_id="UTC+8"
)
try:
session.open(False)
yield session
finally:
session.close()
# 修改使用session的函数
def set_record_data(time, measurement: str, measurement_value: float):
try:
if measurement == '':
return None
with get_session() as session:
session.insert_record(
device_id="root.dt.plc", # 设备路径
timestamp=int(time), # 时间戳
measurements=[measurement], # 测量值列表
data_types=[TSDataType.DOUBLE], # 类型列表
values=[measurement_value] # 值列表
)
return True
except Exception as e:
print("数据记录赋值异常" + str(e))
return False
方案二:使用单例模式管理session
class IoTDBSessionManager:
_instance = None
_session = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def get_session(self):
if self._session is None or not self._session.is_open():
self._session = Session(
host=settings.iotDB_host,
port=settings.iotDB_port,
user=settings.iotDB_username,
password=settings.iotDB_password,
zone_id="UTC+8"
)
self._session.open(False)
return self._session
def close_session(self):
if self._session and self._session.is_open():
self._session.close()
self._session = None
# 使用单例管理器
def set_record_data(time, measurement: str, measurement_value: float):
try:
if measurement == '':
return None
session_manager = IoTDBSessionManager()
session = session_manager.get_session()
session.insert_record(
device_id="root.dt.plc",
timestamp=int(time),
measurements=[measurement],
data_types=[TSDataType.DOUBLE],
values=[measurement_value]
)
return True
except Exception as e:
print("数据记录赋值异常" + str(e))
return False
方案三:在应用启动时初始化session(适用于长时间运行的服务)
# 全局session变量
_global_session = None
def init_global_session():
global _global_session
if _global_session is None:
_global_session = Session(
host=settings.iotDB_host,
port=settings.iotDB_port,
user=settings.iotDB_username,
password=settings.iotDB_password,
zone_id="UTC+8"
)
_global_session.open(False)
def get_global_session():
global _global_session
if _global_session is None or not _global_session.is_open():
init_global_session()
return _global_session
def close_global_session():
global _global_session
if _global_session and _global_session.is_open():
_global_session.close()
_global_session = None
# 使用全局session
def set_record_data(time, measurement: str, measurement_value: float):
try:
if measurement == '':
return None
session = get_global_session()
session.insert_record(
device_id="root.dt.plc",
timestamp=int(time),
measurements=[measurement],
data_types=[TSDataType.DOUBLE],
values=[measurement_value]
)
return True
except Exception as e:
print("数据记录赋值异常" + str(e))
return False
推荐使用方案一(上下文管理器),因为它既保证了资源的正确释放,又避免了连接的频繁创建和销毁。