วิธีการเรียกใช้ Node.js เป็นกระบวนการพื้นหลังและไม่ตาย?


480

ฉันเชื่อมต่อกับเซิร์ฟเวอร์ linux ผ่าน SSH ของ putty ฉันพยายามเรียกใช้เป็นกระบวนการพื้นหลังดังนี้:

$ node server.js &

อย่างไรก็ตามหลังจาก 2.5 ชั่วโมงเทอร์มินัลจะไม่ทำงานและกระบวนการจะหยุดทำงาน มีอยู่แล้วฉันสามารถทำให้กระบวนการยังมีชีวิตอยู่แม้จะมีการยกเลิกการเชื่อมต่อขั้ว?


แก้ไข 1

ที่จริงแล้วฉันพยายามnohupแต่ทันทีที่ฉันปิด Terminal Putty SSH หรือถอดปลั๊กอินเทอร์เน็ตกระบวนการเซิร์ฟเวอร์จะหยุดทันที

มีอะไรที่ฉันต้องทำใน Putty หรือไม่?


แก้ไข 2 (เมื่อ ก.พ. , 2012)

มีความเป็นnode.jsโมดูลตลอดไป มันจะรันเซิร์ฟเวอร์ node.js เป็นบริการ daemon


7
ในกรณีของฉัน nohup exitงานเมื่อฉันออกจากเทอร์โดยการพิมพ์ เมื่อฉันเพิ่งปิดหน้าต่างโป๊วมันล้มเหลว
Pawel Furmaniak

คำตอบ:


513

วิธีแก้ปัญหาง่ายๆ (หากคุณไม่สนใจที่จะกลับมาที่กระบวนการเพียงแค่ต้องการให้มันทำงานต่อไป):

nohup node server.js &

นอกจากนี้ยังมีjobsคำสั่งเพื่อดูรายการที่จัดทำดัชนีของกระบวนการเบื้องหลัง และคุณสามารถฆ่ากระบวนการพื้นหลังโดยการเรียกใช้kill %1หรือkill %2ด้วยจำนวนที่เป็นดัชนีของกระบวนการ

โซลูชันที่มีประสิทธิภาพ (ช่วยให้คุณเชื่อมต่อกับกระบวนการอีกครั้งหากเป็นแบบโต้ตอบ):

screen

จากนั้นคุณสามารถแยกออกได้โดยกด Ctrl + a + d แล้วแนบกลับโดยใช้ screen -r

พิจารณาตัวเลือกที่ใหม่กว่าไปยังหน้าจอ tmux


1
ดังนั้นถ้าฉันใช้ "หน้าจอ" ฉันจะสร้างหน้าจอและทำงานภายในได้ใช่ไหม
murvinlai

30
ใช่แล้วคุณสามารถแยกออกโดยกดปุ่ม Ctrl + a, d แล้วแนบกลับโดยใช้หน้าจอ -r
MK

1
@murvinlai EC2 เป็นสภาพแวดล้อมและไม่มีส่วนเกี่ยวข้องกับสิทธิ์ของรูท มันอาจเกี่ยวกับ AMI ของคุณ ยกตัวอย่างเช่นกับ Amazon AMI sudo bashแน่นอนคุณสามารถ
ShuaiYuan

1
man bash: หากคำสั่งถูกยกเลิกโดยโอเปอเรเตอร์ควบคุม & เชลล์ดำเนินการคำสั่งในพื้นหลังเป็นเชลล์ย่อย เชลล์ไม่รอให้คำสั่งเสร็จสิ้นและสถานะการส่งคืนคือ 0
MK

34
โปรดใครก็ตามที่อ่านสิ่งนี้: การรันเซิร์ฟเวอร์ node.js ภายในหน้าจอหรือเซสชัน tmux เป็นโซลูชันAMATEUR ! อย่าทำอย่างนั้นเว้นแต่ว่าจะทำการทดสอบอย่างรวดเร็ว เพื่อให้กระบวนการทำงานต่อไปคุณจะต้องกำหนดให้ดีอยู่ดี ! ใช้เครื่องมือที่เหมาะสมสำหรับมันเหมือนตลอดไป , PM2หรือธรรมดาเก่าสคริปต์ init.d
Victor Schröder

