์ฑ์ ์คํ ์ค์
๋๋ค.
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
๋ด ๊ธฐ์ต์ผ๋ก๋ ์ด ์ค๋ฅ๋ ํด๋ผ์ด์ธํธ๊ฐ 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๊ฐ ์ ์ฉํ ๋ก๊ทธ๋ฅผ ๋ ธ์ถํ๋ค๊ณ ์๊ฐํ์ง ์์ง๋ง ๋ค์๊ณผ ๊ฐ์
@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!"
๋์์ด ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์ ๋ขฐํ ์ ์๋ ์ฌ์์ฐ์ ์ฐพ๋ ๋ฐ ์ ์ ์๊ฐ์ด ๊ฑธ๋ ธ์ต๋๋ค. 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.8 ๋ฐ 3.9 ๋ถ๊ธฐ์ ๋์ฐฉํ์ง๋ง <= 3.7 EOL์ ๊ณ ๋ คํ๊ณ ์์ผ๋ฉฐ ๋น๋ถ๊ฐ 3.6์ ๊ณ ์ ๋์ด ์์ต๋๋ค. ํ์ฌ gunicorn ์์ฒด์ ์ด ๋ฌธ์ ์ ๋ํ ์๋ ค์ง ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์์ต๋๊น? ๊ณํ๋ ๊ฒ์ด ์์ต๋๊น?
์ฐ๋ฆฌ๋ ์ด๊ฒ์ ํธ๋ฆฌ๊ฑฐํ๊ธฐ ์ํด ์๋น์ค๋ฅผ ๊ทธ๋ ๊ฒ ๋ง์ด ํธ์ถํ ์ ์๋ ๊ฒ์ ์กฐ์ฌํ๊ณ ์์ง๋ง, ์ํฅ์ ๋ฐ๋ ๋ ธ๋์์ ์์ฒญ๋ ๋ฆฌ์์ค ์คํ์ดํฌ๋ฅผ ์ด๋ํ๊ธฐ ๋๋ฌธ์ ๋ฌด์์ ํ ์ ์๋์ง ์์๋ด๋ ค๊ณ ํฉ๋๋ค.
3.8 ์ด์ ์ ๋ฐฑํฌํธํ ์์ฌ๊ฐ ์๋ค๋ jriddy์ ์๊ฒฌ ์ธ์๋ ๋ค๋ฅธ ์ฌ๋์ด ์ด ๋ฌธ์ ๋ฅผ ๊ฒช๊ณ ์๋ค๋ฉด ์์ ์ฌํญ์ด CPython 3.8.6์ ํฌํจ๋๋๋ก ์ค์ ๋์ด ์์ต๋๋ค .
์ด ํธ๋ ์ด์ค๋ฐฑ์ด ์ด๋์์ ๋์ค๋์ง ์ ํํ ๋งํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ ๊ฒฝ์ฐ์๋ gevent
๋ฅผ WSGI ์ฑ ์๋ฒ๋ก ์ง์ ์ฌ์ฉํ๋ฏ๋ก gevent/greenlet ๋ด์ ์ด๋๊ฐ์์ ๋ก๊น
ํธ์ถ์ด๋ผ๊ณ ๊ฐ์ ํ์ง๋ง ์์ง ์ฐพ์ ์ ์์ต๋๋ค. Gunicorn์ ๊ฒฝ์ฐ ๋๊ธฐ ์์
์์ ๊ฒฝ์ฐ ์ฌ๊ธฐ์์ ๋ฐ์ํฉ๋๋ค.
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
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
ํ , ๋ช ๊ฐ์ง ์ถ๊ฐ ์ฐ๊ตฌ๋ฅผ ๋ง์น ํ ์ด๊ฒ์ ์ค์ ๋ก python
ssl
๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ Linux์์ ๋น์ ํ EOF๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ๋ฒ๊ทธ์ผ ์ ์์ต๋๋ค. https://bugs.python.org/issue31122