Gunicorn: μ’…λ£Œ μ‹ ν˜Έκ°€ μ—†λŠ”λ°λ„ "λΆ€νŒ… μž‘μ—…μž"κ°€ λ¬΄ν•œ λ°˜λ³΅λ©λ‹ˆλ‹€.

에 λ§Œλ“  2017λ…„ 12μ›” 11일  Β·  65μ½”λ©˜νŠΈ  Β·  좜처: benoitc/gunicorn

Docker에 gunicorn을 μ„€μ •ν•˜λ €κ³ ν•©λ‹ˆλ‹€. λ‘œμ»¬μ—μ„œ 잘 μž‘λ™ν•˜κ³  ν”„λ‘œλ•μ…˜ μ΄λ―Έμ§€λŠ” 둜컬 이미지와 μ •ν™•νžˆ λ™μΌν•˜μ§€λ§Œ ν”„λ‘œλ•μ…˜ Docker μ—”μ§„μ—μ„œ λ‹€μŒκ³Ό 같은 μ΄μƒν•œ λ™μž‘μ΄ λ‚˜νƒ€λ‚©λ‹ˆλ‹€.

ml-server_1     | [2017-12-11 13:18:50 +0000] [1] [INFO] Starting gunicorn 19.7.1
ml-server_1     | [2017-12-11 13:18:50 +0000] [1] [DEBUG] Arbiter booted
ml-server_1     | [2017-12-11 13:18:50 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
ml-server_1     | [2017-12-11 13:18:50 +0000] [1] [INFO] Using worker: sync
ml-server_1     | [2017-12-11 13:18:50 +0000] [8] [INFO] Booting worker with pid: 8
ml-server_1     | [2017-12-11 13:18:50 +0000] [1] [DEBUG] 1 workers
ml-server_1     | Using TensorFlow backend.
ml-server_1     | [2017-12-11 13:18:54 +0000] [11] [INFO] Booting worker with pid: 11
ml-server_1     | Using TensorFlow backend.
ml-server_1     | [2017-12-11 13:18:58 +0000] [14] [INFO] Booting worker with pid: 14
ml-server_1     | Using TensorFlow backend.
ml-server_1     | [2017-12-11 13:19:02 +0000] [17] [INFO] Booting worker with pid: 17
ml-server_1     | Using TensorFlow backend.

λͺ…λ°±ν•œ 였λ₯˜ λ©”μ‹œμ§€λ‚˜ μ’…λ£Œ μ‹ ν˜Έκ°€ μ—†μŒμ—λ„ λΆˆκ΅¬ν•˜κ³  gunicorn이 4-5μ΄ˆλ§ˆλ‹€ μž‘μ—…μžλ₯Ό λΆ€νŒ…ν•˜λŠ” κ²ƒμ²˜λŸΌ λ³΄μž…λ‹ˆλ‹€. 이 λ™μž‘μ€ μ’…λ£Œλ  λ•ŒκΉŒμ§€ λ¬΄κΈ°ν•œ κ³„μ†λ©λ‹ˆλ‹€.

μž‘μ—…μžκ°€ stderr/stdout에 아무 것도 κΈ°λ‘ν•˜μ§€ μ•Šκ³  μ’…λ£Œν•˜κ±°λ‚˜ μ€‘μž¬μžκ°€ μž‘μ—…μžλ₯Ό λ¬΄ν•œλŒ€λ‘œ 생성할 수 μžˆμŠ΅λ‹ˆκΉŒ?

그것듀은 λ™μΌν•œ 도컀 이미지이기 λ•Œλ¬Έμ— μ •ν™•νžˆ λ™μΌν•œ μ•„ν‚€ν…μ²˜μ—μ„œ μ •ν™•νžˆ λ™μΌν•œ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜κ³  μžˆμœΌλ―€λ‘œ 이것이 무엇인지(버그?) 정말 ν˜Όλž€μŠ€λŸ½μŠ΅λ‹ˆλ‹€. μ–΄λ–€ 도움이든 λŒ€λ‹¨νžˆ κ°μ‚¬ν•©λ‹ˆλ‹€!

Improvement help wanted

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

κ·Έλƒ₯ μ—…λ°μ΄νŠΈ, λ‚˜μ—κ²Œ λ¬Έμ œλŠ” μ‹€μ œλ‘œ λ©”λͺ¨λ¦¬ 였λ₯˜μ˜€μœΌλ©° λ©”λͺ¨λ¦¬ λ¬Έμ œκ°€ μˆ˜μ •λ˜λ©΄ μˆ˜μ •λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

λͺ¨λ“  65 λŒ“κΈ€

ssh -Docker μ»¨ν…Œμ΄λ„ˆμ— μž…λ ₯ν•˜λ©΄ λ‹€μŒ 였λ₯˜κ°€ λ°œκ²¬λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

Illegal instruction (core dumped)

μ•„λ§ˆλ„ gunicorn은 였λ₯˜λ₯Ό μ‚Όν‚€λŠ” λŒ€μ‹  이와 같은 였λ₯˜λ₯Ό ν‘œλ©΄ν™”ν•΄μ•Ό ν• κΉŒμš”, μ•„λ‹ˆλ©΄ λ‹€λ₯΄κ²Œ μ²˜λ¦¬ν•΄μ•Ό ν• κΉŒμš”? ν™•μ‹€ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ‹€λ₯Έ μ‚¬λžŒμ—κ²Œ 도움이 될 수 있기 λ•Œλ¬Έμ— 이것을 올릴 것이라고 μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€!

문제λ₯Ό μ‹ κ³ ν•΄ μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€!

μ–΄λ””μ„œ 이런 일이 λ°œμƒν•˜λŠ”μ§€ μ•Œ 수 μžˆλ‹€λ©΄ 맀우 도움이 될 κ²ƒμž…λ‹ˆλ‹€.

μž‘μ—…μžκ°€ μ’…λ£Œν•  λ•Œ λ‘œκΉ…μ„ μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 일반적으둜 μž‘μ—…μž μžμ²΄λŠ” κΈ°λ‘ν•˜μ§€λ§Œ 맀우 κ°‘μžκΈ° μ’…λ£Œλ˜λ©΄ κΈ°λ‘λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

κ±±μ • 마!

이 μŠ€λ ˆλ“œμ— 방금 μΆ”κ°€ν•œ Spacy에 λ¬Έμ œκ°€ μžˆλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. https://github.com/explosion/spaCy/issues/1589

μ–΄μ¨Œλ“  strace ν™•μΈν•˜λŠ” λŒ€λ‘œ SIGILL strace κ°€ λ°œμƒν•©λ‹ˆλ‹€.

--- SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPN, si_addr=0x7ff48bbe6cea} ---
+++ killed by SIGILL (core dumped) +++
Illegal instruction (core dumped)

λ‚˜λŠ” gunicorn이 이것을 μ‹λ³„ν•˜κ³  μž‘μ—…μžλ₯Ό ν™˜μƒμ μœΌλ‘œ λ‹€μ‹œ μ‹œμž‘ν•˜λŠ” 것보닀 였λ₯˜λ₯Ό 기둝할 수 μžˆλ‹€λ©΄ 쒋을 것이라고 μƒκ°ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λ‚˜λŠ” μ’…λ£Œ μ½”λ“œκ°€ μ–΄λ–»κ²Œ μž‘λ™ν•˜λŠ”μ§€ 거의 μ•Œμ§€ λͺ»ν•©λ‹ˆλ‹€!

일뢀 μ’…λ£Œ μ½”λ“œλŠ” ν™•μ‹€νžˆ νŠΉλ³„ν•œ 의미λ₯Ό 가지며 μ•„λ§ˆλ„ 이λ₯Ό 기둝할 수 μžˆμŠ΅λ‹ˆλ‹€.
http://tldp.org/LDP/abs/html/exitcodes.html

쒋은 μ†Œλ¦¬! λ˜ν•œ μ’…λ£Œ μ½”λ“œκ°€ μ˜ˆμ•½λœ μ’…λ£Œ μ½”λ“œ(예: 이 경우)κ°€ μ•„λ‹Œ 경우 μ„€λͺ… 없이 기둝될 수 있으면 λ©‹μ§ˆ κ²ƒμ΄λ―€λ‘œ μž‘μ—…μžκ°€ μ‹€μ œλ‘œ μ’…λ£Œλ˜κ³  있음이 λΆ„λͺ…ν•©λ‹ˆλ‹€.

