liuq há 4 meses atrás
pai
commit
e35c8fa012
2 ficheiros alterados com 42 adições e 18 exclusões
  1. 5 1
      README.md
  2. 37 17
      backend/app/main.py

+ 5 - 1
README.md

@@ -45,7 +45,10 @@
 # 启动服务
 docker-compose up -d
 ```
-
+```bash
+# 构建并启动服务
+sudo docker-compose up -d --build
+```
 > **❗ Windows 用户特别提示 (构建卡住解决方案)**:
 > 如果直接运行 `docker-compose build` 时遇到 `npm install` 阶段卡住不动(常见于 Windows Docker Desktop 网络环境),请按以下步骤手动构建:
 >
@@ -61,6 +64,7 @@ docker-compose up -d
 > **提示**: 
 > *   `docker-compose.yml` 已配置为优先使用本地 `ai-watch-platform` 镜像。只有当本地不存在该镜像时,才会尝试自动构建。
 > *   如果遇到 "DEPRECATED" 警告,请确保使用新版 `docker compose` 命令。
+> *   **💡 智能重试机制**: 后端服务已内置了数据库连接重试逻辑 (Max 30次, 间隔2s)。即使数据库启动较慢,应用也会耐心等待直到连接成功,无需人工重启。
 
 #### 2. 访问服务
 

+ 37 - 17
backend/app/main.py

@@ -44,23 +44,43 @@ app.mount("/static", StaticFiles(directory="backend/app/static"), name="static")
 
 def init_db_if_not_exists():
     """Check if database exists, create if not."""
-    try:
-        logger.info(f"Connecting to MySQL server at {settings.MYSQL_SERVER} to check database...")
-        conn = pymysql.connect(
-            host=settings.MYSQL_SERVER,
-            user=settings.MYSQL_USER,
-            password=settings.MYSQL_PASSWORD,
-            port=int(settings.MYSQL_PORT),
-            charset='utf8mb4',
-            cursorclass=pymysql.cursors.DictCursor
-        )
-        with conn.cursor() as cursor:
-            logger.info(f"Checking database {settings.MYSQL_DB}...")
-            cursor.execute(f"CREATE DATABASE IF NOT EXISTS {settings.MYSQL_DB} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;")
-            logger.info("Database checked/created.")
-        conn.close()
-    except Exception as e:
-        logger.error(f"Database initialization failed: {e}")
+    max_retries = 30
+    retry_interval = 2  # seconds
+
+    for attempt in range(max_retries):
+        try:
+            logger.info(f"Connecting to MySQL server at {settings.MYSQL_SERVER} to check database (Attempt {attempt + 1}/{max_retries})...")
+            conn = pymysql.connect(
+                host=settings.MYSQL_SERVER,
+                user=settings.MYSQL_USER,
+                password=settings.MYSQL_PASSWORD,
+                port=int(settings.MYSQL_PORT),
+                charset='utf8mb4',
+                cursorclass=pymysql.cursors.DictCursor
+            )
+            with conn.cursor() as cursor:
+                logger.info(f"Checking database {settings.MYSQL_DB}...")
+                cursor.execute(f"CREATE DATABASE IF NOT EXISTS {settings.MYSQL_DB} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;")
+                logger.info("Database checked/created.")
+            conn.close()
+            return  # Success
+        except pymysql.err.OperationalError as e:
+            if e.args[0] == 2003:  # Connection refused
+                logger.warning(f"Database not ready yet, retrying in {retry_interval}s...")
+                import time
+                time.sleep(retry_interval)
+            else:
+                logger.error(f"Database initialization failed: {e}")
+                # Don't raise immediately, maybe transient? But usually logic error.
+                # Let's retry anyway to be safe, or break if critical.
+                time.sleep(retry_interval)
+        except Exception as e:
+            logger.error(f"Database initialization failed: {e}")
+            import time
+            time.sleep(retry_interval)
+    
+    logger.error("Could not connect to database after multiple attempts.")
+    # raise Exception("Database connection failed") # Optional: crash app
 
 # Startup Event
 @app.on_event("startup")