स्प्रिंग बूट एप्लिकेशन को एक सही तरीके से कैसे बंद करें?


121

स्प्रिंग बूट डॉक्यूमेंट में, उन्होंने कहा कि 'प्रत्येक स्प्रिंगएप्लीकेशन JVM के साथ शटडाउन हुक को पंजीकृत करेगा ताकि यह सुनिश्चित हो सके कि ApplicationContext बाहर निकलने पर इनायत हो।'

जब मैं ctrl+cशेल कमांड पर क्लिक करता हूं , तो एप्लिकेशन को इनायत से बंद किया जा सकता है। यदि मैं उत्पादन मशीन में एप्लिकेशन चलाता हूं, तो मुझे कमांड का उपयोग करना होगा java -jar ProApplicaton.jar। लेकिन मैं शेल टर्मिनल को बंद नहीं कर सकता, अन्यथा यह प्रक्रिया को बंद कर देगा।

यदि मैं कमांड चलाता हूं nohup java -jar ProApplicaton.jar &, तो मैं ctrl+cइसे शालीनतापूर्वक बंद करने के लिए उपयोग नहीं कर सकता ।

उत्पादन वातावरण में स्प्रिंग बूट एप्लिकेशन को शुरू करने और रोकने का सही तरीका क्या है?


आपके कॉन्फ़िगरेशन के आधार पर आवेदन की पीआईडी ​​फ़ाइल में लिखी जाती है। आप उस PID को किल सिग्नल भेज सकते हैं। इस अंक में टिप्पणियाँ भी देखें ।
एम। डिनम

मुझे किस संकेत का उपयोग करना चाहिए, मुझे नहीं लगता कि किल -9 एक अच्छा विचार है, है ना?
क्रिस

5
इसीलिए मैंने आपको उस धागे की ओर इशारा किया ... लेकिन कुछ ऐसा kill -SIGTERM <PID>करना चाहिए।
एम। दीनुम

पीड़ के साथ मारना, नहीं -9
Dapeng

1
मार $ (lsof -ti tcp: <port>) - यदि आप एक्ट्यूएटर का उपयोग नहीं करना चाहते हैं और त्वरित मारना चाहते हैं
एलेक्स नोल्को

जवाबों:


63

यदि आप एक्चुएटर मॉड्यूल का उपयोग कर रहे हैं, तो आप एप्लिकेशन को बंद कर सकते हैं JMXया HTTPयदि समापन बिंदु सक्षम है।

इसमें जोड़ें application.properties:

endpoints.shutdown.enabled = true

निम्नलिखित URL उपलब्ध होगा:

/actuator/shutdown - एप्लिकेशन को इनायत शटडाउन (डिफ़ॉल्ट रूप से सक्षम नहीं) होने देता है।

एक समापन बिंदु कैसे उजागर होता है, इसके आधार पर, संवेदनशील पैरामीटर को सुरक्षा संकेत के रूप में उपयोग किया जा सकता है।

उदाहरण के लिए, संवेदनशील एंडपॉइंट्स को उपयोगकर्ता नाम / पासवर्ड की आवश्यकता होगी, जब वे एक्सेस किए जाते हैं HTTP(या वेब सुरक्षा सक्षम नहीं होने पर बस अक्षम हो जाते हैं)।

से वसंत बूट प्रलेखन


1
मैं एक्चुएटर मॉड्यूल को शामिल नहीं करना चाहता। लेकिन मैंने पाया कि, मेरे कंसोल लॉग में, स्प्रिंग बूट पीआईडी ​​को पहली पंक्ति में प्रिंट करता है। क्या एक्ट्यूएटर मॉड्यूल (ApplicationPidListener) को जोड़े बिना स्प्रिंग बूट को पीआईडी ​​को अन्य फाइल में प्रिंट करने की अनुमति है?
क्रिस

2
ध्यान दें कि इस समापन बिंदु के लिए एक http पद होना चाहिए। आप इसे एंडपॉइंट के साथ सक्षम कर सकते हैं।
shutdown.enabled

54

यहां एक और विकल्प है जिसके लिए आपको कोड बदलने या शट-डाउन समापन बिंदु को उजागर करने की आवश्यकता नहीं है। निम्नलिखित स्क्रिप्ट बनाएं और उन्हें अपने ऐप को शुरू करने और रोकने के लिए उपयोग करें।