λ‚˜λŠ” λΉ„μŠ·ν•œ λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€. gunicorn은 http μš”μ²­μ„ ν•  λ•Œ 항상 μƒˆλ‘œμš΄ μž‘μ—…μžλ₯Ό λΆ€νŒ…ν•©λ‹ˆλ‹€. λ‚˜λŠ” μ–΄λ–€ 응닡도받지 λͺ»ν•˜κ³  항상 μƒˆλ‘œμš΄ μž‘μ—…μžλ₯Ό μž¬λΆ€νŒ…ν•©λ‹ˆλ‹€. 두 http μš”μ²­μ˜ 좔적 둜그:

select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = ? ERESTARTNOHAND (To be restarted if no handler)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=510, si_uid=0, si_status=SIGSEGV, si_utime=160, si_stime=32} ---
getpid()                                = 495
rt_sigreturn({mask=[]})                 = -1 EINTR (Interrupted system call)
wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGSEGV && WCOREDUMP(s)}], WNOHANG, NULL) = 510
lseek(8, 0, SEEK_CUR)                   = 0
close(8)                                = 0
wait4(-1, 0x7ffd455ad844, WNOHANG, NULL) = 0
write(4, ".", 1)                        = 1
select(4, [3], [], [], {0, 840340})     = 1 (in [3], left {0, 840338})
read(3, ".", 1)                         = 1
read(3, 0x7f2682025fa0, 1)              = -1 EAGAIN (Resource temporarily unavailable)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
umask(0)                                = 022
getpid()                                = 495
open("/tmp/wgunicorn-q4aa72u7", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, 0600) = 8
fcntl(8, F_SETFD, FD_CLOEXEC)           = 0
chown("/tmp/wgunicorn-q4aa72u7", 0, 0)  = 0
umask(022)                              = 0
unlink("/tmp/wgunicorn-q4aa72u7")       = 0
fstat(8, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
ioctl(8, TIOCGWINSZ, 0x7ffd455b8e50)    = -1 ENOTTY (Not a tty)
lseek(8, 0, SEEK_CUR)                   = 0
lseek(8, 0, SEEK_CUR)                   = 0
rt_sigprocmask(SIG_BLOCK, ~[], [], 8)   = 0
fork()                                  = 558
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
select(0, NULL, NULL, NULL, {0, 37381}[2017-12-28 17:50:23 +0000] [558] [INFO] Booting worker with pid: 558
) = 0 (Timeout)
select(4, [3], [], [], {1, 0}loading test-eu-ovh settings
)          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0}
)          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0})          = ? ERESTARTNOHAND (To be restarted if no handler)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=499, si_uid=0, si_status=SIGSEGV, si_utime=160, si_stime=31} ---
getpid()                                = 495
rt_sigreturn({mask=[]})                 = -1 EINTR (Interrupted system call)
wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGSEGV && WCOREDUMP(s)}], WNOHANG, NULL) = 499
lseek(7, 0, SEEK_CUR)                   = 0
close(7)                                = 0
wait4(-1, 0x7ffd455ad844, WNOHANG, NULL) = 0
write(4, ".", 1)                        = 1
select(4, [3], [], [], {0, 450691})     = 1 (in [3], left {0, 450689})
read(3, ".", 1)                         = 1
read(3, 0x7f2682067de8, 1)              = -1 EAGAIN (Resource temporarily unavailable)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG, st_size=0, ...}) = 0
umask(0)                                = 022
getpid()                                = 495
open("/tmp/wgunicorn-5x9a40ca", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, 0600) = 7
fcntl(7, F_SETFD, FD_CLOEXEC)           = 0
chown("/tmp/wgunicorn-5x9a40ca", 0, 0)  = 0
umask(022)                              = 0
unlink("/tmp/wgunicorn-5x9a40ca")       = 0
fstat(7, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
ioctl(7, TIOCGWINSZ, 0x7ffd455b8e50)    = -1 ENOTTY (Not a tty)
lseek(7, 0, SEEK_CUR)                   = 0
lseek(7, 0, SEEK_CUR)                   = 0
rt_sigprocmask(SIG_BLOCK, ~[], [], 8)   = 0
fork()                                  = 579
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
select(0, NULL, NULL, NULL, {0, 8144}[2017-12-28 17:50:30 +0000] [579] [INFO] Booting worker with pid: 579
)  = 0 (Timeout)
select(4, [3], [], [], {1, 0})          = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0

λ™μΌν•œ λ¬Έμ œμ— μ§λ©΄ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. sync μž‘μ—…μž μœ ν˜•μ— λŒ€ν•΄ gunicorn λΆ€νŒ…μ΄ λͺ‡ 초 내에 λ°˜λ³΅λ©λ‹ˆλ‹€. μž‘μ—…μž μ‹œκ°„ 초과λ₯Ό 900 둜 섀정해도 도움이 λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μž‘μ—… μ „ λ‘œλ“œμ—μ„œ AWS S3μ—μ„œ 데이터λ₯Ό λ‹€μš΄λ‘œλ“œν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. λ‹€μ–‘ν•œ νŒŒμΌμ„ λ‹€μš΄λ‘œλ“œν•˜λŠ” 데 μ•½ 1λΆ„ 10μ΄ˆκ°€ μ†Œμš”λ©λ‹ˆλ‹€.

@sara-02 gunicorn을 μ‹€ν–‰ν•˜λŠ” λͺ…령쀄은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?

@benoitc gunicorn --pythonpath /src -b 0.0.0.0:$SERVICE_PORT --workers=1 -k sync -t $SERVICE_TIMEOUT flask_endpoint:app
여기에 μ œμ‹œ

@sara-02 κ°μ‚¬ν•©λ‹ˆλ‹€.

이전 μž‘μ—…μžκ°€ μ‹€μ œλ‘œ μ’…λ£Œλ©λ‹ˆκΉŒ, μ•„λ‹ˆλ©΄ 온라인 μƒνƒœλ‘œ μœ μ§€λ˜κ³  μƒˆ μž‘μ—…μžκ°€ μƒμ„±λ©λ‹ˆκΉŒ? 디버그 λ‘œκ·ΈλŠ” λ˜ν•œ 무엇을 λ³΄μ—¬μ€λ‹ˆκΉŒ?

λ‘œκ·ΈλŠ” botocore λ‘œκ·Έμ™€ ν˜Όν•©λ˜μ–΄ μžˆμ§€λ§Œ μ΄λ ‡μŠ΅λ‹ˆλ‹€.

[INFO] Booting worker with pid:  a
[INFO] Booting worker with pid:  b
[INFO] Booting worker with pid:  c

κ·ΈλŸ¬λ‚˜ λ…Έλ™μžλŠ” μ£½μž„μ„ λ‹Ήν–ˆμŠ΅λ‹ˆκΉŒ? ps ax|grep gunicorn λͺ…령을 λ°˜ν™˜ν•˜λŠ” 것은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?

@benoitc
screenshot from 2018-07-05 19-14-00

κ·ΈλŸ¬λ‚˜ ν•œ 가지 μ§ˆλ¬Έμ€ μž‘μ—…μž μ œν•œμ΄ 1둜 μ„€μ •λ˜μ–΄ μžˆμ„ λ•Œ 2개의 gunicorn ν”„λ‘œμ„ΈμŠ€κ°€ ν‘œμ‹œλ˜λŠ” μ΄μœ μž…λ‹ˆλ‹€. 주인은 ν•œ μ‚¬λžŒμ΄κ³  일꾼은 ν•œ μ‚¬λžŒμž…λ‹ˆκΉŒ?

1개의 μ€‘μž¬μž ν”„λ‘œμ„ΈμŠ€(λ§ˆμŠ€ν„°)와 N개의 μž‘μ—…μž ν”„λ‘œμ„ΈμŠ€κ°€ μžˆμŠ΅λ‹ˆλ‹€.

κ·Έλž˜μ„œ μž‘μ—…μžκ°€ λΆ€νŒ…ν•  λ•Œλ§ˆλ‹€ λͺ…령을 μ‹€ν–‰ν•©λ‹ˆκΉŒ? κ·Έλ ‡λ‹€λ©΄ 이전 μž‘μ—…μžκ°€ μ£½κ³  μƒˆ μž‘μ—…μžκ°€ μƒμ„±λ˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. μ‘°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€.

@ sara-02 λ§ˆμ§€λ§‰μœΌλ‘œ λ„μ»€μ—μ„œλ„ λ°œμƒν•©λ‹ˆκΉŒ?

@benoitc on docker-compose μ˜ˆμƒλŒ€λ‘œ μž‘λ™ν•˜μ§€λ§Œ Openshift 에 λ™μΌν•œ μ½”λ“œλ₯Ό μž…λ ₯ν•˜λ©΄ 이 였λ₯˜κ°€ ν‘œμ‹œλ©λ‹ˆλ‹€. λ©”λͺ¨λ¦¬ μš”κ΅¬ 사항을 늘리면 μˆ˜μ •λ˜μ—ˆμ§€λ§Œ docker-compose λ₯Ό 톡해 μ‘μš© ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•  λ•Œ limited 미만의 λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

κ·Έλƒ₯ μ—…λ°μ΄νŠΈ, λ‚˜μ—κ²Œ λ¬Έμ œλŠ” μ‹€μ œλ‘œ λ©”λͺ¨λ¦¬ 였λ₯˜μ˜€μœΌλ©° λ©”λͺ¨λ¦¬ λ¬Έμ œκ°€ μˆ˜μ •λ˜λ©΄ μˆ˜μ •λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

@benoitc
λ„μ»€μ—μ„œ 5개의 gunicorn μž‘μ—…μžλ₯Ό μƒμ„±ν•˜λŠ” λ™μ•ˆ λ™μΌν•œ λ¬Έμ œμ— μ§λ©΄ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
@sara-02
λ©”λͺ¨λ¦¬ 였λ₯˜μ˜ 원인을 μ–΄λ–»κ²Œ μ‹λ³„ν–ˆμŠ΅λ‹ˆκΉŒ?

image

@gulshan-gaurav 2가지 도움이 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
λ‚΄ Pod에 ν• λ‹Ήλœ λ©”λͺ¨λ¦¬λ₯Ό 늘리고 μΆ©λŒμ„ λ©ˆμ·„μŠ΅λ‹ˆλ‹€. λ‘˜μ§Έ, Openshift Zabbix 둜그λ₯Ό ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€.

@sara-02
λ‚΄ μŠ€ν…Œμ΄μ§• ν¬λ“œμ—μ„œλ„ λ©”λͺ¨λ¦¬μ— λ‘œλ“œν•˜λŠ” 파일 + λͺ¨λΈμ΄ 50Mbμ΄λ―€λ‘œ 2GB의 λ©”λͺ¨λ¦¬λŠ” 5λͺ…μ˜ μž‘μ—…μžμ—κ²Œ μΆ©λΆ„ν•΄μ•Ό ν•©λ‹ˆλ‹€.

@gulshan-gaurav μ–΄λ–€ λ¬Έμ œμ— 직면해 μžˆμŠ΅λ‹ˆκΉŒ? 거기에 5 개의 ν”„λ‘œμ„ΈμŠ€κ°€ 있으면 μ’‹μ•„ λ³΄μž…λ‹ˆλ‹€ ....

λ‚˜λŠ” 같은 λ¬Έμ œκ°€ μžˆμ—ˆλ‹€. μ •ν™•ν•œ 문제λ₯Ό 찾지 λͺ»ν–ˆμ§€λ§Œ python 3.5μ—μ„œ 3.6으둜 μ—…κ·Έλ ˆμ΄λ“œν•˜λ©΄ ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

Docker μ»¨ν…Œμ΄λ„ˆμ—μ„œ λ™μΌν•œ λ¬Έμ œμ— μ§λ©΄ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. Gunicorn은 μ‹€νŒ¨λ₯Ό μœ λ°œν•˜μ§€λ§Œ μ˜ˆμ™Έ λ˜λŠ” 였λ₯˜κ°€ μ•„λ‹Œ μ—”λ“œν¬μΈνŠΈλ₯Ό ν˜ΈμΆœν•  λ•Œλ§ˆλ‹€ Gunicorn의 둜그 νŒŒμΌμ— 좜λ ₯ν•  λ•Œλ§ˆλ‹€ μƒˆ μž‘μ—…μžλ₯Ό 계속 λ³΄νŒ…ν•©λ‹ˆλ‹€. λ‚΄κ°€ μΈμ‡„ν•˜λ„λ‘ μ„ νƒν•œ ν•­λͺ©μ΄ 기둝된 λ‹€μŒ κ°‘μžκΈ° 둜그 νŒŒμΌμ— "Booting worker with pid..."라고 ν‘œμ‹œλ©λ‹ˆλ‹€.

도움이 된 ν•œ λ‹¨κ³„λŠ” ν™˜κ²½ λ³€μˆ˜ PYTHONUNBUFFEREDλ₯Ό μΆ”κ°€ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. κ·Έ μ „μ—λŠ” 인쇄문쑰차도 사라지고 Gunicorn의 λ‘œκ·Έμ— μ €μž₯λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

μ•±μ˜ λ‹€λ₯Έ 2개 μ—”λ“œν¬μΈνŠΈκ°€ μ˜¬λ°”λ₯΄κ²Œ μž‘λ™ν•©λ‹ˆλ‹€.

λ‚˜λŠ” Gunicorn을 μ‹€ν–‰ν•©λ‹ˆλ‹€ : gunicorn localhost:5000 --enable-stdio-inheritance --error-logfile /var/log/gunicorn/error.log --access-logfile /var/log/gunicorn/access. log --capture-output --log-level 디버그

이미 Python 3.6을 μ‹€ν–‰ 쀑이고 λ©”λͺ¨λ¦¬μ— λ¬Έμ œκ°€ μ—†λŠ”μ§€ ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€.

νŽΈμ§‘: Gunicorn의 잘λͺ»μ΄ μ•„λ‹ˆλΌ Python 문제인 것 κ°™μŠ΅λ‹ˆλ‹€. 일뢀 버전 뢈일치둜 인해 νŠΉμ • μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” λ™μ•ˆ Python이 흔적 없이 μ£½μ—ˆμŠ΅λ‹ˆλ‹€.

μž‘μ—…μž λ…Έλ“œκ°€ 계속 λ‚˜μ˜€λŠ” λΉ„μŠ·ν•œ λ¬Έμ œμ— μ§λ©΄ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
Booting worker with pid: 17636 . 이전 μž‘μ—…μž λ…Έλ“œλ₯Ό 죽이고 μžˆλŠ”μ§€ λ˜λŠ” 이전 μž‘μ—…μž λ…Έλ“œκ°€ μ—¬μ „νžˆ μ‘΄μž¬ν•˜λŠ”μ§€ λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ gunicorn λͺ…령쀄 μΈμˆ˜μ— μ–ΈκΈ‰λœ μž‘μ—…μžμ˜ μˆ˜λŠ” 3 - -workers=3 ν•©λ‹ˆλ‹€. λ˜ν•œ 파이썬 버전 3.7을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

scikit-learn 쒅속성이 μΌμΉ˜ν•˜μ§€ μ•Šμ•˜μ§€λ§Œ 이λ₯Ό ν•΄κ²°ν•œ 후에도 μ—¬μ „νžˆ λ™μΌν•œ λ¬΄ν•œ μž‘μ—…μžκ°€ λ°œμƒν•©λ‹ˆλ‹€. μ–΄λ–€ μ’…λ₯˜μ˜ python 버전 뢈일치λ₯Ό μ°Ύκ³  μ‹λ³„ν•˜λŠ” 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?

OpenShift λ‚΄μ—μ„œ λ™μΌν•œ λ¬Έμ œμ— μ§λ©΄ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

image

μ΄λ―Έμ§€μ—μ„œ λ³Ό 수 μžˆλ“―μ΄ μ €λŠ” 6λͺ…μ˜ μž‘μ—…μžλ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€(3개둜 μ‹œλ„ν–ˆμŠ΅λ‹ˆλ‹€).
ν¬λ“œμ˜ λ©”λͺ¨λ¦¬λ₯Ό λŠ˜λ ΈλŠ”λ° μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λΉŒλ“œ ꡬ성:

image

μ–΄λ–€ 아이디어라도?

감사 ν•΄μš”

elb 뒀에 awsμ—μ„œ 이것을 μ‹€ν–‰ν•˜κ³  μžˆμŠ΅λ‹ˆκΉŒ? elb와 gunicorn 사이에 nginx ingressλ₯Ό λ„£μ–΄ κ·Έ 문제λ₯Ό ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€.

같은 λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€.

flask_1  | [2019-02-23 09:08:17 +0000] [1] [INFO] Starting gunicorn 19.9.0
flask_1  | [2019-02-23 09:08:17 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
flask_1  | [2019-02-23 09:08:17 +0000] [1] [INFO] Using worker: sync
flask_1  | [2019-02-23 09:08:17 +0000] [8] [INFO] Booting worker with pid: 8
flask_1  | [2019-02-23 09:08:19 +0000] [12] [INFO] Booting worker with pid: 12
flask_1  | [2019-02-23 09:08:19 +0000] [16] [INFO] Booting worker with pid: 16
flask_1  | [2019-02-23 09:08:20 +0000] [20] [INFO] Booting worker with pid: 20
flask_1  | [2019-02-23 09:08:21 +0000] [24] [INFO] Booting worker with pid: 24
flask_1  | [2019-02-23 09:08:22 +0000] [28] [INFO] Booting worker with pid: 28
flask_1  | [2019-02-23 09:08:23 +0000] [32] [INFO] Booting worker with pid: 32
flask_1  | [2019-02-23 09:08:25 +0000] [36] [INFO] Booting worker with pid: 36
flask_1  | [2019-02-23 09:08:26 +0000] [40] [INFO] Booting worker with pid: 40
flask_1  | [2019-02-23 09:08:27 +0000] [44] [INFO] Booting worker with pid: 44
flask_1  | [2019-02-23 09:08:29 +0000] [48] [INFO] Booting worker with pid: 48
flask_1  | [2019-02-23 09:08:30 +0000] [52] [INFO] Booting worker with pid: 52
flask_1  | [2019-02-23 09:08:31 +0000] [56] [INFO] Booting worker with pid: 56
flask_1  | [2019-02-23 09:08:33 +0000] [60] [INFO] Booting worker with pid: 60
flask_1  | [2019-02-23 09:08:34 +0000] [64] [INFO] Booting worker with pid: 64
flask_1  | [2019-02-23 09:08:35 +0000] [68] [INFO] Booting worker with pid: 68
flask_1  | [2019-02-23 09:08:36 +0000] [72] [INFO] Booting worker with pid: 72
flask_1  | [2019-02-23 09:08:37 +0000] [76] [INFO] Booting worker with pid: 76
flask_1  | [2019-02-23 09:08:38 +0000] [80] [INFO] Booting worker with pid: 80
flask_1  | [2019-02-23 09:08:40 +0000] [84] [INFO] Booting worker with pid: 84
flask_1  | [2019-02-23 09:08:41 +0000] [88] [INFO] Booting worker with pid: 88
flask_1  | [2019-02-23 09:08:42 +0000] [92] [INFO] Booting worker with pid: 92
flask_1  | [2019-02-23 09:08:44 +0000] [96] [INFO] Booting worker with pid: 96
flask_1  | [2019-02-23 09:08:45 +0000] [100] [INFO] Booting worker with pid: 100
flask_1  | [2019-02-23 09:08:45 +0000] [104] [INFO] Booting worker with pid: 104
flask_1  | [2019-02-23 09:08:46 +0000] [108] [INFO] Booting worker with pid: 108
flask_1  | [2019-02-23 09:08:47 +0000] [112] [INFO] Booting worker with pid: 112
flask_1  | [2019-02-23 09:08:48 +0000] [116] [INFO] Booting worker with pid: 116
flask_1  | [2019-02-23 09:08:49 +0000] [120] [INFO] Booting worker with pid: 120
flask_1  | [2019-02-23 09:08:50 +0000] [124] [INFO] Booting worker with pid: 124
flask_1  | [2019-02-23 09:08:52 +0000] [128] [INFO] Booting worker with pid: 128

λ‹€μŒμ€ docker-compose.yml .

version: '3'
services:
  flask:
    build: .
    command: gunicorn -b 0.0.0.0:5000 hello:app --reload
    environment:
      - FLASK_APP=hello.py
      - FLASK_DEBUG=1
      - PYTHONUNBUFFERED=True
    ports:
      - "5000:5000"
    volumes:
      - ./:/root

μ–΄λ–€ 도컀 이미지λ₯Ό μ‚¬μš©ν•©λ‹ˆκΉŒ?

@benoitc

[ec2-user@ip-172-31-85-181 web-services-course]$ docker --version
Docker version 18.06.1-ce, build e68fc7a215d7133c34aa18e3b72b4a21fd0c6136
[ec2-user@ip-172-31-85-181 web-services-course]$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01

λ‹€μŒ λ§ν¬λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

λ©”λͺ¨λ¦¬ λΆ€μ‘±μœΌλ‘œ μΈν•œ 것일 수 μžˆμŒμ„ μ•Œμ•˜μŠ΅λ‹ˆλ‹€. 앱에 μ‚¬μš© κ°€λŠ₯ν•œ 것보닀 더 λ§Žμ€ λ©”λͺ¨λ¦¬κ°€ ν•„μš”ν•©λ‹ˆλ‹€.
κ·ΈλŸ¬λ‚˜ 그것은 단지 κ°€μ •μž…λ‹ˆλ‹€

정보: 3λͺ…μ˜ μž‘μ—…μžμ— λŒ€ν•œ gunicorn confκ°€ μžˆμ„ λ•Œ μ •ν™•νžˆ 이 λ™μž‘μ„ κ΄€μ°°ν–ˆμ§€λ§Œ 단일 μ½”μ–΄ CPUκ°€ μžˆλŠ” 가상 머신에 μ½”λ“œλ₯Ό λ°°ν¬ν–ˆμŠ΅λ‹ˆλ‹€. 그런 λ‹€μŒ 2개의 μ½”μ–΄λ₯Ό μ‚¬μš©ν•˜λ„λ‘ ν™˜κ²½μ„ λ³€κ²½ν•˜κ³  λΆ„λͺ…νžˆ λ¬Έμ œκ°€ μ‚¬λΌμ‘ŒμŠ΅λ‹ˆλ‹€.

INFO μˆ˜μ€€μ—μ„œλ§Œ 'Worker exiting'이 λ°œμƒν•˜λŠ” μ΄μœ λŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ? 였λ₯˜κ°€ λ°œμƒν•œ 경우λ₯Ό μ œμ™Έν•˜κ³  μž‘μ—…μžκ°€ μ’…λ£Œλ˜λŠ” μ΄μœ λŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ? λ‚΄ μž‘μ—…μž μŠ€λ ˆλ“œκ°€ μ‹œμŠ€ν…œ OOM ν‚¬λŸ¬μ— μ˜ν•΄ μ£½μž„μ„ λ‹Ήν•˜κ³  μžˆλ‹€λŠ” 사싀을 ν™•μΈν•˜λŠ” 데 였랜 μ‹œκ°„μ΄ κ±Έλ ΈμŠ΅λ‹ˆλ‹€. μœ„μ˜ λ‹€λ₯Έ μ‚¬λžŒλ“€μ΄ λ³΄κ³ ν•œ κ²ƒμ²˜λŸΌ λ•Œλ•Œλ‘œ 'pid둜 μž‘μ—…μž λΆ€νŒ…'을 μ œμ™Έν•˜κ³  λ‘œκ·Έμ—λŠ” 아무 것도 μ—†μŠ΅λ‹ˆλ‹€.

μž‘μ—…μžκ°€ μ’…λ£Œν•˜λŠ” 것이 λ°˜λ“œμ‹œ 였λ₯˜λŠ” μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— --max-requests 와 같은 μ˜΅μ…˜μœΌλ‘œ μ’…λ£Œλ  수 μžˆμŠ΅λ‹ˆλ‹€.

@HughWarrington μž‘μ—…μžκ°€ 비정상적인 μ’…λ£Œ μ½”λ“œλ‘œ μ’…λ£Œν•  λ•Œ μ€‘μž¬μžμ— λ‘œκΉ…μ„ μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이에 λŒ€ν•œ 티켓을 μ—΄κ±°λ‚˜ 이 μ½”λ“œλ₯Ό reap_workers λ©”μ„œλ“œμ— μΆ”κ°€ν•˜λŠ” PR을 μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” 같은 λ¬Έμ œκ°€ μžˆμ—ˆκ³  해결책은 ν¬λ“œμ˜ λ©”λͺ¨λ¦¬ 크기λ₯Ό λŠ˜λ¦¬λŠ” 것이 μ—ˆμŠ΅λ‹ˆλ‹€.

λŒ€ν˜• spaCy λͺ¨λΈλ‘œ Dockerμ—μ„œ Gunicorn을 μ‹€ν–‰ν•˜λŠ” 것과 λ™μΌν•œ λ¬Έμ œκ°€ μžˆμ—ˆμ§€λ§Œ 였λ₯˜ λ©”μ‹œμ§€ 없이 μž‘μ—…μžλ₯Ό 계속 λ‹€μ‹œ μ‹œμž‘ν–ˆμŠ΅λ‹ˆλ‹€. 해결책은 Docker μ»¨ν…Œμ΄λ„ˆμ˜ λ©”λͺ¨λ¦¬λ₯Ό λŠ˜λ¦¬λŠ” κ²ƒμž…λ‹ˆλ‹€.

Kubernetesμ—μ„œ μ‹€ν–‰λ˜λŠ” gevent(1.4.0) μž‘μ—…μžκ°€ μžˆλŠ” μ΅œμ‹ (19.9.0) gunicornμ—μ„œ 였늘 이 λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. 앱은 Falcon 앱이고 Docker μ΄λ―Έμ§€λŠ” 3.7.3 νƒœκ·Έκ°€ μžˆλŠ” 곡식 Python 이미지 μž…λ‹ˆλ‹€.

[2019-07-05 00:07:42 +0000] [8] [INFO] Starting gunicorn 19.9.0
[2019-07-05 00:07:42 +0000] [8] [INFO] Listening at: http://0.0.0.0:5000 (8)
[2019-07-05 00:07:42 +0000] [8] [INFO] Using worker: gevent
[2019-07-05 00:07:43 +0000] [35] [INFO] Booting worker with pid: 35
[2019-07-05 00:07:43 +0000] [36] [INFO] Booting worker with pid: 36
[2019-07-05 00:07:43 +0000] [37] [INFO] Booting worker with pid: 37
[2019-07-05 00:07:43 +0000] [38] [INFO] Booting worker with pid: 38
[2019-07-05 00:07:43 +0000] [41] [INFO] Booting worker with pid: 41
[2019-07-05 00:07:43 +0000] [43] [INFO] Booting worker with pid: 43
[2019-07-05 00:07:43 +0000] [45] [INFO] Booting worker with pid: 45
[2019-07-05 00:07:43 +0000] [49] [INFO] Booting worker with pid: 49
[2019-07-05 00:07:43 +0000] [47] [INFO] Booting worker with pid: 47
[2019-07-05 00:07:49 +0000] [53] [INFO] Booting worker with pid: 53
[2019-07-05 00:07:50 +0000] [54] [INFO] Booting worker with pid: 54
[2019-07-05 00:07:53 +0000] [57] [INFO] Booting worker with pid: 57
[...]

ν¬λ“œμ—λŠ” λ‹€μŒ λ¦¬μ†ŒμŠ€ 섀정이 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

resources:
  requests:
    cpu: 250m
    memory: 256Mi
  limits:
    cpu: 500m
    memory: 512Mi

λͺ¨λ“  것을 두 배둜 늘리면 λ¬Έμ œκ°€ ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

ν•œ 가지 ν₯미둜운 점은 호슀트 μ‹œμŠ€ν…œμ—μ„œ dmesg λ₯Ό λ³Ό λ•Œ SSL을 μ‚¬μš©ν•˜μ—¬ μ„œλ²„μ— μ•‘μ„ΈμŠ€ν•  λ•Œ segfault -ing at libcrypto μž„μ„ μ•Œ 수 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

λ©”λͺ¨λ¦¬μ— 큰 λͺ¨λΈμ„ λ‘œλ“œν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— λ©”λͺ¨λ¦¬λŠ” λ¬Έμ œκ°€ λ˜μ§€ μ•ŠλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. μž‘μ—…μžκ°€ 계속 μΆ©λŒν•˜κ³  였λ₯˜ λ©”μ‹œμ§€κ°€ ν‘œμ‹œλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 이에 λŒ€ν•œ μˆ˜μ • 사항이 μžˆμŠ΅λ‹ˆκΉŒ?

image

λ‚˜μ—κ²Œ 같은 문제, κ³ μΉ  생각이 μžˆμŠ΅λ‹ˆκΉŒ? gunicorn 19.9.0이 ν¬ν•¨λœ python 3.6.3

@MrKiven λ‹Ήμ‹ μ˜ 앱은 무엇을 ν•©λ‹ˆκΉŒ? μš”μ²­κ³Ό 같은 것을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆκΉŒ?

λˆ„κ΅°κ°€ 문제λ₯Ό μž¬ν˜„ν•˜λŠ” 방법을 μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆκΉŒ?

νŒŒμ΄ν”„λΌμΈμ—μ„œ μ‹€ν–‰λ˜λŠ” μ—¬λŸ¬ ꡬ성 μš”μ†Œμ˜ κ΄€λ¦¬μžμž…λ‹ˆλ‹€. κ·Έλ“€ 쀑 μΌλΆ€λŠ” λ™μΌν•œ μ‹œμŠ€ν…œ λ˜λŠ” 원격 μ‹œμŠ€ν…œμ˜ λ‹€λ₯Έ ꡬ성 μš”μ†Œμ— λŒ€ν•œ HTTP μš”μ²­μ„ μ‹œμž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€. νŒŒμ΄ν”„λΌμΈμ˜ 일뢀 λͺ¨λ“ˆμ€ λ³‘λ ¬λ‘œ μ‹€ν–‰ν•  수 μžˆμ§€λ§Œ ThreadPoolExecutorλ₯Ό μ‚¬μš©ν•˜μ—¬ μ‹€ν–‰λ©λ‹ˆλ‹€. 곡유 객체λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šμ§€λ§Œ λ‚˜μ€‘μ— 단일 결과둜 μ§‘κ³„λ˜λŠ” 데이터 ꡬ쑰만 μƒμ„±ν•©λ‹ˆλ‹€.

λΆˆν–‰νžˆλ„ μš°λ¦¬κ°€ 가지고 μžˆλŠ” μ‹œμŠ€ν…œμ„ λ…ΈμΆœν•˜μ§€ μ•Šκ³  μ΅œμ†Œν•œμ˜ 예λ₯Ό λ§Œλ“€ 수 μžˆλŠ”μ§€ ν™•μ‹ ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

μš”μ²­μ€ λ•Œλ•Œλ‘œ μƒˆ ν”„λ‘œμ„ΈμŠ€λ₯Ό λΆ„κΈ°ν•˜λŠ” μŠ€λ ˆλ“œλ‘œ λ§Žμ€ μ•ˆμ „ν•˜μ§€ μ•Šμ€ μž‘μ—…μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€. λ‹€λ₯Έ ν΄λΌμ΄μ–ΈνŠΈλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. μš”μ²­μ„ μˆ˜ν–‰ν•˜λŠ” 데 μ‚¬μš©ν•˜λŠ” μ΅œμ†Œν•œ 쀄을 뢙여넣을 수 μžˆμŠ΅λ‹ˆκΉŒ? μ‹œκ°„ 초과 κΈ°λŠ₯을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆκΉŒ?

κ·Έ 쀑 ν•˜λ‚˜λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

try:
     resp = requests.post(self._endpoint, json=request_data)

     if resp.status_code != 200:
          logger.critical("[Error]: status code is {}".format(resp.status_code))
          return None

     response = resp.json()
     return {"intent": response["intent"], "intent_ranking": response["intent_ranking"]}
except ConnectionError as exc:
     logger.critical("[Exception] {}".format(str(exc)))
     return None

감사 ν•΄μš”. λ‚˜λŠ” κ·Έκ²ƒμ—μ„œ κ°„λ‹¨ν•œ 것을 λ§Œλ“€λ €κ³  λ…Έλ ₯ν•  κ²ƒμž…λ‹ˆλ‹€.

μ–΄μ¨Œλ“  λˆ„κ΅°κ°€κ°€ μ˜ˆμ œλ‚˜ λ‹¨μœ„ ν…ŒμŠ€νŠΈλ‘œ λ™μž‘μ„ μž¬ν˜„ν•˜λŠ” pr을 보내어 μ‹€μ œλ‘œ μ˜¬λ°”λ₯Έ 것을 μˆ˜μ •ν•˜κ³  μžˆλŠ”μ§€ 확인할 수 μžˆλ‹€λ©΄ 정말 쒋을 κ²ƒμž…λ‹ˆλ‹€.

λˆ„κ΅°κ°€λ₯Ό λ„μšΈ 수 μžˆλŠ”μ§€ ν™•μ‹€ν•˜μ§€ μ•Šμ§€λ§Œ dockerized flask webapp을 μ‹€ν–‰ν•˜λŠ” λ™μ•ˆ λ™μΌν•œ λ¬Έμ œκ°€ λ°œμƒν•˜μ—¬ dockerfile의 κΈ°λ³Έ 이미지λ₯Ό python:3.6.9-alpine μ—…λ°μ΄νŠΈν•˜μ—¬ ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€.

호슀트의 DmesgλŠ” lilibpython3.6m.so.1.0μ—μ„œ segfaultλ₯Ό ν‘œμ‹œν–ˆμŠ΅λ‹ˆλ‹€.

[626278.653010] gunicorn[19965]: segfault at 70 ip 00007f6423e7faee sp 00007ffc4e9a2a38 error 4 in libpython3.6m.so.1.0[7f6423d8a000+194000]

λ‚΄ 도컀 μ΄λ―Έμ§€λŠ” python:3.6-alpine 기반으둜 apk update λ₯Ό μˆ˜ν–‰ν–ˆμŠ΅λ‹ˆλ‹€.

λ§ν–ˆλ“―μ΄ κΈ°λ³Έ 이미지λ₯Ό python:3.6.9-alpine λ³€κ²½ν•˜λ©΄ ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

Flask + Docker + Kubernetesλ₯Ό μ‹€ν–‰ν•˜λŠ” 것과 λ™μΌν•œ λ¬Έμ œμ— μ§λ©΄ν–ˆμŠ΅λ‹ˆλ‹€. CPU 및 λ©”λͺ¨λ¦¬ μ œν•œμ„ 늘리면 ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

같은 일이 μš°λ¦¬μ—κ²Œλ„ μΌμ–΄λ‚¬μŠ΅λ‹ˆλ‹€. λ¦¬μ†ŒμŠ€ μ œν•œμ„ 늘리면 λ¬Έμ œκ°€ ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

이것은 macOS Catalina(μ»¨ν…Œμ΄λ„ˆν™”λ˜μ§€ μ•ŠμŒ)μ—μ„œ κ°‘μžκΈ° λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.

λ‚˜λ₯Ό λ„μš΄ 것은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  1. openssl μ„€μΉ˜:
brew install openssl
  1. 이것을 μ‹€ν–‰ν•˜κ³  ~/.zshrc :
export DYLD_LIBRARY_PATH=/usr/local/opt/openssl/lib:$DYLD_LIBRARY_PATH

좜처: https://stackoverflow.com/a/58445755/5811984

λΉ„μŠ·ν•œ 도전을 ν•˜κ³  있고 λˆ„κ΅°κ°€κ°€ λ‚˜λ₯Ό λ„μšΈ 수 μžˆλ‹€λ©΄ 감사할 κ²ƒμž…λ‹ˆλ‹€.
이것이 λ‚΄κ°€ 가진 κ²ƒμž…λ‹ˆλ‹€.

" root@ubuntu-s-1vcpu-1gb-nyc1-01 :~# sudo systemctl status gunicorn.service ● gunicorn.service - gunicorn 데λͺ¬ λ‘œλ“œλ¨: λ‘œλ“œλ¨(/etc/systemd/system/gunicorn.service, λΉ„ν™œμ„±ν™”λ¨, 곡급업체 사전 μ„€μ •: ν™œμ„±ν™”λ¨) ν™œμ„±: ν™œμ„±(μ‹€ν–‰ 쀑) 이후 μ›”μš”μΌ 2020-02-24 07:48:04 UTC, 44λΆ„ μ „ 메인 PID: 4846(gunicorn) μž‘μ—…: 4(μ œν•œ: 1151) CGroup: /system.slice/gunicorn.service β”œ ─4846 /home/bright/djangoprojectdir/djangoprojectenv/bin/python /home/bright/djangoprojectdir/djangoprojectenv/bin/gunicorn - β”œβ”€4866 /home/bright/djangoprojectdir/djangoprojectenv/bin/python /home/bright/djangoproject /bin/gunicorn - β”œβ”€4868 /home/bright/djangoprojectdir/djangoprojectenv/bin/python /home/bright/djangoprojectdir/djangoprojectenv/bin/gunicorn - └─4869 /home/bright/djangoprojectdir/djangoprojectenv/home/bin/pyth /bright/djangoprojectdir/djangoprojectenv/bin/gunicorn - 2μ›” 24일 07:48:04 ubuntu-s-1vcpu-1gb-nyc1-01 systemd[1]: gunicorn 데λͺ¬μ΄ μ€‘μ§€λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 2μ›” 24일 07:48:04 ubuntu-s-1vcpu -1GB-nyc1-01 systemd[1 ]: gunicorn 데λͺ¬μ„ μ‹œμž‘ν–ˆμŠ΅λ‹ˆλ‹€. 2μ›” 24일 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: [2020-02-24 07:48:05 +0000] [4846] [INFO] gunicorn μ‹œμž‘ 20.0.4 2μ›” 24일 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: [2020-02-24 07:48:05 +0000] [4846] [INFO] λ“£κΈ°: unix:/run/gunicorn .soc 2μ›” 24일 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: [2020-02-24 07:48:05 +0000] [4846] [INFO] μž‘μ—…μž μ‚¬μš©: sync 2μ›” 24 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: [2020-02-24 07:48:05 +0000] [4866] [INFO] pid둜 μž‘μ—…μž λΆ€νŒ…: 4866 Feb 24 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: [2020-02-24 07:48:05 +0000] [4868] [INFO] pid둜 μž‘μ—…μž λΆ€νŒ…: 4868 Feb 24 07 :48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: [2020-02-24 07:48:05 +0000] [4869] [INFO] pidκ°€ μžˆλŠ” λΆ€νŒ… μž‘μ—…μž: 4869 Feb 24 08: 03:41 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: - - [24/Feb/2020:08:03:41 +0000] "GET / HTTP/1.0" 400 26 "-" "Mozilla /5.0 (Wi 라인 1-20/20(μ’…λ£Œ)" 이 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 데 도움을 쀄 수 μžˆλŠ” μ‚¬λžŒμ΄ μžˆμŠ΅λ‹ˆκΉŒ?

@BrightNana dmesg 을 μ£Όκ³  gunicorn 였λ₯˜κ°€ μžˆλŠ”μ§€ 확인할 수 μžˆμŠ΅λ‹ˆκΉŒ?
dmesg | grep gunicorn λŠ” λ‹€λ₯Έ 였λ₯˜λ₯Ό ν•„ν„°λ§ν•˜λŠ” 데 도움이 될 수 μžˆμŠ΅λ‹ˆλ‹€.

μ•ˆλ…•ν•˜μ‹­λ‹ˆκΉŒ,
λ‚˜λŠ” gunicorn을 systemd μ„œλΉ„μŠ€λ‘œ μ œκ³΅ν•˜κ³  싢을 λ•Œ λ°λΉ„μ•ˆ 9에 같은 버그가 μžˆμŠ΅λ‹ˆλ‹€. CLIμ—μ„œ μ‹œμž‘ν•˜λ©΄ gunicorn이 였λ₯˜ 없이 μ‹€ν–‰λ©λ‹ˆλ‹€.

dmesg | grep gunicorn μ—μ„œ μΆ”μΆœ:

journalctl μ—μ„œ 발췌:
MΓ€r 12 07:01:06 build-server gunicorn[828]: [2020-03-12 07:01:06 +0100] [1054] [INFO] Booting worker with pid: 1054 MΓ€r 12 07:01:06 build-server gunicorn[828]: [2020-03-12 07:01:06 +0100] [1057] [INFO] Booting worker with pid: 1057 MΓ€r 12 07:01:06 build-server gunicorn[828]: [2020-03-12 07:01:06 +0100] [1060] [INFO] Booting worker with pid: 1060 MΓ€r 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1064] [INFO] Booting worker with pid: 1064 MΓ€r 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1067] [INFO] Booting worker with pid: 1067 MΓ€r 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1070] [INFO] Booting worker with pid: 1070 MΓ€r 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1073] [INFO] Booting worker with pid: 1073 MΓ€r 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1076] [INFO] Booting worker with pid: 1076 MΓ€r 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1079] [INFO] Booting worker with pid: 1079 MΓ€r 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1082] [INFO] Booting worker with pid: 1082 MΓ€r 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1085] [INFO] Booting worker with pid: 1085 MΓ€r 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1088] [INFO] Booting worker with pid: 1088 MΓ€r 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1091] [INFO] Booting worker with pid: 1091 MΓ€r 12 07:01:09 build-server gunicorn[828]: [2020-03-12 07:01:09 +0100] [1094] [INFO] Booting worker with pid: 1094
systemctl status μ—μ„œ μΆ”μΆœ:
● api.service - API Server for BuildingChallenge served with Gunicorn Loaded: loaded (/etc/systemd/system/api.service; disabled; vendor preset: enabled) Active: active (running) since Thu 2020-03-12 08:26:01 CET; 22min ago Main PID: 8150 (gunicorn) Tasks: 3 (limit: 4915) Memory: 37.7M (high: 100.0M max: 500.0M) CGroup: /system.slice/api.service β”œβ”€ 8150 /opt/api/venv/bin/python /opt/api/venv/bin/gunicorn --bind unix:api.sock wsgi:app β”œβ”€28936 /opt/api/venv/bin/python /opt/api/venv/bin/gunicorn --bind unix:api.sock wsgi:app └─28938 /usr/bin/python3 -Es /usr/bin/lsb_release -a MΓ€r 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28909] [INFO] Booting worker with pid: 28909 MΓ€r 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28912] [INFO] Booting worker with pid: 28912 MΓ€r 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28915] [INFO] Booting worker with pid: 28915 MΓ€r 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28918] [INFO] Booting worker with pid: 28918 MΓ€r 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28921] [INFO] Booting worker with pid: 28921 MΓ€r 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28924] [INFO] Booting worker with pid: 28924 MΓ€r 12 08:48:02 build-server gunicorn[8150]: [2020-03-12 08:48:02 +0100] [28927] [INFO] Booting worker with pid: 28927 MΓ€r 12 08:48:02 build-server gunicorn[8150]: [2020-03-12 08:48:02 +0100] [28930] [INFO] Booting worker with pid: 28930 MΓ€r 12 08:48:02 build-server gunicorn[8150]: [2020-03-12 08:48:02 +0100] [28933] [INFO] Booting worker with pid: 28933 MΓ€r 12 08:48:02 build-server gunicorn[8150]: [2020-03-12 08:48:02 +0100] [28936] [INFO] Booting worker with pid: 28936

