Làm cách nào để chạy Node.js làm quy trình nền và không bao giờ chết?


480

Tôi kết nối với máy chủ linux thông qua SSH putty. Tôi đã cố chạy nó như một quá trình nền như thế này:

$ node server.js &

Tuy nhiên, sau 2,5 giờ thiết bị đầu cuối không hoạt động và quá trình này chết. Có dù sao tôi có thể giữ cho quá trình sống ngay cả khi thiết bị đầu cuối bị ngắt kết nối?


Chỉnh sửa 1

Trên thực tế, tôi đã thử nohup, nhưng ngay khi tôi đóng thiết bị đầu cuối SSH Putty hoặc rút phích cắm internet của tôi, quá trình máy chủ dừng lại ngay lập tức.

Có điều gì tôi phải làm ở Putty không?


Chỉnh sửa 2 (vào tháng 2 năm 2012)

Có một node.jsmô-đun, mãi mãi . Nó sẽ chạy máy chủ node.js dưới dạng dịch vụ daemon.


7
Trong trường hợp của tôi, nohup hoạt động khi tôi thoát Terminal bằng cách gõ exit. Khi tôi chỉ đóng cửa sổ Putty thì thất bại.
Pawel Furmaniak

Câu trả lời:


513

Giải pháp đơn giản (nếu bạn không quan tâm đến việc quay lại quy trình, chỉ muốn nó tiếp tục chạy):

nohup node server.js &

Ngoài ra còn có jobslệnh để xem danh sách được lập chỉ mục của các quá trình nền. Và bạn có thể giết một tiến trình nền bằng cách chạy kill %1hoặc kill %2với số là chỉ số của tiến trình.

Giải pháp mạnh mẽ (cho phép bạn kết nối lại với quy trình nếu nó tương tác):

screen

Sau đó, bạn có thể tách ra bằng cách nhấn Ctrl + a + d và sau đó đính kèm lại bằng cách chạy screen -r

Cũng xem xét thay thế mới hơn cho màn hình, tmux.


1
Vì vậy, nếu tôi chạy "màn hình", tôi tạo màn hình và chạy bên trong nó, phải không?
murvinlai

30
có và sau đó bạn có thể tách ra bằng cách nhấn Ctrl + a, d và sau đó đính kèm lại bằng cách chạy màn hình -r
MK.

1
@murvinlai EC2 là một môi trường và không liên quan gì đến đặc quyền root. Có lẽ là về AMI của bạn. Ví dụ với Amazon AMI bạn chắc chắn có thể sudo bash.
ShuaiYuan

1
man bash: Nếu một lệnh bị chấm dứt bởi toán tử điều khiển &, shell sẽ thực thi lệnh trong nền trong một lớp con. Shell không chờ lệnh kết thúc và trạng thái trả về là 0.
MK.

34
Xin vui lòng, với bất cứ ai đọc điều này: chạy máy chủ node.js bên trong màn hình hoặc phiên tmux là một giải pháp AMATEUR ! Đừng làm điều đó, trừ khi để kiểm tra nhanh. Để giữ cho một quá trình chạy, bạn cần phải daemon nó! Sử dụng các công cụ thích hợp cho nó, như mãi mãi , pm2 hoặc các tập lệnh init.d cũ đơn giản .
Victor Schröder

1119

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

  1. nohupcó nghĩa là: Không chấm dứt quá trình này ngay cả khi stty bị cắt.
  2. > /dev/null có nghĩa: thiết bị xuất chuẩn đi đến / dev / null (là một thiết bị giả không ghi lại bất kỳ đầu ra nào).
  3. 2>&1 có nghĩa: thiết bị xuất chuẩn cũng đi đến thiết bị xuất chuẩn (đã được chuyển hướng đến /dev/null). Bạn có thể thay thế & 1 bằng đường dẫn tệp để ghi nhật ký lỗi, ví dụ:2>/tmp/myLog
  4. &ở cuối có nghĩa là: chạy lệnh này như một nhiệm vụ nền.

49
Đây phải là câu trả lời được chấp nhận, bởi vì nó có chất lượng cao hơn nhiều so với câu trả lời hiện được chấp nhận.
L0j1k

2
@ L0j1k gây tranh cãi, OP đã chứng minh một mức độ hiểu rằng cần phải có giải thích thêm cho câu trả lời được chấp nhận.
JFA

41
SO không nói về OP nhiều như hàng ngàn người đến câu hỏi của OP để được giúp đỡ.
L0j1k

3
Có cần thiết phải chuyển hướng stdout và stderr? Nó có hoạt động tốt không nếu tôi không chuyển hướng chúng? Hoặc nếu tôi chuyển hướng chúng vào các tập tin thay thế?
Shawn

10
Gửi stdout VÀ stderr đến /dev/null? Chúc mừng đăng nhập ... Chúc may mắn khi cố gắng gỡ lỗi này ...
Victor Schröder

