start_service.sh 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. #!/bin/bash
  2. # Agent 服务管理脚本
  3. # 服务配置
  4. SERVICE_NAME="knowledge-agent"
  5. PID_FILE="/tmp/${SERVICE_NAME}.pid"
  6. LOG_FILE="logs/agent.log"
  7. PORT=8080
  8. # 创建日志目录
  9. mkdir -p logs
  10. # 显示帮助信息
  11. show_help() {
  12. echo "Usage: $0 {start|stop|restart|status|logs}"
  13. echo ""
  14. echo "Commands:"
  15. echo " start - 启动服务"
  16. echo " stop - 停止服务"
  17. echo " restart - 重启服务"
  18. echo " status - 查看服务状态"
  19. echo " logs - 查看实时日志"
  20. echo ""
  21. echo "Examples:"
  22. echo " $0 start # 启动服务"
  23. echo " $0 stop # 停止服务"
  24. echo " $0 logs # 查看实时日志"
  25. echo " tail -f logs/agent.log # 也可以直接使用 tail 命令"
  26. }
  27. # 检查服务是否运行
  28. is_running() {
  29. if [ -f "$PID_FILE" ]; then
  30. pid=$(cat "$PID_FILE")
  31. if ps -p "$pid" > /dev/null 2>&1; then
  32. return 0
  33. else
  34. rm -f "$PID_FILE"
  35. fi
  36. fi
  37. return 1
  38. }
  39. # 启动服务
  40. start_service() {
  41. echo "🚀 启动 ${SERVICE_NAME} 服务..."
  42. # 检查Python环境
  43. if ! command -v python3 &> /dev/null; then
  44. echo "❌ 错误: 未找到 python3 命令"
  45. exit 1
  46. fi
  47. # 检查依赖
  48. echo "📦 检查依赖..."
  49. python3 -c "import fastapi, uvicorn" 2>/dev/null
  50. if [ $? -ne 0 ]; then
  51. echo "❌ 错误: 缺少必要的依赖包"
  52. echo "请运行: pip install -r requirements.txt"
  53. exit 1
  54. fi
  55. # 检查 httpx
  56. echo "🔍 检查 httpx..."
  57. python3 -c "import httpx" 2>/dev/null
  58. if [ $? -ne 0 ]; then
  59. echo "❌ 错误: 缺少 httpx 依赖包"
  60. echo "请运行: pip install httpx"
  61. exit 1
  62. fi
  63. # 检查 LangGraph
  64. echo "🔍 检查 LangGraph..."
  65. python3 -c "import langgraph" 2>/dev/null
  66. if [ $? -ne 0 ]; then
  67. echo "⚠️ 警告: LangGraph 未安装,将使用传统模式"
  68. echo "如需启用 LangGraph,请运行: pip install langgraph"
  69. echo ""
  70. fi
  71. # 检查服务是否已经运行
  72. if is_running; then
  73. echo "⚠️ 警告: 服务已经在运行中 (PID: $(cat "$PID_FILE"))"
  74. echo "如需重启,请使用: $0 restart"
  75. exit 1
  76. fi
  77. # 启动服务
  78. echo "🌟 启动服务..."
  79. echo "📍 服务地址: http://localhost:${PORT}"
  80. echo "📚 API文档: http://localhost:${PORT}/docs"
  81. echo "🔍 健康检查: http://localhost:${PORT}/health"
  82. echo "📝 日志文件: ${LOG_FILE}"
  83. echo ""
  84. # 后台启动服务,记录PID
  85. # 生产环境禁用热重载以减少日志噪音
  86. export RELOAD_ENABLED=false
  87. export LOG_LEVEL=info
  88. export LANGCHAIN_TRACING_V2=true
  89. export LANGCHAIN_API_KEY=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
  90. export LANGCHAIN_PROJECT=knowledge-agent
  91. nohup python3 agent.py > "$LOG_FILE" 2>&1 &
  92. echo $! > "$PID_FILE"
  93. # 等待服务启动
  94. sleep 2
  95. if is_running; then
  96. echo "✅ 服务启动成功! (PID: $(cat "$PID_FILE"))"
  97. echo "📝 查看日志: $0 logs 或 tail -f ${LOG_FILE}"
  98. echo "🛑 停止服务: $0 stop"
  99. else
  100. echo "❌ 服务启动失败,请检查日志: ${LOG_FILE}"
  101. rm -f "$PID_FILE"
  102. exit 1
  103. fi
  104. }
  105. # 停止服务
  106. stop_service() {
  107. echo "🛑 停止 ${SERVICE_NAME} 服务..."
  108. if is_running; then
  109. pid=$(cat "$PID_FILE")
  110. echo "正在停止进程 PID: $pid"
  111. # 尝试优雅停止
  112. kill "$pid" 2>/dev/null
  113. # 等待进程结束
  114. for i in {1..15}; do
  115. if ! ps -p "$pid" > /dev/null 2>&1; then
  116. break
  117. fi
  118. echo "等待进程结束... ($i/15)"
  119. sleep 1
  120. done
  121. # 如果进程仍然存在,强制杀死
  122. if ps -p "$pid" > /dev/null 2>&1; then
  123. echo "强制停止进程..."
  124. kill -9 "$pid" 2>/dev/null
  125. fi
  126. rm -f "$PID_FILE"
  127. echo "✅ 主进程已停止"
  128. else
  129. echo "ℹ️ 主进程未运行"
  130. fi
  131. # 额外清理:查找并终止所有相关进程
  132. echo "🔍 检查是否有残留进程..."
  133. # 查找所有可能的进程类型
  134. REMAINING_PROCESSES=$(ps aux | grep -E "(python.*agent\.py|uvicorn.*agent|knowledge-agent|agent\.py|multiprocessing\.spawn|multiprocessing\.resource_tracker)" | grep -v grep | awk '{print $2}')
  135. if [ ! -z "$REMAINING_PROCESSES" ]; then
  136. echo "⚠️ 发现残留进程,正在清理..."
  137. echo "📋 找到的进程:"
  138. ps aux | grep -E "(python.*agent\.py|uvicorn.*agent|knowledge-agent|agent\.py|multiprocessing\.spawn|multiprocessing\.resource_tracker)" | grep -v grep
  139. # 先尝试优雅终止
  140. for pid in $REMAINING_PROCESSES; do
  141. echo "优雅终止进程 $pid..."
  142. kill -TERM $pid 2>/dev/null
  143. done
  144. # 等待3秒
  145. sleep 3
  146. # 检查是否还有残留
  147. STILL_REMAINING=$(ps aux | grep -E "(python.*agent\.py|uvicorn.*agent|knowledge-agent|agent\.py|multiprocessing\.spawn|multiprocessing\.resource_tracker)" | grep -v grep | awk '{print $2}')
  148. if [ ! -z "$STILL_REMAINING" ]; then
  149. echo "强制终止顽固进程..."
  150. for pid in $STILL_REMAINING; do
  151. echo "强制终止进程 $pid..."
  152. kill -9 $pid 2>/dev/null
  153. done
  154. # 再次等待并检查
  155. sleep 2
  156. FINAL_CHECK=$(ps aux | grep -E "(python.*agent\.py|uvicorn.*agent|knowledge-agent|agent\.py|multiprocessing\.spawn|multiprocessing\.resource_tracker)" | grep -v grep | awk '{print $2}')
  157. if [ ! -z "$FINAL_CHECK" ]; then
  158. echo "⚠️ 仍有进程无法终止,请手动检查:"
  159. ps aux | grep -E "(python.*agent\.py|uvicorn.*agent|knowledge-agent|agent\.py|multiprocessing\.spawn|multiprocessing\.resource_tracker)" | grep -v grep
  160. fi
  161. fi
  162. echo "✅ 残留进程已清理"
  163. else
  164. echo "✅ 没有发现残留进程"
  165. fi
  166. # 检查端口占用
  167. echo "🔍 检查端口${PORT}占用情况..."
  168. PORT_PROCESS=$(lsof -ti:${PORT} 2>/dev/null)
  169. if [ ! -z "$PORT_PROCESS" ]; then
  170. echo "⚠️ 端口${PORT}仍被占用,进程ID: $PORT_PROCESS"
  171. echo "强制终止占用端口的进程..."
  172. kill -9 $PORT_PROCESS 2>/dev/null
  173. echo "✅ 端口已释放"
  174. else
  175. echo "✅ 端口${PORT}已释放"
  176. fi
  177. }
  178. # 重启服务
  179. restart_service() {
  180. echo "🔄 重启 ${SERVICE_NAME} 服务..."
  181. stop_service
  182. sleep 2
  183. start_service
  184. }
  185. # 查看服务状态
  186. show_status() {
  187. echo "🔍 ${SERVICE_NAME} 服务状态:"
  188. if is_running; then
  189. pid=$(cat "$PID_FILE")
  190. echo "✅ 状态: 运行中"
  191. echo "📊 PID: $pid"
  192. echo "📍 端口: $PORT"
  193. echo "📝 日志: $LOG_FILE"
  194. echo "🔗 地址: http://localhost:${PORT}"
  195. # 显示进程信息
  196. echo ""
  197. echo "📋 进程信息:"
  198. ps -p "$pid" -o pid,ppid,cmd,etime
  199. else
  200. echo "❌ 状态: 未运行"
  201. echo "💡 启动服务: $0 start"
  202. fi
  203. }
  204. # 查看实时日志
  205. show_logs() {
  206. echo "📝 查看实时日志 (按 Ctrl+C 退出)..."
  207. echo "日志文件: ${LOG_FILE}"
  208. echo ""
  209. if [ -f "$LOG_FILE" ]; then
  210. tail -f "$LOG_FILE"
  211. else
  212. echo "❌ 日志文件不存在: ${LOG_FILE}"
  213. echo "请先启动服务: $0 start"
  214. exit 1
  215. fi
  216. }
  217. # 主逻辑
  218. case "$1" in
  219. start)
  220. start_service
  221. ;;
  222. stop)
  223. stop_service
  224. ;;
  225. restart)
  226. restart_service
  227. ;;
  228. status)
  229. show_status
  230. ;;
  231. logs)
  232. show_logs
  233. ;;
  234. *)
  235. show_help
  236. exit 1
  237. ;;
  238. esac