λ‹Ήμ‹ μ˜ 도움을 μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€.

μ΄λŸ¬ν•œ 상황을 λ””λ²„κΉ…ν•˜λŠ” 데 도움이 될 수 μžˆλŠ” PR을 κ²Œμ‹œν–ˆμŠ΅λ‹ˆλ‹€. μ•„λ¬΄λ‚˜ λ³Ό 수 μžˆλ‚˜μš”?
https://github.com/benoitc/gunicorn/pull/2315

Docker λ‚΄μ—μ„œ μ‹€ν–‰λ˜λŠ” Flask μ‘μš© ν”„λ‘œκ·Έλž¨κ³Ό λ™μΌν•œ λ¬Έμ œκ°€ μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μž‘μ—…μžλŠ” μ¦κ°€ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€ ID둜 λ¬΄ν•œνžˆ λ‹€μ‹œ μ‹œμž‘λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
image

λ¬Έμ œλŠ” 저와 κ΄€λ ¨λœ λ©”λͺ¨λ¦¬μ˜€μŠ΅λ‹ˆλ‹€. Docker에 ν—ˆμš©λ˜λŠ” λ©”λͺ¨λ¦¬λ₯Ό 늘리면 μž‘μ—…μžκ°€ 효과적으둜 μƒμ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
image

