四零语境后端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

246 lines
6.2 KiB

  1. #!/bin/bash
  2. # ========================================
  3. # Java应用启动/重启脚本
  4. # 使用方法: ./restart-java-app.sh
  5. # ========================================
  6. # ========================================
  7. # 配置参数 - 请根据实际情况修改
  8. # ========================================
  9. JAR_NAME="your-app.jar" # JAR包名称
  10. PORT=8080 # 应用端口号
  11. # ========================================
  12. # 其他配置(一般不需要修改)
  13. # ========================================
  14. JAVA_OPTS="-Xms512m -Xmx1024m" # JVM参数
  15. LOG_FILE="app.log" # 日志文件名
  16. PID_FILE="app.pid" # PID文件名
  17. # 颜色输出
  18. RED='\033[0;31m'
  19. GREEN='\033[0;32m'
  20. YELLOW='\033[1;33m'
  21. BLUE='\033[0;34m'
  22. NC='\033[0m' # No Color
  23. # ========================================
  24. # 函数定义
  25. # ========================================
  26. # 打印带颜色的消息
  27. print_message() {
  28. local color=$1
  29. local message=$2
  30. echo -e "${color}[$(date '+%Y-%m-%d %H:%M:%S')] ${message}${NC}"
  31. }
  32. # 检查JAR文件是否存在
  33. check_jar_exists() {
  34. if [ ! -f "$JAR_NAME" ]; then
  35. print_message $RED "错误: JAR文件 '$JAR_NAME' 不存在!"
  36. print_message $YELLOW "请检查JAR_NAME配置是否正确,或确保JAR文件在当前目录下"
  37. exit 1
  38. fi
  39. }
  40. # 检查端口是否被占用
  41. check_port() {
  42. local port=$1
  43. if command -v netstat >/dev/null 2>&1; then
  44. netstat -tlnp 2>/dev/null | grep ":$port " >/dev/null
  45. elif command -v ss >/dev/null 2>&1; then
  46. ss -tlnp | grep ":$port " >/dev/null
  47. else
  48. # 如果没有netstat和ss,尝试使用lsof
  49. if command -v lsof >/dev/null 2>&1; then
  50. lsof -i :$port >/dev/null 2>&1
  51. else
  52. return 1
  53. fi
  54. fi
  55. }
  56. # 获取运行中的应用PID
  57. get_app_pid() {
  58. if [ -f "$PID_FILE" ]; then
  59. local pid=$(cat "$PID_FILE")
  60. # 检查进程是否真的在运行
  61. if ps -p $pid > /dev/null 2>&1; then
  62. echo $pid
  63. else
  64. # PID文件存在但进程不存在,删除PID文件
  65. rm -f "$PID_FILE"
  66. echo ""
  67. fi
  68. else
  69. # 通过进程名查找
  70. pgrep -f "$JAR_NAME" | head -1
  71. fi
  72. }
  73. # 停止应用
  74. stop_app() {
  75. local pid=$(get_app_pid)
  76. if [ -z "$pid" ]; then
  77. print_message $YELLOW "应用未运行"
  78. return 0
  79. fi
  80. print_message $YELLOW "正在停止应用 (PID: $pid)..."
  81. # 优雅停止
  82. kill $pid
  83. # 等待进程停止
  84. local count=0
  85. while [ $count -lt 30 ]; do
  86. if ! ps -p $pid > /dev/null 2>&1; then
  87. print_message $GREEN "应用已成功停止"
  88. rm -f "$PID_FILE"
  89. return 0
  90. fi
  91. sleep 1
  92. count=$((count + 1))
  93. done
  94. # 如果优雅停止失败,强制停止
  95. print_message $YELLOW "优雅停止超时,强制停止应用..."
  96. kill -9 $pid 2>/dev/null
  97. sleep 2
  98. if ! ps -p $pid > /dev/null 2>&1; then
  99. print_message $GREEN "应用已强制停止"
  100. rm -f "$PID_FILE"
  101. return 0
  102. else
  103. print_message $RED "停止应用失败"
  104. return 1
  105. fi
  106. }
  107. # 启动应用
  108. start_app() {
  109. print_message $BLUE "正在启动应用..."
  110. # 检查端口是否被占用
  111. if check_port $PORT; then
  112. print_message $RED "端口 $PORT 已被占用,请检查是否有其他应用在使用该端口"
  113. return 1
  114. fi
  115. # 启动应用
  116. nohup java $JAVA_OPTS -jar "$JAR_NAME" --server.port=$PORT > "$LOG_FILE" 2>&1 &
  117. local pid=$!
  118. # 保存PID
  119. echo $pid > "$PID_FILE"
  120. # 等待应用启动
  121. print_message $BLUE "等待应用启动..."
  122. sleep 3
  123. # 检查进程是否还在运行
  124. if ps -p $pid > /dev/null 2>&1; then
  125. # 检查端口是否监听
  126. local count=0
  127. while [ $count -lt 30 ]; do
  128. if check_port $PORT; then
  129. print_message $GREEN "应用启动成功!"
  130. print_message $GREEN "PID: $pid"
  131. print_message $GREEN "端口: $PORT"
  132. print_message $GREEN "日志文件: $LOG_FILE"
  133. return 0
  134. fi
  135. sleep 1
  136. count=$((count + 1))
  137. done
  138. print_message $YELLOW "应用进程已启动,但端口 $PORT 未监听,请检查日志文件: $LOG_FILE"
  139. return 1
  140. else
  141. print_message $RED "应用启动失败,请检查日志文件: $LOG_FILE"
  142. rm -f "$PID_FILE"
  143. return 1
  144. fi
  145. }
  146. # 显示应用状态
  147. show_status() {
  148. local pid=$(get_app_pid)
  149. if [ -n "$pid" ]; then
  150. print_message $GREEN "应用正在运行"
  151. print_message $GREEN "PID: $pid"
  152. print_message $GREEN "端口: $PORT"
  153. if check_port $PORT; then
  154. print_message $GREEN "端口状态: 正在监听"
  155. else
  156. print_message $YELLOW "端口状态: 未监听"
  157. fi
  158. else
  159. print_message $YELLOW "应用未运行"
  160. fi
  161. }
  162. # 显示帮助信息
  163. show_help() {
  164. echo "Java应用管理脚本"
  165. echo ""
  166. echo "使用方法:"
  167. echo " $0 [选项]"
  168. echo ""
  169. echo "选项:"
  170. echo " start 启动应用"
  171. echo " stop 停止应用"
  172. echo " restart 重启应用"
  173. echo " status 显示应用状态"
  174. echo " help 显示帮助信息"
  175. echo ""
  176. echo "配置:"
  177. echo " JAR包名称: $JAR_NAME"
  178. echo " 端口号: $PORT"
  179. echo ""
  180. echo "注意: 请确保在脚本开头正确配置 JAR_NAME 和 PORT 参数"
  181. }
  182. # ========================================
  183. # 主程序
  184. # ========================================
  185. # 检查JAR文件是否存在
  186. check_jar_exists
  187. # 处理命令行参数
  188. case "${1:-restart}" in
  189. "start")
  190. start_app
  191. ;;
  192. "stop")
  193. stop_app
  194. ;;
  195. "restart")
  196. print_message $BLUE "重启应用..."
  197. stop_app
  198. if [ $? -eq 0 ]; then
  199. sleep 2
  200. start_app
  201. else
  202. print_message $RED "停止应用失败,取消重启"
  203. exit 1
  204. fi
  205. ;;
  206. "status")
  207. show_status
  208. ;;
  209. "help"|"-h"|"--help")
  210. show_help
  211. ;;
  212. *)
  213. print_message $RED "未知选项: $1"
  214. show_help
  215. exit 1
  216. ;;
  217. esac