sycommon-python-lib 0.1.32__py3-none-any.whl → 0.1.56b5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. sycommon/config/Config.py +6 -2
  2. sycommon/config/RerankerConfig.py +1 -0
  3. sycommon/database/async_base_db_service.py +36 -0
  4. sycommon/database/async_database_service.py +96 -0
  5. sycommon/llm/__init__.py +0 -0
  6. sycommon/llm/embedding.py +149 -0
  7. sycommon/llm/get_llm.py +246 -0
  8. sycommon/llm/llm_logger.py +126 -0
  9. sycommon/llm/llm_tokens.py +119 -0
  10. sycommon/logging/async_sql_logger.py +65 -0
  11. sycommon/logging/kafka_log.py +21 -9
  12. sycommon/logging/logger_levels.py +23 -0
  13. sycommon/middleware/context.py +2 -0
  14. sycommon/middleware/traceid.py +155 -32
  15. sycommon/notice/__init__.py +0 -0
  16. sycommon/notice/uvicorn_monitor.py +195 -0
  17. sycommon/rabbitmq/rabbitmq_client.py +385 -626
  18. sycommon/rabbitmq/rabbitmq_pool.py +287 -71
  19. sycommon/rabbitmq/rabbitmq_service.py +345 -191
  20. sycommon/services.py +104 -64
  21. sycommon/synacos/feign.py +71 -18
  22. sycommon/synacos/feign_client.py +26 -8
  23. sycommon/synacos/nacos_service.py +91 -54
  24. sycommon/tools/merge_headers.py +97 -0
  25. sycommon/tools/snowflake.py +290 -23
  26. {sycommon_python_lib-0.1.32.dist-info → sycommon_python_lib-0.1.56b5.dist-info}/METADATA +17 -12
  27. {sycommon_python_lib-0.1.32.dist-info → sycommon_python_lib-0.1.56b5.dist-info}/RECORD +30 -18
  28. {sycommon_python_lib-0.1.32.dist-info → sycommon_python_lib-0.1.56b5.dist-info}/WHEEL +0 -0
  29. {sycommon_python_lib-0.1.32.dist-info → sycommon_python_lib-0.1.56b5.dist-info}/entry_points.txt +0 -0
  30. {sycommon_python_lib-0.1.32.dist-info → sycommon_python_lib-0.1.56b5.dist-info}/top_level.txt +0 -0
@@ -10,9 +10,8 @@ import yaml
10
10
  import time
11
11
  import atexit
12
12
  import random
13
- from concurrent.futures import ThreadPoolExecutor
14
13
 
15
- from sycommon.config.Config import SingletonMeta
14
+ from sycommon.config.Config import Config, SingletonMeta
16
15
  from sycommon.logging.kafka_log import SYLogger
17
16
 
18
17
 
@@ -34,22 +33,17 @@ class NacosService(metaclass=SingletonMeta):
34
33
  # 添加可重入锁用于状态同步
35
34
  self._state_lock = threading.RLock()
36
35
 
37
- # 优化线程池配置,增加工作线程数量
38
- self._executor = ThreadPoolExecutor(max_workers=1) # 主线程池
39
- self._heartbeat_executor = ThreadPoolExecutor(
40
- max_workers=1) # 增加心跳线程
41
- self._monitor_executor = ThreadPoolExecutor(
42
- max_workers=1) # 增加监控线程
43
-
44
36
  # 配置参数
45
37
  self.max_retries = self.nacos_config.get('maxRetries', 5)
46
- self.retry_delay = self.nacos_config.get('retryDelay', 1)
47
- self.retry_backoff = self.nacos_config.get('retryBackoff', 1.5)
38
+ self.retry_delay = self.nacos_config.get('retryDelay', 5)
48
39
  self.max_retry_delay = self.nacos_config.get('maxRetryDelay', 30)
40
+ # 心跳间隔:优先从配置读取,默认15秒(可通过配置修改)
49
41
  self.heartbeat_interval = self.nacos_config.get(
50
- 'heartbeatInterval', 10)
42
+ 'heartbeatInterval', 15)
43
+ # 心跳超时:固定设置为15秒
44
+ self.heartbeat_timeout = 15
51
45
  self.register_retry_interval = self.nacos_config.get(
52
- 'registerRetryInterval', 5) # 注册重试间隔
46
+ 'registerRetryInterval', 15) # 注册重试间隔
53
47
 