@tilgovi , 당신이 λ¨Όμ € 거기에 λ„μ°©ν•œ μ΄ν›„λ‘œ 당신이 λ‚˜μ˜ λ³€κ²½ 사항을 λ‹Ήμ‹ μ˜ PR에 ν†΅ν•©ν•˜κ³  μ‹Άλ‹€λ©΄ λ‚˜λŠ” μƒκ΄€ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 이것은 μ‹ ν˜Έλ₯Ό 톡해 μ‚΄ν•΄λ˜λŠ” λ…Έλ™μžλ₯Ό λ‹€λ£° κ²ƒμž…λ‹ˆλ‹€.

@mildebrandt ν•œλ²ˆ λ³Όκ²Œμš” κ°μ‚¬ν•©λ‹ˆλ‹€!

λ˜ν•œ Docker μ»¨ν…Œμ΄λ„ˆ λ‚΄λΆ€μ—μ„œ Gunicorn(20.0.4) + Gevent(1.5.0) + Flaskλ₯Ό μ‚¬μš©ν•˜μ—¬ 이 λ™μž‘μ„ κ°‘μžκΈ° 보고 μžˆμŠ΅λ‹ˆλ‹€.

[  328.699160] gunicorn[5151]: segfault at 78 ip 00007fc1113c16be sp 00007ffce50452a0 error 4 in _greenlet.cpython-37m-x86_64-linux-gnu.so[7fc11138d000+3e000]