138

Bạn thực sự nên cố gắng sử dụng screen. Nó phức tạp hơn một chút so với chỉ làm nohup long_running &, nhưng hiểu màn hình một khi bạn không bao giờ quay lại nữa.

Bắt đầu phiên màn hình của bạn lúc đầu:

user@host:~$ screen

Chạy bất cứ thứ gì bạn muốn:

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

Nhấn ctrl + A và sau đó d. Làm xong. Phiên của bạn tiếp tục trong nền.

Bạn có thể liệt kê tất cả các phiên theo screen -lsvà đính kèm một số bằng screen -r 20673.pts-0.srvlệnh, trong đó 0673.pts-0.srv là danh sách mục nhập.


125

Đây là một câu hỏi cũ, nhưng được xếp hạng cao trên Google. Tôi gần như không thể tin vào các câu trả lời được bình chọn cao nhất, bởi vì chạy quy trình node.js bên trong phiên màn hình, với &hoặc thậm chí vớinohup cờ - tất cả chúng - chỉ là cách giải quyết.

Đặc biệt là giải pháp màn hình / tmux, thực sự nên được coi là một giải pháp nghiệp dư . Màn hình và Tmux không có nghĩa là để giữ cho các quy trình hoạt động, nhưng cho các phiên thiết bị đầu cuối ghép kênh. Thật tốt, khi bạn đang chạy một tập lệnh trên máy chủ của mình và muốn ngắt kết nối. Nhưng đối với máy chủ node.js, bạn không muốn quy trình của mình được gắn vào phiên cuối. Điều này quá mong manh. Để giữ cho mọi thứ chạy, bạn cần phải tiến hành quá trình!

Có rất nhiều công cụ tốt để làm điều đó.

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

Một lợi thế lớn mà tôi thấy có lợi cho PM2 là nó có thể tạo tập lệnh khởi động hệ thống để duy trì quá trình giữa các lần khởi động lại:

$ pm2 startup [platform]

Nơi platformcó thể ubuntu|centos|redhat|gentoo|systemd|darwin|amazon.

ever.js : https://github.com/forverjs/forver

# 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

Kịch bản ban đầu :

Tôi không đi sâu vào chi tiết về cách viết tập lệnh init, bởi vì tôi không phải là chuyên gia trong chủ đề này và nó quá dài cho câu trả lời này, nhưng về cơ bản chúng là các tập lệnh shell đơn giản, được kích hoạt bởi các sự kiện OS. Bạn có thể đọc thêm về điều này ở đây

Docker :

Chỉ cần chạy máy chủ của bạn trong bộ chứa Docker với -dtùy chọn và, voilá , bạn có một máy chủ node.js được daemonized!