54
48
  # 长期重试配置
55
49
  self.long_term_retry_delay = self.nacos_config.get(
@@ -57,11 +51,13 @@ class NacosService(metaclass=SingletonMeta):
57
51
  self.max_long_term_retries = self.nacos_config.get(
58
52
  'maxLongTermRetries', -1) # -1表示无限重试
59
53
 
60
- # 注册验证配置
54
+ # 注册验证配置:优化默认值(增加次数+延长间隔)
61
55
  self.registration_verify_count = self.nacos_config.get(
62
56
  'registrationVerifyCount', 1) # 验证次数
63
57
  self.registration_verify_interval = self.nacos_config.get(
64
58
  'registrationVerifyInterval', 1) # 验证间隔
59
+ self.registration_post_delay = self.nacos_config.get(
60
+ 'registrationPostDelay', 3) # 注册后延迟3秒再开始验证
65
61
 
66
62
  self.real_ip = self.get_service_ip(self.host)
67
63
  self._long_term_retry_count = 0 # 长期重试计数器
@@ -79,6 +75,8 @@ class NacosService(metaclass=SingletonMeta):
79
75
  SYLogger.info("nacos:本地开发模式,不初始化Nacos客户端")
80
76
 
81
77
  self.share_configs = self.read_configs()
78
+ # 设置llm相关配置
79
+ Config().set_attr(self.share_configs)
82
80
 
83
81
  # 配置监听器
84
82
  self._config_listeners = {}
@@ -129,8 +127,7 @@ class NacosService(metaclass=SingletonMeta):
129
127
  self._client_initialized = True
130
128
  return True
131
129
  except Exception as e:
132
- delay = min(self.retry_delay * (self.retry_backoff **
133
- attempt), self.max_retry_delay)
130
+ delay = min(self.retry_delay, self.max_retry_delay)
134
131
  SYLogger.error(
135
132
  f"nacos:客户端初始化失败 (尝试 {attempt+1}/{self.max_retries}): {e}")
136
133
  time.sleep(delay)
@@ -193,8 +190,7 @@ class NacosService(metaclass=SingletonMeta):
193
190
 
194
191
  except Exception as e:
195
192
  attempt += 1
196
- delay = min(self.retry_delay * (self.retry_backoff **
197
- (attempt - 1)), self.max_retry_delay)
193
+ delay = min(self.retry_delay, self.max_retry_delay)
198
194
 
199
195
  SYLogger.error(
200
196
  f"nacos:客户端初始化失败 (尝试 {attempt}/{max_attempts}): {e}")
@@ -308,12 +304,12 @@ class NacosService(metaclass=SingletonMeta):
308
304
  if not register_success:
309
305
  raise RuntimeError("nacos:服务注册请求失败")
310
306
 
311
- # 注册请求发送成功后,等待一小段时间让Nacos服务器处理
307
+ # 关键优化1:注册请求发送后,延迟一段时间再验证(默认3秒)
312
308
  SYLogger.info(
313
- f"nacos:服务注册请求已发送,等待 {self.registration_verify_interval} 秒后验证")
314
- time.sleep(self.registration_verify_interval)
309
+ f"nacos:服务注册请求已发送,延迟 {self.registration_post_delay} 秒后开始验证(确保Nacos服务器完成实例写入)")
310
+ time.sleep(self.registration_post_delay)
315
311
 
316
- # 多次验证服务是否真正注册成功
312
+ # 关键优化2:多次验证服务是否真正注册成功(默认3次,每次间隔2秒)
317
313
  registered = self.verify_registration()
318
314
 
319
315
  # 带锁更新注册状态
@@ -342,8 +338,7 @@ class NacosService(metaclass=SingletonMeta):
342
338
  except Exception as e:
343
339
  last_error = str(e)
344
340
  retry_count += 1
345
- delay = min(self.register_retry_interval *
346
- (self.retry_backoff ** (retry_count - 1)), self.max_retry_delay)
341
+ delay = min(self.register_retry_interval, self.max_retry_delay)
347
342
 
348
343
  SYLogger.warning(
349
344
  f"nacos:服务注册尝试 {retry_count} 失败: {last_error},{delay}秒后重试")
@@ -429,8 +424,13 @@ class NacosService(metaclass=SingletonMeta):
429
424
  timeout = 60 # 60秒超时