제 κ²½μš°μ—λŠ” segfaultκ°€ gevent에 μ˜ν•΄ λ°œμƒν•˜λŠ” 것을 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄μƒν•œ 점은 이 μ»¨ν…Œμ΄λ„ˆκ°€ 5일 전에 μ œλŒ€λ‘œ μž‘λ™ν–ˆμœΌλ©° κ·Έ μ΄ν›„λ‘œ μ½”λ“œκ°€ λ³€κ²½λ˜μ§€ μ•Šκ³  라이브러리의 버전이 λ³€κ²½λ˜μ§€ μ•Šκ³  λͺ¨λ‘ νŠΉμ • 릴리슀둜 μ„€μ •λ˜μ—ˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. λ‹€λ₯Έ μ’…μ†μ„±μ˜ 버전을 μ•½κ°„ λ³€κ²½ν–ˆμ„ 수 μžˆλŠ” μ’…μ†μ„±μœΌλ‘œ flask-mail을 μ œκ±°ν–ˆμŠ΅λ‹ˆλ‹€.

gevent==1.5.0μ—μ„œ gevent==20.9.0으둜 μ—…λ°μ΄νŠΈν•˜λ©΄ λ¬Έμ œκ°€ ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

@ifiddes κ·€ν•˜μ˜ λ¬Έμ œλŠ” 관련이 없을 수 μžˆμŠ΅λ‹ˆλ‹€. μ΅œμ‹  λ²„μ „μ˜ greenletκ³Ό 이전 λ²„μ „μ˜ gevent 간에 ABI ν˜Έν™˜μ„± λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. https://github.com/python-greenlet/greenlet/issues/178 μ°Έμ‘°