1119

nohup node server.js > /dev/null 2>&1 &

  1. nohupหมายถึง: อย่ายุติกระบวนการนี้แม้ว่า stty จะถูกตัดออก
  2. > /dev/nullหมายถึง: stdout ไปที่ / dev / null (ซึ่งเป็นอุปกรณ์จำลองที่ไม่บันทึกเอาต์พุตใด ๆ )
  3. 2>&1หมายถึง: stderr ก็ไปที่ stdout (ซึ่งเปลี่ยนเส้นทางไปแล้ว/dev/null) คุณสามารถแทนที่ & 1 ด้วยพา ธ ไฟล์เพื่อเก็บบันทึกข้อผิดพลาดเช่น:2>/tmp/myLog
  4. &ในตอนท้ายหมายถึง: เรียกใช้คำสั่งนี้เป็นงานพื้นหลัง

49
นี่ควรเป็นคำตอบที่ยอมรับได้เพราะมันมีคุณภาพสูงกว่าคำตอบที่ยอมรับในปัจจุบัน
L0j1k

2
@ L0j1k เป็นที่ถกเถียงกันอยู่ OP ได้แสดงให้เห็นถึงระดับของความเข้าใจว่าต้องการคำอธิบายเพิ่มเติมเล็กน้อยสำหรับคำตอบที่ยอมรับ
JFA

41
ดังนั้นไม่เกี่ยวกับ OP เท่าที่เกี่ยวกับคนหลายพันคนที่มาถึงคำถามของ OP เพื่อขอความช่วยเหลือ
L0j1k

3
จำเป็นต้องเปลี่ยนเส้นทาง stdout และ stderr หรือไม่ มันจะใช้งานได้เช่นกันหากฉันไม่ได้เปลี่ยนเส้นทางเลย หรือถ้าฉันเปลี่ยนเส้นทางพวกเขาไปยังไฟล์แทน?
Shawn

10
ส่ง stdout และ stderr ไปที่/dev/null? การบันทึกที่ดี ... ขอให้โชคดีในการแก้ไขข้อบกพร่องนี้ ...
Victor Schröder

138

คุณควรลองใช้screenดู มันซับซ้อนกว่าการทำเพียงเล็กน้อยnohup long_running &แต่เข้าใจหน้าจอเมื่อคุณไม่กลับมาอีก

เริ่มเซสชันหน้าจอของคุณในตอนแรก:

user@host:~$ screen

เรียกใช้สิ่งที่คุณต้องการ:

wget http://mirror.yandex.ru/centos/4.6/isos/i386/CentOS-4.6-i386-binDVD.iso

กด ctrl + A จากนั้น d เสร็จสิ้น เซสชันของคุณดำเนินการต่อในพื้นหลัง

คุณสามารถแสดงรายการเซสชันทั้งหมดโดยscreen -lsและแนบไปกับบางscreen -r 20673.pts-0.srvคำสั่งโดยที่ 0673.pts-0.srv เป็นรายการบันทึก


125

นี่เป็นคำถามเก่า แต่มีอันดับสูงใน Google ฉันแทบจะไม่เชื่อในคำตอบที่ได้รับการโหวตสูงสุดเพราะการรันกระบวนการ node.js ภายในเซสชันหน้าจอด้วย&หรือแม้กระทั่งกับnohupตั้งค่าสถานะ - ทั้งหมดของพวกเขา - เป็นเพียงการแก้ปัญหา

โซลูชัน screen / tmux พิเศษซึ่งควรได้รับการพิจารณาเป็นโซลูชันสมัครเล่น Screen และ Tmux ไม่ได้หมายถึงการทำให้กระบวนการทำงาน แต่สำหรับมัลติเทอร์มินัลเซสชัน ไม่เป็นไรเมื่อคุณเรียกใช้สคริปต์บนเซิร์ฟเวอร์ของคุณและต้องการยกเลิกการเชื่อมต่อ แต่สำหรับเซิร์ฟเวอร์ node.js คุณไม่ต้องการให้กระบวนการของคุณแนบกับเทอร์มินัลเซสชัน นี่มันบอบบางเกินไป เพื่อให้สิ่งต่าง ๆ ทำงานต่อไปคุณจะต้องทำตามขั้นตอน!

