Gunicorn: OSError: [Errno 0] ์˜ค๋ฅ˜

์— ๋งŒ๋“  2018๋…„ 05์›” 08์ผ  ยท  30์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: benoitc/gunicorn

์•ฑ์„ ์‹คํ–‰ ์ค‘์ž…๋‹ˆ๋‹ค.
gunicorn -w 2 -b ' localhost:8585 ' --timeout=200 --certfile=crt.crt --keyfile=key.key ์„œ๋น„์Šค: ์•ฑ

๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‚ด์šฉ์ด ๋‚˜์˜ค๋Š”๋ฐ ํ•ญ์ƒ ๊ทธ๋Ÿฐ ๋‹ต๋ณ€์„ ๋ฐ›๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ณ  ๋Œ€๋ถ€๋ถ„์˜ ์š”์ฒญ์ด ์ œ๋Œ€๋กœ ์ฒ˜๋ฆฌ๋˜์ง€๋งŒ ๊ฐ„ํ˜น ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

[2018-05-08 14:53:36 +0500] [11227] [ERROR] Socket error processing request.
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/gunicorn/workers/sync.py", line 134, in handle
    req = six.next(parser)
  File "/usr/lib/python3/dist-packages/gunicorn/http/parser.py", line 41, in __next__
    self.mesg = self.mesg_class(self.cfg, self.unreader, self.req_count)
  File "/usr/lib/python3/dist-packages/gunicorn/http/message.py", line 153, in __init__
    super(Request, self).__init__(cfg, unreader)
  File "/usr/lib/python3/dist-packages/gunicorn/http/message.py", line 53, in __init__
    unused = self.parse(self.unreader)
  File "/usr/lib/python3/dist-packages/gunicorn/http/message.py", line 165, in parse
    self.get_data(unreader, buf, stop=True)
  File "/usr/lib/python3/dist-packages/gunicorn/http/message.py", line 156, in get_data
    data = unreader.read()
  File "/usr/lib/python3/dist-packages/gunicorn/http/unreader.py", line 38, in read
    d = self.chunk()
  File "/usr/lib/python3/dist-packages/gunicorn/http/unreader.py", line 65, in chunk
    return self.sock.recv(self.mxchunk)
  File "/usr/lib/python3.5/ssl.py", line 922, in recv
    return self.read(buflen)
  File "/usr/lib/python3.5/ssl.py", line 799, in read
    return self._sslobj.read(len, buffer)
  File "/usr/lib/python3.5/ssl.py", line 585, in read
    v = self._sslobj.read(len)