μ•„, κ°μ‚¬ν•©λ‹ˆλ‹€ @jamadden. 이 κ²Œμ‹œλ¬Όμ€ λΆ€νŒ… μž‘μ—…μžμ˜ λ¬΄ν•œ 생성을 검색할 λ•Œ 찾을 수 μžˆλŠ” μ „λΆ€μ˜€μ§€λ§Œ ν•΄λ‹Ή λ¬Έμ œμ™€ ν•΄λ‹Ή 문제의 타이밍이 λ‚΄ λ¬Έμ œμ— λ§žμŠ΅λ‹ˆλ‹€.

Ubuntu 20.04 Server κ°€ μžˆλŠ” μƒˆ AWS λ¨Έμ‹ κ³Ό ν”„λ‘œλ•μ…˜μ—μ„œ μž‘λ™ν•˜λŠ” λ™μΌν•œ μ½”λ“œμ—μ„œ μœ μ‚¬ν•œ 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.

머신은 λ‹€λ₯Έ ν”„λ‘œλ•μ…˜ λ¨Έμ‹ κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ Ansible을 μ‚¬μš©ν•˜μ—¬ κ΅¬μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

[2020-10-15 15:11:49 +0000] [18068] [DEBUG] Current configuration:
  config: None
  bind: ['127.0.0.1:8000']
  backlog: 2048
  workers: 1
  worker_class: uvicorn.workers.UvicornWorker
  threads: 1
  worker_connections: 1000
  max_requests: 0
  max_requests_jitter: 0
  timeout: 30
  graceful_timeout: 30
  keepalive: 2
  limit_request_line: 4094
  limit_request_fields: 100
  limit_request_field_size: 8190
  reload: False
  reload_engine: auto
  reload_extra_files: []
  spew: False
  check_config: False
  preload_app: False
  sendfile: None
  reuse_port: False
  chdir: /var/www/realistico/app
  daemon: False
  raw_env: []
  pidfile: None
  worker_tmp_dir: None
  user: 1001
  group: 1001
  umask: 0
  initgroups: False
  tmp_upload_dir: None
  secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
  forwarded_allow_ips: ['127.0.0.1']
  accesslog: /var/www/realistico/logs/gunicorn/access.log
  disable_redirect_access_to_syslog: False
  access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
  errorlog: /var/www/realistico/logs/gunicorn/error.log
  loglevel: debug
  capture_output: False
  logger_class: gunicorn.glogging.Logger
  logconfig: None
  logconfig_dict: {}
  syslog_addr: udp://localhost:514
  syslog: False
  syslog_prefix: None
  syslog_facility: user
  enable_stdio_inheritance: False
  statsd_host: None
  dogstatsd_tags: 
  statsd_prefix: 
  proc_name: None
  default_proc_name: realistico.asgi:application
  pythonpath: None
  paste: None
  on_starting: <function OnStarting.on_starting at 0x7f7ba5fdd550>
  on_reload: <function OnReload.on_reload at 0x7f7ba5fdd670>
  when_ready: <function WhenReady.when_ready at 0x7f7ba5fdd790>
  pre_fork: <function Prefork.pre_fork at 0x7f7ba5fdd8b0>
  post_fork: <function Postfork.post_fork at 0x7f7ba5fdd9d0>
  post_worker_init: <function PostWorkerInit.post_worker_init at 0x7f7ba5fddaf0>
  worker_int: <function WorkerInt.worker_int at 0x7f7ba5fddc10>
  worker_abort: <function WorkerAbort.worker_abort at 0x7f7ba5fddd30>
  pre_exec: <function PreExec.pre_exec at 0x7f7ba5fdde50>
  pre_request: <function PreRequest.pre_request at 0x7f7ba5fddf70>
  post_request: <function PostRequest.post_request at 0x7f7ba5f6e040>
  child_exit: <function ChildExit.child_exit at 0x7f7ba5f6e160>
  worker_exit: <function WorkerExit.worker_exit at 0x7f7ba5f6e280>
  nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7f7ba5f6e3a0>
  on_exit: <function OnExit.on_exit at 0x7f7ba5f6e4c0>
  proxy_protocol: False
  proxy_allow_ips: ['127.0.0.1']
  keyfile: None
  certfile: None
  ssl_version: 2
  cert_reqs: 0
  ca_certs: None
  suppress_ragged_eofs: True
  do_handshake_on_connect: False
  ciphers: None
  raw_paste_global_conf: []
  strip_header_spaces: False
