SpringCloud微服務啓動腳本

微服務發佈啓動方式很多,大概有以下方式,使用腳本啓動方便運維維護,更方便各種CI,CD等Devops操作,希望能幫助到目前正在開發微服務的同學們。
**

1,命令行方式啓動微服務

**
java -jar package(服務包名,如abc.jar),這種方式比較簡單直接,如果需要參數需要攜帶參數啓動如:
java -Xms500m -Xmx500m -server -XX:+HeapDumpOnOutOfMemoryError -jar $JAR_PATH/abc.jar --spring.profiles.active=test
以上方式在命令行執行容易寫錯,另外每次手動執行也不合適。
**

2,通過腳本方式啓動服務

**
根據服務的參數配置以及使用的具體環境,正常每個項目都有dev,test,prod三個環境,腳本執行需要幾個關鍵參數,
port:服務啓動的端口號,這個確保當前服務未必佔用;
mainclass:入口類,也就是我們main方法所在的class類;
classpath:服務資源路徑,包括配置文件,依賴的其他jar文件的lib庫

下邊是我針對微服務編寫一套基於bashshell腳本,目前已經在各個環境(dev,test,prod)運行,由於是微服務需要依賴不同環境的配置文件,yml配置文件命名規則如下,也是按照springboot環境要求,具體配置內容開發者都雷同,不在贅述。

application-dev.yml(開發環境配置)
application-test.yml(測試環境配置)
application-prod.yml(商用環境配置)

當然最基礎的配置文件必須得有,以SpringCloud Edgware.SR4版本爲例
bootstrap.yml(spring.cloud.config相關配置,eureka相關配置,系統啓動優先加載的參數必須配置在這裏)

spring: 
  cloud:
    bus:
      trace:
        enabled: true
    config:
      name: ${spring.application.name} #application
      profile: ${spring.profiles.active}  #profile
      label: ${branch} 
      fail-fast: true 
      override-system-properties: true
      discovery:
        enabled: true # [new]開啓config服務發現的支持
        service-id: micro-config-server #[new] config-server-application-name
    stream:
      bindings:
        springCloudBusInput:
          destination: springCloudBus
      kafka: 
        binder:
          brokers: ${kafka-brokers}
          zk-nodes: ${zk-nodes}
          configuration:            
            auto:              
              offset:                #可以設置原生kafka屬性,比如設置新的消費組從最新的offset開始消費               
                reset: latest
security:
  user:
    name: admin
    password: admin123              
eureka:
  instance:
    instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${server.port}
    prefer-ip-address: true
    lease-renewal-interval-in-seconds: 15
    lease-expiration-duration-in-seconds: 45
  client:
    serviceUrl:
      defaultZone: ${eureka-url}
    registry-fetch-interval-seconds: 10 #eureka client刷新本地緩存時間 # [new]註冊中erueka-server

application.yml(各個環境的通用配置,spring.application.name,spring.profiles.active)

server:
  port: 8202
  context-path: /acbs
management:
  port: 9202
  security:
    enabled: false    
spring:
  devtools: 
    livereload: 
      port: 35728 
  application: 
    name: micro-acbs
    mainclass: com.zhht.BootstrapApplication
  #profile config
  profiles: 
    active: ${environment}
    
#acbs-service.properties
com: 
  zhht: 
    acbs:  
      charge.feeId.expire: 3600
      charge.feeId.useCache: false
      charge.feeId.cron: 0 0 0/1 * * ? 
      charge.noplate.fee: true
  
feign:
  hystrix: 
    enabled: true
  client:
    config:
      default:
       loggerLevel: BASIC
       
hystrix: 
  threadpool: 
    default:
      coreSize: 20
      maximumSize: 500
      allowMaximumSizeToDivergeFromCoreSize: true
  command:
    default:
      execution:
        timeout: 
          enabled: false
   
ribbon:
  ReadTimeout: 8000
  ConnectTimeout: 3000
  MaxAutoRetries: 0 #對當前服務的重試次數
  MaxAutoRetriesNextServer: 1 #切換相同Server的次數
  retryableStatusCodes: 500
  ServerListRefreshInterval: 10000 #eureka客戶端ribbon刷新時間,默認30s 

 #數據源配置
 #https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
