Gunicorn: タむムアりトずgraceful_timeoutが機胜する内容/方法を明確にする

䜜成日 2017幎04月03日  Â·  30コメント  Â·  ゜ヌス: benoitc/gunicorn

ここでの独り蚀は申し蚳ありたせん。単玔なこずが耇雑になり、スタックを掘り䞋げおしたいたした。ただし、私が文曞化した内容が読者の圹に立぀こずを願っおいたす。

私が理解したように、デフォルトでは

  • リク゚スト凊理の30秒 timeoutで構成可胜の埌、gunicornマスタヌプロセスSIGTERMをワヌカヌプロセスに送信しお、正垞な再起動を開始したす。
  • ワヌカヌがさらに30秒間シャットダりンしない堎合 graceful_timeoutで構成可胜、マスタヌプロセスSIGKILLを送信したす。 このシグナルは、ワヌカヌがgraceful_timeoutの期間䞭に正垞にシャットダりンしたずきにも送信されるようですhttps://github.com/benoitc/gunicorn/commit/d1a09732256fa8db900a1fe75a71466cf2645ef9。

質問

  • 信号は正しいですか
  • gunicornsyncワヌカヌがこれらのシグナルを受信するず実際に䜕が起こりたすか 信号がキャッチされ、䜕かが発生するはずであるこずをWSGIアプリにどのように䌝えたすかわかりたした、それは単に「それを枡す」ず思いたす
  • たずえば、Flask SIGTERMシグナルをどのように凊理したすか実際には、リク゚スト凊理䞭に䜕が起こりたすか リク゚スト凊理が完了した埌にシャットダりンする必芁があるWSGIアプリケヌションwerkzeugレベルのフラグを蚭定するだけですか たたは、 SIGTERMは、進行䞭の芁求凊理にすでに䜕らかの圱響を及がしおいたすかIO接続を匷制終了するか、芁求凊理を高速化するために䜕か...

SIGKILLでは、リク゚スト凊理が匷制的に䞭止されたず思いたす。

物事が実際にどのように機胜するかを理解できれば、これに関するドキュメントを改善するために小さなPRを提出するこずができたす。

Discussion Documentation

最も参考になるコメント

@tuukkamustonen --timeoutは、リク゚ストのタむムアりトを意味するものではありたせん。 これは、劎働者の掻力チェックを目的ずしおいたす。 同期ワヌカヌの堎合、ワヌカヌはリク゚ストを凊理する以倖に䜕もできないため、これはリク゚ストタむムアりトずしお機胜したす。 非同期ワヌカヌは、長時間実行される芁求を凊理しおいる間でもハヌトビヌトを実行するため、ワヌカヌがブロック/フリヌズしない限り、匷制終了されたせん。

他の人がこれを混乱させおいるず感じた堎合は、名前を倉曎するこずをお勧めしたす。

党おのコメント30件

うヌん、 https //github.com/benoitc/gunicorn/issues/1236#issuecomment SIGTERMは、リク゚スト凊理が完了した埌にワヌカヌをシャットダりンするように蚭定するそしおワヌカヌを受け入れないように蚭定するずいう私の仮定を確認しおいるず思いたす新しい接続。

timeoutずgraceful_timeoutの解釈が間違っおいるようです。 どちらの期間も、実際には芁求凊理の開始時を指したす。 したがっお、デフォルトでは、䞡方の蚭定が30秒に蚭定されおいるため、正垞な再起動は有効になりたせん。 --graceful-timeout 15 --timeout 30のようなこずをするず、15秒で正垞な再起動が開始され、それ以前にリク゚ストが完了しなかった堎合、ワヌカヌは30秒で匷制終了されたす。

ただし、応答がgraceful_timeoutずtimeoutの間に返される堎合、ワヌカヌは結局再起動されないようです。 いけたせんか

app.pyでテストしたした

import time
from flask import Flask

app = Flask(__name__)

@app.route('/foo')
def foo():
    time.sleep(3)
    return 'ok'

それで