มีเครื่องมือที่ดีมากมายให้ทำ

PM2 : http://pm2.keymetrics.io/

# basic usage
$ npm install pm2 -g
$ pm2 start server.js

# you can even define how many processes you want in cluster mode:
$ pm2 start server.js -i 4

# you can start various processes, with complex startup settings
# using an ecosystem.json file (with env variables, custom args, etc):
$ pm2 start ecosystem.json

ข้อดีอย่างหนึ่งที่ฉันเห็นได้จาก PM2 ก็คือมันสามารถสร้างสคริปต์เริ่มต้นระบบเพื่อให้กระบวนการคงอยู่ระหว่างการรีสตาร์ท:

$ pm2 startup [platform]

ไหนสามารถplatformubuntu|centos|redhat|gentoo|systemd|darwin|amazon

Forever.js : https://github.com/foreverjs/forever

# basic usage
$ npm install forever -g
$ forever start app.js

# you can run from a json configuration as well, for
# more complex environments or multi-apps
$ forever start development.json

สคริปต์เริ่มต้น :

ฉันไม่ได้ลงรายละเอียดเกี่ยวกับวิธีการเขียนสคริปต์ init เพราะฉันไม่ใช่ผู้เชี่ยวชาญในเรื่องนี้และมันอาจยาวเกินไปสำหรับคำตอบนี้ แต่โดยทั่วไปแล้วพวกเขาเป็นสคริปต์เชลล์แบบง่าย ๆ ซึ่งถูกเรียกใช้โดยเหตุการณ์ของระบบปฏิบัติการ คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ที่นี่

นักเทียบท่า :

เพียงแค่เรียกใช้เซิร์ฟเวอร์ของคุณในภาชนะที่หางมี-dตัวเลือกและvoiláคุณมีเซิร์ฟเวอร์ Node.js daemonized!

นี่คือตัวอย่าง Dockerfile (จากคู่มืออย่างเป็นทางการของ node.js ):

FROM node:argon

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 8080
CMD [ "npm", "start" ]

จากนั้นสร้างภาพของคุณและเรียกใช้คอนเทนเนอร์ของคุณ:

$ docker build -t <your username>/node-web-app .
$ docker run -p 49160:8080 -d <your username>/node-web-app

หวังว่านี่จะช่วยให้บางคนลงจอดบนหน้านี้ ใช้เครื่องมือที่เหมาะสมสำหรับงานเสมอ มันจะช่วยให้คุณประหยัดอาการปวดหัวและอีกหลายชั่วโมง!


2
นี่คือสิ่งที่ฉันกำลังมองหา ด้วยโซลูชัน pm2 มีวิธีเชื่อมต่อเทอร์มินัลในภายหลังหรือไม่?
Quantumplation

4
@ ควอนตัมการจำลองหมายเลข ไม่สามารถทำได้เนื่องจากกระบวนการไม่ทำงานในเซสชันแบบโต้ตอบ แต่คุณสามารถมี "ความรู้สึก" แบบเดียวกันได้โดยtail -fการล็อกไฟล์ที่ pm2 สร้างขึ้น
Victor Schröder

1
คุณระบุscreenวิธีแก้ปัญหาที่หลายคนกำลังค้นหาไม่ทำงานเป็นวิธีแก้ปัญหา มีหลายวิธีในการบรรลุภารกิจเฉพาะ ฉันเชื่อว่ามันเกิดขึ้นที่ (พิจารณาคำถามเฉพาะ) มันเกิดขึ้นเพื่อให้ได้งานเฉพาะที่ยอดrun as background and never dieเยี่ยมสำหรับหลาย ๆ คน นอกจากนี้ยังมีโบนัสเพิ่มเติมเพื่อให้ผู้ใช้สามารถกลับไปใช้งานได้อีกครั้งและทำการเปลี่ยนแปลงหากเขาต้องการ ที่สำคัญคือชิ้นส่วนและbackground never dieโซลูชันทั้งหมดมีโบนัสแน่นอน
LD James

