2014-04-24 10 views
51

Budujesz aplikację node.js z ekspresowym v4.x, a następnie uruchamiasz aplikację przez npm start. Moje pytanie brzmi: jak zatrzymać aplikację? Czy istnieje npm stop?Jak zatrzymać aplikację, która wywołuje komendę node.js express 'npm start'

EDIT zawierać błąd podczas wdrożenia npm przystanek

/home/nodetest2# npm stop 

> [email protected] stop /home/nodetest2 
> pkill -s SIGINT nodetest2 

pkill: invalid argument for option 's' -- SIGINT 

npm ERR! [email protected] stop: `pkill -s SIGINT nodetest2` 
npm ERR! Exit status 2 

Odpowiedz

34

Tak npm przewiduje skrypcie zatrzymania TOO:

npm help npm-scripts

prestop, stop, poststop : Uruchom za pomocą polecenia zatrzymania npm.

Ustaw jeden z powyższym w package.json, a następnie użyj npm stop

npm help npm-stop

Można zrobić to naprawdę proste, jeśli się w app.js,

process.title = myApp;

A potem w scripts.json,

"scripts": { 
    "start": "app.js" 
    , "stop": "pkill --signal SIGINT myApp" 
} 

powiedział, że jeśli to było do mnie, że będę przy użyciu pm2 lub coś automatycznie obchodzić to na podstawie push git.

+1

Dokładnie podążyłem za twoją instrukcją, ale dostałem błąd. Co zrobiłem źle? Czy możesz rzucić okiem? Edytuję pytanie, aby uwzględnić błąd. Dzięki! – ngungo

+0

@ngungo spróbuj 'pkill'. –

+0

Nadal mam błąd. Oczywiście jestem dobrze zorientowany w komendach liniowych. – ngungo

13

