Bắt đầu theo dõi PID sai quy trình - không hồi sinh


11

Ban đầu tôi đã hỏi câu hỏi này trên StackOverflow. Sau đó nhận ra rằng đây có lẽ là một nơi tốt hơn.

Tôi có thiết lập bluepill để theo dõi các quá trình delay_job của mình. (Ứng dụng Ruby On Rails)

Sử dụng Ubuntu 12.10.

Tôi đang bắt đầu và theo dõi chính dịch vụ bluepill bằng Ubuntu upstart. Cấu hình khởi động của tôi là dưới đây ( /etc/init/bluepill.conf).

description "Start up the bluepill service"

start on runlevel [2]
stop on runlevel [016]

expect daemon
exec sudo /home/deploy/.rvm/wrappers/<app_name>/bluepill load /home/deploy/websites/<app_name>/current/config/server/staging/delayed_job.bluepill

# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn

Tôi cũng đã thử với expect forkthay vì expect daemon. Tôi cũng đã cố gắng loại bỏ expect...hoàn toàn dòng.

Khi máy khởi động, bluepill khởi động tốt.

$ ps aux | grep blue
root      1154  0.6  0.8 206416 17372 ?        Sl   21:19   0:00 bluepilld: <app_name>

PID của quá trình bluepill là 1154 ở đây. Nhưng upstartdường như đang theo dõi các PID sai. Nó đang theo dõi một PID không tồn tại.

$ initctl status bluepill
bluepill start/running, process 990

Tôi nghĩ rằng nó đang theo dõi PID của sudoquá trình bắt đầu quá trình bluepill.

Điều này đang ngăn quá trình bluepill không được hồi sinh nếu tôi mạnh tay giết bluepill bằng cách sử dụng kill -9.

Hơn nữa, tôi nghĩ rằng do PID bị theo dõi sai, khởi động lại / tắt máy chỉ bị treo và tôi phải cứng thiết lập lại máy mỗi lần.

Điều gì có thể là vấn đề ở đây?

CẬP NHẬT :

Vấn đề vẫn còn cho đến ngày hôm nay (3/5/2015) trên Ubuntu 14.04.2.

Vấn đề không phải là do sử dụng sudo. Tôi không sử dụng sudo nữa. Cấu hình mới nhất được cập nhật của tôi là:

description "Start up the bluepill service"

start on runlevel [2]
stop on runlevel [016]

# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn

# Give up if restart occurs 10 times in 90 seconds.
respawn limit 10 90

expect daemon

script
    shared_path=/home/deploy/websites/some_app/shared

    bluepill load $shared_path/config/delayed_job.bluepill
end script

Khi máy khởi động, chương trình tải lên tốt. Nhưng mới bắt đầu vẫn theo dõi sai PID, như được mô tả ở trên.

Cách giải quyết được đề cập trong các ý kiến ​​có thể khắc phục vấn đề treo. Tôi đã không thử nó, mặc dù.


Bạn đã thử xem quy trình 990 là gì chưa? ps aux | grep 990nên làm điều đó nhưng pstree 990có thể nhiều thông tin hơn.
Oli

Không có quá trình với PID của 990 tồn tại.
Anjan

2
khi cần khởi động lại để trở lại trạng thái tốt - hãy xem công cụ tuyệt vời này: github.com/ion1/workaround-upstart-snafu
andersonbd1

và bạn có thể tăng tốc công cụ đó bằng lệnh này: $ echo 3000 | sudo tee / Proc / sys / kernel / pid_max
andersonbd1

Câu trả lời:


8

Khá muộn, nhưng hy vọng điều này có thể giúp ích cho những người dùng khác.

Có một lỗi được ghi lại trong phần khởi động có thể khiến initctl theo dõi sai PID nếu bạn chỉ định khổ forkthơ không chính xác trong cấu hình khởi động: https://bugs.launchpad.net/upstart/+bug/406394

Điều gì xảy ra là khởi động kiểm tra khổ forkthơ và xác định có bao nhiêu quá trình rẽ nhánh cần kiểm tra trước khi chọn PID "thực" của chương trình được điều khiển. Nếu bạn chỉ định expect forkhoặc expect daemonnhưng chương trình của bạn không đủ số lần, startsẽ bị treo. Mặt khác, nếu quá trình của bạn thực hiện quá nhiều lần, initctlsẽ theo dõi sai PID. Về mặt lý thuyết, nó nên được ghi lại trong phần này của cuốn sách dạy nấu ăn mới nổi , nhưng như bạn có thể thấy trong tình huống này, có một PID liên quan đến quá trình bị giết khi không nên có.

Ý nghĩa của việc này được giải thích trong các bình luận về bugtracker, nhưng tôi sẽ tóm tắt ở đây: bên cạnh việc initctlkhông thể dừng quá trình trình nền và bị mắc kẹt trong trạng thái không có giấy tờ / bất hợp pháp <service> start/killed, process <pid>, nếu quá trình thuộc về PID đó dừng lại (và nó thường sẽ ) sau đó hệ thống được giải phóng để hệ thống sử dụng lại.