start.sh

#!/bin/bash
java -jar myapp.jar & echo $! > ./pid.file &

अपना ऐप शुरू करता है और प्रोसेस आईडी को फाइल में सेव करता है

stop.sh

#!/bin/bash
kill $(cat ./pid.file)

सहेजे गए प्रक्रिया आईडी का उपयोग करके अपना ऐप बंद कर देता है

start_silent.sh

#!/bin/bash
nohup ./start.sh > foo.out 2> foo.err < /dev/null &

यदि आपको किसी दूरस्थ मशीन या CI पाइपलाइन से ssh का उपयोग करके ऐप को शुरू करने की आवश्यकता है तो अपना ऐप शुरू करने के बजाय इस स्क्रिप्ट का उपयोग करें। स्टार्ट.श का प्रयोग सीधे शेल को हैंग करने के लिए छोड़ सकता है।

उदा के बाद। अपने ऐप को फिर से परिनियोजित करना / उपयोग करना आप इसे पुनः आरंभ कर सकते हैं:

sshpass -p password ssh -oStrictHostKeyChecking=no userName@www.domain.com 'cd /home/user/pathToApp; ./stop.sh; ./start_silent.sh'

इसका उत्तर होना चाहिए। मैंने अभी पुष्टि की है कि एक सिग्नल 15 शटडाउन बसंत को शिद्दत से इनायत करने के लिए कहता है।
चाड

1
आप java - jar निष्पादन को nohup के साथ start.sh के अंदर क्यों नहीं कहते हैं, बल्कि java - jar निष्पादन को start.sh के अंदर कहते हैं, जिसे अन्य बाहरी शेल स्क्रिप्ट के अंदर nohup कहा जाता है ??
आनंद वर्की फिलिप्स

2
@AnandVarkeyPhilips एकमात्र कारण यह है कि मैं कभी-कभी परीक्षण के उद्देश्यों के लिए कमांड लाइन से start.sh को कॉल करता हूं, लेकिन अगर आपको हमेशा आवश्यकता होती है, nohupतो आप केवल कमांड को मर्ज कर सकते हैं
जेन्स

@ जेन्स, जानकारी के लिए धन्यवाद। क्या आप मुझे ऐसा करने के लिए कह सकते हैं: foo.out 2> foo.err </ dev / null &
आनंद वर्के फिलिप्स

1
@ जेन्स, धन्यवाद मैंने इसे सफलतापूर्वक किया है और मैंने अपनी शुरुआत और स्टॉप स्क्रिप्ट यहाँ पोस्ट की है। ( stackoverflow.com/questions/26547532/… )
आनंद वर्की फिलिप्स

52

@ जीन-फिलिप बॉन्ड के उत्तर के रूप में,

यहाँ मावेन उपयोगकर्ता के लिए एक मावेन क्विक उदाहरण है जो स्प्रिंग एंड बूट स्टार्टर-एक्ट्यूएटर का उपयोग करके स्प्रिंग बूट वेब ऐप को बंद करने के लिए HTTP एंडपॉइंट को कॉन्फ़िगर करता है ताकि आप कॉपी और पेस्ट कर सकें:

1. मावेन pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2.application.properties:

#No auth  protected 
endpoints.shutdown.sensitive=false

#Enable shutdown endpoint
endpoints.shutdown.enabled=true

सभी समापन बिंदु यहां सूचीबद्ध हैं :

3. एप्लिकेशन को बंद करने के लिए एक पोस्ट विधि भेजें:

curl -X POST localhost:port/shutdown

सुरक्षा नोट:

यदि आपको शटडाउन विधि को संरक्षित करने की आवश्यकता है, तो आपको आवश्यकता भी हो सकती है

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>

विवरण कॉन्फ़िगर करें :


दूसरे चरण के बाद, जब प्रयास करने का प्रयास करें, इस त्रुटि संदेश से मुलाकात की: विवरण: विधि का पैरामीटर 0 org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter में पैरामीटर का एक प्रकार की आवश्यकता है। .annotation.authentication.configuration.AuthenticationConfiguration 'जो खोजा नहीं जा सका। क्रिया: अपने कॉन्फ़िगरेशन में 'org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration' प्रकार की सेम को परिभाषित करने पर विचार करें।
रॉबर्टो

