0

I like to write a shell script for a backend server using Spring Boot (v2.1.1) to start multiple microservices in a certain order - some services depend on other to be running.

What is the 'best practice'?

Of course i could run the .jars like this (original post):

#!/bin/bash

java -jar myjar1.jar &
java -jar myjar2.jar &
java -jar myjar3.jar &

But this would start the .jars simultaneously, afaik.

How can i ensure, that a certain service myjar1.jar started properly and after that, another service myjar2.jar is started. Because every service is a SpringBootApplication i assume that there are certain possibilities to do so?!

I read this SO solution but I don't want to create any symlinks, because i just need that for development purposes.

2 Answers 2

0

Well it is very specific to your service as to when it gets started. At process level, as soon as you execute the command service is running, so you will need your service to share the state when its up. One way i can think of is in your script start the service, expose health api and check if its up. if it is move to next one. You need to make use of curl and sleep command in your scripts.

But I would like to know why you want to do that. Specially for your microservices, your services should not depend on each other. They may need some data, but they should be resilient to the fact that services may come and go. You should have a very strong reason to do as you are doing, cause in real world env, it is very difficult to ensure order is maintained.

Sign up to request clarification or add additional context in comments.

Comments

0

I have a shell script for starting microservices in multiple applications (test1,test2, and test3 are different applications that have several services in them). first, you need to create daemons for each service that you are required to start or stop.

Example:-

  • Create .service (ex:- umm.service) files in "/etc/systemd/system/" location
    [Unit]
    Description=Umm Service
    After=syslog.target remote-fs.target nss-lookup.target gateway.service

    [Service]
    Type=simple
    User=user
    WorkingDirectory=/home/user/umm.service
    ExecStart=/bin/bash -c "/home/user/java8/bin/java -Xms128m -Xmx256m -jar umm-service.jar"
    KillMode=process
  • Then copy the script and run it
#!/bin/bash
#prerequisites **** install rlwrap package, create .txt file with including service names.
#please note that service names should be in the right order in the particular .txt file and a particular port should be in front of the service name.
#Ex:- If you need to start config service first, discovery service second and gateway service third, you need to add services as below.
#config.service <port>
#discovery.service <port>
#gateway.service <port>
#and so on ..........

echo "$(tput setaf 6)

███    ███ ██   ██ ██████   ██████      ███████   ██ ██████  ██ ██████  ████████ 
████  ████ ██  ██  ██   ██ ██  ████     ██       ██  ██   ██ ██ ██   ██    ██    
██ ████ ██ ██ ██   ██████  ██ ██ ██     ███████ ██   ██████  ██ ██████     ██    
██  ██  ██     ██  ██   ██ ████  ██          ██  ██  ██   ██    ██         ██    
██      ██ ██   ██ ██   ██  ██████      ███████   ██ ██   ██ ██ ██         ██    
                                                                                 
                                                                                 
$(tput sgr0)"

echo "$(tput setaf 2)
Version 3.0
Enter TAB For Auto Completion
Enter exit at every stage for EXIT entire programme
$(tput sgr0)"
echo "$(tput setaf 3)
`date +"%A, %e %B %Y, %r"`
`uname -srmo`$(tput setaf 1)
$(tput sgr0)"


unset getservice
unset service
unset port
unset startsingle
unset portofservice
unset stopsingle
unset Kservice
unset Kport
unset stopsingleorall
unset startsingleorall

singleorall=(single all exit) #custom bash completion
servicearray=(test1 test2 test3) 
test1singlearray=(test1config.service test1discovery.service test1gateway.service test1auth.service test1umm.service test1backend.service test1frontend.service test1imagesystem.service exit)
test2singlearray=(test2config.service test2discovery.service test2gateway.service test2auth.service test2umm.service test2backend.service test2frontend.service exit)
test3singlearray=(test3config.service test3discovery.service test3gateway.service test3auth.service test3umm.service test3dashboard.service test3samlauth.service exit)

next=(yes no)

service_check=( "test1" "test2" "test3" )
stopsingleorall_check=( "single" "all" "exit" )
startsingleorall_check=( "single" "all" "exit" )
next_check=( "yes" "no" )

VAR1="single"
VAR2="all"

########################################################################* FUNCTIONS *##############################################################################