Dưới đây là một Dockerfile mẫu (từ hướng dẫn chính thức của 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" ]

Sau đó, xây dựng hình ảnh của bạn và chạy container của bạn:

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

Hy vọng điều này sẽ giúp ai đó hạ cánh trên trang này. Luôn luôn sử dụng các công cụ thích hợp cho công việc. Nó sẽ giúp bạn tiết kiệm rất nhiều đau đầu và qua nhiều giờ!


2
Đây là những gì tôi đang tìm kiếm. Với giải pháp pm2, có cách nào để gắn thiết bị đầu cuối vào nó sau này không?
Lượng tử hóa

4
@Quantumplation, không. Điều đó là không thể vì quy trình không chạy trong phiên tương tác. Nhưng bạn có thể có "cảm giác" tương tự bằng cách tail -fnhập tệp nhật ký mà pm2 tạo ra.
Victor Schröder

1
Bạn chỉ định screengiải pháp mà nhiều người đang tìm kiếm thực hiện công việc là một cách giải quyết. Có rất nhiều cách để đạt được một nhiệm vụ cụ thể. Tôi tin rằng nó xảy ra rằng (xem xét câu hỏi cụ thể) nó sẽ đạt được nhiệm vụ cụ thể xuất sắc run as background and never diecho nhiều người. Nó cũng có thêm phần thưởng cho phép người dùng quay lại để tương tác lại và thực hiện các thay đổi nếu anh ta muốn. Chìa khóa là các thành phần là backgroundnever die. Tất cả các giải pháp đều có tiền thưởng nhất định.
LD James

@Rakshith Ravi - Tôi không đồng ý. Tất cả đều yêu cầu tải xuống / phần mềm / công cụ bổ sung (ngoại trừ giải pháp init, không có giải pháp nào được đưa ra). Đây nohup giải pháp. Nó được đưa vào Linux, và đó là những gì nó dành cho. Đó là một dòng, nó sạch sẽ, và nó hoạt động như dự định, mọi lúc, bất kể cập nhật. Mọi người nên thực sự cố gắng tránh sử dụng các công cụ của bên thứ ba cho các trường hợp sử dụng cơ bản như thế này. Ví dụ về docker (ví dụ) dài dòng và tài nguyên chuyên sâu hơn rất nhiều so với một lệnh đơn giản trong câu trả lời được bình chọn hàng đầu. Docker tình yêu, nhưng không phải vì điều này.
Jack_Hu

1
@Jack_Hu, tôi không nghi ngờ gì về chi phí, nhưng nohupgiải pháp không thỏa mãn yêu cầu "không bao giờ chết". Trừ khi bạn viết một trapvòng lặp vô cùng phức tạp hoặc khó khăn , tôi không thấy làm thế nào để giữ tiến trình được trình bày mà không sử dụng các công cụ được viết đặc biệt cho mục đích này (tất nhiên là một đoạn script do chính bạn viết).
Victor Schröder

24

một giải pháp khác từ chối công việc

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

từ chối chính xác là những gì tôi đang tìm kiếm, nhưng cờ -h làm gì? Tôi không thể tìm thấy nó trong hướng dẫn
Rimantas Jacikevicius

từ trang man: Nếu tùy chọn -h được đưa ra, mỗi jobspec sẽ không bị xóa khỏi bảng, nhưng được đánh dấu để SIGHUP không được gửi đến công việc nếu shell nhận được SIGHUP. Nếu không có jobspec nào được cung cấp, tùy chọn -a có nghĩa là loại bỏ hoặc đánh dấu tất cả các công việc;
myururdurmaz

14

nohupsẽ cho phép chương trình tiếp tục ngay cả sau khi thiết bị đầu cuối chết. Tôi thực sự đã có tình huống nohupngăn phiên SSH kết thúc chính xác, vì vậy bạn cũng nên chuyển hướng đầu vào:

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

Tùy thuộc vào cách nohupcấu hình, bạn cũng có thể cần chuyển hướng đầu ra tiêu chuẩn và lỗi tiêu chuẩn sang các tệp.


7

Tôi có chức năng này trong tệp RC shell của mình, dựa trên câu trả lời của @ Yoichi:

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

Bạn có thể sử dụng nó theo cách này:

nohup-template "command you would execute here"

7

Nohup và màn hình cung cấp các giải pháp ánh sáng tuyệt vời để chạy Node.js trong nền. Trình quản lý quy trình Node.js ( PM2 ) là một công cụ tiện dụng để triển khai. Cài đặt nó với npm trên toàn cầu trên hệ thống của bạn:

npm install pm2 -g

để chạy ứng dụng Node.js dưới dạng daemon:

pm2 start app.js

Bạn có thể tùy ý liên kết nó với Keymetrics.io một SAAS giám sát được thực hiện bởi Unitech.


6
$ disown node server.js &

Nó sẽ xóa lệnh khỏi danh sách tác vụ đang hoạt động và gửi lệnh đến nền



3

Để chạy lệnh như một dịch vụ hệ thống trên debian với sysv init:

Sao chép tập lệnh bộ xương và điều chỉnh nó cho nhu cầu của bạn, có lẽ tất cả những gì bạn phải làm là đặt một số biến. Tập lệnh của bạn sẽ kế thừa các giá trị mặc định tốt /lib/init/init-d-script, nếu có gì đó không phù hợp với nhu cầu của bạn - ghi đè lên tập lệnh của bạn. Nếu có lỗi xảy ra, bạn có thể xem chi tiết trong nguồn /lib/init/init-d-script. Vars bắt buộc là DAEMONNAME. Script sẽ sử dụng start-stop-daemonđể chạy lệnh của bạn, trong đó START_ARGSbạn có thể xác định các tham số bổ sung start-stop-daemonđể sử dụng.

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

Đó là cách tôi chạy một số nội dung python cho wiki wikidia của mình:

...
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
}

Bên cạnh việc cài đặt vars, tôi phải ghi đè do_stop_cmdvì python thay thế tệp thực thi, vì vậy dịch vụ không dừng đúng cách.


3

Ngoài các giải pháp tuyệt vời ở trên, tôi cũng đề cập đến các công cụ giám sát và monit cho phép bắt đầu quá trình, theo dõi sự hiện diện của nó và khởi động nó nếu nó chết. Với 'monit', bạn cũng có thể chạy một số kiểm tra hoạt động như kiểm tra xem quy trình có đáp ứng yêu cầu http không


3

Đối với Ubuntu tôi sử dụng cái này:

(thực hiện PROG_SH &> / dev / null &)

Trân trọng


Điểm nhỏ: 'exec' là không cần thiết nếu PROG_SH là một tệp thực thi. Quan điểm của giải pháp mà David đề xuất là tách đứa trẻ ra khỏi vỏ đang chạy. Cha mẹ của đứa trẻ trở thành 'pid 1' và sẽ không bị ảnh hưởng khi vỏ kết thúc.
SoloPilot

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.