Ketika proses menerima SIGTERM
, itu harus ditutup dan ditutup, dengan operasi sesedikit mungkin dan tanpa mencetak apa pun.
Proses werkzeug.serving.run_simple
menerima SIGTERM
biasanya menghasilkan kode yang dikembalikan 141 (gejala gagal penanganan SIGPIPE
), dan saat menggunakan reloader prosesnya menjadi zombie ( untuk dibunuh secara manual, karena port tetap terikat).
Menambahkan penangan sinyal untuk SIGTERM
yang hanya memanggil sys.exit(0)
sudah cukup untuk memperbaiki masalah (karena tidak ada lagi kesalahan dalam prosesnya), tetapi saya tidak yakin itu adalah perbaikan yang benar.
Saya mengikat penangan sinyal sekarang saat dijalankan dengan reloader. Semoga membantu.
Dalam versi apa perbaikan ini? Ini masih menjadi masalah di Flask 0.8.
Ini masih menjadi masalah, cukup mengganggu saat menggunakan Flask dengan IDE - setiap kali Anda berhenti men-debug, proses tetap ada dan terus melayani permintaan.
Saya membuka kembali masalah ini karena tampaknya masih ada, lihat diskusi berikut dari IRC hari ini.
20:20 < mcdonc> can somebody fix flask's reloader so when you send the process a sigint it actually stops the child process
20:20 < untitaker> mcdonc: it seems to work for me
20:21 < untitaker> mcdonc: it used to cause problems but for me it's fixed in latest master
20:21 < mcdonc> ah good. i just got some number of complaints from people who run it under supervisor.
20:22 < untitaker> mcdonc: you are talking about the one from the Py3 port?
20:22 < untitaker> released versions should work properly
20:22 < mcdonc> no.. i am talking about.. well.. yes, i dont actually know what i'm talking about ;-) i dont use it, i just get people telling me they need to send a stop signal to the entire process group instead of to the process to make sure its killed.
20:23 < mcdonc> this is not recent.. for the last year or so
20:23 < mcdonc> why people run the reloader under supervisor (presumably in production) i cannot fathom
20:23 < mcdonc> but they do
20:24 < Alex_Gaynor> mcdonc: I've toyed with using supervisord in dev, FWIW
20:24 < Alex_Gaynor> mcdonc: for cases where you don't just have web proc, you've also got background daemons and such, it could be nice
[...]
20:32 < DasIch> untitaker: the supervisor issue is independent from the threading/thread issue
20:32 < untitaker> DasIch: ah okay
20:32 < untitaker> didn't know that
20:32 < untitaker> DasIch: is the reloader behaving weird in supervisor?
20:33 < DasIch> untitaker: I guess what happens if you run the reloader in supervisor is that supervisor kill the reloading process but that doesn't kill the process started by the reloader
20:34 < untitaker> DasIch: couldn't one write a wrapper shell script that kills both?
20:34 < untitaker> at least for now
20:34 < DasIch> untitaker: I think you shouldn't use the reloader in production
20:35 < untitaker> well yeah
20:35 < asdf`> (supervisord has a 'kill as group' thing)
20:35 < DasIch> right there is that as well
20:35 < asdf`> (it even mentions the werkzeug reloader in the docs paragraph about it!)
20:36 < mcdonc> yes i put it there
20:37 < asdf`> (then you might want to fix it, because AFAIR it actually says 'flask', while the reloader is part of werkzeug. But i admit 'flask' is something more people will know)
20:37 < mcdonc> nobody reads docs anyway ;)
20:38 < DasIch> I just wanted to mention I don't care unless someone creates an issue with a valid use case for that but apparently this seems to be it https://github.com/mitsuhiko/werkzeug/issues/58
20:38 < mcdonc> like alex said, it's not entirely crazy to want to use the reloader under supervisor in dev, esp. if your app is reliant on other processes being started
20:39 < mcdonc> i actually dont run my own apps under supervisor, but that's because i don't use a reloader, i just press ctrl-c.. because i'm a savage
20:40 < DasIch> I do use the reloader but I tend to save so often with bad syntax that I end up restarting manually all the time
Saya pikir itu masih relevan.
Melakukan os.kill(parent_id, signal.SIGTERM)
tidak membunuh proses anak-anak.
Saya mengalami masalah ini juga saat mengerjakan ulang testsuite untuk werkzeug.serving
. Saya mengatasinya dengan mematikan seluruh grup proses: https://github.com/mitsuhiko/werkzeug/blob/a00377315bbf02ec48fdad22c6bb08433fc1e9c1/tests/conftest.py#L158
Saya mengalami masalah yang sama di Flask dengan mode debug (use_debugger = True). Namun, saya melihat kode pengembalian 0 pada proses "induk". Tanpa mode debug diaktifkan, SIGTERM bekerja dengan baik dan proses keluar dengan kode 143. Python 2.7.5.
Terkena bug ini juga, dalam kasus saya docker stop
mengirim SIGTERM
ke server bertenaga werkzeug (moto), tetapi server mengabaikan dan kemudian buruh pelabuhan membunuhnya dengan SIGKILL
dihasilkan menjadi kode keluar bukan nol.
Solusinya adalah dengan menentukan SIGINT
(Ctrl + C) sebagai sinyal stop yang disukai di Dockerfile ( STOPSIGNAL SIGINT
), setelah itu kontainer ditutup dengan bersih.
Saya memiliki masalah yang sama saat menjalankan aplikasi Flask di dalam Docker; namun, STOPSIGNAL SIGINT
masih belum cukup untuk menghentikan penampung. Saya harus menggunakan SIGKILL
.
Saya tidak dapat membuat ulang masalah tersebut. Saya telah mencoba ini dengan wadah Python resmi dengan tag 2.7 dan 3.7. Saya menggunakan Dockerfile berikut:
FROM python:2.7
WORKDIR /usr/src/app
RUN pip install click \
werkzeug \
sqlalchemy \
jinja2
COPY . .
RUN python manage-shorty.py initdb
ENTRYPOINT ["python"]
CMD ["manage-shorty.py", "runserver"]
Dan membangun kontainer dari Dockerfile di direktori examples
dengan perintah:
docker build -t werkzeug-examples .
Saya kemudian akan menjalankan penampung dalam mode interaktif dan membatalkan dengan:
$ docker run -it --name werkzeug-example werkzeug-examples
* Running on http://localhost:5000/ (Press CTRL+C to quit)
* Restarting with stat
^C
Menjalankan docker ps
menunjukkan keluar dengan 0
:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8c708ea4ef77 werkzeug-examples "python manage-short…" About a minute ago Exited (0) 58 seconds ago werkzeug-example
Menjalankan wadah dan berhenti dengan docker stop werkzeug-example
juga keluar dengan 0
.
Berikut adalah hasil dari Versi Docker di komputer saya menjalankan perintah ini:
Client: Docker Engine - Community
Version: 18.09.2
API version: 1.39
Go version: go1.10.8
Git commit: 6247962
Built: Sun Feb 10 04:12:39 2019
OS/Arch: darwin/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.2
API version: 1.39 (minimum version 1.12)
Go version: go1.10.6
Git commit: 6247962
Built: Sun Feb 10 04:13:06 2019
OS/Arch: linux/amd64
Experimental: false
Dapatkah Anda memberikan contoh yang dapat mereproduksi masalah yang Anda alami?
Sampai kita bisa mendapatkan skenario yang dapat direproduksi, saya akan menutup ini karena tidak dapat direproduksi di versi terbaru Docker dan Werkzeug.
Komentar yang paling membantu
Terkena bug ini juga, dalam kasus saya
docker stop
mengirimSIGTERM
ke server bertenaga werkzeug (moto), tetapi server mengabaikan dan kemudian buruh pelabuhan membunuhnya denganSIGKILL
dihasilkan menjadi kode keluar bukan nol.Solusinya adalah dengan menentukan
SIGINT
(Ctrl + C) sebagai sinyal stop yang disukai di Dockerfile (STOPSIGNAL SIGINT
), setelah itu kontainer ditutup dengan bersih.