Po wypróbowaniu sugerowanego rozwiązania zdałem sobie sprawę, że nazwa mojej aplikacji została obcięta. I przeczytać na process.title w dokumentacji nodejs (https://nodejs.org/docs/latest/api/process.html#process_process_title) i mówi

W systemach Linux i OS X, jest ograniczone do wielkości nazwy binarnej plus długość argumentów wiersza poleceń, ponieważ nadpisuje pamięć argv .

Moja aplikacja nie używa żadnych argumentów, więc mogę dodać poniższy wiersz kodu do mojego app.js

process.title = process.argv[2]; 

a następnie dodać te kilka wierszy do mojego package.json pliku

"scripts": { 
    "start": "node app.js this-name-can-be-as-long-as-it-needs-to-be", 
    "stop": "killall -SIGINT this-name-can-be-as-long-as-it-needs-to-be" 
    }, 

do używaj naprawdę długich nazw procesów. npm start i npm stop praca, oczywiście npm stop zawsze zakończy wszystkie uruchomione procesy, ale to jest dla mnie ok.

18

Wszystkie inne rozwiązania są zależne od systemu operacyjnego. Niezależne rozwiązanie dla dowolnego systemu operacyjnego używa socket.io w następujący sposób.

package.json ma dwa scenariusze:

"scripts": { 
    "start": "node server.js", 
    "stop": "node server.stop.js" 
} 

serwer.JS - Twój zwykły ekspresowy rzeczy tu mieszka

const express = require('express'); 
const app = express(); 
const server = http.createServer(app); 
server.listen(80,() => { 
    console.log('HTTP server listening on port 80'); 
}); 

// Now for the socket.io stuff - NOTE THIS IS A RESTFUL HTTP SERVER 
// We are only using socket.io here to respond to the npmStop signal 
// To support IPC (Inter Process Communication) AKA RPC (Remote P.C.) 

const io = require('socket.io')(server); 
io.on('connection', (socketServer) => { 
    socketServer.on('npmStop',() => { 
    process.exit(0); 
    }); 
}); 

server.stop.js

const io = require('socket.io-client'); 
const socketClient = io.connect('http://localhost'); // Specify port if your express server is not using default port 80 

socketClient.on('connect',() => { 
    socketClient.emit('npmStop'); 
    setTimeout(() => { 
    process.exit(0); 
    }, 1000); 
}); 

przetestować go

npm start (aby uruchomić serwer jak zwykle)

npm stop (ta teraz zatrzyma twój działający serwer)

The abov e kod nie został przetestowany (jest to wycięta wersja mojego kodu, mój kod działa), ale mam nadzieję, że działa tak, jak jest. Tak czy inaczej, podaje ogólny kierunek, jeśli chcesz użyć socket.io, aby zatrzymać serwer.

+2

Witaj Dan, tylko szybkie przypomnienie, że twój (w przeciwnym razie pomocny) post pojawił się ponownie podczas mojej "rewizji w puchu". Materiały takie jak podziękowania, pozdrowienia, pozdrowienia, terminy, jak trudny jest problem, a rzeczy, które nie są istotne dla tego stanowiska, są zazwyczaj edytowane, więc często najlepiej jest nie dodawać ich w pierwszej kolejności - po prostu tworzą pracę dla redaktorzy. [Tutaj jest związany post Meta] (http://meta.stackoverflow.com/q/320874/472495), mam nadzieję, że pomaga. Dzięki! – halfer

+1

Myślę, że to powinna być akceptowana odpowiedź, która jest niezależna od platformy i całkiem schludna. – noego

2

Oto kolejne rozwiązanie, które łączy pomysły z poprzednich odpowiedzi. Podejście typu "zabij proces" przy jednoczesnym uwzględnieniu obaw dotyczących niezależności platformy.

Opiera się na pakiecie tree-kill, aby poradzić sobie z zabiciem drzewa procesów serwera. Zauważyłem, że zabicie całego drzewa procesów jest niezbędne w moich projektach, ponieważ niektóre narzędzia (na przykład babel-node) odradzają procesy potomne. Jeśli chcesz zabić tylko jeden proces, możesz zamienić zabijanie drzewa za pomocą wbudowanej metody process.kill().

Rozwiązanie następująco (pierwsze dwa argumenty spawn() powinny zostać zmienione w celu odzwierciedlenia specyficzną recepturę działa serwer):

build/start-server.js

import { spawn } from 'child_process' 
import fs from 'fs' 

const child = spawn('node', [ 
    'dist/server.js' 
], { 
    detached: true, 
    stdio: 'ignore' 
}) 
child.unref() 

if (typeof child.pid !== 'undefined') { 
    fs.writeFileSync('.server.pid', child.pid, { 
    encoding: 'utf8' 
    }) 
} 

build /stop-server.js

import fs from 'fs' 
import kill from 'tree-kill' 

const serverPid = fs.readFileSync('.server.pid', { 
    encoding: 'utf8' 
}) 
fs.unlinkSync('.server.pid') 

kill(serverPid) 

package.json

"scripts": { 
    "start": "babel-node build/start-server.js", 
    "stop": "babel-node build/stop-server.js" 
} 

Należy zauważyć, że rozwiązanie to odłącza skrypt startowy z serwera (tj npm start powróci natychmiast i nie będzie blokowany, dopóki serwer nie zostanie zatrzymany). Jeśli wolisz tradycyjne blokowanie, po prostu usuń argument options.detached do spawn(), a połączenie do child.unref().

1

Sprawdź z netstat -nptl wszystkich procesów

Active Internet connections (only servers) 
Proto Recv-Q Send-Q Local Address   Foreign Address   State  PID/Program name 
tcp  0  0 127.0.0.1:27017   0.0.0.0:*    LISTEN  1736/mongod  
tcp  0  0 0.0.0.0:22    0.0.0.0:*    LISTEN  1594/sshd  
tcp6  0  0 :::3977     :::*     LISTEN  6231/nodejs  
tcp6  0  0 :::22     :::*     LISTEN  1594/sshd  
tcp6  0  0 :::3200     :::*     LISTEN  5535/nodejs 

A ona po prostu zabija proces odniesienia PID .... W moim przypadku chcę zatrzymać 6231/nodejs więc wykonać następujące command:

kill -9 6231 
Powiązane problemy