@ Rakshith Ravi - ฉันไม่เห็นด้วย สิ่งเหล่านี้ต้องการการดาวน์โหลดเพิ่มเติม / ซอฟต์แวร์ / เครื่องมือเพิ่มเติม (ยกเว้นโซลูชัน init ซึ่งไม่มีวิธีแก้ไข) nohup เป็นวิธีการแก้ปัญหา มันถูกอบเข้าสู่ลีนุกซ์และเป็นสิ่งที่มีอยู่ เป็นหนึ่งบรรทัดสะอาดและทำงานได้ตามที่ตั้งใจทุกครั้งโดยไม่คำนึงถึงการปรับปรุง ผู้คนควรพยายามหลีกเลี่ยงการใช้เครื่องมือของบุคคลที่สามสำหรับกรณีการใช้งานพื้นฐานเช่นนี้ ตัวอย่างนักเทียบท่า (ตัวอย่าง) เป็น verbose และทรัพยากรที่เข้มข้นมากกว่าคำสั่งง่ายๆในคำตอบที่ได้รับการโหวตสูงสุด รักนักเทียบท่า แต่ไม่ใช่สำหรับสิ่งนี้
Jack_Hu

1
@ Jack_Hu ฉันไม่มีข้อสงสัยเกี่ยวกับค่าใช้จ่าย แต่nohupวิธีการแก้ปัญหาไม่เป็นไปตามข้อกำหนด "ไม่เคยตาย" นอกจากว่าคุณจะเขียนtrapวนซ้ำไม่ จำกัด หรือแฮ็คผมก็ไม่เห็นว่าจะทำให้กระบวนการ daemonized โดยไม่ต้องใช้เครื่องมือที่เขียนขึ้นเป็นพิเศษเพื่อจุดประสงค์นี้ (หรือสคริปต์เริ่มต้นที่เขียนด้วยตัวเองแน่นอน)
Victor Schröder

24

วิธีการแก้ปัญหาอื่นปฏิเสธงาน

$ nohup node server.js &
[1] 1711
$ disown -h %1

การปฏิเสธเป็นสิ่งที่ฉันกำลังมองหา แต่แฟล็ก -h ทำอะไร ฉันหามันไม่พบในคู่มือ
Rimantas Jacikevicius

จาก man page: หากกำหนดอ็อพชัน -h ไว้แต่ละ jobspec จะไม่ถูกลบออกจากตาราง แต่ถูกทำเครื่องหมายเพื่อไม่ให้ SIGHUP ถูกส่งไปยังงานหากเชลล์ได้รับ SIGHUP หากไม่มีการระบุ jobspec ตัวเลือก -a หมายถึงการลบหรือทำเครื่องหมายงานทั้งหมด
myururdurmaz

14

nohupจะอนุญาตให้โปรแกรมดำเนินการต่อแม้ว่าเทอร์มินัลจะตาย ฉันมีสถานการณ์ที่nohupป้องกันเซสชัน SSH จากการยกเลิกอย่างถูกต้องดังนั้นคุณควรเปลี่ยนเส้นทางอินพุตด้วย:

$ nohup node server.js </dev/null &

nohupคุณอาจต้องเปลี่ยนเส้นทางเอาต์พุตมาตรฐานและข้อผิดพลาดมาตรฐานไปยังไฟล์ทั้งนี้ขึ้นอยู่กับวิธีกำหนดค่า


7

ฉันมีฟังก์ชั่นนี้ในไฟล์ shell rc ของฉันตามคำตอบของ @ Yoichi:

nohup-template () {
    [[ "$1" = "" ]] && echo "Example usage:\nnohup-template urxvtd" && return 0
    nohup "$1" > /dev/null 2>&1 &
}

คุณสามารถใช้วิธีนี้:

nohup-template "command you would execute here"

7

Nohup และหน้าจอนำเสนอโซลูชันแสงที่ยอดเยี่ยมสำหรับการเรียกใช้ Node.js ในพื้นหลัง ผู้จัดการกระบวนการ Node.js ( PM2 ) เป็นเครื่องมือที่มีประโยชน์สำหรับการปรับใช้ ติดตั้งด้วย npm ทั่วโลกในระบบของคุณ:

npm install pm2 -g

เพื่อเรียกใช้แอป Node.js เป็น daemon:

pm2 start app.js

คุณสามารถเลือกที่จะเชื่อมโยงไปยังKeymetrics.io SAAS การตรวจสอบที่ทำโดย Unitech


6
$ disown node server.js &

มันจะลบคำสั่งจากรายการงานที่ใช้งานและส่งคำสั่งไปยังพื้นหลัง



3

ในการเรียกใช้คำสั่งเป็นบริการระบบบนเดเบียนด้วย sysv init:

คัดลอกสคริปต์โครงกระดูกและปรับให้เข้ากับความต้องการของคุณอาจเป็นสิ่งที่คุณต้องทำคือการตั้งค่าตัวแปรบางอย่าง สคริปต์ของคุณจะสืบทอดค่าเริ่มต้นที่ดี/lib/init/init-d-scriptหากมีบางอย่างไม่ตรงกับความต้องการของคุณ - แทนที่สคริปต์นั้นในสคริปต์ของคุณ /lib/init/init-d-scriptถ้ามีอะไรผิดพลาดคุณสามารถดูรายละเอียดแหล่งที่มา vars บังคับอยู่และDAEMON NAMEสคริปต์จะใช้start-stop-daemonเพื่อเรียกใช้คำสั่งของคุณในSTART_ARGSคุณสามารถกำหนดพารามิเตอร์เพิ่มเติมของstart-stop-daemonการใช้

cp /etc/init.d/skeleton /etc/init.d/myservice
chmod +x /etc/init.d/myservice
nano /etc/init.d/myservice

/etc/init.d/myservice start
/etc/init.d/myservice stop

นั่นคือวิธีที่ฉันใช้งานไพ ธ อนสำหรับวิกิมีเดียของฉัน:

...
DESC="mediawiki articles converter"
DAEMON='/home/mss/pp/bin/nslave'
DAEMON_ARGS='--cachedir /home/mss/cache/'
NAME='nslave'
PIDFILE='/var/run/nslave.pid'
START_ARGS='--background --make-pidfile --remove-pidfile --chuid mss --chdir /home/mss/pp/bin'

export PATH="/home/mss/pp/bin:$PATH"

do_stop_cmd() {
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \
        $STOP_ARGS \
        ${PIDFILE:+--pidfile ${PIDFILE}} --name $NAME
    RETVAL="$?"
    [ "$RETVAL" = 2 ] && return 2
    rm -f $PIDFILE
    return $RETVAL
}

นอกจากนี้การตั้งค่า vars ฉันต้องแทนที่do_stop_cmdเพราะ python แทนการปฏิบัติการดังนั้นการบริการไม่ได้หยุดอย่างถูกต้อง


3

นอกเหนือจากวิธีแก้ปัญหาที่ยอดเยี่ยมที่ฉันได้พูดถึงยังเกี่ยวกับเครื่องมือ supervisord และ monit ที่อนุญาตให้เริ่มกระบวนการตรวจสอบสถานะและเริ่มต้นถ้ามันตาย ด้วย 'monit' คุณสามารถเรียกใช้การตรวจสอบที่ใช้งานอยู่ได้เช่นตรวจสอบว่ากระบวนการตอบสนองการร้องขอ http หรือไม่


3

สำหรับ Ubuntu ฉันใช้สิ่งนี้:

(exec PROG_SH &> / dev / null &)

ความนับถือ


จุดเล็ก ๆ น้อย ๆ : 'exec' ไม่จำเป็นถ้า PROG_SH สามารถใช้งานได้ ประเด็นของการแก้ปัญหาที่ David เสนอให้คือการยกเลิกการเชื่อมโยงเด็กจากเชลล์ที่รันอยู่ในปัจจุบัน ผู้ปกครองของเด็กกลายเป็น 'pid 1' และจะไม่ได้รับผลกระทบเมื่อเชลล์ยุติ
SoloPilot

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.