2
कृपया ध्यान दें: यदि मैंने server.contextPath=/appNameअपने application.properties में ऐसा कुछ शामिल किया है तो अब बंद करने की आज्ञा बन जाएगी: curl -X POST localhost:8080/appName/shutdown आशा है कि यह किसी की मदद कर सकता है। इस गलती की वजह से मुझे बहुत संघर्ष करना पड़ा।
नवीन कुमार

स्प्रिंग बूट 1.5.8 के साथ, यह सुझाव दिया गया है, अगर सुरक्षा के बिना, अनुप्रयोग में endpoints.shutdown.enabled=true management.security.enabled=false
स्टेफानो स्कार्पांति

यदि आप अंतिम बिंदु को उजागर नहीं करना चाहते हैं और शेल स्क्रिप्ट के माध्यम से रोकने और शुरू करने के लिए पीआईडी ​​फ़ाइल का उपयोग करते हैं, तो यह प्रयास करें: stackoverflow.com/questions/26547532/…
आनंद वर्की फिलिप्स

27

आप पीआईडी ​​को फ़ाइल में लिखने के लिए स्प्रिंगबूट एप्लिकेशन बना सकते हैं और आप बैश स्क्रिप्ट का उपयोग करके स्थिति को रोकने या फिर से शुरू करने या प्राप्त करने के लिए पीआईडी ​​फ़ाइल का उपयोग कर सकते हैं। PID को किसी फ़ाइल में लिखने के लिए, नीचे दिए गए अनुसार ApplicationPidFileWriter का उपयोग करके स्प्रिंगपेप्लिएशन के लिए एक श्रोता को पंजीकृत करें:

SpringApplication application = new SpringApplication(Application.class);
application.addListeners(new ApplicationPidFileWriter("./bin/app.pid"));
application.run();

फिर स्प्रिंग बूट एप्लिकेशन को चलाने के लिए एक बैश स्क्रिप्ट लिखें। संदर्भ

अब आप स्क्रिप्ट का उपयोग शुरू करने, रोकने या फिर से शुरू करने के लिए कर सकते हैं।


जेनेरिक और जेनकिंस संगत पूर्ण शुरुआत और स्टॉप शैल स्क्रिप्ट यहां पाई जा सकती है ( stackoverflow.com/questions/26547532/… )
आनंद वर्की फिलिप्स


14

सभी उत्तर इस तथ्य को याद कर रहे हैं कि आपको सुंदर बंद के दौरान समन्वित फैशन में काम के कुछ हिस्से को पूरा करने की आवश्यकता हो सकती है (उदाहरण के लिए, एक उद्यम अनुप्रयोग में)।

@PreDestroyआपको व्यक्तिगत सेम में शटडाउन कोड निष्पादित करने की अनुमति देता है। कुछ और अधिक परिष्कृत इस तरह दिखेगा:

@Component
public class ApplicationShutdown implements ApplicationListener<ContextClosedEvent> {
     @Autowired ... //various components and services

     @Override
     public void onApplicationEvent(ContextClosedEvent event) {
         service1.changeHeartBeatMessage(); // allows loadbalancers & clusters to prepare for the impending shutdown
         service2.deregisterQueueListeners();
         service3.finishProcessingTasksAtHand();
         service2.reportFailedTasks();
         service4.gracefullyShutdownNativeSystemProcessesThatMayHaveBeenLaunched(); 
         service1.eventLogGracefulShutdownComplete();
     }
}

यही वह चीज है जिसकी मुझे जरूरत थी। आवेदन को निष्पादित करने के बाद, ctrl-c दबाएं @Michal
क्लाउडियो

8

मैं किसी भी एंडपॉइंट को उजागर नहीं करता हूं और शुरू करता हूं ( बैकग्राउंड में nohup और nohup के माध्यम से बनाई गई फ़ाइलों के बिना ) और शेल स्क्रिप्ट के साथ रुकें ( KILL PID के साथ इनायत और बलपूर्वक मारें यदि ऐप अभी भी 3 मिनट के बाद चल रहा है )। मैं केवल निष्पादन योग्य जार बनाता हूं और पीआईडी ​​फ़ाइल लेखक का उपयोग करता हूं पीआईडी ​​फाइल लिखने के लिए और जार और पीआईडी ​​को फ़ोल्डर में स्टोर करता हूं एक ही नाम के साथ आवेदन नाम और शेल स्क्रिप्ट भी शुरू के साथ एक ही नाम है और अंत में बंद करें। मैं इन स्टॉप स्क्रिप्ट को कॉल करता हूं और जेनकिंस पाइपलाइन के माध्यम से स्क्रिप्ट भी शुरू करता हूं। अब तक कोई मुद्दा नहीं। पूरी तरह से 8 अनुप्रयोगों के लिए काम कर रहे हैं (बहुत ही सामान्य स्क्रिप्ट और किसी भी ऐप के लिए आवेदन करना आसान है)।