function start_all_services () {

            echo "getservice='$getservice'"

            nuofline=`cat $getservice.txt | wc -l`   #get number of lines in defined .txt file

            echo $nuofline
            for ((i=1; i<=$nuofline; i++ ));      #for loop until i=nuofline
            do
            #echo $i

            service=$(awk -v "i=$i" '{ if (NR == i) print $1}' $getservice.txt)    #get service name from the text file
            port=$(awk -v "i=$i" '{ if (NR == i) print $2}' $getservice.txt)       #get port number from the text file

            systemctl start $service                #start the service

            echo "Starting $service"

            while ! netstat -tna | grep 'LISTEN\>' | grep -q "$port"   #sleep until assign the particular port for the service
            do
            echo "$service Is Not Started Yet"
            sleep 10 # time in seconds, tune it as needed
            done
            echo "$service Started Successfully with Port $port !"  #output
            done
}

function stop_all_services () {

            nuofline=`cat $getservice.txt | wc -l`   #get number of lines in defined .txt file
            echo $nuofline

            for ((i=1; i<=$nuofline; i++ ));      #for loop until i=nuofline
            do
            Kport=$(awk -v "i=$i" '{ if (NR == i) print $2}' $getservice.txt)
            Kservice=$(lsof -i :$Kport | awk '{print $2}' | grep -Eiv 'PID')
            kill -9  $Kservice
done
} 

function start_single_service () {

if [ $startsingle != "exit" ]
             then
             systemctl start $startsingle
             watch -n1 systemctl status $startsingle
             while ! netstat -tna | grep 'LISTEN\>' | grep -q "$portofservice"   #sleep until assign the particular port for the service
             do
             echo "$startsingle Is Not Started Yet"
             sleep 10 # time in seconds, tune it as needed
             done
             echo "$startsingle Started Successfully with Port $portofservice !"  #output
             echo
             fi

}

function stop_single_service () {
if [ $stopsingle != "exit" ]
            then
            Kport=$portofservice
            Kservice=$(lsof -i :$Kport | awk '{print $2}' | grep -Eiv 'PID')
            kill -9 $Kservice
            echo "$stopsingle Stoped Successfully"  #output
            echo
fi
}

function switchcase() {

            case "$getservice" in
            #case 1
            "test1") arr=("${test1singlearray[@]}")
                   stopsingle_check=( "test1config.service" "test1discovery.service" "test1gateway.service" "test1auth.service" "test1umm.service" "test1backend.service" "test1frontend.service" "test1imagesystem.service" "exit" )
                   startsingle_check=( "test1config.service" "test1discovery.service" "test1gateway.service" "test1auth.service" "test1umm.service" "test1backend.service" "test1frontend.service" "test1imagesystem.service" "exit" );;

            #case 2
            "test2") arr=("${test2singlearray[@]}")
                   stopsingle_check=( "test2config.service" "test2discovery.service" "test2gateway.service" "test2auth.service" "test2umm.service" "test2backend.service" "test2frontend.service" "exit" )
                   startsingle_check=( "test2config.service" "test2discovery.service" "test2gateway.service" "test2auth.service" "test2umm.service" "test2backend.service" "test2frontend.service" "exit" );;

            #case 3
            "test3") arr=("${test3singlearray[@]}")
                     stopsingle_check=( "test3config.service" "test3discovery.service" "test3gateway.service" "test3auth.service" "test3umm.service" "test3dashboard.service" "test3samlauth.service" "exit" )
                     startsingle_check=( "test3config.service" "test3discovery.service" "test3gateway.service" "test3auth.service" "test3umm.service" "test3dashboard.service" "test3samlauth.service" "exit" );;


            esac

}

function check_micro() {
           
           nuofline=`cat $getservice.txt | wc -l`   #get number of lines in defined .txt file
           echo
           echo "APPLICATION STATUS ( UP $(tput setaf 2)██ $(tput sgr0) DOWN $(tput setaf 1)██$(tput sgr0) )"
           echo "NUMBER OF SERVICES $nuofline"
           echo
           for ((i=1; i<=$nuofline; i++ ));      #for loop until i=nuofline
           do
           service=$(awk -v "i=$i" '{ if (NR == i) print $1}' $getservice.txt)    #get service name from the text file
           port=$(awk -v "i=$i" '{ if (NR == i) print $2}' $getservice.txt)       #get port number from the text file
           if ! netstat -tna | grep 'LISTEN\>' | grep -q "$port"
           then
           echo " $(tput setaf 1)$service $(tput sgr0)"
           else
           echo " $(tput setaf 2)$service $(tput sgr0)"
           fi
           done
}

#########################################################* MAIN SCRIPT *################################################################################

