auto-restart.sh 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #!/bin/bash
  2. # Delta中性交易策略自动重启脚本
  3. # 监控并自动重启交易进程
  4. # 配置
  5. MAX_RESTARTS=100 # 最大重启次数
  6. RESTART_DELAY=10 # 重启延迟(秒)
  7. LOG_FILE="logs/auto-restart.log"
  8. PID_FILE="trading.pid"
  9. HEALTH_CHECK_INTERVAL=30 # 健康检查间隔(秒)
  10. MAX_NO_OUTPUT_TIME=300 # 最大无输出时间(秒)
  11. # 颜色定义
  12. RED='\033[0;31m'
  13. GREEN='\033[0;32m'
  14. YELLOW='\033[1;33m'
  15. NC='\033[0m' # No Color
  16. # 创建日志目录
  17. mkdir -p logs
  18. # 日志函数
  19. log() {
  20. echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
  21. }
  22. # 启动交易程序
  23. start_trading() {
  24. log "🚀 启动交易程序..."
  25. # 运行交易程序并捕获PID
  26. yarn trade > logs/trading.log 2>&1 &
  27. local pid=$!
  28. echo $pid > "$PID_FILE"
  29. log "✅ 交易程序已启动 (PID: $pid)"
  30. return $pid
  31. }
  32. # 检查进程是否存活
  33. check_process() {
  34. local pid=$1
  35. if kill -0 $pid 2>/dev/null; then
  36. return 0
  37. else
  38. return 1
  39. fi
  40. }
  41. # 检查日志文件是否有新输出
  42. check_log_activity() {
  43. local log_file="logs/trading.log"
  44. if [ ! -f "$log_file" ]; then
  45. return 1
  46. fi
  47. # 获取文件最后修改时间
  48. local last_modified=$(stat -f %m "$log_file" 2>/dev/null || stat -c %Y "$log_file" 2>/dev/null)
  49. local current_time=$(date +%s)
  50. local time_diff=$((current_time - last_modified))
  51. if [ $time_diff -gt $MAX_NO_OUTPUT_TIME ]; then
  52. log "⚠️ 交易程序超过${MAX_NO_OUTPUT_TIME}秒无输出"
  53. return 1
  54. fi
  55. return 0
  56. }
  57. # 优雅关闭进程
  58. graceful_shutdown() {
  59. local pid=$1
  60. log "🛑 正在优雅关闭进程 (PID: $pid)..."
  61. # 发送SIGTERM信号
  62. kill -TERM $pid 2>/dev/null
  63. # 等待进程退出(最多10秒)
  64. local count=0
  65. while [ $count -lt 10 ]; do
  66. if ! check_process $pid; then
  67. log "✅ 进程已优雅关闭"
  68. return 0
  69. fi
  70. sleep 1
  71. count=$((count + 1))
  72. done
  73. # 强制结束
  74. log "⚠️ 强制结束进程"
  75. kill -9 $pid 2>/dev/null
  76. sleep 2
  77. return 0
  78. }
  79. # 清理函数
  80. cleanup() {
  81. log "🧹 清理资源..."
  82. if [ -f "$PID_FILE" ]; then
  83. local pid=$(cat "$PID_FILE")
  84. if check_process $pid; then
  85. graceful_shutdown $pid
  86. fi
  87. rm -f "$PID_FILE"
  88. fi
  89. log "👋 自动重启脚本退出"
  90. exit 0
  91. }
  92. # 捕获退出信号
  93. trap cleanup SIGINT SIGTERM
  94. # 主循环
  95. main() {
  96. log "==================================="
  97. log "🤖 Delta中性交易自动重启脚本启动"
  98. log "==================================="
  99. log "最大重启次数: $MAX_RESTARTS"
  100. log "重启延迟: ${RESTART_DELAY}秒"
  101. log "健康检查间隔: ${HEALTH_CHECK_INTERVAL}秒"
  102. log ""
  103. local restart_count=0
  104. local consecutive_failures=0
  105. while [ $restart_count -lt $MAX_RESTARTS ]; do
  106. # 启动交易程序
  107. start_trading
  108. local trading_pid=$!
  109. # 重置连续失败计数
  110. if [ $consecutive_failures -gt 0 ]; then
  111. consecutive_failures=0
  112. log "✅ 重置连续失败计数"
  113. fi
  114. # 监控进程
  115. while true; do
  116. sleep $HEALTH_CHECK_INTERVAL
  117. # 检查进程是否存活
  118. if ! check_process $trading_pid; then
  119. log "❌ 进程已停止,准备重启..."
  120. restart_count=$((restart_count + 1))
  121. consecutive_failures=$((consecutive_failures + 1))
  122. # 检查连续失败次数
  123. if [ $consecutive_failures -ge 5 ]; then
  124. log "🚨 连续失败5次,延长重启等待时间至60秒"
  125. sleep 60
  126. consecutive_failures=0
  127. else
  128. sleep $RESTART_DELAY
  129. fi
  130. break
  131. fi
  132. # 检查日志活动
  133. if ! check_log_activity; then
  134. log "⚠️ 进程可能卡死,准备重启..."
  135. graceful_shutdown $trading_pid
  136. restart_count=$((restart_count + 1))
  137. consecutive_failures=$((consecutive_failures + 1))
  138. sleep $RESTART_DELAY
  139. break
  140. fi
  141. # 显示状态
  142. echo -ne "\r[$(date '+%H:%M:%S')] 🟢 交易程序运行中 (PID: $trading_pid) | 重启次数: $restart_count/$MAX_RESTARTS"
  143. done
  144. log "📊 重启统计: $restart_count/$MAX_RESTARTS"
  145. done
  146. log "🚨 达到最大重启次数,脚本退出"
  147. cleanup
  148. }
  149. # 检查是否已有实例在运行
  150. if [ -f "$PID_FILE" ]; then
  151. old_pid=$(cat "$PID_FILE")
  152. if check_process $old_pid; then
  153. echo -e "${RED}⚠️ 交易程序已在运行 (PID: $old_pid)${NC}"
  154. echo "如需重新启动,请先运行: kill $old_pid"
  155. exit 1
  156. else
  157. rm -f "$PID_FILE"
  158. fi
  159. fi
  160. # 运行主函数
  161. main