feat(data-ana): 完整实现 data-ana 数据分析服务
包含 CDC consumer、analytics/mastery/warning service、grpc server、repository、ClickHouse DDL 等
This commit is contained in:
@@ -1,46 +1,97 @@
|
||||
"""配置管理."""
|
||||
"""配置管理(pydantic-settings 完整配置项).
|
||||
|
||||
from pydantic_settings import BaseSettings
|
||||
对齐 02-architecture-design.md §15 配置清单.
|
||||
环境变量前缀 DATA_ANA_(如 DATA_ANA_HTTP_PORT=3006).
|
||||
"""
|
||||
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
"""应用配置.
|
||||
|
||||
ClickHouse 连接参数为可选:当 clickhouse_host 为空字符串时,
|
||||
服务进入降级模式(查询方法返回 None / 空数据),保证服务可启动。
|
||||
|
||||
Kafka 连接参数为可选:当 kafka_brokers 为空字符串时,
|
||||
CDC 消费者不启动(降级模式),保证服务可启动。
|
||||
所有外部依赖(ClickHouse / Kafka / Redis / iam gRPC)均为可选:
|
||||
未配置或不可达时服务进入降级模式,返回骨架数据 + details.degraded: true.
|
||||
"""
|
||||
|
||||
port: int = 3006
|
||||
# ClickHouse 连接(可选:留空则降级模式)
|
||||
# 服务
|
||||
service_name: str = "data-ana"
|
||||
http_port: int = 3006
|
||||
grpc_port: int = 50055
|
||||
log_level: str = "INFO"
|
||||
dev_mode: bool = False
|
||||
|
||||
# ClickHouse(可选:留空则降级模式)
|
||||
clickhouse_host: str = ""
|
||||
clickhouse_port: int = 8123
|
||||
clickhouse_database: str = "edu_analytics"
|
||||
clickhouse_user: str = ""
|
||||
clickhouse_password: str = ""
|
||||
# 可观测性
|
||||
otel_endpoint: str = "http://localhost:4318"
|
||||
log_level: str = "info"
|
||||
# 开发模式开关
|
||||
dev_mode: bool = False
|
||||
# Kafka brokers(CDC 消费;留空则不启动消费者)
|
||||
# 主机访问用 localhost:9092,容器内访问用 kafka:29092
|
||||
kafka_brokers: str = ""
|
||||
# CDC 消费组 id
|
||||
kafka_group_id: str = "data-ana-cdc-consumer"
|
||||
# 要消费的 CDC topic(Debezium 默认命名:<prefix>.<database>.<table>)
|
||||
# 用逗号分隔多个 topic
|
||||
clickhouse_connect_timeout_ms: int = 3000
|
||||
clickhouse_query_timeout_s: int = 3 # P4 退出标准 5s,查询 3s 超时降级
|
||||
|
||||
# Kafka
|
||||
kafka_brokers: str = "" # 留空则不启动 CDC 消费者
|
||||
kafka_consumer_group: str = "data-ana-cdc"
|
||||
kafka_cdc_topics: str = (
|
||||
"edu-cdc.next_edu_cloud.core_edu_grades,"
|
||||
"edu-cdc.next_edu_cloud.core_edu_exams,"
|
||||
"edu-cdc.next_edu_cloud.classes"
|
||||
"edu-cdc.next_edu_cloud.core_edu_homework_submissions,"
|
||||
"edu-cdc.next_edu_cloud.core_edu_attendance,"
|
||||
"edu-cdc.next_edu_cloud.classes,"
|
||||
"edu-cdc.next_edu_cloud.iam_users,"
|
||||
"edu-cdc.next_edu_cloud.content_knowledge_points"
|
||||
)
|
||||
# 消费者自动偏移重置策略(earliest / latest)
|
||||
kafka_auto_offset_reset: str = "earliest"
|
||||
kafka_mastery_topic: str = "edu.insight.mastery.updated"
|
||||
kafka_warning_topic: str = "edu.insight.mastery.updated" # 复用 mastery topic(总裁裁决 §2.11)
|
||||
kafka_ai_usage_topic: str = "edu.insight.ai.usage"
|
||||
kafka_enable_auto_commit: bool = False # v2: 手动 commit(at-least-once)
|
||||
kafka_auto_offset_reset: str = "latest"
|
||||
kafka_producer_transactional_id: str = "data-ana-producer"
|
||||
|
||||
model_config = {"env_file": ".env", "env_prefix": ""}
|
||||
# iam gRPC
|
||||
iam_grpc_endpoint: str = "" # 留空则使用降级兜底(按 role 映射 DataScope)
|
||||
iam_grpc_timeout_s: int = 2
|
||||
datascope_cache_ttl_s: int = 300 # 5min
|
||||
|
||||
# Redis
|
||||
redis_url: str = "" # 留空则跳过缓存
|
||||
redis_pool_size: int = 10
|
||||
redis_socket_timeout_ms: int = 200
|
||||
|
||||
# OTel
|
||||
otel_endpoint: str = "http://localhost:4318"
|
||||
otel_service_name: str = "data-ana"
|
||||
|
||||
# 掌握度算法
|
||||
mastery_window_size: int = 5
|
||||
mastery_decay_base: float = 0.6
|
||||
mastery_forgetting_half_life_days: int = 30
|
||||
mastery_min_samples: int = 3
|
||||
|
||||
# 预警阈值
|
||||
warning_low_mastery_threshold: float = 0.4
|
||||
warning_critical_mastery_threshold: float = 0.2
|
||||
warning_score_drop_percent: float = 0.2
|
||||
warning_absent_per_week: int = 3
|
||||
|
||||
# 降级
|
||||
degraded_mode_enabled: bool = True
|
||||
|
||||
# 向后兼容:旧代码引用 settings.port / settings.kafka_group_id
|
||||
@property
|
||||
def port(self) -> int:
|
||||
return self.http_port
|
||||
|
||||
@property
|
||||
def kafka_group_id(self) -> str:
|
||||
return self.kafka_consumer_group
|
||||
|
||||
model_config = SettingsConfigDict(
|
||||
env_file=".env",
|
||||
env_prefix="DATA_ANA_",
|
||||
extra="ignore",
|
||||
)
|
||||
|
||||
|
||||
settings = Settings()
|
||||
|
||||
Reference in New Issue
Block a user