430
425
  start_time = time.time()
431
426
 
432
- # 启动注册线程,不阻塞主线程
433
- instance._executor.submit(instance.register_with_retry)
427
+ # 启动注册线程,不阻塞主线程(替换原线程池)
428
+ register_thread = threading.Thread(
429
+ target=instance.register_with_retry,
430
+ daemon=True,
431
+ name="NacosRegisterThread"
432
+ )
433
+ register_thread.start()
434
434
 
435
435
  # 等待注册完成或超时
436
436
  while True:
@@ -461,7 +461,7 @@ class NacosService(metaclass=SingletonMeta):
461
461
 
462
462
  # 启动连接监控线程
463
463
  threading.Thread(target=instance.monitor_connection,
464
- daemon=True).start()
464
+ daemon=True, name="NacosConnectionMonitorThread").start()
465
465
  else:
466
466
  SYLogger.info("nacos:本地开发模式,跳过服务注册流程")
467
467
 
@@ -485,7 +485,11 @@ class NacosService(metaclass=SingletonMeta):
485
485
  )
486
486
  self._heartbeat_thread.daemon = True
487
487
  self._heartbeat_thread.start()
488
- SYLogger.info(f"nacos:心跳线程启动,线程ID: {self._heartbeat_thread.ident}")
488
+ SYLogger.info(
489
+ f"nacos:心跳线程启动,线程ID: {self._heartbeat_thread.ident},"
490
+ f"心跳间隔: {self.heartbeat_interval}秒,"
491
+ f"心跳超时: {self.heartbeat_timeout}秒"
492
+ )
489
493
 
490
494
  def _send_heartbeat_loop(self):
491
495
  """优化后的心跳发送循环,确保严格按间隔执行"""
@@ -493,7 +497,8 @@ class NacosService(metaclass=SingletonMeta):
493
497
  thread_ident = current_thread.ident
494
498
  SYLogger.info(
495
499
  f"nacos:心跳循环启动 - 线程ID: {thread_ident}, "
496
- f"配置间隔: {self.heartbeat_interval}"
500
+ f"配置间隔: {self.heartbeat_interval}秒, "
501
+ f"超时时间: {self.heartbeat_timeout}秒"
497
502
  )
498
503
 
499
504
  consecutive_fail = 0 # 连续失败计数器
@@ -512,7 +517,7 @@ class NacosService(metaclass=SingletonMeta):
512
517
  f"nacos:服务未注册,跳过心跳 - 线程ID: {thread_ident}")
513
518
  consecutive_fail = 0
514
519
  else:
515
- # 发送心跳
520
+ # 发送心跳(10秒超时)
516
521
  success = self.send_heartbeat()
517
522
  if success:
518
523
  consecutive_fail = 0
@@ -545,26 +550,46 @@ class NacosService(metaclass=SingletonMeta):
545
550
  SYLogger.info(f"nacos:心跳循环已停止 - 线程ID: {thread_ident}")
546
551
 
547
552
  def send_heartbeat(self):
548
- """发送心跳并添加超时控制"""
553
+ """发送心跳并添加10秒超时控制(替换线程池实现)"""
549
554
  if not self.ensure_client_connected():
550
555
  SYLogger.warning("nacos:客户端未连接,心跳发送失败")
551
556
  return False
552
557
 
553
- try:
554
- # 严格控制心跳超时(3秒)
555
- future = self._heartbeat_executor.submit(
556
- self._send_heartbeat_internal)
557
- result = future.result(timeout=3) # 超时后抛出异常
558
-
559
- if result:
560
- # 只有确认成功才更新时间戳
561
- self._last_successful_heartbeat = time.time()
562
- return result
563
- except Exception as e:
564
- SYLogger.error(f"nacos:发送心跳时发生异常: {e}")
558
+ # 用线程+join实现10秒超时控制
559
+ result_list = [] # 用于线程间传递结果
560
+
561
+ def heartbeat_task():
562
+ """心跳实际执行任务"""
563
+ try:
564
+ result = self._send_heartbeat_internal()
565
+ result_list.append(result)
566
+ except Exception as e:
567
+ SYLogger.error(f"nacos:心跳任务执行异常: {e}")
568
+ result_list.append(False)
569
+
570
+ # 启动心跳任务线程
571
+ task_thread = threading.Thread(
572
+ target=heartbeat_task,
573
+ daemon=True,
574
+ name="NacosHeartbeatTaskThread"
575
+ )
576
+ task_thread.start()
577
+
578
+ # 等待线程完成,最多等待10秒
579
+ task_thread.join(timeout=self.heartbeat_timeout)
580
+
581
+ # 处理结果
582
+ if not result_list:
583
+ # 超时未返回
584
+ SYLogger.error(f"nacos:心跳发送超时({self.heartbeat_timeout}秒)")
565
585
  self._client_initialized = False # 强制重连
