ããã«ã¡ã¯ãFlask+ Gunicorn + Herokuã䜿çšããæ¬çªç°å¢ã§ãã®åé¡ãçºçããŸããããåå ãåé¿çãèŠã€ããããšãã§ããŸããã§ããã
POSTãã©ã¡ãŒã¿ã䜿çšããç¹å®ã®POSTãªã¯ãšã¹ãã®å Žåããªã¯ãšã¹ãã¯Herokuã®ã«ãŒã¿ãŒã§H18ãšã©ãŒïŒsock = backendïŒã§å€±æãããµãŒããŒããœã±ãããéããã¹ãã§ã¯ãªããšãã«éããããšã瀺ããŸãã
倱æãããšã³ããã€ã³ãã®å¿çãµã€ãºã13kããŒã¯ä»è¿ã«çµã蟌ããŸã§ãçž®å°ãå§ããŸããã 13kæªæºãéä¿¡ããå Žåãå¿çã¯åžžã«æ©èœããŸãã 13kãè¶ ããŠéä¿¡ããå Žåãã»ãšãã©ã®å Žåãå¿çã¯æ©èœããŸããã
ãããåçŸããã³ãŒãã¯https://github.com/erjiang/gunicorn-issueã§å ¥æã§ããŸã
æ¬åœã«åœ¹ç«ã€ã¬ããŒãã@ erjiangã«æè¬ããŸãã
ãã¹ãããHerokuã¢ã«ãŠã³ãããããŸããã ãã®ãããªã¢ã«ãŠã³ããæã£ãŠãã人ã¯èª°ã§ãããããã¹ãã§ããŸããïŒ cc @tilgovi @kennethreitz
å¬ããã§ãããç§ã¯ããããããã«ããã«å°éããããšã¯ãããŸããã
ç°¡åãªå¥å šæ§ãã§ãã¯ãšããŠãããŒã«ã«ã§å®è¡ããã«ãŒã«ã䜿çšããŠãŠã§ã€ãã¬ã¹ãšgunicornãæ¯èŒããããã«ããã€ãã®ããšããã§ãã¯ããŸããã
次ã«ãTCPã¬ãã«ã§éãããããã©ããã«ã€ããŠèå³ããããŸãã ããããtcpdumpããŠãäœãæªãããã®ã«æ°ä»ããã©ããã確èªããŸãã
åãã«ãŒã«ã©ã€ã³ã§ãgunicornãæ¥ç¶ãåæããŸããããŠã§ã€ãã¬ã¹ã¯æ¥ç¶ãéãããŸãŸã«ããŠããããšã«æ°ã¥ããŸããã ããããã®æãããã¯ãŸã ãããŸãããããããç°ãªã£ãŠããã®ã¯ç§ãèŠãããšãã§ããå¯äžã®ããšã§ãã
@tilgoviãŠã§ã€ãã¬ã¹ã§èŠãããåäœã¯ãã¹ã¬ããã¯ãŒã«ãŒã§åçŸã§ãããšæããŸãã ãšã«ããããã®äžè©±ãããŠãããŠããããšã:)
ããã«ã¡ã¯ãã¿ããªã
åãåé¡ãçºçããŠããŸãã ãã®åé¡ããã£ãšåŸ¹åºçã«èª¿ã¹ãæ©äŒãåŸã人ã¯ããŸããïŒ
@tilgovi @erjiang @benoitc
也æ¯
ããã·ã
@maximkgnãã©ã¹ã³ã䜿çšããŠããŸããïŒ ãã以äžã®è©³çŽ°ã¯ãããŸããïŒ
ç§ã¯django1.7ã䜿çšããŠããŸãã
åžžã«13kããé·ãç¹å®ã®äºåŸå¿çããããç¹å®ã®ç¢ºçã§ã0.5ã§ãã¯ã©ã€ã¢ã³ãã®å¿çã¯13kãå°ãè¶
ãããŸã§åãæšãŠãããŸãã herokuãã°ã§åãh18ãšã©ãŒãçºçããPythonã³ãŒãã§ãšã©ãŒãçºçããŠããªãããšã確èªããåŸãherokuãšPythonã®éã®gunicornã¬ã€ã€ãŒã§ãšã©ãŒãçºçããŠãããšçµè«ä»ããå¿
èŠããããŸããã
ãŠã§ã€ãã¬ã¹/ uwsgiã«åãæ¿ãããšããã°ã¯çºçããªããªããŸããã
@maximkgn --threads
èšå®ã䜿çšãããšã©ããªããŸããïŒ
ããããã¹ãã§ãã人ã¯ããŸããïŒ
ãã©ã¹ã³ãšgunicornã§åãåé¡ãçºçããŸãïŒãã¹ãæžã¿ããŒãžã§ã³19.3ããã³19.4.5ïŒã @benoitc 1ã2ãããã³4ã¹ã¬ããïŒ--threadsã䜿çšïŒãªãã·ã§ã³ãè©ŠããŸããããéãã¯ãããŸããã
äœããã®æ¹æ³ã§ããããã¹ãããã®ãæäŒãããšãã§ãããã©ããæããŠãã ããã
@cbainesãªã¯ãšã¹ãã¯ã©ã®ããã«èŠããŸããïŒ
Friendpasteã¯100äžä»¶ä»¥äžã®æçš¿ãåãå ¥ããããšãã§ããŸãããããã£ãŠãgunicornå ã«å¶éã¯ãããŸããã
çãã¯ãããŸããã§ããã åçŸæ§ããªããããåé¡ãã¯ããŒãºããŸãã å¿ èŠã«å¿ããŠããæ°è»œã«åéããŠãã ããã
äŸåé¢ä¿ãæŽæ°ããŠFlask1.0.2ãšgunicorn19.9.0ãå«ããåŸããåŒãç¶ãåçŸãããŸãã ãã ããããã«ã€ããŠHerokuã®èª°ãã®æ³šæãåŒãã®ã¯è¯ãããšãããããŸãã-圌ãã«ã¯Pythonã®ç±å¿ãªäººã ããããšèããŠããŸãã
ããã§ææ°ã®ã³ããããåç §ããŠãã ããïŒ https ïŒ
ãŸãã倧ããªGETãªã¯ãšã¹ãã§ãã®H18ãšã©ãŒãå®æçã«åãåããŸãã
ãŠã§ã€ãã¬ã¹ã«åãæ¿ãããšåé¡ã¯è§£æ±ºããŸããã gunicornããããçæããçç±ã¯ããããŸãããããŸã£ããåãã³ãŒããå®è¡ãããŠããŸãã
å¿çæ¬æã¯21.54KBã§ã
äŸåé¢ä¿ãæŽæ°ããŠFlask1.0.2ãšgunicorn19.9.0ãå«ããåŸããåŒãç¶ãåçŸãããŸãã ãã ããããã«ã€ããŠHerokuã®èª°ãã®æ³šæãåŒãã®ã¯è¯ãããšãããããŸãã-圌ãã«ã¯Pythonã®ç±å¿ãªäººã ããããšèããŠããŸãã
ããã§ææ°ã®ã³ããããåç §ããŠãã ããïŒ https ïŒ
Herokuã§ãµããŒããã±ãããäœæããŸããã äœã圹ã«ç«ã€ãã®ãããã°ãããã§æŽæ°ããŸãã
@benoitcã¯ã @ erjiangãåçŸå¯èœãªäŸãæäŸããããã«èŠããŸãã ãããéããŠããããŸããïŒ
åéããŸããã èªå·±å²ãåœãŠããå¯èœãªå Žåã¯ç¢ºèªããŸãã
äŸåé¢ä¿ãæŽæ°ããŠFlask1.0.2ãšgunicorn19.9.0ãå«ããåŸããåŒãç¶ãåçŸãããŸãã ãã ããããã«ã€ããŠHerokuã®èª°ãã®æ³šæãåŒãã®ã¯è¯ãããšãããããŸãã-圌ãã«ã¯Pythonã®ç±å¿ãªäººã ããããšèããŠããŸãã
ããã§ææ°ã®ã³ããããåç §ããŠãã ããïŒ https ïŒHerokuã§ãµããŒããã±ãããäœæããŸããã äœã圹ã«ç«ã€ãã®ãããã°ãããã§æŽæ°ããŸãã
herokuããè¿ä¿¡ããããŸãããïŒ
https://github.com/erjiang/gunicorn-issueïŒgunicorn 19.9.0ãPython 2.7.14ãåæã¯ãŒã«ãŒã --workers 4
ã䜿çšïŒã®ãã¹ãã±ãŒã¹ã䜿çšããŠåçŸã§ããŸããã 泚ç®ãã¹ãã¯ãgunicornã®ã¢ã¯ã»ã¹ãã°åºåããHTTP200ãè¿ãããšä¿¡ããŠããããšãå ±åããŠããããšã§ãã
Python 3.7.3 + gunicorn master
ã«æŽæ°ãã --workers 1
æžãããŠãåçŸæ§ã«åœ±é¿ã¯ãããŸãã--log-level debug
ã䜿çšããŠããéèŠãªããšã¯äœãæããã«ãªããŸãã[DEBUG] POST /test1
è¡ã®ã¿
次ã«--spew
ãè©ŠããŸããããåé¡ã¯åçŸãããŸããã§ããã ããã«ãããããã§resp.close()
åã«time.sleep(1)
è¿œå ããŠã¿ãŸãããããã«ãããåæ§ã«åé¡ãåé¿ãããŸããã
ãã®ããã close()
æç¹ã§ãœã±ããéä¿¡ãããã¡ãŒã空ã«ãªã£ãŠããªãå¯èœæ§ããããå¿çã倱ãããå¯èœæ§ãããããšãåå ã®ããã§ãã
泚ïŒ
close()
ã¯ãæ¥ç¶ã«é¢é£ä»ããããŠãããªãœãŒã¹ã解æŸããŸãããå¿ ãããããã«æ¥ç¶ãéãããšã¯éããŸããã ã¿ã€ã ãªãŒã«æ¥ç¶ãéãããå Žåã¯ãclose()
åã«shutdown()
åŒã³åºããŸãã
ïŒhttps://docs.python.org/3/library/socket.html#socket.socket.closeãåç §ããŠãã ããïŒ
ããã§sock.close()
åã«sock.shutdown(socket.SHUT_RDWR)
ïŒ docs ïŒãè¿œå ãããšãåé¡ã解決ããŸããã å¥ã®ä¿®æ£ã¯ããããSO_LINGER
ã䜿çšããããšãããããŸããããç§ãèªãã ããšããã¯ãã¬ãŒããªãããããŸãã
ãã®ããŒãã«é¢ããããã¥ã¡ã³ããå
¥æããã®ã¯é£ããã§ãããç§ã¯æ¬¡ã®ããšãçºèŠããŸããã
https://stackoverflow.com/questions/8874021/close-socket-directly-after-send-unsafe
https://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable
ã圹ã«ç«ãŠã°å¹žãã§ã:-)
ãã«STRïŒ
heroku login
ã䜿çšããŠCLIã«ãã°ã€ã³ããŸãgit clone https://github.com/erjiang/gunicorn-issue && cd gunicorn-issue
heroku create
ïŒããã«ãããã©ã³ãã ã«çæãããååã§ç¡æã®Herokuã¢ããªãäœæããã heroku
ãšããååã®gitãªã¢ãŒããæ§æãããŸãïŒgit push heroku master
curl --data "foo=bar" https://YOUR_GENERATED_APP_NAME.herokuapp.com/test1
ïŒ75ïŒ
以äžã®ç¢ºçã§å€±æïŒheroku destroy
ãå®è¡ããŠã¢ããªãåé€ããŸãã@tilgovi @edmorleyã®ããã«èãããŸãããäœãåé¡ãªã®ãã«ã€ããŠãã£ãšãããã説æãäœæããŸããã ããªãã¯èŠãŠãæ£ããä¿®æ£ãäœã§ããããèŠãããšãã§ããŸããïŒ PRãéä¿¡ããŠsock.shutdown()
ãè¿œå ããããšãã§ããŸããããããæ£ããä¿®æ£ã§ãããã©ããããŸãã¯ä»ã®ç¶æ³ã«æªåœ±é¿ãäžãããã©ãããå€æããã®ã«ååãªããšã¯ããããŸããã
ããã«ã¡ã¯ãç§ã¯503KBã®å¿çãµã€ãºã§åãåé¡ã«ã¶ã€ãããŸããã å¿çããŒã¿ã¯JSONé
åã§ãã
芳å¯ãããåäœã¯æ¬¡ã®ãšããã§ãã
ããã¯äž¡æ¹ã§
ã©ã³ã¿ã€ã ç°å¢ã®ã»ããã¢ãã
meinheld-gunicorn-dockerç»åã«_python3.6_ã®ã¿ã°ãä»ããããPython 3.6.7ã Flask 1.0.2ã flask-restplus 0.12.1ãsimpeFlask -caching
Dockeræ§æïŒ3 CPUãRAM 1024 MB
Gunicornã®æ§æïŒ
https://github.com/benoitc/gunicorn/issues/2015ã§ãä»ã®èª°ããmeinheldã¯ãŒã«ãŒãã¶ãäžãã£ãŠãããšããåé¡ãæ±ããŠããŠãå¥ã®ã¯ãŒã«ãŒã¿ã€ãã䜿çšããŠåé¡ã解決ããŸããã ããã«ã¯äžè¬çãªåé¡ãããã®ã ãããã @stapetroå¥ã®ã¯ãŒã«ãŒãè©Šãããšã¯ã§ããŸããïŒ
ããã«ã¡ã¯@jamadden ã
ããªãã®ææ¡ã¯åé¡ãä¿®æ£ããŸããã _gevent_ãš_gthread_ã®äž¡æ¹ã®ã¯ãŒã«ãŒã¯ã©ã¹ã«åé¡ã¯ãããŸããã ç§ã¯èªåã®æããé¢ããŸããã è¿
éãªè¿ä¿¡ãšãã«ããããããšãïŒ :)
ãã«STRïŒ
- https://signup.heroku.comã§ç¡æã®Herokuã¢ã«ãŠã³ããäœæã
- Heroku CLIãã€ã³ã¹ããŒã«ããŸãïŒhttps://devcenter.heroku.com/articles/heroku-cliãåç §ïŒ
heroku login
ã䜿çšããŠCLIã«ãã°ã€ã³ããŸãgit clone https://github.com/erjiang/gunicorn-issue && cd gunicorn-issue
heroku create
ïŒããã«ãããã©ã³ãã ã«çæãããååã§ç¡æã®Herokuã¢ããªãäœæãããheroku
ãšããååã®gitãªã¢ãŒããæ§æãããŸãïŒgit push heroku master
curl --data "foo=bar" https://YOUR_GENERATED_APP_NAME.herokuapp.com/test1
ïŒ75ïŒ ä»¥äžã®ç¢ºçã§å€±æïŒ- çµäºãããã
heroku destroy
ãå®è¡ããŠã¢ããªãåé€ããŸãã
ç§ã®ã¢ããªã§ãéåžžã«ãã䌌ãåäœãããŸããããcurl--dataã®ä»£ããã«curl-Hã䜿çšãããšïŒGETãªã¯ãšã¹ãã§ããããïŒãã¢ããªïŒDjangoãGunicornãHerukoïŒã§æ©èœããããšãããããŸããã gunicorn-issueã¢ããªã§ã¯ãã¹ãããŠããŸããã ããã¯èª°ãã«åœ¹ç«ã€ãããããªããšæã£ãã
@mikkelhnã¯ãã Flask / Flask RestPlusãšGunicornãåããã¢ããªã¯ã次ã®ããã«åäœããŸããPOSTãªã¯ãšã¹ãã«å¿çãããš503ãšã©ãŒãçºçããŸã[ãã€ããŒã> 13kã®å Žå]ããã¢ããªãGETã«å¿çããå Žåã¯ãšã©ãŒã¯çºç
誰ãããã®éåžžã«è¿·æãªè¡åã説æã§ããŸããïŒ ãã®åé¡ã解決ããããã®å¯äžã®åé¿çã¯ãŠã§ã€ãã¬ã¹ã«åãæ¿ããããšã§ããïŒ Gunicornããæäœæ¥ã§ãå€æŽããããšã¯å®è¡å¯èœãªè§£æ±ºçã§ã¯ãªããšæããŸã...
ç§ã¯å ã«é²ã¿ãcloseïŒïŒã®åã«shutdownïŒïŒãåŒã³åºãããã«PRãéããŸããã ççŽã«èšã£ãŠãHerokuã§ããã©ã«ãã§å£ããŠãããšãã«ãHerokuãGunicornãæšå¥šãç¶ããã®ã¯å°ãã¯ã€ã«ãã§ãã
@erijangãæ£ããè¿°ã¹ãŠããããã«ãGunicornãé²ãã¹ãéã§ã¯ãªããšãã«HerokuãGunicornãæšå¥šããå ŽåïŒGunicornã®ã·ã³ãã«ã§å®è¡å¯èœãªä»£æ¿æ段ïŒããã³Herokuã§ããããæé©ã«æ§æããæ¹æ³ïŒã¯ã©ãã§ããïŒ
AFAIKãå€ãã®ã客æ§ã¯ããµãŒããŒã¢ãŒããã¯ãã£ãšæ§æã®è©³çŽ°ã«é¢ããæ·±ãç¥èãå¿
èŠãšããªããšããçç±ã ãã§HerokuãéžæããŠããŸã...ïŒ|
@RinaldoNaniã©ãããæå³ã§ããïŒ ãŸããã©ã®åŽåè ã«ã€ããŠè©±ããŠããã®ã§ããïŒ ã
@benoitcãã®åé¡ã¯ã次ã®ããã«ãè€æ°ã®ã¯ãŒã«ãŒã¿ã€ãã«åœ±é¿ããŸãã
https://github.com/benoitc/gunicorn/issues/840#issuecomment -482491267
ããã«ã¡ã¯@benoitcã 以åã®æçš¿ã§è¿°ã¹ãããã«ãPython / FlaskãµãŒããŒåŽã¢ããªã±ãŒã·ã§ã³ã®ãããã€ã«é¢ããHerokuã®ãŠããããã«ãGunicornåæãWebãã®äœ¿çšãææ¡ããŠããŸãïŒã«åŸã£ãŠãéåžžã«åçŽãªFlask / FlaskRestPlusã¢ããªãHerokuã«ãããã€ããŸãã
ã¢ããªã®åäœã¯ããã®ã¹ã¬ããã®ã¿ã€ãã«ãåæ ããŠããŸãã
ããŒã«ã«ã§ãã¹ãããããã¹ãŠãæ£åžžã«æ©èœããã¢ããªã¯åé¡ãªã20k以äžã®JSONãæäŸããŸãã ãã ããã¢ããªãHerokuã«ãããã€ããããšã503ãšã©ãŒã®åé¡ãäœç³»çã«ãªããŸããæåéããã©ãã£ãã¯ããªãå Žåã§ããåºåã¯é
ä¿¡ãããŸããã
ä»ã®äººãææããŠããããã«ããã°ã¯HTTPã¬ãã«ã§ã¯ãã¹ãŠãåé¡ãªãããã«èŠããããšã瀺ããŠããŸãïŒ200ã®å¿çã³ãŒãããã°ã«èšé²ãããŸãïŒã
ãã€ããŒãã13kæªæºã®å ŽåãHeroku / Gunicornã¯æåŸ
ã©ããã«POSTã«å¿çããŸãã
POSTïŒïŒïŒïŒïŒãšã³ããã€ã³ããåé¿ãã代ããã«GETã䜿çšãããšãã@mikkelhnã®ã¢ã€ãã¢ã«åŸã
ç§ãã¡ã¯Gunicornã®å°é家ã§ã¯ãããŸãããççŽã«èšã£ãŠãç§ãã¡ã®åçŽãªãŠãŒã¹ã±ãŒã¹ã¯ãç®±ããåºããŠãæ©èœããããšãæåŸ
ããŠããŸããã
ããªããç§ãã¡ãå©ããããã«äœãææ¡ãããã°ãç§ãã¡ã¯æ°žé ã«æè¬ããŸã:)
@RinaldoNaniæéã®äžã§æ®åœ±...ãªã¯ãšã¹ããã³ãã©ã®ã©ããã§ã request.data
ãã¹ãŠèªãã§ã¿ãŠãã ããã äŸãã°ïŒ
@route('/whatever', methods=['POST'])
def whatever_handler():
str(request.data)
return flask.jsonify(...)
ããã¯ããªãã®ãšã©ãŒã«åœ±é¿ãåãŒããŸããïŒ
ç§ã¯ãããåå1æã«æžããŠããŸããH18ã®åé¡ã§2é±é以äžããã¹ã«ããåŸã§ãïŒå ±æããã®ãåŸ ã¡ãããŸããã§ããïŒã
ç§ã¯å·šå€§ãªããŒã¿ã»ããã䜿çšããŠããã18Kãã20Kã®ã¬ã³ãŒããããããã«å¿çããŠããŸãã H18ã¯éåžžã«ã©ã³ãã ãªãšã©ãŒãšããŠçºçããŸããã ããŸãããããšããããŸããããã¹ãŠã®ãã©ãŠã¶ã§ãã³ã³ãã³ãããããŒã®é·ããäžèŽããŸããããšã¹ããŒãããŸãã ç§ã¯ãã®åé¡ã«ã€ããŠè°è«ãããã»ãšãã©ãã¹ãŠã®è§£æ±ºçãè©ŠããŸããããéããããŸããã§ããã ç§ãè©Šãã2ã€ã®ããšãæçµçã«æ©èœããŸããïŒ
æãåèã«ãªãã³ã¡ã³ã
https://github.com/erjiang/gunicorn-issueïŒgunicorn 19.9.0ãPython 2.7.14ãåæã¯ãŒã«ãŒã
--workers 4
ã䜿çšïŒã®ãã¹ãã±ãŒã¹ã䜿çšããŠåçŸã§ããŸããã 泚ç®ãã¹ãã¯ãgunicornã®ã¢ã¯ã»ã¹ãã°åºåããHTTP200ãè¿ãããšä¿¡ããŠããããšãå ±åããŠããããšã§ããPython 3.7.3 + gunicorn
master
ã«æŽæ°ãã--workers 1
æžãããŠãåçŸæ§ã«åœ±é¿ã¯ãããŸãã--log-level debug
ã䜿çšããŠããéèŠãªããšã¯äœãæããã«ãªããŸãã[DEBUG] POST /test1
è¡ã®ã¿æ¬¡ã«
--spew
ãè©ŠããŸããããåé¡ã¯åçŸãããŸããã§ããã ããã«ãããããã§resp.close()
åã«time.sleep(1)
è¿œå ããŠã¿ãŸãããããã«ãããåæ§ã«åé¡ãåé¿ãããŸããããã®ããã
close()
æç¹ã§ãœã±ããéä¿¡ãããã¡ãŒã空ã«ãªã£ãŠããªãå¯èœæ§ããããå¿çã倱ãããå¯èœæ§ãããããšãåå ã®ããã§ããïŒhttps://docs.python.org/3/library/socket.html#socket.socket.closeãåç §ããŠãã ããïŒ
ããã§
sock.close()
åã«sock.shutdown(socket.SHUT_RDWR)
ïŒ docs ïŒãè¿œå ãããšãåé¡ã解決ããŸããã å¥ã®ä¿®æ£ã¯ããããSO_LINGER
ã䜿çšããããšãããããŸããããç§ãèªãã ããšããã¯ãã¬ãŒããªãããããŸãããã®ããŒãã«é¢ããããã¥ã¡ã³ããå ¥æããã®ã¯é£ããã§ãããç§ã¯æ¬¡ã®ããšãçºèŠããŸããã
https://stackoverflow.com/questions/8874021/close-socket-directly-after-send-unsafe
https://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable
ã圹ã«ç«ãŠã°å¹žãã§ã:-)