[2020-10-15 15:11:49 +0000] [18068] [INFO] Starting gunicorn 20.0.4
[2020-10-15 15:11:49 +0000] [18068] [DEBUG] Arbiter booted
[2020-10-15 15:11:49 +0000] [18068] [INFO] Listening at: unix:/run/gunicorn.sock (18068)
[2020-10-15 15:11:49 +0000] [18068] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2020-10-15 15:11:49 +0000] [18080] [INFO] Booting worker with pid: 18080
[2020-10-15 15:11:49 +0000] [18068] [DEBUG] 1 workers
[2020-10-15 15:11:51 +0000] [18083] [INFO] Booting worker with pid: 18083
[2020-10-15 15:11:53 +0000] [18086] [INFO] Booting worker with pid: 18086
...
[2020-10-15 15:12:09 +0000] [18120] [INFO] Booting worker with pid: 18120
[2020-10-15 15:12:11 +0000] [18123] [INFO] Booting worker with pid: 18123

이 문제λ₯Ό μ„±κ³΅ν•˜μ§€ μ•Šκ³ (그리고 λ‘œκ·Έμ— λŒ€ν•œ 였λ₯˜ 없이) ν•΄κ²°ν•˜λ €κ³  λ§Žμ€ μ‹œκ°„μ„ ν—ˆλΉ„ν•œ ν›„ 이 Hello Worldλ₯Ό μ‚¬μš©ν•΄ λ³΄μ•˜κ³  λ‹€μŒ 였λ₯˜λ₯Ό λ°œκ²¬ν–ˆμŠ΅λ‹ˆλ‹€.

