四零语境后端代码仓库
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.

272 lines
7.3 KiB

  1. #!/bin/bash
  2. # ========================================
  3. # Java应用启动/重启脚本
  4. # 使用方法: ./restart-java-app.sh
  5. # ========================================
  6. # ========================================
  7. # 配置参数 - 请根据实际情况修改
  8. # ========================================
  9. JAR_NAME="" # 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. # 如果JAR_NAME为空,自动检测当前目录下的JAR文件
  35. if [ -z "$JAR_NAME" ]; then
  36. local jar_files=(*.jar)
  37. local jar_count=${#jar_files[@]}
  38. # 检查是否存在JAR文件
  39. if [ ! -f "${jar_files[0]}" ]; then
  40. print_message $RED "错误: 当前目录下没有找到JAR文件!"
  41. print_message $YELLOW "请将JAR文件放在脚本同一目录下,或在脚本中指定JAR_NAME"
  42. exit 1
  43. fi
  44. # 如果只有一个JAR文件,自动使用它
  45. if [ $jar_count -eq 1 ]; then
  46. JAR_NAME="${jar_files[0]}"
  47. print_message $BLUE "自动检测到JAR文件: $JAR_NAME"
  48. else
  49. print_message $RED "错误: 当前目录下有多个JAR文件,请在脚本中指定JAR_NAME:"
  50. for jar in "${jar_files[@]}"; do
  51. print_message $YELLOW " - $jar"
  52. done
  53. exit 1
  54. fi
  55. else
  56. # 检查指定的JAR文件是否存在
  57. if [ ! -f "$JAR_NAME" ]; then
  58. print_message $RED "错误: JAR文件 '$JAR_NAME' 不存在!"
  59. print_message $YELLOW "请检查JAR_NAME配置是否正确,或确保JAR文件在当前目录下"
  60. exit 1
  61. fi
  62. fi
  63. }
  64. # 检查端口是否被占用
  65. check_port() {
  66. local port=$1
  67. if command -v netstat >/dev/null 2>&1; then
  68. netstat -tlnp 2>/dev/null | grep ":$port " >/dev/null
  69. elif command -v ss >/dev/null 2>&1; then
  70. ss -tlnp | grep ":$port " >/dev/null
  71. else
  72. # 如果没有netstat和ss,尝试使用lsof
  73. if command -v lsof >/dev/null 2>&1; then
  74. lsof -i :$port >/dev/null 2>&1
  75. else
  76. return 1
  77. fi
  78. fi
  79. }
  80. # 获取运行中的应用PID
  81. get_app_pid() {
  82. if [ -f "$PID_FILE" ]; then
  83. local pid=$(cat "$PID_FILE")
  84. # 检查进程是否真的在运行
  85. if ps -p $pid > /dev/null 2>&1; then
  86. echo $pid
  87. else
  88. # PID文件存在但进程不存在,删除PID文件
  89. rm -f "$PID_FILE"
  90. echo ""
  91. fi
  92. else
  93. # 通过进程名查找
  94. pgrep -f "$JAR_NAME" | head -1
  95. fi
  96. }
  97. # 停止应用
  98. stop_app() {
  99. local pid=$(get_app_pid)
  100. if [ -z "$pid" ]; then
  101. print_message $YELLOW "应用未运行"
  102. return 0
  103. fi
  104. print_message $YELLOW "正在停止应用 (PID: $pid)..."
  105. # 优雅停止
  106. kill $pid
  107. # 等待进程停止
  108. local count=0
  109. while [ $count -lt 30 ]; do
  110. if ! ps -p $pid > /dev/null 2>&1; then
  111. print_message $GREEN "应用已成功停止"
  112. rm -f "$PID_FILE"
  113. return 0
  114. fi
  115. sleep 1
  116. count=$((count + 1))
  117. done
  118. # 如果优雅停止失败,强制停止
  119. print_message $YELLOW "优雅停止超时,强制停止应用..."
  120. kill -9 $pid 2>/dev/null
  121. sleep 2
  122. if ! ps -p $pid > /dev/null 2>&1; then
  123. print_message $GREEN "应用已强制停止"
  124. rm -f "$PID_FILE"
  125. return 0
  126. else
  127. print_message $RED "停止应用失败"
  128. return 1
  129. fi
  130. }
  131. # 启动应用
  132. start_app() {
  133. print_message $BLUE "正在启动应用..."
  134. # 检查端口是否被占用
  135. if check_port $PORT; then
  136. print_message $RED "端口 $PORT 已被占用,请检查是否有其他应用在使用该端口"
  137. return 1
  138. fi
  139. # 启动应用
  140. nohup java $JAVA_OPTS -jar "$JAR_NAME" --server.port=$PORT > "$LOG_FILE" 2>&1 &
  141. local pid=$!
  142. # 保存PID
  143. echo $pid > "$PID_FILE"
  144. # 等待应用启动
  145. print_message $BLUE "等待应用启动..."
  146. sleep 3
  147. # 检查进程是否还在运行
  148. if ps -p $pid > /dev/null 2>&1; then
  149. # 检查端口是否监听
  150. local count=0
  151. while [ $count -lt 30 ]; do
  152. if check_port $PORT; then
  153. print_message $GREEN "应用启动成功!"
  154. print_message $GREEN "PID: $pid"
  155. print_message $GREEN "端口: $PORT"
  156. print_message $GREEN "日志文件: $LOG_FILE"
  157. return 0
  158. fi
  159. sleep 1
  160. count=$((count + 1))
  161. done
  162. print_message $YELLOW "应用进程已启动,但端口 $PORT 未监听,请检查日志文件: $LOG_FILE"
  163. return 1
  164. else
  165. print_message $RED "应用启动失败,请检查日志文件: $LOG_FILE"
  166. rm -f "$PID_FILE"
  167. return 1
  168. fi
  169. }
  170. # 显示应用状态
  171. show_status() {
  172. local pid=$(get_app_pid)
  173. if [ -n "$pid" ]; then
  174. print_message $GREEN "应用正在运行"
  175. print_message $GREEN "PID: $pid"
  176. print_message $GREEN "端口: $PORT"
  177. if check_port $PORT; then
  178. print_message $GREEN "端口状态: 正在监听"
  179. else
  180. print_message $YELLOW "端口状态: 未监听"
  181. fi
  182. else
  183. print_message $YELLOW "应用未运行"
  184. fi
  185. }
  186. # 显示帮助信息
  187. show_help() {
  188. echo "Java应用管理脚本"
  189. echo ""
  190. echo "使用方法:"
  191. echo " $0 [选项]"
  192. echo ""
  193. echo "选项:"
  194. echo " start 启动应用"
  195. echo " stop 停止应用"
  196. echo " restart 重启应用"
  197. echo " status 显示应用状态"
  198. echo " help 显示帮助信息"
  199. echo ""
  200. echo "配置:"
  201. echo " JAR包名称: ${JAR_NAME:-"自动检测"}"
  202. echo " 端口号: $PORT"
  203. echo ""
  204. echo "注意: 如果目录下只有一个JAR文件,可以将JAR_NAME留空实现自动检测"
  205. }
  206. # ========================================
  207. # 主程序
  208. # ========================================
  209. # 检查JAR文件是否存在
  210. check_jar_exists
  211. # 处理命令行参数
  212. case "${1:-restart}" in
  213. "start")
  214. start_app
  215. ;;
  216. "stop")
  217. stop_app
  218. ;;
  219. "restart")
  220. print_message $BLUE "重启应用..."
  221. stop_app
  222. if [ $? -eq 0 ]; then
  223. sleep 2
  224. start_app
  225. else
  226. print_message $RED "停止应用失败,取消重启"
  227. exit 1
  228. fi
  229. ;;
  230. "status")
  231. show_status
  232. ;;
  233. "help"|"-h"|"--help")
  234. show_help
  235. ;;
  236. *)
  237. print_message $RED "未知选项: $1"
  238. show_help
  239. exit 1
  240. ;;
  241. esac