#mybatis
mybatis:
  #entity掃描的包名
  type-aliases-package: com.zhht.busiconf
  #Mapper.xml所在的位置
  mapper-locations: classpath:/mapper/*Mapper.xml
  #開啓MyBatis的二級緩存
  configuration:
    cache-enabled: false
    
#分頁插件
pagehelper:
  helper-dialect: mysql
  reasonable: true
  support-methods-arguments: true
  params: count=countSql

**

3,微服務啓動腳本

編寫bootstrap.sh微服務啓動腳本
**

#!/bin/bash
# This bootstap script support minimum of JDK 1.8 ,with inner webserver of Tomcat8.
# please regarding copyright ownership.
# author:ningquan
# writted:2018-06-26
# -----------------------------------------------------------------------------
# Start Script for the Springboot Server
# -----------------------------------------------------------------------------
#set -x
#set JAVA_OPTS

JAVA_OPTS="-server -Xms${ProgramMemory} -Xmx${ProgramMemory} -Xss512k -XX:MetaspaceSize=60m -XX:MaxMetaspaceSize=256m"
ONS_VAR="-Dons.client.logRoot=/data/ons -Dons.client.logLevel=INFO -Dons.client.logFileMaxIndex=10"
BOOT_LOGDIR='/data/logs'
source /etc/profile
#JAVACMD=$JAVA_HOME/bin/java,search jre.
echofont(){
 echo -e "\033[37;"$1"m $2 \033[0m"
}
if [ -z $JAVACMD ] ; then
  if [ -n $JAVA_HOME  ] ; then
      JAVACMD=$JAVA_HOME/bin/java
  else
    JAVACMD=`which java`
  fi
fi

if [ -z $JAVACMD ] ;then
  echo "please check JAVA_HOME,not found JAVA runtime environment......"
  exit 1
fi

if [ ! -x "$JAVACMD" ] ; then
  echo "Error: JAVA_HOME is not defined correctly."
  echo "  We cannot execute $JAVACMD"
  exit 1
fi
echofont 32 "JAVACMD="$JAVACMD

#setting perform path
BASEDIR=`dirname $0`/..
BASEDIR=`(cd $BASEDIR; pwd)`
echofont 32 "BASEDIR="$BASEDIR

#grep -w 'port:' application.yml |sed s/[[:space:]]//g |cut -d: -f 2
APPLICATION_CONFIG_FILE="$BASEDIR/conf/application.yml"
if [ -f $APPLICATION_CONFIG_FILE ] ;then
 if [ ! -r $APPLICATION_CONFIG_FILE ] ; then
   echofont 31 "Error: current user can't read file application.yml,suggest use root user"
   exit 1
 fi
else
  echofont 31 "Error: not found application.yml in your config path /conf"
  exit 1
fi

SERVER_PORT=`grep -E '^[^#]*+port:' $APPLICATION_CONFIG_FILE |sed s/[[:space:]]//g |awk -F':' '/70|71|72|73|74|80|81|82|83|84/{print $2}'`
#echo "server.port="$SERVER_PORT
#profiles active
PROFILE_ACTIVE=`grep -E '^[^#max_]*+active:' $BASEDIR/conf/application.yml | sed s/[[:space:]]//g | awk -F':' '{print $2}'`
echofont 32 "spring.profiles.active="$PROFILE_ACTIVE
SERVER_PROFILE_ACTIVE_FILE=""
#if [ -n $PROFILE_ACTIVE ] ; then
# eval SERVER_PROFILE_ACTIVE_FILE='$BASEDIR/conf/application-"$PROFILE_ACTIVE".yml'
# echofont 32 "spring.profiles.active.file="$SERVER_PROFILE_ACTIVE_FILE
# if [ -f $SERVER_PROFILE_ACTIVE_FILE ] ;then
#   if [ ! -r $SERVER_PROFILE_ACTIVE_FILE ] ; then
#     echofont 31 "Error: current user can't read file:application-"$PROFILE_ACTIVE".yml,suggest use root user"
#     exit 1
#   fi
# fi
#else
#  echofont 33 "Warning: not found profile active file:application-"$PROFILE_ACTIVE".yml"
#fi

#according to profile active of environment that get ralative config
if [ ! -z $SERVER_PROFILE_ACTIVE_FILE ] ;then
 SERVER_PORT=`grep -E '^[^#]*+port:' $SERVER_PROFILE_ACTIVE_FILE |sed s/[[:space:]]//g |awk -F':' '/70|71|72|73|74|80|81|82|83|84/{print $2}'`
 echofont 32 "final server.port="$SERVER_PORT
fi

#get spring boot application main class,through springboot param 'spring.application.mainclass' property obtain.
MAIN_CLASS=`grep -w 'mainclass:' $APPLICATION_CONFIG_FILE | sed s/[[:space:]]//g | awk -F':' '{print $2}'`
APPLICATION_NAME=`grep -w 'name:' $APPLICATION_CONFIG_FILE | sed s/[[:space:]]//g | awk -F':' '/micro|api/{print $2}'`
echofont 32 "application-name="$APPLICATION_NAME
if [ -z $MAIN_CLASS ] ;then
 echofont 31 "Error: springboot application not set main class,please check config file of application.yml and set property: spring.application.mainclass"
 exit 1
fi
echofont 32 "main-class:"$MAIN_CLASS

CLASSPATH="$BASEDIR"/conf:"$BASEDIR"/boot/*:"$BASEDIR"/lib/*:$CLASSPATH
#echo "CLASSPATH=$CLASSPATH"
#according to diffrent case run someone scripts
#CHECK APPLICATION PROCESS STATUS
APPLICATION_PID="" #`netstat -anp |grep $SERVER_PORT |grep LISTEN |awk '{print $7}' | awk -F'/' '{print $1}'`
check_exist(){
 APPLICATION_PID=`netstat -anutp |grep $SERVER_PORT |grep LISTEN |awk '{print $7}' | awk -F'/' '{print $1}'`
 if [ -z $APPLICATION_PID ] ; then
   return 1
 fi
 return 0
}
status(){
 echofont 32 "start check current server status:"
 check_exist
 if [ $? -eq 0 ] ; then
   echofont 32 "application:"$APPLICATION_NAME" is running. The process pid:"$APPLICATION_PID
 else
   echofont 33 "application:"$APPLICATION_NAME" is not running"
 fi
}

start(){
 echofont 32 "=================start application server====================="
 if [ ! -d "$BOOT_LOGDIR/$APPLICATION_NAME/" ] ; then
   `mkdir -p "$BOOT_LOGDIR/$APPLICATION_NAME/"`
 fi
 check_exist
 if [ $? -eq 0 ] ; then
   echofont 31 "Error:application:"$APPLICATION_NAME" is already running. The process pid="$APPLICATION_PID
   exit 1
 fi
 nohup $JAVACMD $JAVA_OPTS \
  -classpath "$CLASSPATH" \
  -Dbasedir="$BASEDIR" \
  -Dfile.encoding="UTF-8" \
  -Djava.awt.headless="true" \
  -Dsun.net.client.defaultConnectTimeout="60000" \
  -Dsun.net.client.defaultReadTimeout="60000" \
  -Djmagick.systemclassloader="no" \
  -Dnetworkaddress.cache.ttl="300" \
  -Dsun.net.inetaddr.ttl=300 \
  -XX:+UseG1GC \
  -XX:+DisableExplicitGC \
  -XX:+HeapDumpOnOutOfMemoryError \
  -XX:-OmitStackTraceInFastThrow \
  -XX:HeapDumpPath="$BOOT_LOGDIR/" \
  -XX:ErrorFile="$BOOT_LOGDIR/$APPLICATION_NAME/javadump_error_%p.log" \
  $ONS_VAR \
  $MAIN_CLASS \
  "$@" >$BOOT_LOGDIR/$APPLICATION_NAME/catalina-out.log 2>&1 &
  #APPLICATION_PID=$$
  #echo "checking process......"
  sleep 5
  #status
  runpid=`ps aux |grep java |grep $APPLICATION_NAME |awk '{print $2}'`
  if [ ! -z $runpid ] ; then
    echo $runpid > $BASEDIR/bin/server.pid
    echofont 32 "===================server start success!======================"
    echofont 32 "===========Ning Quan wish you have a good job!================"
  else
    echofont 31 "Error:server start fail,please cat /data/logs/cataout.log"
  fi
}

restart(){
 echofont 32 "==============restart application server================="
 stop
 start
}

stop(){
 echofont 32 "===========stop application server start================="
 check_exist
 if [ $? -eq 0 ] ; then
   `kill  $APPLICATION_PID`
   sleep 5
   check_exist
   if [ $? -eq 0 ] ; then
     stop
   fi
   #exit 1
 fi
 echofont 32 "=========stop application server finish!================="
}

usage(){
 echofont 33 "Usage: sh bootstrap.sh [start|stop|restart|status]"
 echofont 33 "eg: ./bootstrap.sh start"
 exit 1
}
#CHECK APPLICATION PROCESS STATUS
APPLICATION_PID="" #`netstat -anp |grep $SERVER_PORT |grep LISTEN |awk '{print $7}' | awk -F'/' '{print $1}'`
check_exist(){
 APPLICATION_PID=`netstat -anutp |grep $SERVER_PORT |grep LISTEN |awk '{print $7}' | awk -F'/' '{print $1}'`
 if [ -z $APPLICATION_PID ] ; then
   return 1
 fi
 return 0
}
echofont(){
 echo -e "\033[37;"$1"m $2 \033[0m"
}
case "$1" in
  "start")
    start
    ;;
  "stop")
    stop
    ;;
  "status")
    status
    ;;
  "restart")
    restart
    ;;
  *)
    usage
    ;;
esac
exit 0

**

4,啓動微服務

**

chmod a+x bootstrap.sh
./bootstrap.sh start

**

5,關閉微服務

**

./bootstrap.sh stop
./bootstrap.sh status(當前微服務狀態檢查)

以上腳本可以結合Jenkins做持續集成發佈,也可以通過自己內部監控系統靈活執行腳本。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章