ModuleNotFoundError: No module named 'httptools'

httptools μ„€μΉ˜ ν›„ Hello world μ‘μš© ν”„λ‘œκ·Έλž¨μ΄ μ œλŒ€λ‘œ μž‘λ™ν•˜κ³  예기치 μ•Šκ²Œ λ‚΄ μ‘μš© ν”„λ‘œκ·Έλž¨λ„ μž‘λ™ν•©λ‹ˆλ‹€.

μ™œ 였λ₯˜κ°€ κΈ°λ‘λ˜μ§€ μ•Šμ•˜λŠ”μ§€ λ˜λŠ” 이 λΌμ΄λΈŒλŸ¬λ¦¬κ°€ λ‹€λ₯Έ μ»΄ν“¨ν„°μ—λŠ” μ„€μΉ˜λ˜μ—ˆμ§€λ§Œ μƒˆ μ»΄ν“¨ν„°μ—λŠ” μ„€μΉ˜λ˜μ§€ μ•Šμ€ 이유λ₯Ό μ•Œ 수 μ—†μ§€λ§Œ 이 λ°©λ²•μœΌλ‘œ λ¬Έμ œκ°€ ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

μ΅œκ·Όμ— 이런 일이 λ°œμƒν•˜κ³  λͺ¨λ“  CPUλ₯Ό μ†ŒλΉ„ν•˜μ—¬ 그것이 μžˆμ—ˆλ˜ kubernetes λ…Έλ“œλ₯Ό μ€‘λ‹¨ν•˜μ‹­μ‹œμ˜€. dmesg 에 λŒ€ν•œ 힌트 덕뢄에 κ²°κ΅­ 였λ₯˜λ₯Ό μ°Ύμ•˜μŠ΅λ‹ˆλ‹€.

[225027.348869] traps: python[44796] general protection ip:7f8bd8f8f8b0 sp:7ffc21a0b370 error:0 in libpython3.7m.so.1.0[7f8bd8dca000+2d9000]

κ²°κ΅­ λ‚΄ λ¬Έμ œλŠ” https://github.com/python-greenlet/greenlet/issues/178의 또 λ‹€λ₯Έ μΈμŠ€ν„΄μŠ€μ˜€μœΌλ©° gunicorn, gevent 및 greenlet을 μ΅œμ‹  λ²„μ „μœΌλ‘œ μ—…λ°μ΄νŠΈν•˜μ—¬ ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ μœ ν˜•μ˜ μ˜ˆμ™ΈλŠ” 파이썬 둜그λ₯Ό μƒμ„±ν•˜μ§€ μ•Šκ³  μž‘μ„ 수 μ—†μœΌλ©° μ’…λ£Œ μ½”λ“œ 0을 λ°˜ν™˜ν•˜κ³  λ°œμƒ μ‹œ μ‹œμŠ€ν…œμ„ μ€‘λ‹¨μ‹œν‚¬ 수 μžˆμœΌλ―€λ‘œ κ΄€λ¦¬ν•˜κΈ°κ°€ μƒλ‹Ήνžˆ μ–΄λ ΅μŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” gunicorn이 μ΄λŸ¬ν•œ νŠΉμ„±μ˜ λΉ λ₯Έ 좩돌 λ°˜λ³΅μ„ κ°μ§€ν•˜κ³ 

  • μƒˆλ‘œμš΄ μž‘μ—…μž 생성을 ν¬κΈ°ν•˜κ±°λ‚˜ 속도 μ œν•œ
  • μ‚¬λžŒλ“€μ—κ²Œ 이 λ¬Έμ œμ™€ https://github.com/python-greenlet/greenlet/issues/178 을 μ•Œλ €μ£ΌλŠ” μœ μš©ν•œ λ©”μ‹œμ§€λ₯Ό 제곡

μ•„λ§ˆλ„ max_consecutive_startup_crashes 이고 기본값은 num_workers * 10 μž…λ‹ˆκΉŒ?

#2504μ—μ„œ ν¬λž˜μ‹œ 루프 κΈ°λŠ₯ μš”μ²­μ„ 좔적해 λ³΄κ² μŠ΅λ‹ˆλ‹€. #2315에 μΆ”κ°€ λ‘œκ·ΈμΈμ„ μœ„ν•œ PR도 μžˆμŠ΅λ‹ˆλ‹€. λͺ¨λ“  μ‚¬λžŒμ΄ 문제λ₯Ό λ””λ²„κΉ…ν•œ 것 κ°™κΈ° λ•Œλ¬Έμ— 이 문제λ₯Ό λ‹«κ² μŠ΅λ‹ˆλ‹€. 이제 μ•žμœΌλ‘œ λ‹€λ₯Έ μ‚¬λžŒλ“€μ„ 돕기 μœ„ν•œ λͺ‡ 가지 κΈ°λŠ₯ μš”μ²­κ³Ό κ°œμ„  사항이 μžˆμŠ΅λ‹ˆλ‹€. κ°μ‚¬ν•©λ‹ˆλ‹€!

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