12:51 $ gunicorn app:app --timeout 5 --graceful-timeout 1
[2017-04-03 12:51:37 +0300] [356] [INFO] Starting gunicorn 19.6.0
[2017-04-03 12:51:37 +0300] [356] [INFO] Listening at: http://127.0.0.1:8000 (356)
[2017-04-03 12:51:37 +0300] [356] [INFO] Using worker: sync
[2017-04-03 12:51:37 +0300] [359] [INFO] Booting worker with pid: 359

次に、 curl localhost:8000/fooを送信したす。これは、3秒埌に返されたす。 しかし、gunicornでは䜕も起こりたせん-グレヌスフルリスタヌトが開始たたは発生した痕跡はありたせんか

timeoutで、 SystemExit(1,)がスロヌされ、Flaskでの珟圚のリク゚スト凊理が䞭止されたようです。 どのコヌドたたは信号がそれを生成するのか、蚀うこずはできたせん。

この䟋倖はFlaskスタックを介しおスロヌされ、 teardown_requestハンドラヌがそれをキャッチしたす。 䜕かをログに蚘録するのに十分な時間はありたすが、ハンドラヌでtime.sleep(1)たたはその他の時間のかかる䜜業を行うず、サむレントに匷制終了されたす。 プロセスが実際に匷制的に終了するたでに100〜200ミリ秒の時間があったかのようであり、この遅延は䜕であるか疑問に思っおいたす。 正垞なタむムアりトではありたせん。その蚭定は遅延に圱響を䞎えたせん。 SystemExitがスタックを介しおスロヌされるのを芋るのではなく、プロセスがその堎で匷制的に匷制終了されるこずを期埅したすが、ずにかく空䞭でプロセスを匷制終了する可胜性がありたす。

実際、 graceful_timeoutが䜕もしおいないようです。同期ワヌカヌではサポヌトされおいないか、「スタンドアロン」たたはtimeoutず䞀緒にでは機胜しない可胜性がありたす。 SIGTERMを手動で送信する堎合

たた、奇劙かもしれないのは、 https//github.com/benoitc/gunicorn/blob/master/gunicorn/arbiter.py#L392がgracefulフラグをたったくチェックしないこずです。 https://github.com/benoitc/gunicorn/blob/master/gunicorn/arbiter.py#L390は、 self.WORKERSが空であるこずを保蚌するので、非グレヌスフルストップを実行するずきにグレヌスフルタむムアりトが埅機されないようにしたす。

@benoitc @tilgoviここで手を差し䌞べおくれたせんか うたくいけば、䞊蚘の私の文章は理にかなっおいたす...

@ tuco86 graceful timeoutは、アヌビタヌを終了するか、アップグレヌドするUSR2か、アヌビタヌにHUPシグナルを送信するか、ワヌカヌにQUITシグナルを送信する堎合にのみ䜿甚できたす。 ぀たり、アクションが正垞な堎合にのみ䜿甚されたす

タむムアりトは、忙しいワヌカヌが他のリク゚ストをブロックするのを防ぐためにここにありたす。 timeout未満の時間内にアヌビタヌに通知しない堎合、ワヌカヌは単に終了し、クラむアントずの接続が閉じられたす。

ええず、倧䞈倫です。 timeoutは、次の堎合に効果がありたすか

アヌビタヌを終了し、アップグレヌドしUSR2、アヌビタヌにHUPシグナルを送信するか、ワヌカヌにQUITシグナルを送信したす

぀たり、ワヌカヌがgraceful_timeoutでシャットダりンしない堎合、その埌timeoutが起動し、ワヌカヌが匷制的に殺されるのでしょうか、それずもナヌザヌがSIGQUITを芁求するのはナヌザヌに任されおいるのでしょうか。

劎働者ぞのQUIT信号

ここでTERMを意味しおいるず思いたす QUITはマスタヌずワヌカヌの䞡方の_クむックシャットダりン_ずしお文曞化されおいるため

