第124集Java应用迁移与部署运维实战 | 字数总计: 5.8k | 阅读时长: 26分钟 | 阅读量:
1. Java应用迁移概述 Java应用迁移是运维工作中的重要环节,涉及应用部署、配置管理、性能优化和故障处理等多个方面。本文将详细介绍Java应用迁移与部署运维的实战经验,包括应用迁移策略、部署管理、性能优化、故障处理的完整解决方案。
1.1 核心功能
应用迁移 : 不同环境间的Java应用迁移
部署管理 : 自动化部署和版本管理
配置管理 : 环境配置和参数管理
性能优化 : 应用性能调优和监控
故障处理 : 常见故障的诊断和处理
1.2 技术架构 1 2 3 源环境 → 应用打包 → 配置迁移 → 目标环境 → 部署验证 ↓ ↓ ↓ ↓ ↓ 备份策略 → 版本管理 → 环境配置 → 自动化部署 → 健康检查
2. 环境准备 2.1 系统要求检查 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 #!/bin/bash log () { echo "[$(date '+%Y-%m-%d %H:%M:%S') ] $1 " } check_os_version () { log "检查系统版本..." if [ -f /etc/os-release ]; then . /etc/os-release log "操作系统: $NAME $VERSION " else log "无法确定操作系统版本" fi } check_java_version () { log "检查Java版本..." JAVA_VERSION=$(java -version 2>&1 | head -1 | cut -d'"' -f2) log "Java版本: $JAVA_VERSION " if [[ $JAVA_VERSION == 1.8* ]] || [[ $JAVA_VERSION == 11* ]] || [[ $JAVA_VERSION == 17* ]]; then log "Java版本符合要求" else log "Java版本不符合要求,需要Java 8+" exit 1 fi } check_maven_version () { log "检查Maven版本..." if command -v mvn > /dev/null 2>&1; then MAVEN_VERSION=$(mvn -version | head -1 | cut -d' ' -f3) log "Maven版本: $MAVEN_VERSION " else log "Maven未安装" exit 1 fi } check_application_ports () { log "检查应用端口..." PORTS=(8080 8081 8082 9090 9091) for port in "${PORTS[@]} " ; do if netstat -tlnp | grep ":$port " > /dev/null; then log "端口 $port 已被占用" else log "端口 $port 可用" fi done } check_disk_space () { log "检查磁盘空间..." df -h | grep -E "(/$|/var|/tmp|/home)" | while read line; do log "磁盘使用: $line " done } check_memory () { log "检查内存使用..." TOTAL_MEM=$(free -h | grep Mem | awk '{print $2}' ) USED_MEM=$(free -h | grep Mem | awk '{print $3}' ) AVAIL_MEM=$(free -h | grep Mem | awk '{print $7}' ) log "总内存: $TOTAL_MEM " log "已使用: $USED_MEM " log "可用内存: $AVAIL_MEM " } check_network () { log "检查网络连接..." if ping -c 3 8.8.8.8 > /dev/null 2>&1; then log "网络连接正常" else log "网络连接异常" exit 1 fi } main () { log "开始Java应用环境检查..." check_os_version check_java_version check_maven_version check_application_ports check_disk_space check_memory check_network log "Java应用环境检查完成" } main "$@ "
3. 应用打包脚本 3.1 应用打包脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 #!/bin/bash APP_NAME="demo-app" APP_VERSION="1.0.0" SOURCE_DIR="/opt/source" TARGET_DIR="/opt/target" LOG_FILE="/var/log/java_app_package.log" log () { echo "[$(date '+%Y-%m-%d %H:%M:%S') ] $1 " | tee -a $LOG_FILE } create_target_dir () { log "创建目标目录..." PACKAGE_DATE=$(date +%Y%m%d_%H%M%S) PACKAGE_DIR="$TARGET_DIR /${APP_NAME} -${APP_VERSION} -${PACKAGE_DATE} " mkdir -p $PACKAGE_DIR if [ $? -eq 0 ]; then log "目标目录创建成功: $PACKAGE_DIR " else log "目标目录创建失败" exit 1 fi } compile_application () { log "编译应用..." cd $SOURCE_DIR mvn clean if [ $? -eq 0 ]; then log "Maven清理成功" else log "Maven清理失败" exit 1 fi mvn compile if [ $? -eq 0 ]; then log "应用编译成功" else log "应用编译失败" exit 1 fi mvn test if [ $? -eq 0 ]; then log "测试执行成功" else log "测试执行失败" exit 1 fi } package_application () { log "打包应用..." cd $SOURCE_DIR mvn package -DskipTests if [ $? -eq 0 ]; then log "应用打包成功" else log "应用打包失败" exit 1 fi JAR_FILE=$(find target -name "*.jar" -not -name "*sources.jar" -not -name "*javadoc.jar" | head -1) if [ -n "$JAR_FILE " ]; then log "找到JAR文件: $JAR_FILE " else log "未找到JAR文件" exit 1 fi } copy_application_files () { log "复制应用文件..." cp $SOURCE_DIR /$JAR_FILE $PACKAGE_DIR / if [ $? -eq 0 ]; then log "JAR文件复制成功" else log "JAR文件复制失败" exit 1 fi if [ -d "$SOURCE_DIR /src/main/resources" ]; then cp -r $SOURCE_DIR /src/main/resources $PACKAGE_DIR / log "配置文件复制成功" fi if [ -f "$SOURCE_DIR /start.sh" ]; then cp $SOURCE_DIR /start.sh $PACKAGE_DIR / chmod +x $PACKAGE_DIR /start.sh log "启动脚本复制成功" fi if [ -f "$SOURCE_DIR /stop.sh" ]; then cp $SOURCE_DIR /stop.sh $PACKAGE_DIR / chmod +x $PACKAGE_DIR /stop.sh log "停止脚本复制成功" fi } generate_deployment_scripts () { log "生成部署脚本..." cat > $PACKAGE_DIR /start.sh << 'EOF' APP_NAME="demo-app" APP_VERSION="1.0.0" JAR_FILE="demo-app-1.0.0.jar" JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC" LOG_DIR="/var/log/$APP_NAME " mkdir -p $LOG_DIR nohup java $JAVA_OPTS -jar $JAR_FILE > $LOG_DIR /app.log 2>&1 &echo $! > $APP_NAME .pidecho "应用启动成功,PID: $!" EOF cat > $PACKAGE_DIR /stop.sh << 'EOF' APP_NAME="demo-app" PID_FILE="$APP_NAME .pid" if [ -f "$PID_FILE " ]; then PID=$(cat $PID_FILE ) if ps -p $PID > /dev/null; then kill $PID echo "应用停止成功,PID: $PID " else echo "应用进程不存在" fi rm -f $PID_FILE else echo "PID文件不存在" fi EOF chmod +x $PACKAGE_DIR /start.sh chmod +x $PACKAGE_DIR /stop.sh log "部署脚本生成成功" } generate_config_files () { log "生成配置文件..." cat > $PACKAGE_DIR /application.yml << 'EOF' server: port: 8080 servlet: context-path: /api spring: application: name: demo-app profiles: active: prod logging: level: root: INFO com.demo: DEBUG pattern: console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" file: name: /var/log/demo-app/app.log max-size: 100MB max-history: 30 spring: datasource: url: jdbc:mysql://localhost:3306/demo_db?useSSL=false &serverTimezone=Asia/Shanghai username: root password: password driver-class-name: com.mysql.cj.jdbc.Driver hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000 management: endpoints: web: exposure: include: "*" metrics: export : prometheus: enabled: true EOF log "配置文件生成成功" } compress_package () { log "压缩应用包..." cd $TARGET_DIR tar -czf "${APP_NAME} -${APP_VERSION} -${PACKAGE_DATE} .tar.gz" ${APP_NAME} -${APP_VERSION} -${PACKAGE_DATE} if [ $? -eq 0 ]; then log "应用包压缩成功" PACKAGE_SIZE=$(ls -lh "${APP_NAME} -${APP_VERSION} -${PACKAGE_DATE} .tar.gz" | awk '{print $5}' ) log "应用包大小: $PACKAGE_SIZE " rm -rf ${APP_NAME} -${APP_VERSION} -${PACKAGE_DATE} else log "应用包压缩失败" exit 1 fi } generate_package_report () { log "生成打包报告..." REPORT_FILE="$TARGET_DIR /package_report_${PACKAGE_DATE} .txt" echo "Java应用打包报告" > $REPORT_FILE echo "打包时间: $(date) " >> $REPORT_FILE echo "应用名称: $APP_NAME " >> $REPORT_FILE echo "应用版本: $APP_VERSION " >> $REPORT_FILE echo "打包文件: ${APP_NAME} -${APP_VERSION} -${PACKAGE_DATE} .tar.gz" >> $REPORT_FILE echo "文件大小: $(ls -lh $TARGET_DIR/${APP_NAME}-${APP_VERSION}-${PACKAGE_DATE}.tar.gz | awk '{print $5}') " >> $REPORT_FILE echo "================================" >> $REPORT_FILE log "打包报告生成: $REPORT_FILE " } main () { log "开始Java应用打包..." create_target_dir compile_application package_application copy_application_files generate_deployment_scripts generate_config_files compress_package generate_package_report log "Java应用打包完成" } main "$@ "
4. 应用部署脚本 4.1 应用部署脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 #!/bin/bash APP_NAME="demo-app" APP_VERSION="1.0.0" PACKAGE_FILE="/opt/target/demo-app-1.0.0.tar.gz" DEPLOY_DIR="/opt/apps" BACKUP_DIR="/opt/backup" LOG_FILE="/var/log/java_app_deploy.log" log () { echo "[$(date '+%Y-%m-%d %H:%M:%S') ] $1 " | tee -a $LOG_FILE } check_deploy_environment () { log "检查部署环境..." if ! command -v java > /dev/null 2>&1; then log "Java环境未安装" exit 1 fi if [ ! -d "$DEPLOY_DIR " ]; then mkdir -p $DEPLOY_DIR log "部署目录创建: $DEPLOY_DIR " fi if [ ! -d "$BACKUP_DIR " ]; then mkdir -p $BACKUP_DIR log "备份目录创建: $BACKUP_DIR " fi if [ ! -f "$PACKAGE_FILE " ]; then log "应用包文件不存在: $PACKAGE_FILE " exit 1 fi log "部署环境检查完成" } stop_old_application () { log "停止旧应用..." APP_DIR="$DEPLOY_DIR /$APP_NAME " if [ -d "$APP_DIR " ]; then if [ -f "$APP_DIR /$APP_NAME .pid" ]; then PID=$(cat $APP_DIR /$APP_NAME .pid) if ps -p $PID > /dev/null; then log "停止运行中的应用,PID: $PID " kill $PID sleep 5 if ps -p $PID > /dev/null; then kill -9 $PID log "强制停止应用,PID: $PID " fi fi fi BACKUP_DATE=$(date +%Y%m%d_%H%M%S) BACKUP_PATH="$BACKUP_DIR /${APP_NAME} -${BACKUP_DATE} " mv $APP_DIR $BACKUP_PATH log "旧应用已备份到: $BACKUP_PATH " else log "未找到旧应用" fi } deploy_new_application () { log "部署新应用..." APP_DIR="$DEPLOY_DIR /$APP_NAME " mkdir -p $APP_DIR tar -xzf $PACKAGE_FILE -C $APP_DIR --strip-components=1 if [ $? -eq 0 ]; then log "应用包解压成功" else log "应用包解压失败" exit 1 fi chown -R app:app $APP_DIR chmod +x $APP_DIR /*.sh log "新应用部署成功" } configure_application () { log "配置应用..." APP_DIR="$DEPLOY_DIR /$APP_NAME " if [ -f "$APP_DIR /application.yml" ]; then sed -i "s/localhost:3306/prod-db-server:3306/g" $APP_DIR /application.yml sed -i "s/root: password/prod-user:prod-password/g" $APP_DIR /application.yml sed -i "s/demo_db/prod_demo_db/g" $APP_DIR /application.yml log "配置文件更新成功" fi if [ -f "$APP_DIR /start.sh" ]; then sed -i "s/-Xms512m/-Xms1024m/g" $APP_DIR /start.sh sed -i "s/-Xmx1024m/-Xmx2048m/g" $APP_DIR /start.sh log "启动脚本更新成功" fi } start_application () { log "启动应用..." APP_DIR="$DEPLOY_DIR /$APP_NAME " cd $APP_DIR ./start.sh if [ $? -eq 0 ]; then log "应用启动成功" else log "应用启动失败" exit 1 fi sleep 10 if [ -f "$APP_DIR /$APP_NAME .pid" ]; then PID=$(cat $APP_DIR /$APP_NAME .pid) if ps -p $PID > /dev/null; then log "应用运行正常,PID: $PID " else log "应用启动失败" exit 1 fi else log "PID文件不存在" exit 1 fi } verify_deployment () { log "验证部署..." APP_DIR="$DEPLOY_DIR /$APP_NAME " if [ -f "$APP_DIR /$APP_NAME .pid" ]; then PID=$(cat $APP_DIR /$APP_NAME .pid) if ps -p $PID > /dev/null; then log "应用进程检查通过,PID: $PID " else log "应用进程检查失败" exit 1 fi fi if netstat -tlnp | grep ":8080 " > /dev/null; then log "应用端口检查通过" else log "应用端口检查失败" exit 1 fi if command -v curl > /dev/null 2>&1; then if curl -f http://localhost:8080/api/health > /dev/null 2>&1; then log "应用健康检查通过" else log "应用健康检查失败" exit 1 fi fi if [ -f "/var/log/$APP_NAME /app.log" ]; then ERROR_COUNT=$(grep -c "ERROR" /var/log/$APP_NAME /app.log) if [ $ERROR_COUNT -eq 0 ]; then log "应用日志检查通过" else log "应用日志检查失败,错误数量: $ERROR_COUNT " fi fi } generate_deployment_report () { log "生成部署报告..." DEPLOY_DATE=$(date +%Y%m%d_%H%M%S) REPORT_FILE="$BACKUP_DIR /deployment_report_${DEPLOY_DATE} .txt" echo "Java应用部署报告" > $REPORT_FILE echo "部署时间: $(date) " >> $REPORT_FILE echo "应用名称: $APP_NAME " >> $REPORT_FILE echo "应用版本: $APP_VERSION " >> $REPORT_FILE echo "部署目录: $DEPLOY_DIR /$APP_NAME " >> $REPORT_FILE echo "备份目录: $BACKUP_DIR " >> $REPORT_FILE echo "================================" >> $REPORT_FILE echo "应用信息:" >> $REPORT_FILE if [ -f "$DEPLOY_DIR /$APP_NAME /$APP_NAME .pid" ]; then PID=$(cat $DEPLOY_DIR /$APP_NAME /$APP_NAME .pid) echo "进程ID: $PID " >> $REPORT_FILE fi echo "端口状态:" >> $REPORT_FILE netstat -tlnp | grep ":8080 " >> $REPORT_FILE log "部署报告生成: $REPORT_FILE " } main () { log "开始Java应用部署..." check_deploy_environment stop_old_application deploy_new_application configure_application start_application verify_deployment generate_deployment_report log "Java应用部署完成" } main "$@ "
5. 性能监控脚本 5.1 性能监控脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 #!/bin/bash APP_NAME="demo-app" APP_DIR="/opt/apps/$APP_NAME " LOG_FILE="/var/log/java_app_monitor.log" MONITOR_INTERVAL=30 log () { echo "[$(date '+%Y-%m-%d %H:%M:%S') ] $1 " | tee -a $LOG_FILE } check_application_status () { log "检查应用状态..." if [ -f "$APP_DIR /$APP_NAME .pid" ]; then PID=$(cat $APP_DIR /$APP_NAME .pid) if ps -p $PID > /dev/null; then log "应用运行正常,PID: $PID " return 0 else log "应用进程不存在,PID: $PID " return 1 fi else log "PID文件不存在" return 1 fi } monitor_application_performance () { log "监控应用性能..." if [ -f "$APP_DIR /$APP_NAME .pid" ]; then PID=$(cat $APP_DIR /$APP_NAME .pid) CPU_USAGE=$(ps -p $PID -o %cpu --no-headers | awk '{print $1}' ) log "CPU使用率: $CPU_USAGE %" MEMORY_USAGE=$(ps -p $PID -o %mem --no-headers | awk '{print $1}' ) log "内存使用率: $MEMORY_USAGE %" MEMORY_SIZE=$(ps -p $PID -o rss --no-headers | awk '{print $1}' ) MEMORY_SIZE_MB=$((MEMORY_SIZE / 1024 )) log "内存使用量: ${MEMORY_SIZE_MB} MB" THREAD_COUNT=$(ps -p $PID -o nlwp --no-headers | awk '{print $1}' ) log "线程数: $THREAD_COUNT " FD_COUNT=$(lsof -p $PID | wc -l) log "文件描述符数: $FD_COUNT " fi } monitor_application_logs () { log "监控应用日志..." LOG_FILE_PATH="/var/log/$APP_NAME /app.log" if [ -f "$LOG_FILE_PATH " ]; then ERROR_COUNT=$(tail -100 $LOG_FILE_PATH | grep -c "ERROR" ) if [ $ERROR_COUNT -gt 0 ]; then log "发现错误日志,数量: $ERROR_COUNT " fi WARN_COUNT=$(tail -100 $LOG_FILE_PATH | grep -c "WARN" ) if [ $WARN_COUNT -gt 0 ]; then log "发现警告日志,数量: $WARN_COUNT " fi EXCEPTION_COUNT=$(tail -100 $LOG_FILE_PATH | grep -c "Exception" ) if [ $EXCEPTION_COUNT -gt 0 ]; then log "发现异常日志,数量: $EXCEPTION_COUNT " fi else log "日志文件不存在: $LOG_FILE_PATH " fi } monitor_application_ports () { log "监控应用端口..." if netstat -tlnp | grep ":8080 " > /dev/null; then log "应用端口8080正常" else log "应用端口8080异常" fi if netstat -tlnp | grep ":9090 " > /dev/null; then log "管理端口9090正常" else log "管理端口9090异常" fi } monitor_application_health () { log "监控应用健康状态..." if command -v curl > /dev/null 2>&1; then if curl -f http://localhost:8080/api/health > /dev/null 2>&1; then log "应用健康检查通过" else log "应用健康检查失败" fi if curl -f http://localhost:9090/actuator/metrics > /dev/null 2>&1; then log "应用指标端点正常" else log "应用指标端点异常" fi else log "curl命令不可用,跳过健康检查" fi } monitor_system_resources () { log "监控系统资源..." CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1) log "系统CPU使用率: $CPU_USAGE %" MEMORY_USAGE=$(free | grep Mem | awk '{printf "%.2f", $3/$2 * 100.0}' ) log "系统内存使用率: $MEMORY_USAGE %" DISK_USAGE=$(df -h / | awk 'NR==2{print $5}' | cut -d'%' -f1) log "系统磁盘使用率: $DISK_USAGE %" LOAD_AVERAGE=$(uptime | awk -F'load average:' '{print $2}' ) log "系统负载: $LOAD_AVERAGE " } generate_monitor_report () { log "生成监控报告..." MONITOR_DATE=$(date +%Y%m%d_%H%M%S) REPORT_FILE="/var/log/monitor_report_${MONITOR_DATE} .txt" echo "Java应用监控报告" > $REPORT_FILE echo "监控时间: $(date) " >> $REPORT_FILE echo "应用名称: $APP_NAME " >> $REPORT_FILE echo "================================" >> $REPORT_FILE echo "应用状态:" >> $REPORT_FILE if [ -f "$APP_DIR /$APP_NAME .pid" ]; then PID=$(cat $APP_DIR /$APP_NAME .pid) echo "进程ID: $PID " >> $REPORT_FILE echo "CPU使用率: $(ps -p $PID -o %cpu --no-headers | awk '{print $1}') %" >> $REPORT_FILE echo "内存使用率: $(ps -p $PID -o %mem --no-headers | awk '{print $1}') %" >> $REPORT_FILE fi echo "系统状态:" >> $REPORT_FILE echo "CPU使用率: $(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1) %" >> $REPORT_FILE echo "内存使用率: $(free | grep Mem | awk '{printf "%.2f" , $3/$2 * 100.0}') %" >> $REPORT_FILE echo "磁盘使用率: $(df -h / | awk 'NR==2{print $5}' | cut -d'%' -f1) %" >> $REPORT_FILE log "监控报告生成: $REPORT_FILE " } main () { log "开始Java应用监控..." if ! check_application_status; then log "应用状态异常,停止监控" exit 1 fi monitor_application_performance monitor_application_logs monitor_application_ports monitor_application_health monitor_system_resources generate_monitor_report log "Java应用监控完成" } main "$@ "
6. 故障处理脚本 6.1 故障诊断脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 #!/bin/bash APP_NAME="demo-app" APP_DIR="/opt/apps/$APP_NAME " LOG_FILE="/var/log/java_app_troubleshoot.log" log () { echo "[$(date '+%Y-%m-%d %H:%M:%S') ] $1 " | tee -a $LOG_FILE } check_application_status () { log "检查应用状态..." if [ -f "$APP_DIR /$APP_NAME .pid" ]; then PID=$(cat $APP_DIR /$APP_NAME .pid) if ps -p $PID > /dev/null; then log "应用进程运行中,PID: $PID " return 0 else log "应用进程未运行,PID: $PID " return 1 fi else log "PID文件不存在" return 1 fi } check_application_logs () { log "检查应用日志..." LOG_FILE_PATH="/var/log/$APP_NAME /app.log" if [ -f "$LOG_FILE_PATH " ]; then log "日志文件存在: $LOG_FILE_PATH " tail -50 $LOG_FILE_PATH | grep -i error tail -50 $LOG_FILE_PATH | grep -i exception tail -50 $LOG_FILE_PATH | grep -i warn else log "日志文件不存在: $LOG_FILE_PATH " fi } check_application_config () { log "检查应用配置..." if [ -f "$APP_DIR /application.yml" ]; then log "配置文件存在: $APP_DIR /application.yml" grep -E "^(server|spring|logging)" $APP_DIR /application.yml else log "配置文件不存在: $APP_DIR /application.yml" fi if [ -f "$APP_DIR /start.sh" ]; then log "启动脚本存在: $APP_DIR /start.sh" grep -E "^-X" $APP_DIR /start.sh else log "启动脚本不存在: $APP_DIR /start.sh" fi } check_system_resources () { log "检查系统资源..." free -h df -h top -bn1 | grep "Cpu(s)" iostat -x 1 1 } check_network () { log "检查网络连接..." netstat -tlnp | grep -E "(8080|9090)" if command -v ufw > /dev/null 2>&1; then ufw status elif command -v firewall-cmd > /dev/null 2>&1; then firewall-cmd --list-all else iptables -L fi } check_java_environment () { log "检查Java环境..." java -version ps aux | grep java | grep -v grep if [ -f "$APP_DIR /$APP_NAME .pid" ]; then PID=$(cat $APP_DIR /$APP_NAME .pid) if ps -p $PID > /dev/null; then jstat -gc $PID fi fi } fix_common_issues () { log "修复常见问题..." if [ -d "$APP_DIR " ]; then chown -R app:app $APP_DIR chmod +x $APP_DIR /*.sh log "修复应用目录权限" fi LOG_DIR="/var/log/$APP_NAME " if [ -d "$LOG_DIR " ]; then chown -R app:app $LOG_DIR chmod 755 $LOG_DIR log "修复日志目录权限" fi } restart_application () { log "重启应用..." if [ -f "$APP_DIR /stop.sh" ]; then cd $APP_DIR ./stop.sh sleep 5 fi if [ -f "$APP_DIR /start.sh" ]; then cd $APP_DIR ./start.sh sleep 10 fi if check_application_status; then log "应用重启成功" return 0 else log "应用重启失败" return 1 fi } main () { log "开始Java应用故障诊断..." if ! check_application_status; then log "应用状态异常,尝试重启..." restart_application fi check_application_logs check_application_config check_system_resources check_network check_java_environment fix_common_issues log "Java应用故障诊断完成" } main "$@ "
7. 总结 Java应用迁移与部署运维是运维工作中的重要组成部分。通过本文的详细介绍,我们了解了:
应用迁移 : 不同环境间的Java应用迁移
部署管理 : 自动化部署和版本管理
配置管理 : 环境配置和参数管理
性能监控 : 应用性能监控和告警
故障处理 : 常见故障的诊断和处理
通过合理的运维策略和工具,可以确保Java应用的稳定运行和高性能。
运维实战要点 :
应用迁移前做好备份,确保数据安全
部署时注意环境配置和参数设置
定期监控应用状态,及时发现问题
性能调优需要根据实际业务场景进行
故障处理要有完整的诊断流程
代码注解说明 :
日志函数: 统一日志格式,便于问题追踪
错误处理: 完善的错误检查和异常处理
配置管理: 灵活的配置参数管理
监控告警: 实时监控和告警机制
自动化运维: 脚本化运维提高效率