Gunicorn: gevent ์ž‘์—…์ž์˜ IO ๋ฐ”์ธ๋”ฉ ํ”„๋กœ์„ธ์Šค์— ๋Œ€ํ•œ ์งˆ๋ฌธ

์— ๋งŒ๋“  2019๋…„ 04์›” 15์ผ  ยท  3์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: benoitc/gunicorn

์—ฌ๋Ÿฌ๋ถ„ ์•ˆ๋…•ํ•˜์„ธ์š”,

์—ฌ๋Ÿฌ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์ผ๋ถ€ ์ฒ˜๋ฆฌ์™€ ๊ฒฐํ•ฉํ•˜๊ณ  ์–ด๋”˜๊ฐ€์— ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๋Š” API๋ฅผ ์ž‘์—… ์ค‘์ž…๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ถ„๋ช…ํžˆ IO ๋ฐ”์šด๋“œ์ด๊ธฐ ๋•Œ๋ฌธ์— Greenlet ์ž‘์—…์ž๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ฝ์€ ๋‚ด์šฉ์—์„œ gunicorn ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฐ greenlet์€ ์Šค๋ ˆ๋“œ์ฒ˜๋Ÿผ ์ž‘๋™ํ•˜๋ฏ€๋กœ IO ์ฐจ๋‹จ ํ˜ธ์ถœ์ด IO๋ฅผ ๊ธฐ๋‹ค๋ ค์•ผ ํ•  ๋•Œ greenlet์€ ํŠน์ • gunicorn ์š”์ฒญ์„ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‚ด ์•ฑ(ํ”Œ๋ผ์Šคํฌ btw ์‚ฌ์šฉ) ํ•ธ๋“ค๋Ÿฌ์—์„œ Greenlet์ด ๋‹ค์Œ requests.get() ๊นŒ์ง€ ์ฐจ๋‹จํ•  requests.get(...) ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ์Šต๋‹ˆ๋‹ค.

def fetch(pid):
    response0 = requests.get('http://some-micro-service-0.com/')
    response1 = requests.get('http://some-micro-service-1.com/')
    response2 = requests.get('http://some-micro-service-2.com/')
    return combine_response(response0, response1, response2)

grequests๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌ๊ธฐ์— ๋” ๋งŽ์€ ๋™์‹œ์„ฑ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ œ๊ฐ€ ์ฐพ๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค). ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ œ์•ˆ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์—ฌ๋Ÿฌ ์š”์ฒญ์„ ์ˆ˜์ง‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ œ์•ˆ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

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

grequests๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌ๊ธฐ์— ๋” ๋งŽ์€ ๋™์‹œ์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

grequests.map() ๋Š” ์œ„์—์„œ ์ œ๊ณตํ•œ ์ฝ”๋“œ ์กฐ๊ฐ์˜ ์ถ•์•ฝํ˜• ๋ฒ„์ „์ž…๋‹ˆ๋‹ค.

๊ทธ ์™ธ์—๋Š” grequests ๊ฐ€ ๋ณ„๋กœ ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฃผ๋กœ ์ˆ˜์ž…๋  ๋•Œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์›์ˆญ์ด ํŒจ์น˜ํ•˜๊ธฐ ์œ„ํ•ด ์กด์žฌํ•˜์ง€๋งŒ gunicorn์€ ์ด๋ฏธ ๊ทธ๋ ‡๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

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

gevent ์—๋Š” ์—ฌ๋Ÿฌ ์š”์ฒญ์„ ๋ณ‘๋ ฌ๋กœ ๋ฐœ์†กํ•˜๊ณ  ์™„๋ฃŒ๋œ ํ›„์—๋งŒ ์ฒ˜๋ฆฌ

(๋‹น์‹ ์˜ ๊ฒฝ์šฐ๋Š” ์•ฝ๊ฐ„ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธ์‡„ํ•˜๋Š” ๋Œ€์‹  response ๋ฅผ ๋ฐ˜ํ™˜ํ•œ ๋‹ค์Œ ๊ฒฐํ•ฉํ•ฉ๋‹ˆ๋‹ค.)

๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ๋กœ Group.map API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

from gevent import pool

jobs = pool.Group()
responses = jobs.map(requests.get, 
                     ('http://one', 'http://two', 'http://three'))

grequests๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌ๊ธฐ์— ๋” ๋งŽ์€ ๋™์‹œ์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

grequests.map() ๋Š” ์œ„์—์„œ ์ œ๊ณตํ•œ ์ฝ”๋“œ ์กฐ๊ฐ์˜ ์ถ•์•ฝํ˜• ๋ฒ„์ „์ž…๋‹ˆ๋‹ค.

๊ทธ ์™ธ์—๋Š” grequests ๊ฐ€ ๋ณ„๋กœ ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฃผ๋กœ ์ˆ˜์ž…๋  ๋•Œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์›์ˆญ์ด ํŒจ์น˜ํ•˜๊ธฐ ์œ„ํ•ด ์กด์žฌํ•˜์ง€๋งŒ gunicorn์€ ์ด๋ฏธ ๊ทธ๋ ‡๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

ํ•œ๋™์•ˆ ํ™œ๋™์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ‹ฐ์ผ“์„ ๋‹ซ์Šต๋‹ˆ๋‹ค.

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