while [[ $next != "no" ]]
    do
    while [[ " ${service_check[*]} " != *" ${getservice} "* ]]
    do
    getservice=$(rlwrap -S 'Select The Application Name You Need To Start Or Stop? (Enter "CTRL + C" For EXIT): ' -H ~/.service.history -e '' -i -f <(echo "${servicearray[@]}") -o cat) #geting service name need to start from the user
    getservice="${getservice// /}"

    if [[ " ${service_check[*]} " != *" ${getservice} "* ]]
    then
    echo "$(tput setaf 1) YOU MUST SELECT AN APPLICATION TO PROCEED FURTHER!!!$(tput sgr0)"
    echo "$(tput setaf 2) press the TAB key twice for list the applications$(tput sgr0)"
    else
    check_micro

    fi
    echo
    done

##########

while [[ " ${stopsingleorall_check[*]} " != *" ${stopsingleorall} "* ]]
    do
    stopsingleorall=$(rlwrap -S 'Do You Need To Stop All The Services or Stop Single Service? (Enter exit For EXIT): ' -H ~/.service.history -e '' -i -f <(echo "${singleorall[@]}") -o cat) #geting service name need to start from the user
    stopsingleorall="${stopsingleorall// /}"

    if [[ " ${stopsingleorall_check[*]} " != *" ${stopsingleorall} "* ]]
    then
    echo "$(tput setaf 1) INVALID ENTRY!!! $(tput sgr0)"
    echo "$(tput setaf 2) press the TAB key twice for list  $(tput sgr0)"
    fi

    echo
    done

    if [[ "$stopsingleorall" == "$VAR1" ]];then

    switchcase
#############

while [ "$stopsingle" != "exit" ]
     do
    stopsingle=$(rlwrap -S 'Enter The Service Name You Need To Stop? (Enter exit For EXIT): ' -H ~/.single.history -e '' -i -f <(echo "${arr[@]}") -o cat) #geting service name need to start from the user
    stopsingle="${stopsingle// /}"
    portofservice=$(cat $getservice.txt | awk -v i="$stopsingle" '$0~i' | awk '{ print $2 }')
    if [[ " ${stopsingle_check[*]} " == *" ${stopsingle} "* ]]
    then
    stop_single_service
  
     
    else
    echo "$(tput setaf 1) INVALID ENTRY!!! $(tput sgr0)"
    echo "$(tput setaf 2) press the TAB key twice for list the services $(tput sgr0)"
    fi
     
    done
#############

elif [[ "$stopsingleorall" == "$VAR2" ]]; then
    stop_all_services
fi
############

while [[ " ${startsingleorall_check[*]} " != *" ${startsingleorall} "* ]]
    do
    startsingleorall=$(rlwrap -S 'Do You Need To Start All The Services or Start Single Service? (Enter exit For EXIT): ' -H ~/.service.history -e '' -i -f <(echo "${singleorall[@]}") -o cat) #geting service name need to start from the user
    startsingleorall="${startsingleorall// /}"

    if [[ " ${startsingleorall_check[*]} " != *" ${startsingleorall} "* ]]
    then
    echo "$(tput setaf 1) INVALID ENTRY!!! $(tput sgr0)"
    echo "$(tput setaf 2) press the TAB key twice for list  $(tput sgr0)"
    fi
    echo
    done

if [[ "$startsingleorall" == "$VAR1" ]];then

    switchcase
#############

while [ "$startsingle" != "exit" ]
    do
#     echo ${arr[@]}
#     echo ${test1singlearray[@]}
    startsingle=$(rlwrap -S 'Enter The Service Name You Need To Start? (Enter exit For EXIT):' -H ~/.single.history -e '' -i -f <(echo "${arr[@]}") -o cat) #geting service name need to start from the user
    startsingle="${startsingle// /}"
    portofservice=$(cat $getservice.txt | awk -v i="$startsingle" '$0~i' | awk '{ print $2 }')
    if [[ " ${startsingle_check[*]} " == *" ${startsingle} "* ]]
    then
    start_single_service
     
    else
    echo "$(tput setaf 1) INVALID ENTRY!!!$(tput sgr0)"
    echo "$(tput setaf 2) press the TAB key twice for list the services $(tput sgr0)"
    fi

    done
#############

elif [[ "$startsingleorall" == "$VAR2" ]]; then
    start_all_services
fi
##############

unset getservice
unset service
unset port
unset startsingle
unset portofservice
unset stopsingle
unset Kservice
unset Kport
unset stopsingleorall
unset startsingleorall

echo

next=$(rlwrap -S 'Do You Need To Start or Stop Another Application? (Enter "no" For EXIT): ' -H ~/.service.history -e '' -i -f <(echo "${next[@]}") -o cat) #geting service name need to start from the user
next="${next// /}"
echo

done

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.