爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      基于Shell脚本的Java服务管理与配置初始化自动化方案

      首页 知识中心 软件开发 文章详情页

      基于Shell脚本的Java服务管理与配置初始化自动化方案

      2025-03-21 06:56:46 阅读次数:6

      日志,服务,脚本,配置,配置文件

      在现代的微服务架构中,如何高效地管理和启动Java服务,以及如何动态配置应用程序成为关键挑战。本文将详细介绍一套基于Shell脚本的Java服务管理和配置初始化自动化方案,涵盖服务的启动、停止、状态监控和配置文件的动态更新。通过这套方案,可以显著简化服务管理流程,提升系统的稳定性和维护效率。

      基于Shell脚本的Java服务管理与配置初始化自动化方案

      一、app.sh对焦

      Shell脚本目标:用于管理一个Java服务的启动、停止、重启和状态查询。

      (一)主要功能概述

      • 启动(start):检查服务是否已经运行,如果没有则使用Java命令启动服务,并将进程ID写入PID文件。
      • 停止(stop):从PID文件中读取服务进程ID,然后先发送普通kill信号,等待一段时间后检查进程是否停止,如未停止则发送强制kill信号。
      • 状态(status):检查服务是否在运行,如果在运行则输出进程ID,否则显示未运行信息。
      • 重启(restart):先停止服务,然后再启动服务,实现服务的重启操作。

      (二)代码展示

      #!/bin/sh
      ## java env
      export JAVA_HOME=/opt/jdk1.8.0
      
      SERVICE_NAME=servicename
      JAR_NAME=$SERVICE_NAME-pkgvernum-RELEASE.jar
      #PID  代表是PID文件
      PID=/home/zhangyanfeng/microsvr/$SERVICE_NAME/$SERVICE_NAME.pid
      
      #使用说明,用来提示输入参数
      usage() {
          echo "Usage: sh app.sh [start|stop|restart|status]"
          exit 1
      }
      
      #检查程序是否在运行
      is_exist(){
        pid=`ps -ef|grep $JAR_NAME|grep -v grep|awk '{print $2}' `
        #如果不存在返回1,存在返回0     
        if [ -z "${pid}" ]; then
         return 1
        else
          return 0
        fi
      }
      
      #启动方法
      start(){
        is_exist
        if [ $? -eq "0" ]; then 
          echo ">>> ${SERVICE_NAME} is already running PID=${pid} <<<" 
        else 
          nohup $JAVA_HOME/bin/java -Xms256m -Xmx512m -Djava.security.auth.login.config=./config/kafka_zoo_server_jaas.properties -jar $JAR_NAME >/dev/null 2>&1 &
          echo $! > $PID
          echo ">>> start $SERVICE_NAME successed PID=$! <<<" 
         fi
        }
      
      #停止方法
      stop(){
        #is_exist
        pidf=$(cat $PID)
        #echo "$pidf"  
        echo ">>> ${SERVICE_NAME} PID = $pidf begin kill $pidf <<<"
        kill $pidf
        rm -rf $PID
        sleep 2
        is_exist
        if [ $? -eq "0" ]; then 
          echo ">>> ${SERVICE_NAME} 2 PID = $pid begin kill -9 $pid  <<<"
          kill -9  $pid
          sleep 2
          echo ">>> $SERVICE_NAME process stopped <<<"  
        else
          echo ">>> ${SERVICE_NAME} is not running <<<"
        fi  
      }
      
      #输出运行状态
      status(){
        is_exist
        if [ $? -eq "0" ]; then
          echo ">>> ${SERVICE_NAME} is running PID is ${pid} <<<"
        else
          echo ">>> ${SERVICE_NAME} is not running <<<"
        fi
      }
      
      #重启
      restart(){
        stop
        start
      }
      
      cd /home/zhangyanfeng/microsvr/$SERVICE_NAME/
      #根据输入参数,选择执行对应方法,不输入则执行使用说明
      case "$1" in
        "start")
          start
          ;;
        "stop")
          stop
          ;;
        "status")
          status
          ;;
        "restart")
          restart
          ;;
        *)
          usage
          ;;
      esac
      exit 0
      

      优点分析

      • 功能完整,覆盖了服务的启动、停止、重启和状态查询,使用简单直观。
      • 使用了PID文件来跟踪和管理服务进程,确保了操作的精确性。
      • 对Java环境的配置和服务启动命令使用了标准化的设置,提高了可移植性和可维护性。

      (三)改进空间思考

      • 安全性:在获取PID并执行kill操作时,可以增加安全性检查,确保只杀死属于当前用户的进程。
      • 错误处理:增加更多的错误处理和日志记录,以便于故障排查和调试。
      • 健壮性:在启动和停止服务时,可以增加超时机制或重试逻辑,以应对异常情况。
      • 可维护性:脚本中出现了一些硬编码路径(如PID文件路径),可以考虑将这些路径定义为变量,提高代码的灵活性和可维护性。增加注释和文档,解释脚本的各个部分功能和用法,方便他人理解和修改。

      • 扩展性:脚本当前只支持单个服务的管理,如需支持多个服务,可以考虑增加参数来动态传递服务名称和相关配置。

      (四)改进和优化

      可以从几个方面入手,包括安全性、错误处理、可维护性和扩展性等。

      增强安全性

      • 限制kill权限:在执行kill操作之前,可以添加权限检查,确保只能kill当前用户的进程,防止误操作或恶意行为。
      # 在stop函数中添加权限检查
      if [ $(id -u) -ne $(stat -c %u $PID) ]; then
          echo "Error: You don't have permission to stop this service."
          return 1
      fi
      
      • 加强PID文件安全性:PID文件应当使用更安全的权限设置,仅限当前用户和相关服务进程访问。
      PID=/var/run/$SERVICE_NAME.pid
      

      改进错误处理

      • 增加错误日志:在关键操作处增加错误日志,记录到日志文件中,便于后续故障排查和调试。

      # 示例:在启动方法中增加错误日志
      start(){
        is_exist
        if [ $? -eq "0" ]; then 
          echo ">>> ${SERVICE_NAME} is already running PID=${pid} <<<" 
        else 
          nohup $JAVA_HOME/bin/java -Xms256m -Xmx512m -Djava.security.auth.login.config=./config/kafka_zoo_server_jaas.properties -jar $JAR_NAME >/dev/null 2>&1 &
          echo $! > $PID
          if [ $? -eq 0 ]; then
            echo ">>> start $SERVICE_NAME successed PID=$! <<<" 
          else
            echo "!!! Failed to start $SERVICE_NAME !!!"
            return 1
          fi
        fi
      }
      
      • 超时和重试机制:在停止服务时,可以添加超时和重试机制,确保服务能够在合理的时间内停止。

      提高可维护性

      • 参数化路径和配置:将硬编码的路径和配置参数化,提高灵活性和可维护性。

      # 示例:参数化JAR包路径和PID文件路径
      JAR_NAME="$SERVICE_NAME-pkgvernum-RELEASE.jar"
      PID_DIR="/var/run/${SERVICE_NAME}"
      PID_FILE="${PID_DIR}/${SERVICE_NAME}.pid"
      
      • 增加注释和文档:在关键代码处添加注释,解释脚本的功能和逻辑,以及每个函数的用途和参数说明。
      # 示例:增加函数注释和使用说明
      # 启动服务
      start(){
        is_exist
        if [ $? -eq "0" ]; then 
          echo ">>> ${SERVICE_NAME} is already running PID=${pid} <<<" 
        else 
          nohup $JAVA_HOME/bin/java -Xms256m -Xmx512m -Djava.security.auth.login.config=./config/kafka_zoo_server_jaas.properties -jar $JAR_NAME >/dev/null 2>&1 &
          echo $! > $PID_FILE
          if [ $? -eq 0 ]; then
            echo ">>> start $SERVICE_NAME successed PID=$! <<<" 
          else
            echo "!!! Failed to start $SERVICE_NAME !!!"
            return 1
          fi
        fi
      }
      

      增强扩展性

      • 支持多个服务管理:允许脚本通过参数化的方式管理多个不同名称的服务,增强脚本的通用性。

      # 示例:支持通过参数管理不同的服务
      case "$1" in
        "start")
          SERVICE_NAME="$2" # 第二个参数为服务名称
          start
          ;;
        "stop")
          SERVICE_NAME="$2"
          stop
          ;;
        ...
      esac
      
      • 支持配置文件:将常用的配置参数提取到配置文件中,如Java路径、服务名称等,以便统一管理和修改。

      (五)优化后的代码展示

      #!/bin/bash
      #
      # app.sh
      # Description: Script to manage a Java service
      #
      
      # Java environment
      export JAVA_HOME=/opt/jdk1.8.0
      
      # Service variables
      SERVICE_NAME=servicename
      JAR_NAME=$SERVICE_NAME-pkgvernum-RELEASE.jar
      PID_DIR=/var/run/${SERVICE_NAME}
      PID_FILE=${PID_DIR}/${SERVICE_NAME}.pid
      
      # Usage function
      usage() {
          echo "Usage: $0 [start|stop|restart|status] [service_name]"
          exit 1
      }
      
      # Check if the service is running
      is_exist() {
          pid=$(cat $PID_FILE 2>/dev/null)
          if [ -z "$pid" ]; then
              return 1 # Not running
          else
              if ps -p $pid > /dev/null; then
                  return 0 # Running
              else
                  return 1 # Not running
              fi
          fi
      }
      
      # Start the service
      start() {
          is_exist
          if [ $? -eq 0 ]; then 
              echo ">>> $SERVICE_NAME is already running with PID=$pid <<<" 
          else 
              nohup $JAVA_HOME/bin/java -Xms256m -Xmx512m -Djava.security.auth.login.config=./config/kafka_zoo_server_jaas.properties -jar $JAR_NAME >/dev/null 2>&1 &
              echo $! > $PID_FILE
              if [ $? -eq 0 ]; then
                  echo ">>> $SERVICE_NAME started successfully with PID=$(cat $PID_FILE) <<<" 
              else
                  echo "!!! Failed to start $SERVICE_NAME !!!"
                  return 1
              fi
          fi
      }
      
      # Stop the service
      stop() {
          if [ ! -f $PID_FILE ]; then
              echo ">>> $SERVICE_NAME is not running <<<"
              return 1
          fi
      
          pid=$(cat $PID_FILE)
          echo ">>> Stopping $SERVICE_NAME PID=$pid <<<"
          kill $pid
          sleep 2
          if ps -p $pid > /dev/null; then
              echo ">>> Force stopping $SERVICE_NAME PID=$pid <<<"
              kill -9 $pid
              sleep 2
          fi
          rm -f $PID_FILE
          echo ">>> $SERVICE_NAME stopped <<<"
      }
      
      # Check the status of the service
      status() {
          is_exist
          if [ $? -eq 0 ]; then
              echo ">>> $SERVICE_NAME is running with PID=$(cat $PID_FILE) <<<"
          else
              echo ">>> $SERVICE_NAME is not running <<<"
          fi
      }
      
      # Restart the service
      restart() {
          stop
          start
      }
      
      # Change directory to the service location
      cd /home/zhangyanfeng/microsvr/$SERVICE_NAME/
      
      # Main script execution based on input arguments
      case "$1" in
          "start")
              SERVICE_NAME=${2:-$SERVICE_NAME} # Use provided or default service name
              start
              ;;
          "stop")
              SERVICE_NAME=${2:-$SERVICE_NAME}
              stop
              ;;
          "status")
              SERVICE_NAME=${2:-$SERVICE_NAME}
              status
              ;;
          "restart")
              SERVICE_NAME=${2:-$SERVICE_NAME}
              restart
              ;;
          *)
              usage
              ;;
      esac
      
      exit 0
      

      二、start.sh对焦

      Shell脚本 start.sh 的主要功能和目的是管理一个Java服务的运行环境。

      (一)主要功能思考

      • 管理日志和配置:确保服务日志和配置文件的管理,包括定时清理旧日志和初始化配置文件。

      • 动态配置更新:通过 confd 和 writeConfigValue 函数,实现动态更新服务的配置,避免了手动修改配置文件的复杂性和错误风险。

      • 服务重启和维护:使用 ${MICRODIR}/app.sh restart 命令来管理Java服务的启动和重启,保证配置变更后服务的正常运行。

      • 安全和可靠性:通过权限设置和错误处理,保证了脚本执行的安全性和可靠性,避免了意外操作对系统的影响。

      这段脚本的设计旨在简化运维工作,自动化配置更新和服务重启,提高了系统的可维护性和稳定性。

      (二)具体代码展示

      #!/bin/sh
      cd /home/
      find ./ -maxdepth 1 -name "start*.log" -mtime +7 -exec rm {} \;
      TODAY=`date +"%Y%m%d"`
      
      getTimeStamp()
      {
        echo `date +"%Y-%m-%d %H:%M:%S"`
      }
      
      log()
      {
        echo " $1"
        echo "`getTimeStamp` : $1" >> /home/start-${TODAY}.log
      }
      
      MICRODIR=/home/zhangyanfeng/microsvr/zyf-service-user
      CONFIGDIR=${MICRODIR}/config
      TEMPLDIR=/etc/confd/templates
      NOWTIME=`date +"%Y%m%d%H%M%S"`
      
      init_confd()
      {
         log "init confd ..."
         if [ ! -f ${TEMPLDIR}/application.tmpl ]
         then
            log "cp -af ${CONFIGDIR}/application.properties ${TEMPLDIR}/application.tmpl"
            cp -af ${CONFIGDIR}/application.properties ${TEMPLDIR}/application.tmpl
         else
            log "${TEMPLDIR}/application.tmpl is exist, ignore."
         fi 
         
         if [ ! -f ${TEMPLDIR}/bootstrap.tmpl ]
         then
            log "cp -af ${CONFIGDIR}/bootstrap.properties ${TEMPLDIR}/bootstrap.tmpl"
            cp -af ${CONFIGDIR}/bootstrap.properties ${TEMPLDIR}/bootstrap.tmpl
         else
            log "${TEMPLDIR}/bootstrap.tmpl is exist, ignore."
         fi 
         
         chmod 755 -R ${TEMPLDIR}
      }
      
      common_softlink()
      {
         targetdir=$1
         sourcedir=$2
         
         if [ ! -d ${targetdir} ]
         then 
            mkdir -p ${targetdir}
            log "mkdir -p ${targetdir}"
         fi
         
         if [ -L ${sourcedir} ] 
         then
            log "rm ${sourcedir}"
            rm ${sourcedir}
         fi
         
         if [ -d ${sourcedir} ]
         then
            log "mv -f ${sourcedir} ${sourcedir}_${NOWTIME}"
            mv -f ${sourcedir} ${sourcedir}_${NOWTIME}
         fi
         
         ln -s ${targetdir} ${sourcedir}
         
         chmod 755 ${sourcedir}
         chown zxin10:root ${sourcedir}
         chmod -R 755 ${targetdir}
         chown -R zxin10:root ${targetdir}
      }
      
      init_softlink()
      {
         UNAME=`uname -a`
         MICRONAME1=`echo $UNAME | cut -d ' ' -f 2`
         MICRONAME2=`echo $MICRONAME1 | cut -d '-' -f 1-3`
         log_dir=/home/log/$MICRONAME2/$MICRONAME1
         common_softlink "${log_dir}" "/home/zhangyanfeng/microsvr/zyf-service-user/logs" 
      }
      
      start_confd()
      {
         log "start confd..."
         CONFDPID= `ps -ef|grep "confd"|grep -v grep|awk '{print $2}'`
         if [ -n "${CONFDPID}" ]
         then
            log "stop confd"
            kill -9 ${CONFDPID}
      	  sleep 3
         fi
         
         ETCDCONFPATH="/home/zhangyanfeng/confdconfig/confd-general-config.conf"
         ETCD_SERVER_IP=`grep ETCD_SERVER_HOSTIP ${ETCDCONFPATH} | awk -F '=' '{print $2}'`
         ETCD_SERVER_PORT=`grep ETCD_SERVER_PORT ${ETCDCONFPATH} | awk -F '=' '{print $2}'`
         CONFD_SERVER=${ETCD_SERVER_IP}":"${ETCD_SERVER_PORT}
         
         log "/usr/bin/confd -interval 60 -backend etcd -node http://${CONFD_SERVER} &"
         /usr/bin/confd -interval 60 -backend etcd -node http://${CONFD_SERVER} &
      }
      
      function getConfigValue
      {
          [ $# -ne 2 ] && echo  "function getConfigValue arguments error"
          local fileName=$1
          local key=$2
          echo `cat ${fileName}| grep "${key}"| grep "=" | awk -F= '{print $2}' | tr -d " "`	
      }
      
      function writeConfigValue()
      {
          K8SCONFIGDIR=/home/zhangyanfeng/confdconfig
          K8SCONFIGFILE=${K8SCONFIGDIR}/confd-general-config.conf
          
          DBMASTURL=`getConfigValue ${K8SCONFIGFILE} pgconn | awk -F ',' '{print $1}'`
          DBSLAVEURL=`getConfigValue ${K8SCONFIGFILE} pgconn | awk -F ',' '{print $2}'`
          
          REDISURL=`getConfigValue ${K8SCONFIGFILE} redisconn`
          KAFKAURL=`getConfigValue ${K8SCONFIGFILE} kafkaconn`
          ZOOKEEPURL=`getConfigValue ${K8SCONFIGFILE} zkconn`
          IPSEGEMENT=`getConfigValue ${K8SCONFIGFILE} innernetworksegement`
      	LIANCHUANGURL=`getConfigValue ${K8SCONFIGFILE} lianchuang_url`
          
          if [ -f ${CONFIGDIR}/application.properties ]
          then
            if [ -n ${IPSEGEMENT} ]
            then
              sed -i -e "/^genid/s/\/[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]./\/${IPSEGEMENT}./g" ${CONFIGDIR}/application.properties
            fi
                
            if [ -n ${ZOOKEEPURL} ]
            then
              sed -i -e "/^spring.cloud.stream.kafka.binder.zk-nodes/s/spring.cloud.stream.kafka.binder.zk-nodes=.*/spring.cloud.stream.kafka.binder.zk-nodes=${ZOOKEEPURL}/" ${CONFIGDIR}/application.properties
            fi
            
            if [ -n ${KAFKAURL} ]
            then
              sed -i -e "/^kafka.binder.brokers/s/kafka.binder.brokers=.*/kafka.binder.brokers=${KAFKAURL}/" ${CONFIGDIR}/application.properties
              sed -i -e "/^spring.cloud.stream.kafka.binder.brokers/s/spring.cloud.stream.kafka.binder.brokers=.*/spring.cloud.stream.kafka.binder.brokers=${KAFKAURL}/" ${CONFIGDIR}/application.properties
            fi
      	  
      	  if [ -n ${LIANCHUANGURL} ]
            then
      		BRFOREVALUE=`getConfigValue ${CONFIGDIR}/application.properties lianchuang.url`
      		BRFORE=${BRFOREVALUE#*//}
      		sed -i "s/${BRFORE}/${LIANCHUANGURL}/g" ${CONFIGDIR}/application.properties
            fi
          fi
          
          if [ -f ${CONFIGDIR}/bootstrap.properties ]
          then
            if [ -n ${IPSEGEMENT} ]
            then
              sed -i -e "/^eureka.client.serviceUrl.defaultZone/s/\/[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]./\/${IPSEGEMENT}./g" ${CONFIGDIR}/bootstrap.properties
            fi
          fi
      }
      
      ==============  MAIN FUNCTION  ===============
      init_softlink
      #init_confd
      #start_confd
      writeConfigValue
      
      cd ${MICRODIR}
      log "${MICRODIR}/app.sh restart"
      ${MICRODIR}/app.sh restart
      export TERM=linux
      /usr/sbin/sshd -D
      

      (三)改进空间思考

      • 错误处理和日志记录增强:在关键操作前后增加更详细的错误处理和日志记录,特别是在文件操作、进程管理和配置更新过程中,确保可以追踪到每一步的执行情况和可能的异常。

      • 参数化和配置文件分离:将脚本中的硬编码路径和配置参数提取为变量,甚至考虑将配置信息存储在单独的配置文件中,这样可以使脚本更具灵活性和可配置性,便于维护和部署到不同的环境。

      • 安全性增强:在涉及到重启服务和管理权限的地方,确保操作的安全性。可以考虑使用更严格的权限控制或者使用特定的用户执行关键操作,以防止误操作或者恶意访问。

      • 代码重构和模块化:如果脚本变得足够复杂,可以考虑将功能模块化,每个函数尽可能独立和可测试。这样可以简化逻辑,提高代码的复用性和可读性。

      • 定时任务和自动化:如果需要定时执行清理日志或者其他操作,可以考虑将脚本集成到系统的定时任务中,或者使用专门的自动化工具来管理和调度任务,避免手动执行。

      • 文档和注释:在脚本中增加详细的注释和文档,解释每个函数的作用、输入参数和返回值。这样可以帮助新的开发人员或者维护者快速理解脚本的功能和设计思路。

      (四)优化后的代码展示

      #!/bin/bash
      
      # Set Java environment
      export JAVA_HOME=/opt/jdk1.8.0
      
      # Service configuration
      SERVICE_NAME=servicename
      JAR_NAME=${SERVICE_NAME}-pkgvernum-RELEASE.jar
      PID_FILE=/home/zhangyanfeng/microsvr/${SERVICE_NAME}/${SERVICE_NAME}.pid
      
      # Directories
      MICRO_DIR=/home/zhangyanfeng/microsvr/zyf-service-user
      CONFIG_DIR=${MICRO_DIR}/config
      TEMPLATE_DIR=/etc/confd/templates
      LOG_DIR=/home/log
      
      # Log function to timestamp logs
      log() {
        local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
        echo "$timestamp : $1"
        echo "$timestamp : $1" >> /home/start-$(date +"%Y%m%d").log
      }
      
      # Initialize confd templates
      init_confd() {
        log "Initializing confd..."
        for tmpl_file in "${TEMPLATE_DIR}/application.tmpl" "${TEMPLATE_DIR}/bootstrap.tmpl"; do
          if [ ! -f "${tmpl_file}" ]; then
            log "Copying ${CONFIG_DIR}/$(basename "${tmpl_file}") to ${TEMPLATE_DIR}"
            cp -af "${CONFIG_DIR}/$(basename "${tmpl_file}")" "${tmpl_file}"
          else
            log "${tmpl_file} already exists, skipping."
          fi
        done
        chmod -R 755 "${TEMPLATE_DIR}"
      }
      
      # Function to manage symbolic links
      manage_symlink() {
        local target_dir="$1"
        local source_dir="$2"
        
        if [ ! -d "${target_dir}" ]; then
          mkdir -p "${target_dir}"
          log "Created directory ${target_dir}"
        fi
        
        if [ -L "${source_dir}" ]; then
          log "Removing existing symlink ${source_dir}"
          rm "${source_dir}"
        fi
        
        if [ -d "${source_dir}" ]; then
          log "Moving existing directory ${source_dir} to ${source_dir}_${NOWTIME}"
          mv "${source_dir}" "${source_dir}_${NOWTIME}"
        fi
        
        ln -s "${target_dir}" "${source_dir}"
        chmod 755 "${source_dir}"
        chown zxin10:root "${source_dir}"
        chmod -R 755 "${target_dir}"
        chown -R zxin10:root "${target_dir}"
      }
      
      # Initialize symbolic links
      init_softlink() {
        local uname_info=$(uname -a)
        local microname1=$(echo "${uname_info}" | cut -d ' ' -f 2)
        local microname2=$(echo "${microname1}" | cut -d '-' -f 1-3)
        local log_dir="/home/log/${microname2}/${microname1}"
        
        manage_symlink "${log_dir}" "/home/zhangyanfeng/microsvr/zyf-service-user/logs"
      }
      
      # Start confd service
      start_confd() {
        log "Starting confd..."
        local confd_pid=$(pgrep -f "confd")
        if [ -n "${confd_pid}" ]; then
          log "Stopping existing confd process (PID ${confd_pid})"
          kill -9 "${confd_pid}"
          sleep 3
        fi
        
        local confd_config_file="/home/zhangyanfeng/confdconfig/confd-general-config.conf"
        local etcd_server_host=$(grep ETCD_SERVER_HOSTIP "${confd_config_file}" | cut -d '=' -f 2)
        local etcd_server_port=$(grep ETCD_SERVER_PORT "${confd_config_file}" | cut -d '=' -f 2)
        local confd_server="${etcd_server_host}:${etcd_server_port}"
        
        log "Starting confd with backend etcd and node http://${confd_server}"
        /usr/bin/confd -interval 60 -backend etcd -node "http://${confd_server}" &
      }
      
      # Function to get configuration value from file
      getConfigValue() {
        if [ $# -ne 2 ]; then
          log "getConfigValue arguments error"
          return 1
        fi
        
        local file_name="$1"
        local key="$2"
        grep "${key}" "${file_name}" | grep "=" | awk -F '=' '{print $2}' | tr -d " "
      }
      
      # Function to write configuration values to application.properties and bootstrap.properties
      writeConfigValue() {
        local k8s_config_dir="/home/zhangyanfeng/confdconfig"
        local k8s_config_file="${k8s_config_dir}/confd-general-config.conf"
        
        local db_master_url=$(getConfigValue "${k8s_config_file}" "pgconn" | awk -F ',' '{print $1}')
        local db_slave_url=$(getConfigValue "${k8s_config_file}" "pgconn" | awk -F ',' '{print $2}')
        local redis_url=$(getConfigValue "${k8s_config_file}" "redisconn")
        local kafka_url=$(getConfigValue "${k8s_config_file}" "kafkaconn")
        local zookeeper_url=$(getConfigValue "${k8s_config_file}" "zkconn")
        local ip_segment=$(getConfigValue "${k8s_config_file}" "innernetworksegement")
        local lianchuang_url=$(getConfigValue "${k8s_config_file}" "lianchuang_url")
        
        if [ -f "${CONFIG_DIR}/application.properties" ]; then
          if [ -n "${ip_segment}" ]; then
            sed -i -e "/^genid/s/\/[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]./\/${ip_segment}./g" "${CONFIG_DIR}/application.properties"
          fi
          
          if [ -n "${zookeeper_url}" ]; then
            sed -i -e "/^spring.cloud.stream.kafka.binder.zk-nodes/s/spring.cloud.stream.kafka.binder.zk-nodes=.*/spring.cloud.stream.kafka.binder.zk-nodes=${zookeeper_url}/" "${CONFIG_DIR}/application.properties"
          fi
          
          if [ -n "${kafka_url}" ]; then
            sed -i -e "/^kafka.binder.brokers/s/kafka.binder.brokers=.*/kafka.binder.brokers=${kafka_url}/" "${CONFIG_DIR}/application.properties"
            sed -i -e "/^spring.cloud.stream.kafka.binder.brokers/s/spring.cloud.stream.kafka.binder.brokers=.*/spring.cloud.stream.kafka.binder.brokers=${kafka_url}/" "${CONFIG_DIR}/application.properties"
          fi
          
          if [ -n "${lianchuang_url}" ]; then
            local before_value=$(getConfigValue "${CONFIG_DIR}/application.properties" "lianchuang.url")
            local before=$(echo "${before_value}" | sed 's#^.*//##')
            sed -i "s/${before}/${lianchuang_url}/g" "${CONFIG_DIR}/application.properties"
          fi
        fi
        
        if [ -f "${CONFIG_DIR}/bootstrap.properties" ]; then
          if [ -n "${ip_segment}" ]; then
            sed -i -e "/^eureka.client.serviceUrl.defaultZone/s/\/[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]./\/${ip_segment}./g" "${CONFIG_DIR}/bootstrap.properties"
          fi
        fi
      }
      
      # Main function
      main() {
        init_softlink
        # init_confd   # Uncomment if confd initialization is required
        # start_confd  # Uncomment if confd start is required
        writeConfigValue
        
        cd "${MICRO_DIR}"
        log "Restarting ${MICRO_DIR}/app.sh"
        "${MICRO_DIR}/app.sh" restart
        export TERM=linux
        /usr/sbin/sshd -D
      }
      
      # Entry point
      main
      

      三、总结思考

      在这个自动化管理和配置Java服务的方案中,我们通过优化和整合多个脚本,实现了一套完整的管理工具。主要脚本包括 app.sh 和 start.sh,它们分别负责启动、停止、重启服务,以及初始化配置、软链接管理、动态更新配置文件和日志记录等功能。

      通过 app.sh,我们可以方便地对服务进行操作,包括启动、停止、重启和查询状态,保证了服务的稳定运行。在 start.sh 中,我们实现了对配置文件的动态更新,通过 confd 工具实时同步配置信息,确保服务配置的灵活性和实时性。同时,脚本中的日志记录功能,能够帮助追踪和排查问题,保障服务的可靠性和可维护性。

      我们不仅简化了管理流程,提高了运维效率,还增强了服务的可配置性和自动化程度。通过这样的自动化工具链,我们能够更专注于业务逻辑的开发和优化,同时保持对服务稳定性和可管理性的高度把控。

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://zyfcodes.blog.csdn.net/article/details/88667231,作者:张彦峰ZYF,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:PHP代码审计方法与套路

      下一篇:shell编程(编写、执行,shell变量、传参、字符串、运算符使用)

      相关文章

      2025-05-19 09:05:01

      【Linux】HDP集群日志配置和日志删除脚本

      HDP 集群 默认安装的,日志放在数据盘,但是 namenode和snamenode的数据盘本身不大只有 500G,在不经意间 数据盘被日志装满,首先从集群配置着手。

      2025-05-19 09:05:01
      log4j , 日志 , 集群
      2025-05-19 09:04:44

      FinalShell 配置SSH密钥登陆

      FinalShell 配置SSH密钥登陆

      2025-05-19 09:04:44
      密钥 , 服务器 , 配置
      2025-05-19 09:04:38

      完美解决tomcat启动异常:Invalid byte tag in constant pool: 19;Unable to process Jar entry [module-info.class]

      完美解决tomcat启动异常:Invalid byte tag in constant pool: 19;Unable to process Jar entry [module-info.class]

      2025-05-19 09:04:38
      jar , tomcat , 版本 , 配置文件
      2025-05-19 09:04:38

      DataGuard GAP 修复3-- 归档日志不存在

      DataGuard GAP 修复3-- 归档日志不存在

      2025-05-19 09:04:38
      归档 , 日志
      2025-05-16 09:15:24

      WCF 配置文件分解

      WCF 配置文件分解

      2025-05-16 09:15:24
      localhost , WCF , 地址 , 服务 , 配置
      2025-05-14 10:33:25

      webpack5基础--02_基本配置( 5 大核心概念)

      webpack5基础--02_基本配置( 5 大核心概念)

      2025-05-14 10:33:25
      config , loader , webpack , Webpack , 文件 , 模式 , 配置文件
      2025-05-14 10:03:13

      【Mybatis】-防止SQL注入

      【Mybatis】-防止SQL注入

      2025-05-14 10:03:13
      SQL , 执行 , 日志 , 注入 , 缓存 , 编译 , 语句
      2025-05-14 10:02:48

      SQL Server 事务日志体系结构1--基本术语

      事务包括对数据库的一次更改或一系列更改。它有一个明确开始和明确结束。开始时使用BEGIN TRANSACTION语句,或者SQL Server会自动为您开始一个事务。

      2025-05-14 10:02:48
      Server , SQL , 事务 , 数据库 , 日志 , 磁盘
      2025-05-13 09:51:17

      rac dg节点2在修改完alert_oracle_sid.log文件名,主库切换日志后备库节点2不产生新的日志文件

      rac dg节点2在修改完alert_oracle_sid.log文件名,主库切换日志后备库节点2不产生新的日志文件

      2025-05-13 09:51:17
      dg , rac , 日志 , 节点
      2025-05-13 09:51:17

      搭建ogg时无法启动目标端复制进程,告警日志报错OGG-02091

      搭建ogg时无法启动目标端复制进程,告警日志报错OGG-02091

      2025-05-13 09:51:17
      ogg , OGG , 报错 , 日志
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5250378

      查看更多

      最新文章

      shell基础_开发规范解读

      2025-05-13 09:49:27

      JS学习(3)(JS代码——三种书写位置的写法与总结)

      2025-05-13 09:49:12

      C#Windows服务:一些方法(启动、停止等)

      2025-05-12 08:43:47

      RestTemplate请求UnknownContentTypeException:no suitable HttpMessageConverter异常

      2025-05-09 08:51:09

      SpringBoot3基础用法

      2025-05-07 09:09:52

      springboot系列教程(十二):基于转账案例,演示事务管理操作

      2025-05-07 09:08:54

      查看更多

      热门文章

      Python编程:configparser读写ini配置文件

      2023-02-20 10:27:59

      基于XML的DI-为Spring配置多个子配置文件——平等关系

      2022-12-29 09:29:46

      Python基础教程(第3版)中文版 第19章 趣味编程 (笔记)

      2024-09-25 10:14:21

      Spring5入门到实战------2、IOC容器底层原理

      2023-02-28 10:45:09

      Python:使用 mysqlsmom 模块实时同步MySQL数据到ElasticSearch

      2023-03-16 07:45:26

      VSCode与Prettier代码格式化工具的使用

      2023-03-16 07:45:26

      查看更多

      热门标签

      java Java python 编程开发 代码 开发语言 算法 线程 Python html 数组 C++ 元素 javascript c++
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      Java中的微服务架构设计与实施

      软件架构的历程及区别

      Spring Boot集成Spring Cloud Config进行集中配置管理

      3.3 日志

      shell编程规范与变量

      低代码开发重要工具:jvs-rules 规则引擎,让业务调整更智能

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号