""" agent_jrxml 统一启动/停止脚本 用法: python start.py [--frontend] """ import subprocess import sys import time import signal import os import socket PROCESSES = [] def kill_port(port): """杀掉占用指定端口的所有进程""" killed = [] try: result = subprocess.run( ['netstat', '-ano'], capture_output=True, text=True, timeout=10 ) for line in result.stdout.splitlines(): if f':{port}' in line and 'LISTENING' in line: parts = line.strip().split() pid = parts[-1] try: subprocess.run(['taskkill', '/F', '/PID', pid], capture_output=True, timeout=5) killed.append(pid) except: pass except: pass if killed: print(f"[清理] 端口 {port} 已清理 {len(killed)} 个进程: {', '.join(killed)}") return len(killed) def wait_port(port, timeout=30): """等待端口就绪""" for i in range(timeout * 2): try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(1) s.connect(('127.0.0.1', port)) s.close() return True except: time.sleep(0.5) return False def start(port, module, cwd=None): """启动一个 uvicorn 服务""" cmd = [ sys.executable, '-c', f"import uvicorn; uvicorn.run('{module}', host='0.0.0.0', port={port}, reload=False)" ] proc = subprocess.Popen(cmd, cwd=cwd) PROCESSES.append((port, proc)) print(f"[启动] {module} -> :{port} (PID: {proc.pid})") return proc def cleanup(): """清理所有子进程""" print("\n[清理] 正在停止所有服务...") for port, proc in PROCESSES: try: proc.terminate() except: pass time.sleep(2) for port, proc in PROCESSES: try: proc.kill() except: pass kill_port(port) print("[清理] 完成") def main(): frontend = '--frontend' in sys.argv # 1. 清理残留进程 print("=" * 50) print("agent_jrxml 启动脚本") print("=" * 50) kill_port(8000) kill_port(8001) if frontend: kill_port(5173) # 2. 启动服务(基于脚本所在目录自动定位项目) project = os.path.dirname(os.path.abspath(__file__)) start(8000, 'api_server:app', cwd=project) start(8001, 'validation_service.main:app', cwd=project) if frontend: # 前端用 npm 启动 frontend_dir = os.path.join(project, 'frontend') proc = subprocess.Popen( ['npm', 'run', 'dev'], cwd=frontend_dir, shell=True ) PROCESSES.append((5173, proc)) print(f"[启动] frontend (Vite) -> :5173") # 3. 等待就绪 print("\n[等待] 等待服务就绪...") ok = True for port, _ in PROCESSES: if wait_port(port): print(f" :{port} ✓") else: print(f" :{port} ✗ 超时!") ok = False if not ok: print("\n[错误] 部分服务启动失败") cleanup() sys.exit(1) print(f"\n{'='*50}") print("服务就绪:") print(f" API: http://localhost:8000/docs") print(f" 验证: http://localhost:8001/health") if frontend: print(f" 前端: http://localhost:5173") print(f"\n按 Ctrl+C 停止所有服务") print(f"{'='*50}") # 4. 等待退出信号 try: while True: time.sleep(1) except KeyboardInterrupt: pass finally: cleanup() if __name__ == '__main__': main()