मुख्य वर्ग

@SpringBootApplication
public class MyApplication {

    public static final void main(String[] args) {
        SpringApplicationBuilder app = new SpringApplicationBuilder(MyApplication.class);
        app.build().addListeners(new ApplicationPidFileWriter());
        app.run();
    }
}

YML फ़ाइल

spring.pid.fail-on-write-error: true
spring.pid.file: /server-path-with-folder-as-app-name-for-ID/appName/appName.pid

यहाँ शुरू स्क्रिप्ट है (start-appname.sh):

#Active Profile(YAML)
ACTIVE_PROFILE="preprod"
# JVM Parameters and Spring boot initialization parameters
JVM_PARAM="-Xms512m -Xmx1024m -Dspring.profiles.active=${ACTIVE_PROFILE} -Dcom.webmethods.jms.clientIDSharing=true"
# Base Folder Path like "/folder/packages"
CURRENT_DIR=$(readlink -f "$0")
BASE_PACKAGE="${CURRENT_DIR%/bin/*}"
# Shell Script file name after removing path like "start-yaml-validator.sh"
SHELL_SCRIPT_FILE_NAME=$(basename -- "$0")
# Shell Script file name after removing extension like "start-yaml-validator"
SHELL_SCRIPT_FILE_NAME_WITHOUT_EXT="${SHELL_SCRIPT_FILE_NAME%.sh}"
# App name after removing start/stop strings like "yaml-validator"
APP_NAME=${SHELL_SCRIPT_FILE_NAME_WITHOUT_EXT#start-}

PIDS=`ps aux |grep [j]ava.*-Dspring.profiles.active=$ACTIVE_PROFILE.*$APP_NAME.*jar | awk {'print $2'}`
if [ -z "$PIDS" ]; then
  echo "No instances of $APP_NAME with profile:$ACTIVE_PROFILE is running..." 1>&2
else
  for PROCESS_ID in $PIDS; do
        echo "Please stop the process($PROCESS_ID) using the shell script: stop-$APP_NAME.sh"
  done
  exit 1
fi

# Preparing the java home path for execution
JAVA_EXEC='/usr/bin/java'
# Java Executable - Jar Path Obtained from latest file in directory
JAVA_APP=$(ls -t $BASE_PACKAGE/apps/$APP_NAME/$APP_NAME*.jar | head -n1)
# To execute the application.
FINAL_EXEC="$JAVA_EXEC $JVM_PARAM -jar $JAVA_APP"
# Making executable command using tilde symbol and running completely detached from terminal
`nohup $FINAL_EXEC  </dev/null >/dev/null 2>&1 &`
echo "$APP_NAME start script is  completed."

यहाँ स्टॉप स्क्रिप्ट है (stop-appname.sh):

#Active Profile(YAML)
ACTIVE_PROFILE="preprod"
#Base Folder Path like "/folder/packages"
CURRENT_DIR=$(readlink -f "$0")
BASE_PACKAGE="${CURRENT_DIR%/bin/*}"
# Shell Script file name after removing path like "start-yaml-validator.sh"
SHELL_SCRIPT_FILE_NAME=$(basename -- "$0")
# Shell Script file name after removing extension like "start-yaml-validator"
SHELL_SCRIPT_FILE_NAME_WITHOUT_EXT="${SHELL_SCRIPT_FILE_NAME%.*}"
# App name after removing start/stop strings like "yaml-validator"
APP_NAME=${SHELL_SCRIPT_FILE_NAME_WITHOUT_EXT:5}

# Script to stop the application
PID_PATH="$BASE_PACKAGE/config/$APP_NAME/$APP_NAME.pid"

if [ ! -f "$PID_PATH" ]; then
   echo "Process Id FilePath($PID_PATH) Not found"
else
    PROCESS_ID=`cat $PID_PATH`
    if [ ! -e /proc/$PROCESS_ID -a /proc/$PROCESS_ID/exe ]; then
        echo "$APP_NAME was not running with PROCESS_ID:$PROCESS_ID.";
    else
        kill $PROCESS_ID;
        echo "Gracefully stopping $APP_NAME with PROCESS_ID:$PROCESS_ID..."
        sleep 5s
    fi
fi
PIDS=`/bin/ps aux |/bin/grep [j]ava.*-Dspring.profiles.active=$ACTIVE_PROFILE.*$APP_NAME.*jar | /bin/awk {'print $2'}`
if [ -z "$PIDS" ]; then
  echo "All instances of $APP_NAME with profile:$ACTIVE_PROFILE has has been successfully stopped now..." 1>&2
else
  for PROCESS_ID in $PIDS; do
    counter=1
    until [ $counter -gt 150 ]
        do
            if ps -p $PROCESS_ID > /dev/null; then
                echo "Waiting for the process($PROCESS_ID) to finish on it's own for $(( 300 - $(( $counter*5)) ))seconds..."
                sleep 2s
                ((counter++))
            else
                echo "$APP_NAME with PROCESS_ID:$PROCESS_ID is stopped now.."
                exit 0;
            fi
    done
    echo "Forcefully Killing $APP_NAME with PROCESS_ID:$PROCESS_ID."
    kill -9 $PROCESS_ID
  done
fi

7

स्प्रिंग बूट ने कई एप्लिकेशन श्रोता प्रदान किए, जबकि अनुप्रयोग संदर्भ बनाने का प्रयास उनमें से एक ApplicationFailedEvent है। हम मौसम को जानने के लिए उपयोग कर सकते हैं कि आवेदन का संदर्भ प्रारंभिक है या नहीं।

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.context.event.ApplicationFailedEvent; 
    import org.springframework.context.ApplicationListener;

    public class ApplicationErrorListener implements 
                    ApplicationListener<ApplicationFailedEvent> {

        private static final Logger LOGGER = 
        LoggerFactory.getLogger(ApplicationErrorListener.class);

        @Override
        public void onApplicationEvent(ApplicationFailedEvent event) {
           if (event.getException() != null) {
                LOGGER.info("!!!!!!Looks like something not working as 
                                expected so stoping application.!!!!!!");
                         event.getApplicationContext().close();
                  System.exit(-1);
           } 
        }
    }

स्प्रिंगडिप्लीकेशन में उपरोक्त श्रोता वर्ग में जोड़ें।

    new SpringApplicationBuilder(Application.class)
            .listeners(new ApplicationErrorListener())
            .run(args);  

सबसे अच्छा जवाब मुझे मिला! धन्यवाद!
वागीफ

[@ user3137438], यह पूर्व विध्वंस एनोटेशन के अंदर प्रवेश करने से कैसे अलग है?
आनंद वर्की फिलिप्स

6

वसंत बूट 2.3 और बाद में, एक निर्मित सुंदर शटडाउन है तंत्र है।

प्री-स्प्रिंग बूट 2.3 , कोई आउट-ऑफ-द-बॉक्स सुंदर शटडाउन तंत्र नहीं है। कुछ स्प्रिंग-बूट स्टार्टर्स यह कार्यक्षमता प्रदान करते हैं:

  1. https://github.com/jihor/hiatus-spring-boot
  2. https://github.com/gesellix/graceful-shutdown-spring-boot
  3. https://github.com/corentin59/spring-boot-graceful-shutdown

मैं nr का लेखक हूं। 1. स्टार्टर का नाम "Hiatus for Spring Boot" रखा गया है। यह लोड बैलेंसर स्तर पर काम करता है, अर्थात बस सेवा को OUT_OF_SERVICE के रूप में चिह्नित करता है, किसी भी तरह से आवेदन के संदर्भ में हस्तक्षेप नहीं करता है। यह एक सुंदर शटडाउन करने की अनुमति देता है और इसका मतलब है कि, यदि आवश्यक हो, तो सेवा को कुछ समय के लिए सेवा से बाहर किया जा सकता है और फिर जीवन में वापस लाया जा सकता है। नकारात्मक पक्ष यह है कि यह JVM को नहीं रोकता है, आपको इसे killकमांड के साथ करना होगा । जैसा कि मैंने कंटेनरों में सब कुछ चलाया है, यह मेरे लिए कोई बड़ी बात नहीं थी, क्योंकि मुझे कंटेनर को वैसे भी रोकना और निकालना होगा।

एंडी विल्किंसन की इस पोस्ट के आधार पर कमोबेश 2 और 3 हैं । वे एक तरफ़ा काम करते हैं - एक बार ट्रिगर होने पर, वे अंततः संदर्भ को बंद कर देते हैं।


5

स्प्रिंगएप्लिकेशन का स्पष्ट रूप से यह सुनिश्चित करने के लिए जेवीएम के साथ शटडाउन हुक को पंजीकृत करता है कि बाहर निकलने पर ApplicationContext को बंद कर दिया जाता है। यह भी सभी बीन तरीकों के साथ एनोटेट कहा जाएगा @PreDestroy। इसका मतलब है कि हमें बूट एप्लिकेशन में किसी registerShutdownHook()विधि का स्पष्ट रूप से उपयोग नहीं करना है ConfigurableApplicationContext, जैसे हमें स्प्रिंग कोर एप्लीकेशन में करना है।

@SpringBootConfiguration
public class ExampleMain {
    @Bean
    MyBean myBean() {
        return new MyBean();
    }

    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(ExampleMain.class, args);
        MyBean myBean = context.getBean(MyBean.class);
        myBean.doSomething();

        //no need to call context.registerShutdownHook();
    }

    private static class MyBean {

        @PostConstruct
        public void init() {
            System.out.println("init");
        }

        public void doSomething() {
            System.out.println("in doSomething()");
        }

        @PreDestroy
        public void destroy() {
            System.out.println("destroy");
        }
    }
}

के विकल्प के रूप में @PostConstructऔर @PreDestroyमैंने एनोटेशन के भीतर initMethodऔर destroyMethodविशेषताओं का उपयोग किया @Bean। तो इस उदाहरण के लिए @Bean(initMethod="init", destroyMethod="destroy"):।
आकर ९

@PreDestroyकुछ डेवलपर्स के बारे में एक पकड़ पता नहीं हो सकता है, इस तरह के तरीकों को केवल सिंगलटन दायरे के साथ सेम के लिए कहा जाता है। डेवलपर्स को अन्य स्कोप
एग्स के

2

वे एक वसंत आवेदन को बंद करने के कई तरीके हैं। एक को कॉल करना है ApplicationContext:

ApplicationContext ctx =
    SpringApplication.run(HelloWorldApplication.class, args);
// ...
ctx.close()

आपका प्रश्न यह सुझाव देता है कि आप अपना आवेदन बंद करके करना चाहते हैं Ctrl+C , जिसका उपयोग अक्सर किसी आदेश को समाप्त करने के लिए किया जाता है। इस मामले में...

उपयोग endpoints.shutdown.enabled=trueसबसे अच्छा नुस्खा नहीं है। इसका मतलब है कि आप अपने आवेदन को समाप्त करने के लिए एक अंतिम बिंदु को उजागर करते हैं। इसलिए, आपके उपयोग के मामले और आपके वातावरण के आधार पर, आपको इसे सुरक्षित करना होगा ...

Ctrl+Cअपने मामले में बहुत अच्छा काम करना चाहिए। मुझे लगता है कि आपका मुद्दा एम्परसेंड (और) के कारण है और अधिक स्पष्टीकरण:

स्प्रिंग एप्लीकेशन प्रसंग में जेवीएम रनटाइम के साथ शटडाउन हुक रजिस्टर हो सकता है। ApplicationContext प्रलेखन देखें ।

मुझे नहीं पता कि स्प्रिंग बूट ने इस हुक को स्वचालित रूप से कॉन्फ़िगर किया है जैसा कि आपने कहा था। मुझे लगता है कि यह है।

पर Ctrl+C, आपका शेल INTअग्रभूमि अनुप्रयोग के लिए एक संकेत भेजता है । इसका अर्थ है "कृपया अपने निष्पादन को बाधित करें"। आवेदन इस संकेत को फंसा सकता है और इसकी समाप्ति (वसंत द्वारा पंजीकृत हुक) से पहले सफाई कर सकता है, या बस इसे (खराब) अनदेखा कर सकता है।

nohupवह कमांड है जो HUP सिग्नल को अनदेखा करने के लिए एक जाल के साथ निम्नलिखित प्रोग्राम को निष्पादित करता है। HUP का उपयोग प्रोग्राम को समाप्त करने के लिए किया जाता है, जब आप हैंग हो जाते हैं (उदाहरण के लिए अपने ssh कंसेशन को बंद करें)। इसके अलावा यह इस बात से बचने के लिए आउटपुट को पुनर्निर्देशित करता है कि आपका प्रोग्राम गायब टीटीवाई पर ब्लॉक करता है। nohupINT संकेत की अनदेखी नहीं करता है। तो यह Ctrl+Cकाम करने के लिए नहीं रोकता है।

मुझे लगता है कि आपका मुद्दा एम्परसेंड (और) के कारण है, नोह द्वारा नहीं। Ctrl+Cअग्रभूमि प्रक्रियाओं के लिए एक संकेत भेजता है। एम्परसैंड आपके एप्लिकेशन को पृष्ठभूमि में चलाने का कारण बनता है। एक समाधान: करते हैं

kill -INT pid

उपयोग kill -9 या kill -KILLखराब है क्योंकि एप्लिकेशन (यहां JVM) इसे शान से समाप्त करने के लिए नहीं फंसा सकता है।

एक अन्य उपाय यह है कि अपने आवेदन को अग्रभूमि में वापस लाया जाए। फिर Ctrl+Cकाम करेंगे। बैश जॉब कंट्रोल पर एक नजर, अधिक सटीक रूप से fg


2

exit()अपने स्प्रिंग बूट एप्लिकेशन को शालीनतापूर्वक बंद करने के लिए स्प्रिंगऐप्लिकेशन क्लास में स्थिर विधि का उपयोग करें ।

public class SomeClass {
    @Autowire
    private ApplicationContext context

    public void close() {
        SpringApplication.exit(context);
    }
}

यह मेरे लिए काम करता है। बहुत बहुत धन्यवाद।
खाचरौंच सांगसेन

1

स्प्रिंग बूट अब ग्रेसफुल शट डाउन (वर्तमान में रिलीज़-पूर्व संस्करणों में 2.3.0.BUILD-SNAPSHOT) का समर्थन करता है

जब सक्षम किया जाता है, तो एप्लिकेशन को बंद करने के लिए कॉन्फ़िगर करने योग्य अवधि की एक अनुग्रह अवधि शामिल होगी। इस रियायती अवधि के दौरान, मौजूदा अनुरोधों को पूरा करने की अनुमति दी जाएगी लेकिन किसी नए अनुरोध की अनुमति नहीं दी जाएगी

आप इसे सक्षम कर सकते हैं:

server.shutdown.grace-period=30s

https://docs.spring.io/spring-boot/docs/2.3.0.BUILD-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-graceful-shutdown


0

यदि आप मावेन का उपयोग कर रहे हैं तो आप मावेन ऐप असेंबलर प्लगइन का उपयोग कर सकते हैं

डेमन मोजो (जो JSW को एम्बेड करता है ) शेल स्क्रिप्ट को स्टार्ट / स्टॉप तर्क के साथ आउटपुट करेगा। stopइच्छा बंद / शान से अपने स्प्रिंग आवेदन मार डालते हैं।

उसी स्क्रिप्ट का उपयोग आपके मावेन एप्लिकेशन को लिनक्स सेवा के रूप में उपयोग करने के लिए किया जा सकता है।


0

यदि आप एक Linux वातावरण में हैं, तो आपको बस इतना करना है कि /etc/inline.d/ के अंदर से अपनी .jar फ़ाइल के लिए एक सिमलिंक बनाना है।

sudo ln -s /path/to/your/myboot-app.jar /etc/init.d/myboot-app

फिर आप किसी अन्य सेवा की तरह आवेदन शुरू कर सकते हैं

sudo /etc/init.d/myboot-app start

एप्लिकेशन को बंद करने के लिए

sudo /etc/init.d/myboot-app stop

इस तरह, जब आप टर्मिनल से बाहर निकलेंगे तो एप्लिकेशन समाप्त नहीं होगा। और एप्लिकेशन स्टॉप कमांड के साथ सुशोभित रूप से बंद हो जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.