566
586
  return False
567
587
 
588
+ # 检查心跳结果
589
+ if result_list[0]:
590
+ self._last_successful_heartbeat = time.time()
591
+ return result_list[0]
592
+
568
593
  def _send_heartbeat_internal(self):
569
594
  """实际的心跳发送逻辑"""
570
595
  result = self.nacos_client.send_heartbeat(
@@ -620,9 +645,13 @@ class NacosService(metaclass=SingletonMeta):
620
645
  else:
621
646
  self.registered = False
622
647
  SYLogger.warning(f"nacos:服务实例未注册,尝试重新注册")
623
- # 不在锁内调用可能耗时的操作
624
- self._monitor_executor.submit(
625
- self.register_with_retry)
648
+ # 启动临时线程执行重新注册(替换原线程池)
649
+ retry_thread = threading.Thread(
650
+ target=self.register_with_retry,
651
+ daemon=True,
652
+ name="NacosRetryRegisterThread"
653
+ )
654
+ retry_thread.start()
626
655
 
627
656
  # 20%的概率执行深度检查
628
657
  if random.random() < 0.2:
@@ -673,13 +702,6 @@ class NacosService(metaclass=SingletonMeta):
673
702
  SYLogger.error(f"nacos:注销服务时发生错误: {e}")
674
703
  finally:
675
704
  self._shutdown_event.set()
676
- # 优雅地关闭线程池
677
- if self._executor and not self._executor._shutdown:
678
- self._executor.shutdown(wait=True)
679
- if self._heartbeat_executor and not self._heartbeat_executor._shutdown:
680
- self._heartbeat_executor.shutdown(wait=True)
681
- if self._monitor_executor and not self._monitor_executor._shutdown:
682
- self._monitor_executor.shutdown(wait=True)
683
705
 
684
706
  def handle_signal(self, signum, frame):
685
707
  """处理退出信号"""
@@ -751,8 +773,18 @@ class NacosService(metaclass=SingletonMeta):
751
773
  for data_id, callback in list(self._config_listeners.items()):
752
774
  new_config = self.get_config(data_id)
753
775
  if new_config and new_config != self._config_cache.get(data_id):
754
- self._executor.submit(callback, new_config)
776
+ # 直接执行回调(替换原线程池,配置回调通常为轻量操作)
777
+ callback(new_config)
755
778
  self._config_cache[data_id] = new_config
779
+ try:
780
+ self.share_configs[data_id] = json.loads(
781
+ new_config)
782
+ except json.JSONDecodeError:
783
+ try:
784
+ self.share_configs[data_id] = yaml.safe_load(
785
+ new_config)
786
+ except yaml.YAMLError:
787
+ SYLogger.error(f"nacos:无法解析 {data_id} 的内容")
756
788
  except Exception as e:
757
789
  SYLogger.error(f"nacos:配置监视线程异常: {str(e)}")
758
790
  self._shutdown_event.wait(check_interval)
@@ -785,6 +817,11 @@ class NacosService(metaclass=SingletonMeta):
785
817
  return []
786
818
 
787
819
  all_instances = instances.get('hosts', [])
820
+ # 筛选已上线实例
821
+ all_instances = [
822
+ instance for instance in all_instances
823
+ if instance.get('enabled', True) # 默认True担心阿里变更sdk
824
+ ]
788
825
  SYLogger.info(
789
826
  f"nacos:共发现 {len(all_instances)} 个 {service_name} 服务实例")
790
827
 
@@ -0,0 +1,97 @@
1
+ def merge_headers(
2
+ source_headers, # 来源headers(支持多种格式:字典/MutableHeaders/键值对列表/元组)
3
+ target_headers, # 目标headers(原有值需保留,同名覆盖source)
4
+ keep_keys=None, # 需保留的key集合(None表示保留所有)
5
+ delete_keys={'content-length', 'accept',
6
+ 'content-type', 'sec-fetch-mode',
7
+ 'sec-fetch-dest', 'sec-fetch-site',
8
+ 'pragma', 'cache-control',
9
+ 'accept-encoding', 'priority'}, # 需删除的source key集合
10
+ encoding='utf-8' # 字符编码(处理bytes转换)
11
+ ) -> dict:
12
+ """
13
+ 合并headers,最终规则:
14
+ 1. 所有key统一转为小写进行比较判断(完全大小写无关)
15
+ 2. target_headers 同名key 完全覆盖 source_headers(source同名key不生效)
16
+ 3. delete_keys 作用于source_headers:source中所有该列表内的key一律不添加(无论是否新增)
17
+ 4. target_headers 中的key即使在delete_keys也始终保留,不受删除规则影响
18
+ 5. 自动处理bytes/其他类型的键值转换为字符串
19
+ 6. 最终输出的key全部为小写
20
+ """
21
+ # 初始化并统一转为小写集合
22
+ keep_keys = {k.lower() for k in keep_keys} if keep_keys else set()
23
+ delete_keys = {k.lower() for k in delete_keys} if delete_keys else set()
24
+
25
+ # 修复1:兼容 MutableHeaders/普通字典/None 等 target_headers 类型
26
+ if target_headers is None:
27
+ target_dict = {}
28
+ elif hasattr(target_headers, 'items'):
29
+ # 支持 MutableHeaders/Headers/普通字典(都有items()方法)
30
+ target_dict = dict(target_headers.items())
31
+ else:
32
+ # 兜底:可迭代对象转为字典
33
+ target_dict = dict(target_headers) if isinstance(
34
+ target_headers, (list, tuple)) else {}
35
+
36
+ # 标准化target_headers:key转为小写,保留原有值
37
+ processed_headers = {k.lower(): v for k, v in target_dict.items()}
38
+ target_original_keys = set(processed_headers.keys())
39
+
40
+ # 修复2:统一处理 source_headers 格式,确保是键值对迭代器
41
+ # 步骤1:将source_headers转为标准的键值对列表
42
+ if source_headers is None:
43
+ source_kv_list = []
44
+ elif hasattr(source_headers, 'items'):
45
+ # 字典/MutableHeaders → 转为键值对列表
46
+ source_kv_list = list(source_headers.items())
47
+ elif isinstance(source_headers, (list, tuple)):
48
+ # 列表/元组 → 校验并过滤合法的键值对(仅保留长度为2的元组/列表)
49
+ source_kv_list = []
50
+ for item in source_headers:
51
+ if isinstance(item, (list, tuple)) and len(item) == 2:
52
+ source_kv_list.append(item)
53
+ else:
54
+ # 跳过非法格式(如长度≠2的元素),避免解包报错
55
+ continue
56
+ else:
57
+ # 其他类型 → 空列表(避免迭代报错)
58
+ source_kv_list = []
59
+
60
+ # 处理来源headers的键值转换和合并(遍历标准化后的键值对)
61
+ for key, value in source_kv_list:
62
+ # 转换key为字符串并统一转为小写(判断用)
63
+ if not isinstance(key, str):
64
+ try:
65
+ key = key.decode(encoding, errors='replace') if isinstance(
66
+ key, bytes) else str(key)
67
+ except Exception:
68
+ # 极端情况:无法转换的key直接跳过
69
+ continue
70
+
71
+ key_lower = key.lower()
72
+
73
+ # 转换value为字符串
74
+ if not isinstance(value, str):
75
+ try:
76
+ value = value.decode(encoding, errors='replace') if isinstance(
77
+ value, bytes) else str(value)
78
+ except Exception:
79
+ # 无法转换的value设为空字符串
80
+ value = ""
81
+
82
+ # 过滤1:source的key在删除列表 → 直接跳过
83
+ if key_lower in delete_keys:
84
+ continue
85
+
86
+ # 过滤2:仅保留指定的key(如果设置了keep_keys)
87
+ if keep_keys and key_lower not in keep_keys:
88
+ continue
89
+
90
+ # 过滤3:target已有同名key → 直接跳过(target值覆盖source)
91
+ if key_lower in target_original_keys:
92
+ continue
93
+
94
+ # 仅添加符合条件的key-value(最终key为小写)
95
+ processed_headers[key_lower] = value
96
+
97
+ return processed_headers