feat: stabilize multi-region runtime sync and worker orchestration

This commit is contained in:
root
2026-04-27 15:48:12 +08:00
parent 7cbde2aa78
commit 215a364891
137 changed files with 31931 additions and 1943 deletions

View File

@@ -11,6 +11,7 @@
import time
from loguru import logger
from app.utils.database import Database
from app.utils.detection_results import normalize_detector_result
from app.detectors.rdap_detector import RDAPDetector
from app.detectors.wayback_detector import WaybackDetector
from app.detectors.baidu_detector import BaiduDetector
@@ -32,6 +33,10 @@ class DetectEngine:
"""
检测引擎
"""
OUTCOME_SUCCESS = "success"
OUTCOME_BLACKLISTED = "blacklisted"
OUTCOME_FAILED = "failed"
def __init__(self):
"""
@@ -49,6 +54,9 @@ class DetectEngine:
self.jucha_detector = JuchaDetector()
def detect_domain(self, domain_id):
return self._detect_domain_with_outcome(domain_id) == self.OUTCOME_SUCCESS
def _detect_domain_with_outcome(self, domain_id):
"""
检测域名
@@ -69,24 +77,30 @@ class DetectEngine:
self.db.update_domain_detect_status(domain_id, DETECT_STATUS_RUNNING)
# 1. 基础检测
if not self._basic_detect(domain_id, domain):
basic_outcome = self._basic_detect(domain_id, domain)
if basic_outcome != self.OUTCOME_SUCCESS:
logger.info(f"基础检测失败,停止后续检测: {domain}")
return False
if basic_outcome == self.OUTCOME_FAILED:
self.db.update_domain_detect_status(domain_id, DETECT_STATUS_FAILED)
return basic_outcome
# 2. 深度检测
if not self._deep_detect(domain_id, domain):
deep_outcome = self._deep_detect(domain_id, domain)
if deep_outcome != self.OUTCOME_SUCCESS:
logger.info(f"深度检测失败: {domain}")
return False
if deep_outcome == self.OUTCOME_FAILED:
self.db.update_domain_detect_status(domain_id, DETECT_STATUS_FAILED)
return deep_outcome
# 更新检测状态为正常
self.db.update_domain_detect_status(domain_id, DETECT_STATUS_COMPLETED)
logger.info(f"域名检测完成: {domain}")
return True
return self.OUTCOME_SUCCESS
except Exception as e:
logger.error(f"检测域名出错: {e}")
# 更新检测状态为检测失败
self.db.update_domain_detect_status(domain_id, DETECT_STATUS_FAILED)
return False
return self.OUTCOME_FAILED
def _basic_detect(self, domain_id, domain):
"""
@@ -94,7 +108,7 @@ class DetectEngine:
:param domain_id: 域名ID
:param domain: 域名
:return: bool - 是否检测通过
:return: str - 检测结果
"""
# 1. 检查是否为一口价域名
is_ykj = self.db.is_ykj_domain(domain_id)
@@ -108,7 +122,7 @@ class DetectEngine:
if self.db.is_blacklisted(domain):
logger.info(f"域名在黑名单中: {domain}")
self.db.update_domain_detect_status(domain_id, DETECT_STATUS_BLACKLISTED)
return False
return self.OUTCOME_BLACKLISTED
# 4. 时光机快照年份采集
snapshot_years = self.wayback_detector.get_snapshot_years(domain)
@@ -120,9 +134,9 @@ class DetectEngine:
logger.info(f"域名包含敏感词: {domain}")
self.db.update_domain_detect_status(domain_id, DETECT_STATUS_BLACKLISTED)
self.db.add_to_blacklist(domain, "快照包含敏感词")
return False
return self.OUTCOME_BLACKLISTED
return True
return self.OUTCOME_SUCCESS
def _deep_detect(self, domain_id, domain):
"""
@@ -130,38 +144,52 @@ class DetectEngine:
:param domain_id: 域名ID
:param domain: 域名
:return: bool - 是否检测通过
:return: str - 检测结果
"""
# 1. 百度历史/Site
baidu_history = self.baidu_detector.check_history(domain)
baidu_site = self.baidu_detector.check_site(domain)
# 2. 360 Site
qihu360_site = self.qihu360_detector.check_site(domain)
# 3. Google Site
google_site = self.google_detector.check_site(domain)
# 4. 站长之家
chinaz_info = self.chinaz_detector.check_domain(domain)
# 5. 爱站网
aizhan_info = self.aizhan_detector.check_domain(domain)
# 6. 桔子SEO
juziseo_info = self.juziseo_detector.check_domain(domain)
# 7. 聚查
jucha_info = self.jucha_detector.check_domain(domain)
# 检查是否有风险
if self._check_risk(domain_id, domain, baidu_history, baidu_site, qihu360_site, google_site, chinaz_info, aizhan_info, juziseo_info, jucha_info):
return False
detector_results = {}
detector_steps = [
("baidu_history", lambda: self.baidu_detector.check_history(domain)),
("baidu_site", lambda: self.baidu_detector.check_site(domain)),
("qihu360_site", lambda: self.qihu360_detector.check_site(domain)),
("google_site", lambda: self.google_detector.check_site(domain)),
("chinaz_info", lambda: self.chinaz_detector.check_domain(domain)),
("aizhan_info", lambda: self.aizhan_detector.check_domain(domain)),
("juziseo_info", lambda: self.juziseo_detector.check_domain(domain)),
("jucha_info", lambda: self.jucha_detector.check_domain(domain)),
]
for detector_name, runner in detector_steps:
detector_results[detector_name] = normalize_detector_result(detector_name, runner())
detector_error = detector_results[detector_name].get("error")
if detector_error:
logger.error(
f"深度检测存在第三方检测错误: {domain}, detector={detector_name}, error={detector_error}"
)
return self.OUTCOME_FAILED
if self._check_risk(
domain_id,
domain,
detector_results.get("baidu_history"),
detector_results.get("baidu_site"),
detector_results.get("qihu360_site"),
detector_results.get("google_site"),
detector_results.get("chinaz_info"),
detector_results.get("aizhan_info"),
detector_results.get("juziseo_info"),
detector_results.get("jucha_info"),
):
self._persist_detection_results(domain_id, detector_results)
return self.OUTCOME_BLACKLISTED
# 保存检测结果
self.db.add_detection_result(domain_id, baidu_history, baidu_site, qihu360_site, google_site, chinaz_info, aizhan_info, juziseo_info, jucha_info)
persisted = self._persist_detection_results(domain_id, detector_results)
if not persisted:
logger.error(f"保存检测结果失败: {domain}")
return self.OUTCOME_FAILED
return True
return self.OUTCOME_SUCCESS
def _check_risk(self, domain_id, domain, baidu_history, baidu_site, qihu360_site, google_site, chinaz_info, aizhan_info, juziseo_info, jucha_info):
"""
@@ -180,7 +208,9 @@ class DetectEngine:
:return: bool - 是否有风险
"""
# 检查百度历史过灰
if baidu_history and '' in str(baidu_history):
if (
isinstance(baidu_history, dict) and baidu_history.get('has_gray')
) or (baidu_history and '' in str(baidu_history)):
logger.info(f"百度历史过灰: {domain}")
self.db.update_domain_detect_status(domain_id, DETECT_STATUS_BLACKLISTED)
self.db.add_to_blacklist(domain, "百度历史过灰")
@@ -215,7 +245,7 @@ class DetectEngine:
# 检查WHOIS状态
if jucha_info and 'whois' in jucha_info:
if jucha_info['whois'].get('status') in ['clientHold', 'serverHold']:
if jucha_info['whois'].get('whois_status') in ['clientHold', 'serverHold']:
logger.info(f"WHOIS状态异常: {domain}")
self.db.update_domain_detect_status(domain_id, DETECT_STATUS_BLACKLISTED)
self.db.add_to_blacklist(domain, "WHOIS状态异常")
@@ -225,11 +255,24 @@ class DetectEngine:
if jucha_info and 'intercept' in jucha_info:
if not jucha_info['intercept'].get('normal', True):
logger.info(f"拦截检测异常: {domain}")
self.db.update_domain_detect_status(domain_id, 4) # 4 表示黑名单
self.db.update_domain_detect_status(domain_id, DETECT_STATUS_BLACKLISTED)
self.db.add_to_blacklist(domain, "拦截检测异常")
return True
return False
def _persist_detection_results(self, domain_id, detector_results):
return self.db.add_detection_result(
domain_id,
detector_results.get("baidu_history"),
detector_results.get("baidu_site"),
detector_results.get("qihu360_site"),
detector_results.get("google_site"),
detector_results.get("chinaz_info"),
detector_results.get("aizhan_info"),
detector_results.get("juziseo_info"),
detector_results.get("jucha_info"),
)
def _contains_sensitive_words(self, text):
"""
@@ -264,11 +307,12 @@ class DetectEngine:
self.db.update_task_status(task_id, 1) # 1 表示执行中
# 执行检测
success = self.detect_domain(domain_id)
outcome = self._detect_domain_with_outcome(domain_id)
# 更新任务状态
if success:
if outcome in (self.OUTCOME_SUCCESS, self.OUTCOME_BLACKLISTED):
self.db.update_task_status(task_id, 2) # 2 表示完成
return True
else:
# 增加重试次数
retry_count = task.get('retry_count', 0) + 1
@@ -277,8 +321,7 @@ class DetectEngine:
self.db.update_task_status(task_id, 0) # 0 表示待执行
else:
self.db.update_task_status(task_id, 3) # 3 表示失败
return success
return False
except Exception as e:
logger.error(f"处理任务出错: {e}")
# 更新任务状态为失败