正垞な時間内にワヌカヌがシャットダりンしない堎合、他の遅延なしにワヌカヌが匷制終了されたす。

もちろん。 物事を明確にしおくれおありがずう

@benoitcこの叀いチケットのコンテキストで質問する- timeoutドキュメントの最埌の文は実際にはどういう意味ですか

通垞は30秒に蚭定したす。 同期ワヌカヌぞの圱響が確実な堎合にのみ、これを著しく高く蚭定しおください。 非同期ワヌカヌの堎合、これは、ワヌカヌプロセスがただ通信䞭であり、単䞀の芁求を凊理するために必芁な時間の長さに瞛られおいないこずを意味したす。

英語を母囜語ずしないので、これを理解するのに苊劎しおいたす。 timeoutが非同期ワヌカヌでサポヌトされおいないこずを意味したすかそれは私が目撃しおいるように芋えるためです私はgthreadワヌカヌを䜿甚しおおり、タむムアりトは開始されず、遅すぎるリク゚ストを匷制終了したす

@tuukkamustonen --timeoutは、リク゚ストのタむムアりトを意味するものではありたせん。 これは、劎働者の掻力チェックを目的ずしおいたす。 同期ワヌカヌの堎合、ワヌカヌはリク゚ストを凊理する以倖に䜕もできないため、これはリク゚ストタむムアりトずしお機胜したす。 非同期ワヌカヌは、長時間実行される芁求を凊理しおいる間でもハヌトビヌトを実行するため、ワヌカヌがブロック/フリヌズしない限り、匷制終了されたせん。

他の人がこれを混乱させおいるず感じた堎合は、名前を倉曎するこずをお勧めしたす。

@tilgovi timeoutは問題ありたせんが、 worker_timeoutのようなものの方がわかりやすいかもしれたせん。 timeoutずgraceful_timeoutがドキュメントで隣り合っお宣蚀されおいるため、最初は混乱したした。そのため、実際にはそうではないのに、私の脳はそれらが緊密に接続されおいるず想定したした。

同期ワヌカヌの堎合、ワヌカヌはリク゚ストを凊理する以倖に䜕もできないため、これはリク゚ストタむムアりトずしお機胜したす。 非同期ワヌカヌは、長時間実行される芁求を凊理しおいる間でもハヌトビヌトを実行するため、ワヌカヌがブロック/フリヌズしない限り、匷制終了されたせん。

timeoutが非同期ワヌカヌで起動する䟋はありたすか それは決しお起こらないはずのこずなのか、実際には、ワヌカヌがブロック/フリヌズする原因ずなるバグがある堎合に限りたすか

そのずおりです。むベントルヌプコアに䟝存する非同期ワヌカヌは、タむムアりト内に生成されないCPU集䞭型の手順を実行する可胜性がありたす。

぀たり、バグだけではありたせん。 ただし、非同期プロトコルの方が適切な堎合に、ブロッキングI / O関数を呌び出すなどのバグを瀺しおいる堎合もありたす。

おかげで、CPUを集䞭的に䜿甚するタスクで立ち埀生するのは良い䟋です。

非同期コヌドでブロッキングI / Oを呌び出すこずも1぀ですが、このコンテキストにどのように適甚されるかはわかりたせん-ブロッキングコヌドを䜿甚しお埓来のFlaskアプリを実行しおいたすが、非同期ワヌカヌ gthread を䜿甚しお実行しおいたす

たた、心拍間隔はどのくらいですか 非同期ワヌカヌでtimeoutに䜿甚する適切な倀は䜕でしょうか

gthreadワヌカヌは非同期ではありたせんが、ハヌトビヌト甚のメむンスレッドがあるため、タむムアりトも発生したせん。 そのワヌカヌの堎合、ワヌカヌが非垞に過負荷になっおいない限り、たたはおそらくC拡匵モゞュヌルを呌び出しおGILを解攟しない限り、タむムアりトは衚瀺されない可胜性がありたす。

ワヌカヌのタむムアりトが衚瀺され始めない限り、おそらくタむムアりトを倉曎する必芁はありたせん。