OSError: [Errno 0] Error
( FeaturSSL

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

ํ , ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ์—ฐ๊ตฌ๋ฅผ ๋งˆ์นœ ํ›„ ์ด๊ฒƒ์€ ์‹ค์ œ๋กœ python ssl ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ Linux์—์„œ ๋น„์ •ํ˜• EOF๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์˜ ๋ฒ„๊ทธ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://bugs.python.org/issue31122

๋ชจ๋“  30 ๋Œ“๊ธ€

๋‚ด ๊ธฐ์–ต์œผ๋กœ๋Š” ์ด ์˜ค๋ฅ˜๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ SSL ์—†์ด ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์—๊ฒŒ๋„ ๊ทธ๋Ÿด ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚ด๊ฐ€ ๋‹ซ์€ ๋‹ค๋ฅธ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๊ท€ํ•˜์˜ ๊ฒŒ์‹œ๋ฌผ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ์ œ ๋Œ“๊ธ€์ด ์›์ธ์ด ์•„๋‹ˆ๋ผ๋ฉด ์‚ฌ๊ณผ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

์ด๋Ÿฐ ์‹์œผ๋กœ ์š”์ฒญ์ด ์‹คํŒจํ•˜๋Š” ํŒจํ„ด์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@usmetanina ์–ด๋–ค ํด๋ผ์ด์–ธํŠธ๊ฐ€ Gunicorn์—๋„ ์—ฐ๊ฒฐ๋˜๋‚˜์š”? ๋ช…์‹œ์ ์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” SSL ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์ด๊ฒƒ์€ ์ด๋ฏธ ํ•ด๊ฒฐ ๋˜์—ˆ์Šต๋‹ˆ๊นŒ? @usmetanina , ์ •ํ™•ํžˆ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—

@benoitc ๋‚˜๋Š” @usmetanina๊ฐ€ '์ž์ฃผ python3.6 ๋ฐ gunicorn ์‚ฌ์šฉํ•˜์—ฌ ์ •ํ™•ํ•œ ์˜ค๋ฅ˜์—์š” ์ฐธ์กฐ 19.9.0 .

์•„๋ž˜ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ๋‚ด์—์„œ ์‹คํ–‰๋˜๋Š” ํ”Œ๋ผ์Šคํฌ ์•ฑ์œผ๋กœ gunicorn์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

gunicorn --workers=3 --bind=0.0.0.0:8000 --config=gunicorn_config.py --preload main

๊ตฌ์„ฑ ํŒŒ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค(domain-with-cert.com์€ ๋ฌผ๋ก  ์‹ค์ œ ๋„๋ฉ”์ธ ์ด๋ฆ„์˜ ์ž๋ฆฌ ํ‘œ์‹œ์ž์ž„).

workers = 3
bind = '0.0.0.0:443'
certfile = '/etc/letsencrypt/live/domain-with-cert.com/fullchain.pem'
keyfile = '/etc/letsencrypt/live/domain-with-cert.com/privkey.pem'

๋””๋ฒ„๊น…์— ๋Œ€ํ•œ ๋ชจ๋“  ์ƒ๊ฐ์€ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•˜๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”.

@willpatera , ๋‚ด ์˜๊ฒฌ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋‚ด ๊ธฐ์–ต์œผ๋กœ๋Š” ์ด ์˜ค๋ฅ˜๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ SSL ์—†์ด ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•  ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์—๊ฒŒ๋„ ๊ทธ๋Ÿด ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@tilgovi ์œ„์˜ ๋Œ“๊ธ€์„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ๊ฐ€ SSL์„ ํ†ตํ•ด ์—ฐ๊ฒฐํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. ๋””๋ฒ„๊น… ์ œ์•ˆ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@willpatera ์•ก์„ธ์Šค ๋กœ๊ทธ๋ฅผ ์ผœ๊ณ  ์–ด๋–ค ์š”์ฒญ์ด ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. gunicorn ์•ž์— ์—ญ๋ฐฉํ–ฅ ํ”„๋ก์‹œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์•ก์„ธ์Šค ๋กœ๊ทธ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์—ฌ gunicorn์ด ๋กœ๊ทธ๋ฅผ ๊ธฐ๋กํ•˜์ง€ ์•Š๋”๋ผ๋„ ์–ด๋–ค ์š”์ฒญ์ด gunicorn์— ์˜ค๋ฅ˜๋ฅผ ์ผ์œผํ‚ค๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@tilgovi ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์ •๋ณด๊ฐ€ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์•„ ์•ฝ๊ฐ„ ์ˆ˜์ •ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.
gunicorn์— ๋Œ€ํ•œ ์š”์ฒญ์€ ํ•ญ์ƒ ์ •ํ™•ํžˆ ๋™์ผํ•œ ์š”์ฒญ์ž…๋‹ˆ๋‹ค(๊ทธ๋Ÿฌ๋‚˜ ๋ณธ๋ฌธ์€ ๋‹ค๋ฆ„). ๋”ฐ๋ผ์„œ http๊ฐ€ ์•„๋‹Œ https๋ผ๋Š” ๊ฒƒ์€ ์˜์‹ฌ์˜ ์—ฌ์ง€๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
๋‚ด๊ฐ€ ์ฃผ๋ชฉํ•˜๋Š” ๊ฒƒ์€ ์š”์ฒญ ์–‘์ด ์ฆ๊ฐ€ํ•  ๋•Œ ํ•ญ์ƒ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„๊ฐ€ ๋ฐ”์˜๋ฉด ์š”์ฒญ์„ ์ œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์•„๋งˆ๋„ ์ด๊ฒƒ์€ ์ž‘์—…์ž ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ๊ฒƒ๊ณผ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ตฌ์„ฑ ์ œ์•ˆ ์‚ฌํ•ญ์ด ์žˆ์œผ๋ฉด ๊ธฐ๊บผ์ด ํ…Œ์ŠคํŠธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„, ์ €๋Š” ์—ฌ์ „ํžˆ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์šฐ๋ฆฌ๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ์˜ต์…˜์€ ์ผ๋ฐ˜ HTTP๋กœ ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ „ํ˜€ ์‹คํ˜„ ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ฐ™์€ ๊ฒƒ์„ ๋ชฉ๊ฒฉํ–ˆ์Šต๋‹ˆ๋‹ค. Gunicorn + Flask(๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ ๋’ค)๋ฅผ ์‹คํ–‰ํ•˜๋Š” ํ”„๋กœ๋•์…˜ ์„œ๋ฒ„๊ฐ€ ๋ช‡ ๋‹ฌ ๋™์•ˆ ์ œ๋Œ€๋กœ ์ž‘๋™ํ–ˆ๋Š”๋ฐ ๊ฐ‘์ž๊ธฐ ๋ชจ๋“  ์š”์ฒญ์ด Gunicorn์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•  ๋•Œ๊นŒ์ง€ ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

[2019-11-21 07:27:36 +0000] [24245] [ERROR] Socket error processing request.
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/sync.py", line 134, in handle
    req = six.next(parser)
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/http/parser.py", line 41, in __next__
    self.mesg = self.mesg_class(self.cfg, self.unreader, self.req_count)
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/http/message.py", line 181, in __init__
    super(Request, self).__init__(cfg, unreader)
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/http/message.py", line 54, in __init__
    unused = self.parse(self.unreader)
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/http/message.py", line 193, in parse
    self.get_data(unreader, buf, stop=True)
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/http/message.py", line 184, in get_data
    data = unreader.read()
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/http/unreader.py", line 38, in read
    d = self.chunk()
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/http/unreader.py", line 65, in chunk
    return self.sock.recv(self.mxchunk)
  File "/usr/lib/python3.6/ssl.py", line 997, in recv
    return self.read(buflen)
  File "/usr/lib/python3.6/ssl.py", line 874, in read
    return self._sslobj.read(len, buffer)
  File "/usr/lib/python3.6/ssl.py", line 633, in read
    v = self._sslobj.read(len)
OSError: [Errno 0] Error

์ด๋Ÿฌํ•œ ์˜ค๋ฅ˜ ์ด์ „์˜ ๋กœ๊ทธ์—๋Š” ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•”์‹œํ•˜๋Š” ๋‚ด์šฉ์ด ์—†์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‹จ์ผ ์ฝ”์–ด ์„œ๋ฒ„์—์„œ 3๋ช…์˜ ์ž‘์—…์ž์™€ ํ•จ๊ป˜ ์‹คํ–‰๋˜๋Š” Gunicorn 19.9.0์˜ ๊ฒฝ์šฐ์˜€์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ์ฒ˜์Œ ๋ณธ ๊ฒƒ์ด๋ฏ€๋กœ ๋‹ค์‹œ ์žฌํ˜„ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์žฅ๋‹ดํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Ÿฌํ•œ ์ผ์ด ๋‹ค์‹œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ์œ ์šฉํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋Š” ๋กœ๊น… ๋˜๋Š” ๊ธฐํƒ€ ์ง„๋‹จ ์ฝ”๋“œ๊ฐ€ ๋ˆ„๊ตฐ๊ฐ€ ์ €์—๊ฒŒ ์šฐ๋ฆฌ ์„œ๋ฒ„์— ์ถ”๊ฐ€ํ–ˆ์œผ๋ฉด ํ•˜๋Š” ๋‚ด์šฉ์ด ์žˆ๋‹ค๋ฉด ์ €๋Š” ๋ชจ๋‘ ๊ท€๋ฅผ ๊ธฐ์šธ์ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

LB๊ฐ€ ํŠน์ • ์—”๋“œํฌ์ธํŠธ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๊นŒ? LB ์š”์ฒญ์— ์–ด๋–ป๊ฒŒ ์‘๋‹ตํ•ฉ๋‹ˆ๊นŒ?

๋‚ด๊ฐ€ "๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ"๋ผ๊ณ  ๋งํ–ˆ์„ ๋•Œ, ๋‚˜๋Š” ์ •๋ง๋กœ CDN ๋˜๋Š” ์บ์‹ฑ ๋ ˆ์ด์–ด๋ฅผ ๋งํ–ˆ์–ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ: Amazon Cloudfront์ž…๋‹ˆ๋‹ค. ์š”์ฒญ์„ Gunicorn ์„œ๋ฒ„(EC2 ์ธ์Šคํ„ด์Šค์—์„œ ์‹คํ–‰)๋กœ ์ „๋‹ฌํ•˜๊ณ  ์ž ์‹œ ๋™์•ˆ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œํ•ฉ๋‹ˆ๋‹ค.

hrm์€ amazon cloudfront๊ฐ€ SSL ์š”์ฒญ์„ ์ข…๋ฃŒํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๊นŒ? @ํญ๋ฐœ์–‘๋ฐฐ์ถ” . ์™œ gunicorn์ด ๋’ค์—์„œ ssl์„ ๋“ค์–ด์•ผํ•ฉ๋‹ˆ๊นŒ?

@benoitc ๋”ฐ๋ผ์„œ ์•„ํ‚คํ…์ฒ˜์— ๊ด€๋ จ๋œ SSL์„ ์‚ฌ์šฉํ•˜๋Š” ๋‘ ๊ฐœ์˜ ๋ ˆ์ด์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. HTTPS๋ฅผ ํ†ตํ•ด ์šฐ๋ฆฌ์˜ CloudFront๋ฅผ ๋„๋ฉ”์ธ์„ ํ†ตํ•ด ์šฐ๋ฆฌ์˜ ์›น ์‚ฌ์ดํŠธ์— ๊ณต๊ฐœ ์—ฐ๊ฒฐ์˜ ํšŒ์› ํ•œ ๋‹ค์Œ CloudFront๋ฅผ๋„ (๋‹ค๋ฅธ ๋„๋ฉ”์ธ ์ด๋ฆ„๊ณผ ์ธ์ฆ์„œ๋กœ) HTTPS๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, Gunicorn์„ ์‹คํ–‰ํ•˜๋Š” ์šฐ๋ฆฌ์˜ ๋ฐฑ์—”๋“œ ๋…ธ๋“œ์— ์š”์ฒญ์„์ด ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œํ•˜๊ณ , ๊ทธ๊ฒƒ์„ ์ œ๊ณต ๊ณต๊ณต์˜.

๋‚ด๋ถ€ ์š”์ฒญ์— ๋Œ€ํ•ด SSL์„ ์‚ฌ์šฉํ•˜๋Š” ์š”์ ์ด ๋ฌด์—‡์ธ์ง€ ๊ถ๊ธˆํ•˜์‹ ๊ฐ€์š”? ๋ฌด์˜๋ฏธํ•˜๋‹ค๊ณ  ์ฃผ์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (๋น„๋ก ๊ทธ๋ ‡์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. Amazon์ด ๋‚ด๋ถ€ ๋„คํŠธ์›Œํฌ์—์„œ ์šฐ๋ฆฌ ํ†ต์‹ ์„ ์Šค๋ˆ„ํ•‘ํ•˜๋Š” ๊ฒƒ์„ ์ค‘์ง€ํ•˜๊ณ  ๊ทœ์ œ์ƒ์˜ ์ด์œ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ํšŒ์‚ฌ์˜ ์‚ฐ์—…์„ ๊ฐ์•ˆํ•  ๋•Œ ์šฐ๋ฆฌ๋Š” ํŒŒ์ดํ”„๋ผ์ธ ์ „์ฒด์— ๊ฑธ์ณ ์•”ํ˜ธํ™”). ๋ฌด์˜๋ฏธํ•˜๋“  ์•„๋‹ˆ๋“  ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ํ•ฉ๋‹ˆ๋‹ค. ยฏ\_(ใƒ„)_/ยฏ

ํด๋ผ์šฐ๋“œํ”„๋ก ํŠธ๊ฐ€ ์—”๋“œํฌ์ธํŠธ์— ์ผ๋ฐ˜ HTTP ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ํด๋ผ์šฐ๋“œํ”„๋ก ํŠธ ๋กœ๊ทธ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ ๋ณผ ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@benoitc CloudFront๊ฐ€ ์œ ์šฉํ•œ ๋กœ๊ทธ๋ฅผ ๋…ธ์ถœํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์ง€๋งŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€

  • ๋ฐฐํฌ๋Š” "HTTPS ์ „์šฉ"์„ ํ†ตํ•ด Gunicorn ์˜ค๋ฆฌ์ง„์— ์—ฐ๊ฒฐํ•˜๋„๋ก CloudFront ์ฝ˜์†”์—์„œ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  • Gunicorn์ด ํฌํŠธ 80์—์„œ ์ˆ˜์‹  ๋Œ€๊ธฐํ•˜์ง€ ์•Š์Œ
  • ๋‚ด๊ฐ€ HTTP๋ฅผ ํ†ตํ•ด ์šฐ๋ฆฌ์˜ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„์— ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žฌ์ƒ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค (ํฌํŠธ 443์—์„œ HTTP๋ฅผ ๊ฐ•์ œ ํฌํ•จ) OSError๋Š” ์œ„์— ์ธ์šฉ
  • ์œ„์—์„œ ์ธ์šฉํ•œ OSError๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„์—์„œ Gunicorn์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ์ฆ‰์‹œ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

@ExplodingCabbage ok 20.0.1์ด ๋‚˜์˜จ ํ›„์— ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ ์–ด๋–ค ๋ฒ„์ „์˜ Python์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

3.6.8

์œ„์˜ ์ด์•ผ๊ธฐ์—์„œ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ๋น ๋œจ๋ ธ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. Gunicorn์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— Gunicorn์ด LetsEncrypt์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” SSL ์ธ์ฆ์„œ๋„ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์–ด์ œ ์˜ค๋ฅ˜๊ฐ€ ์‹œ์ž‘๋œ ๋‚  ์ธ์ฆ์„œ๊ฐ€ ๋งŒ๋ฃŒ๋  ์ผ์ด ์—†๊ณ  ์ธ์ฆ์„œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์‹ค์ œ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จ์ด ์—†๋‹ค๊ณ  ์ž˜๋ชป ๊ฒฐ๋ก ์„ ๋‚ด๋ ธ๊ธฐ ๋•Œ๋ฌธ์— ์ด์— ๋Œ€ํ•ด ์–ธ๊ธ‰ํ•  ์ƒ๊ฐ์„ ํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ผ๋ถ€ ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•œ ๊ฒฐ๊ณผ ์˜ค๋ฅ˜๊ฐ€ ์‹ค์ œ๋กœ๋Š” ์ด์ „ ์ธ์ฆ์„œ๊ฐ€ ๋งŒ๋ฃŒ๋˜๋Š” ๋‚ ๋ถ€ํ„ฐ ์‹œ์ž‘๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—๋Š” ์—ฌ์ „ํžˆ ๋ฏธ์Šคํ„ฐ๋ฆฌ์™€ ๊ฐœ์„ ์˜ ์—ฌ์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค(์ด ์˜ค๋ฅ˜๊ฐ€ ์ •ํ™•ํžˆ ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋ฉฐ Gunicorn์ด ๋” ์œ ์šฉํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์—†๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?). ๋ช…๋ฐฑํ•œ ์›์ธ ์—†์ด - ์˜ณ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. CloudFront๊ฐ€ Gunicorn ์„œ๋ฒ„์—์„œ ๋งŒ๋ฃŒ๋œ ์ธ์ฆ์„œ๋ฅผ ๋ณธ ๊ฒƒ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ์—ฐ๊ฒฐ์„ ์ข…๋ฃŒํ•˜๊ณ  ์žˆ์—ˆ๊ณ  Gunicorn์ด ์ด๋ฅผ ์ดํ•ดํ•˜๊ณ  ์˜๋ฏธ ์žˆ๊ฒŒ ๋ณด๊ณ ํ•˜๋Š” ๋Œ€์‹  ๋ฉ”์‹œ์ง€ ์—†๋Š” OSError๊ฐ€ ๋ฐœ์ƒํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

์ œ๋ณด ์ „ ์ œ ์˜ค๋ฆฌ๋“ค์„ ์—ฐ๋‹ฌ์•„ ์˜ฌ๋ฆฌ์ง€ ๋ชปํ•œ ์  ์‚ฌ๊ณผ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋” ์šฐ์•„ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ด ์˜ˆ์™ธ๋ฅผ ๋งˆ์Œ๋Œ€๋กœ ์žฌํ˜„ํ•˜๊ธฐ๊ฐ€ ๋” ์‰ฌ์›Œ์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@ExplodingCabbage ์˜ค ๊ฝค

๋ฐฉ๊ธˆ ๋™์ผํ•œ ๋ฌธ์ œ์— ์žฌํ˜„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์‹คํ–‰๋˜์—ˆ์œผ๋ฉฐ ์ผ์ข…์˜ ๋ฆฌ์†Œ์Šค ๊ณ ๊ฐˆ์˜ ๊ฒฐ๊ณผ๋ผ๊ณ  ์–ด๋Š ์ •๋„ ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜์—๊ฒŒ ๊ทธ๊ฒƒ์€ ์ฐจ๋‹จ ํ˜ธ์ถœ๊ณผ ๋ˆ„์  ์š”์ฒญ์— ๋Œ€ํ•œ ์‹œ๊ฐ„ ์ดˆ๊ณผ๋ฅผ ์žŠ์–ด๋ฒ„๋ ค์„œ ์ด‰๋ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

HTH

์—ฌ๋ณด์„ธ์š”! ์ด ์ •ํ™•ํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ ๋’ค์— ์žˆ๋Š” ECS ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์‹คํ–‰ ์ค‘์ธ gunicorn/flask ์„œ๋น„์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋ฒ„์ „ ์‚ฌ์–‘:

python    - 3.7.4
gunicorn  - 19.9.0
flask     - 1.0.4

์„œ๋น„์Šค๋Š” ๋ฌธ์ œ ์—†์ด TLS๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์—์„œ ์˜ค๋Š” ์š”์ฒญ์— ์‘๋‹ตํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋‚ด ๋กœ๊ทธ๋Š” OSErrors๋กœ ๊ฐ€๋“ ์ฐจ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์•Œ ์ˆ˜ ์žˆ๋Š” ํ•œ, ์ด๋Š” ๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ(TCP)์—์„œ ์˜ค๋Š” ์ƒํƒœ ํ™•์ธ ์š”์ฒญ์œผ๋กœ ์ธํ•ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ˆ˜์‹  ํฌํŠธ(์ด ๊ฒฝ์šฐ 8000)์—์„œ ์ˆ˜๋™์œผ๋กœ TCP ์—ฐ๊ฒฐ์„ ์—ด๊ณ  ๋‹ซ์•„ ๋กœ์ปฌ์—์„œ ์˜ค๋ฅ˜๋ฅผ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

$ nc -vz 127.0.0.1 8000
localhost [127.0.0.1] 8000 (irdmi) open

๊ทธ ๊ฒฐ๊ณผ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

Traceback (most recent call last):
    File "/nix/store/nh3v0c2nipihwblkdn0mh2kqyv3jq9nz-python3-3.7.4-env/lib/python3.7/site-packages/gunicorn/workers/sync.py" line 134 in handle
        req = six.next(parser)
    File "/nix/store/nh3v0c2nipihwblkdn0mh2kqyv3jq9nz-python3-3.7.4-env/lib/python3.7/site-packages/gunicorn/http/parser.py" line 41 in __next__
        self.mesg = self.mesg_class(self.cfg, self.unreader, self.req_count)
    File "/nix/store/nh3v0c2nipihwblkdn0mh2kqyv3jq9nz-python3-3.7.4-env/lib/python3.7/site-packages/gunicorn/http/message.py" line 181 in __init__
        super(Request, self).__init__(cfg, unreader)
    File "/nix/store/nh3v0c2nipihwblkdn0mh2kqyv3jq9nz-python3-3.7.4-env/lib/python3.7/site-packages/gunicorn/http/message.py" line 54 in __init__
        unused = self.parse(self.unreader)
    File "/nix/store/nh3v0c2nipihwblkdn0mh2kqyv3jq9nz-python3-3.7.4-env/lib/python3.7/site-packages/gunicorn/http/message.py" line 193 in parse
        self.get_data(unreader, buf, stop=True)
    File "/nix/store/nh3v0c2nipihwblkdn0mh2kqyv3jq9nz-python3-3.7.4-env/lib/python3.7/site-packages/gunicorn/http/message.py" line 184 in get_data
        data = unreader.read()
    File "/nix/store/nh3v0c2nipihwblkdn0mh2kqyv3jq9nz-python3-3.7.4-env/lib/python3.7/site-packages/gunicorn/http/unreader.py" line 38 in read
        d = self.chunk()
    File "/nix/store/nh3v0c2nipihwblkdn0mh2kqyv3jq9nz-python3-3.7.4-env/lib/python3.7/site-packages/gunicorn/http/unreader.py" line 65 in chunk
        return self.sock.recv(self.mxchunk)
    File "/nix/store/azwzsm1pkbzjxpkiq88w68p4jdghgasl-python3-3.7.4/lib/python3.7/ssl.py" line 1056 in recv
        return self.read(buflen)
    File "/nix/store/azwzsm1pkbzjxpkiq88w68p4jdghgasl-python3-3.7.4/lib/python3.7/ssl.py" line 931 in read
        return self._sslobj.read(len)
OSError: [Errno 0] Error

๋„์›€์ด ๋˜์—ˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค!

ํ , ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ์—ฐ๊ตฌ๋ฅผ ๋งˆ์นœ ํ›„ ์ด๊ฒƒ์€ ์‹ค์ œ๋กœ python ssl ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ Linux์—์„œ ๋น„์ •ํ˜• EOF๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์˜ ๋ฒ„๊ทธ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. https://bugs.python.org/issue31122

@shevisjohnson ์ด ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด "nc -vz hostname port_no"๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ด ์˜ค๋ฅ˜๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.
์•„๋ž˜์˜ ๋กœ๊น… ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ๊ทธ ํŒŒ์ผ์—์„œ ์ด ์˜ค๋ฅ˜๋ฅผ ์–ต์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$cat logging_config.yml

version: 1

formatters:
  simple:
    format: " %(asctime)s || %(name)s || %(levelname)s || %(message)s"

  test_api:
    format: "[%(asctime)s] [%(process)s] [%(levelname)s] %(message)s"

handlers:

  console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
    stream: ext://sys.stdout

  test_api_file_handler:
     class: logging.handlers.RotatingFileHandler
     level: DEBUG
     formatter: test_api
     filename: logs/test.log
     maxBytes: 2000000000
     backupCount: 1
     encoding: utf8

loggers:

  test_api: 
    level: DEBUG
    handlers: [test_api_file_handler]
    propagate: 0

root:
  level: DEBUG
  handlers: [console]

๋‹ค์Œ์€ ํŒŒ์ด์ฌ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.

import logging
import yaml
from flask import Flask

app = Flask(__name__)

def logSetter(logger_name:str) -> logging:
    with open("logging_config.yml", 'r') as f:
        config = yaml.safe_load(f)
    logging.config.dictConfig(config)
    logger = logging.getLogger(logger_name)
    return logger

logger=logSetter(logger_name="test_api")

@app.route("/api/test")
def hello():
     app.logger.info("hey from api")
     return "Hello from Python!"

๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋™์‹œ ๋กœ๋“œ ์ค‘์— ํ”„๋กœ๋•์…˜์—์„œ ์ด ์˜ค๋ฅ˜๋กœ ์ธํ•ด ์—ฌ๋Ÿฌ Gunicorn ์•ฑ์ด ์‹คํŒจํ•˜๋Š” ๊ฒƒ์„ ๊ฐ„ํ—์ ์œผ๋กœ ๊ด€์ฐฐํ–ˆ์Šต๋‹ˆ๋‹ค.

์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์žฌ์ƒ์‚ฐ์„ ์ฐพ๋Š” ๋ฐ ์ž ์‹œ ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค. hey ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ gthread ์ž‘์—…์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์‹  Gunicorn(20.0.4)์— 100๊ฐœ์˜ ๋™์‹œ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

$ hey -n 100 -c 100 https://127.0.0.1:8000

```
$ gunicorn app:app -k gthread --certfile=... --keyfile=...
...
[2020-07-11 19:10:58 +0000] [3628247] [ERROR] ์†Œ์ผ“ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ์š”์ฒญ์ž…๋‹ˆ๋‹ค.
์—ญ์ถ”์ (๊ฐ€์žฅ ์ตœ๊ทผ ํ˜ธ์ถœ ๋งˆ์ง€๋ง‰):
๋ฐ˜ํ™˜ self._sslobj.read(len)
OSError: [Errno 0] ์˜ค๋ฅ˜


Using a Debian 9 / Linux 4.14.67 based environment.

The WSGI app to reproduce need not be anything beyond:
```python
# app.py
def app(environ, start_response):
    start_response("200 OK", [])
    return ""

์ด๊ฒƒ๋„ ๋„์›€์ด๋œ๋‹ค๋ฉด!

๊ทผ๋ณธ ์›์ธ์ด ์‹ค์ œ๋กœ https://bugs.python.org/issue31122์ธ ๊ฒฝ์šฐ :

  • 3์›” 4์ผ์— ์ˆ˜์ • ์‚ฌํ•ญ์ด ์ œ์ถœ๋˜์—ˆ์ง€๋งŒ(python/cpython#18772), ์—ฌ์ „ํžˆ ํ•ต์‹ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด๋ฅผ ์ธ์ •ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์•„๋งˆ๋„ Gunicorn ์œ ์ง€ ๊ด€๋ฆฌ์ž๊ฐ€ ๊ฑฐ๊ธฐ์— ๋˜๋Š” BPO-31122์— ๊ทธ๊ฒƒ์ด gunicorn ์‚ฌ์šฉ์ž์—๊ฒŒ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ณ  ์žˆ๋‹ค๋Š” ์˜๊ฒฌ์„ ๋‚จ๊ธฐ๋ฉด ๋„์›€์ด ๋ ๊นŒ์š”?
  • Gunicorn์€ ํ•ด๋‹น ์ˆ˜์ • ์‚ฌํ•ญ์ด ๋ฆด๋ฆฌ์Šค๋˜๊ธฐ ์ด์ „์˜ ์ง€์›๋˜๋Š” Python ๋ฒ„์ „์— ๋Œ€ํ•ด ์—ฌ์ „ํžˆ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ์˜๊ฒฌ์— ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ๋ฌผ์–ด๋ณผ ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด๋Š” ์ƒ์‚ฐ ์ค‘์ธ ๋‚ด ์กฐ์ง์—๋„ ์˜ํ–ฅ์„ ๋ฏธ์น˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฒ„๊ทธ ์ˆ˜์ • ์ด 3.8 ๋ฐ 3.9 ๋ถ„๊ธฐ์— ๋„์ฐฉํ–ˆ์ง€๋งŒ <= 3.7 EOL์„ ๊ณ ๋ คํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋‹น๋ถ„๊ฐ„ 3.6์— ๊ณ ์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ gunicorn ์ž์ฒด์— ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์•Œ๋ ค์ง„ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๊ณ„ํš๋œ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋น„์Šค๋ฅผ ๊ทธ๋ ‡๊ฒŒ ๋งŽ์ด ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์กฐ์‚ฌํ•˜๊ณ  ์žˆ์ง€๋งŒ, ์˜ํ–ฅ์„ ๋ฐ›๋Š” ๋…ธ๋“œ์—์„œ ์—„์ฒญ๋‚œ ๋ฆฌ์†Œ์Šค ์ŠคํŒŒ์ดํฌ๋ฅผ ์ดˆ๋ž˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋‚ด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

3.8 ์ด์ „์— ๋ฐฑํฌํŠธํ•  ์˜์‚ฌ๊ฐ€ ์—†๋‹ค๋Š” jriddy์˜ ์˜๊ฒฌ ์™ธ์—๋„ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ์ด ๋ฌธ์ œ๋ฅผ ๊ฒช๊ณ  ์žˆ๋‹ค๋ฉด ์ˆ˜์ • ์‚ฌํ•ญ์ด CPython 3.8.6์— ํฌํ•จ๋˜๋„๋ก ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค .

์ด ํŠธ๋ ˆ์ด์Šค๋ฐฑ์ด ์–ด๋””์—์„œ ๋‚˜์˜ค๋Š”์ง€ ์ •ํ™•ํžˆ ๋งํ•˜๋Š” ๋ฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ œ ๊ฒฝ์šฐ์—๋Š” gevent ๋ฅผ WSGI ์•ฑ ์„œ๋ฒ„๋กœ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ gevent/greenlet ๋‚ด์˜ ์–ด๋”˜๊ฐ€์—์„œ ๋กœ๊น… ํ˜ธ์ถœ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜์ง€๋งŒ ์•„์ง ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. Gunicorn์˜ ๊ฒฝ์šฐ ๋™๊ธฐ ์ž‘์—…์ž์˜ ๊ฒฝ์šฐ ์—ฌ๊ธฐ์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

https://github.com/benoitc/gunicorn/blob/e636bf81989bb833d2b99104feb11e86c3f2c43a/gunicorn/workers/sync.py#L150

Gunicorn์˜ ๊ฒฝ์šฐ ๋กœ๊ทธ์˜ ๋…ธ์ด์ฆˆ๊ฐ€ ๊ฑฑ์ •๋œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import logging

class HandshakeFilter(logging.Filter):
    # example: https://docs.python.org/3/howto/logging-cookbook.html
    # I have not tested this
    def filter(self, record):
        return "socket error processing request" in record.msg.casefold()

logging.getLogger("gunicorn").addFilter(HandshakeFilter())

๊ด€๋ จ gevent ๋ฌธ์ œ: https://github.com/gevent/gevent/issues/1671

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