Nếu bạn phát hành initctl stop <service>hoặc service <service> stop, initctlsẽ giết chết PID đó vào lần tiếp theo. Điều này có nghĩa là, ở một nơi nào đó trên đường nếu bạn không khởi động lại sau khi mắc lỗi này, quá trình tiếp theo để sử dụng PID đó sẽ bị giết ngay lập tức initctlmặc dù nó sẽ không phải là daemon. Nó có thể là một cái gì đó đơn giản cathoặc phức tạp như vậy ffmpeg, và bạn sẽ có một thời gian khó khăn để tìm ra lý do tại sao gói phần mềm của bạn bị hỏng giữa một số hoạt động thường ngày.

Vì vậy, vấn đề là bạn đã chỉ định expecttùy chọn sai cho số lượng dĩa mà quy trình trình nền của bạn thực sự tạo ra. Họ nói rằng có một bản viết lại mới nhất giải quyết vấn đề này, nhưng kể từ phiên bản 1.8 (phiên bản Ubuntu 13.04 / tháng 1 năm 2014 mới nhất), vấn đề vẫn còn.

Vì bạn đã sử dụng expect daemonvà kết thúc với vấn đề này, tôi khuyên bạn nên thử expect fork.

Chỉnh sửa: Đây là tập lệnh tương thích với Ubuntu BASH ( bản gốc của Wade Fitzpatrick đã sửa đổi để sử dụng Ubuntu sleep), sinh ra các quy trình cho đến khi không gian địa chỉ ID quy trình có sẵn bị cạn kiệt, tại thời điểm đó, nó bắt đầu trở về 0 và hoạt động theo cách "bị kẹt" PID. Một quá trình sau đó được sinh ra tại PID initctlđược treo lên và initctlgiết chết nó và đặt lại.

#!/bin/bash

# usage: sh /tmp/upstart_fix.sh <pid>

sleep 0.001 &
firstPID=$!
#first lets exhaust the space
while (( $! >= $firstPID ))
do
    sleep 0.001 &
done

# [ will use testPID itself, we want to use the next pid
declare -i testPID
testPID=$(($1 - 1))
while (( $! < $testPID ))
do
    sleep 0.001 &
done

# fork a background process then die so init reaps its pid
sleep 3 &
echo "Init will reap PID=$!"
kill -9 $$
# EOF

Câu trả lời này có một số thông tin hữu ích và thú vị tuy nhiên tôi không rõ câu trả lời này trả lời câu hỏi ban đầu như @Anjan đã đề cập "Tôi cũng đã thử với ngã ba kỳ vọng thay vì daemon mong đợi. "
user12345

5

Đối với ví dụ được cung cấp:

$ initctl status bluepill
bluepill start/running, process 990

một giải pháp nhanh chóng cho tôi là:

# If upstart gets stuck for some job in stop/killed state
export PID=990
cd /usr/local/bin
wget https://raw.github.com/ion1/workaround-upstart-snafu/master/workaround-upstart-snafu
chmod +x workaround-upstart-snafu
./workaround-upstart-snafu $PID

nguồn: https://bugs.debian.org/cgi-bin/orpreport.cgi?orms=582745#37

Tôi hy vọng điều này sẽ có ích. Những gì đang xảy ra được giải thích trong các câu trả lời khác.


Kịch bản hay. Điều này có thể mất một hoặc hai phút. A rebootđôi khi có thể được ưa thích hơn và cũng sửa lỗi này.
Peter Ilfrich

0

Trừ khi bạn đang chạy một công việc ở cấp độ người dùng mới bắt đầu hoặc sử dụng khổ thơ setuid - thì công việc của bạn đang chạy dưới quyền root.

Vì Upstart đã chạy bằng root, tại sao bạn cần sử dụng sudo trong khổ execthơ của mình ?

Sử dụng sudohoặc sutrong khổ execthơ đã gây ra những vấn đề tương tự cho tôi như bạn mô tả ở đây.

Thông thường tôi sẽ trải nghiệm mục 1 HOẶC cả 1 VÀ 2:

  1. khởi động theo sau PID không chính xác
  2. khởi động bị treo khi tôi cố gắng dừng quá trình

Tất nhiên, ngoài ra, bạn phải có khổ expectthơ phản ánh đúng số lượng dĩa.

YMMV, nhưng đối với tôi:

  • sử dụng sudo hoặc su trong khổ execthơ với số lượng dĩa chính xác được chỉ định thường dẫn đến tình huống 1 ở trên.
  • số lượng dĩa được chỉ định không chính xác (không có sudo / su của chúng tôi exec) dẫn đến tình huống 1 VÀ 2 ở trên.
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.