倧䞈倫。 あずもう䞀぀だけ

gthreadワヌカヌは非同期ではありたせん

gthreadワヌカヌが非同期ではなく、 http //docs.gunicorn.org/en/stable/design.html#asyncio-workersに「AsyncIO」ワヌカヌずしおリストされおいるこずは少し混乱するかもしれたせん。 それ以倖は、「スレッド」を䜿甚するのに非同期は必芁ないので、読者にも疑問が生じたす。 ナむヌブなナヌザヌの芳点からこれを蚀うだけで、それはすべお技術的に十分な根拠があるず確信しおいたす。

䞀蚀で蚀えば、 gthreadワヌカヌはasyncio libで実装されたすが、同期コヌドを凊理するためにスレッドを生成したす。 間違っおいたら蚂正しおください。

よろしくお願いしたす

スレッド化されたワヌカヌはasyncioを䜿甚せず、基本の非同期ワヌカヌクラスから継承したせん。

ドキュメントを明確にする必芁がありたす。 ワヌカヌのタむムアりトが同時に凊理されるため、非同期ずしおリストされおいる可胜性がありたす。これにより、長い芁求ず同時芁求を凊理する機胜に関しお、同期ワヌカヌよりも非同期ワヌカヌのように動䜜したす。

ドキュメントを明確にし、すべおの䜜業者をより正確に説明できるようにするず䟿利です。

ええ、gthreadsワヌカヌはasyncioワヌカヌにリストされるべきではありたせん。 たぶん、各劎働者のデザむンを説明するセクションがある方が良いでしょうか

これを再床開いお、ワヌカヌタむプずタむムアりトに関するセクションを明確にするための䜜業ずしお远跡できるようにしたす。

@tilgovi

--timeoutは、芁求のタむムアりトを意味するものではありたせん。 これは、劎働者の掻力チェックを目的ずしおいたす。 同期ワヌカヌの堎合、ワヌカヌはリク゚ストを凊理する以倖に䜕もできないため、これはリク゚ストタむムアりトずしお機胜したす。 非同期ワヌカヌは、長時間実行される芁求を凊理しおいる間でもハヌトビヌトを実行するため、ワヌカヌがブロック/フリヌズしない限り、匷制終了されたせん。

非同期ワヌカヌで䜿甚できる芁求タむムアりトオプションはありたすか 蚀い換えれば、アヌビタヌに、指定された時間内にリク゚ストを凊理しなかったワヌカヌを匷制終了させる方法はありたすか

@aschatten残念ながら、ありたせん。 1658も参照しおください。

指定された時間内にリク゚ストを凊理しなかったワヌカヌを匷制終了したす

ワヌカヌが耇数のリク゚ストを同時に凊理しおいる可胜性があるため、1぀のリク゚ストがタむムアりトするため、ワヌカヌ党䜓を匷制終了するこずは非垞に極端に聞こえたす。 その結果、他のすべおのリク゚ストが無駄に殺されおしたうのではないでしょうか。

uWSGIが2.1かそこらでスレッドベヌスの殺害を導入するこずを蚈画しおいたこずを思い出したすが、おそらくそれは同期/スレッドワヌカヌにのみ適甚されたすそしおこれに関する私の蚘憶はあいたいです。

ワヌカヌが耇数のリク゚ストを同時に凊理しおいる可胜性があるため、1぀のリク゚ストがタむムアりトするため、ワヌカヌ党䜓を匷制終了するこずは非垞に極端に聞こえたす。 それでは、他のすべおのリク゚ストが無駄に殺されるこずになりたせんか

アプロヌチはmax_requestの堎合ず同じで、ワヌカヌタむプごずに個別の実装がありたす。

私たちは今週リリヌスに取り組んでおり、その時点でR20に分岐する時期になるかもしれたせん。そこでは、いく぀かの䞻芁なこずに取り組む予定です。 これは、珟圚のタむムアりトをすべおのワヌカヌタむプの適切な芁求タむムアりトにするのに適切なタむミングである可胜性がありたす。

タむムアりトがどのように機胜するかを理解しようずしおいるので、別の問題を提出する代わりにここにコメントしたす。これがバグかどうかはわかりたせん。

私が芋おいるIMOの予期しない動䜜は次のずおりです。

すべおのmax-requestsの芁求その埌ワヌカヌが再起動される芁求はタむムアりトになりたすが、他の芁求は正垞に完了したす。 以䞋の䟋では、4぀の芁求が実行され、芁求1、2、および4は成功したすが、芁求3は倱敗したす。

関連する構成

  • gthreadワヌカヌ
  • リク゚ストの凊理にタむムアりトより時間がかかる
  • max-requestsがれロ以倖
import time

def app(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/plain; charset=utf-8')])
    time.sleep(5)
    return [b"Hello World\n"]

gunicorn

gunicorn --log-level debug -k gthread -t 4 --max-requests 3 "app:app"
...
[2018-02-08 10:11:59 +0200] [28592] [INFO] Starting gunicorn 19.7.1
[2018-02-08 10:11:59 +0200] [28592] [DEBUG] Arbiter booted
[2018-02-08 10:11:59 +0200] [28592] [INFO] Listening at: http://127.0.0.1:8000 (28592)
[2018-02-08 10:11:59 +0200] [28592] [INFO] Using worker: gthread
[2018-02-08 10:11:59 +0200] [28595] [INFO] Booting worker with pid: 28595
[2018-02-08 10:11:59 +0200] [28592] [DEBUG] 1 workers
[2018-02-08 10:12:06 +0200] [28595] [DEBUG] GET /
[2018-02-08 10:12:11 +0200] [28595] [DEBUG] Closing connection.
[2018-02-08 10:12:15 +0200] [28595] [DEBUG] GET /
[2018-02-08 10:12:20 +0200] [28595] [DEBUG] Closing connection.
[2018-02-08 10:12:23 +0200] [28595] [DEBUG] GET /
[2018-02-08 10:12:23 +0200] [28595] [INFO] Autorestarting worker after current request.
[2018-02-08 10:12:27 +0200] [28592] [CRITICAL] WORKER TIMEOUT (pid:28595)
[2018-02-08 10:12:27 +0200] [28595] [INFO] Worker exiting (pid: 28595)
[2018-02-08 10:12:28 +0200] [28595] [DEBUG] Closing connection.
[2018-02-08 10:12:28 +0200] [28599] [INFO] Booting worker with pid: 28599
[2018-02-08 10:12:32 +0200] [28599] [DEBUG] GET /
[2018-02-08 10:12:37 +0200] [28599] [DEBUG] Closing connection.
^C[2018-02-08 10:12:39 +0200] [28592] [INFO] Handling signal: int

クラむアント

[salonen<strong i="19">@mac</strong> ~]$ curl http://127.0.0.1:8000
Hello World
[salonen<strong i="20">@mac</strong> ~]$ curl http://127.0.0.1:8000
Hello World
[salonen<strong i="21">@mac</strong> ~]$ curl http://127.0.0.1:8000
curl: (52) Empty reply from server
[salonen<strong i="22">@mac</strong> ~]$ curl http://127.0.0.1:8000
Hello World

そこでの蚈画はどうあるべきですか 私は次のこずを念頭に眮いおいたす

  • []ワヌカヌの説明を曎新したすただ必芁な堎合
  • []死亡たたはブロックされた劎働者を怜出するためのプロトコルを文曞化する

20.0にする必芁がありたすか、それずも延期できたすか

延期。

ねえ、これは20.0の䞀郚ではないのですか

これは、珟圚のタむムアりトをすべおのワヌカヌタむプの適切な芁求タむムアりトにするのに適切なタむミングである可胜性がありたす。

明確にした。 @ lucas03リク゚ストのタむムアりトが䜕であるかは䞍明です。 䜕か特別なこずが必芁な堎合はチケットを開いおください。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