์ด ๋ฌธ์๋ ์ด ์ ์ฅ์๋ฅผ ์ฒ์ ๋ณด๋ ์ฌ๋์ด ์ฝ๋ ํ๋ฆ, Redis ์ฌ์ฉ ๋ฐฉ์, Producer/Worker ๊ตฌ์กฐ๋ฅผ ๋น ๋ฅด๊ฒ ์ดํดํ๋๋ก ๋๊ธฐ ์ํ ํ์ต์ฉ ๊ฐ์ด๋๋ค.
์ด ํ๋ก์ ํธ๋ ์์ฃผ ์ ํ์ ์ธ Producer -> Queue -> Worker ๊ตฌ์กฐ๋ฅผ ๊ตฌํํ ์์ ๋ค.
๊ตฌ์ฑ์ ๋จ์ํ๋ค.
- ํด๋ผ์ด์ธํธ๊ฐ API์ ์์ ์ ์์ฒญํ๋ค.
- API๋ ์์ ๋ด์ฉ์ Redis์ ์ ์ฅํ๊ณ ํ์ ๋ฃ๋๋ค.
- Worker๊ฐ ํ์์ ์์ ์ ๊บผ๋ด ์ฒ๋ฆฌํ๋ค.
- ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ค์ Redis์ ๊ธฐ๋กํ๋ค.
- API๋ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ ธ๋ค๊ฐ ์ต์ข ์๋ต์ ๋ฐํํ๋ค.
์ฆ, ๊ฒ์ผ๋ก๋ HTTP API์ฒ๋ผ ๋ณด์ด์ง๋ง, ๋ด๋ถ์์๋ Redis๊ฐ ์์ ์ค๊ฐ์ ์ญํ ์ ํ๋ค.
Client
|
| HTTP POST /jobs
v
FastAPI app/api.py
|
| Redis์ job ์ ์ฅ + queue์ job_id push
v
Redis
|
| worker๊ฐ BLPOP์ผ๋ก ๋๊ธฐ
v
Worker app/worker_demo.py
|
| ์์
์ฒ๋ฆฌ ํ result/reply ์ ์ฅ
v
Redis
|
| API๊ฐ reply๋ฅผ BLPOP์ผ๋ก ๊ธฐ๋ค๋ฆผ
v
FastAPI response
ํต์ฌ ํฌ์ธํธ๋ ์์
๋ณธ๋ฌธ ์ ์ฒด๋ฅผ ํ์ ๋ฃ์ง ์๊ณ job_id๋ง ํ์ ๋ฃ๋๋ค๋ ์ ์ด๋ค. ์ค์ payload๋ ๋ณ๋ key์ ์ ์ฅํ๋ค.
app/config.py: Redis ์ ์ ์ ๋ณด, key ์ด๋ฆ, TTL, ํ์์์ ์ฌ์ ์๊ฐ์ ๋ชจ์๋ ์ค์ ํ์ผapp/api.py: FastAPI ์๋ฒ. ์์ ๋ฑ๋ก, ์ํ ์กฐํ, ๊ฒฐ๊ณผ ์กฐํ, health/stats ์ ๊ณตapp/worker_demo.py: Redis ํ๋ฅผ ์๋นํ๋ Worker ํ๋ก์ธ์คapp/producer_demo.py: ๋ก์ปฌ์์ ๋์ ํ์ธํ ๋ ์ฐ๋ CLI Producerdocker-compose.yml: Redis, API, Worker, Locust๋ฅผ ํ ๋ฒ์ ๋์ฐ๋ ์คํ ๊ตฌ์ฑ
app/config.py์์ ์๋ key๋ค์ ์ ์ํ๋ค.
demo:queuedemo:job:<job_id>demo:status:<job_id>demo:result:<job_id>demo:reply:<job_id>
๊ฐ ์ญํ ์ ์ด๋ ๋ค.
queue: ์ฒ๋ฆฌ ๋๊ธฐ์ดjob: ์ค์ ์์ payload ์ ์ฅstatus: ํ์ฌ ์ํ ์ถ์ result: ์ต์ข ๊ฒฐ๊ณผ ์ ์ฅreply: API๊ฐ ์ฆ์ ์๋ต๋ฐ๊ธฐ ์ํ 1ํ์ฑ ์๋ต ์ฑ๋
์ด ๊ตฌ์กฐ๊ฐ ์ข์ ์ด์ ๋ ์ญํ ์ด ๋ถ๋ฆฌ๋ผ ์๊ธฐ ๋๋ฌธ์ด๋ค.
- ํ๋ ์์ ๋ณด์ฅ์ ์ง์ค
- job key๋ payload ๋ณด๊ด์ ์ง์ค
- status key๋ ๋ชจ๋ํฐ๋ง์ ์ง์ค
- result/reply key๋ ์๋ต ์ ๋ฌ์ ์ง์ค
์ด๋ณด์๊ฐ ์ ์ผ ๋จผ์ ๋ด์ผ ํ ์ค๊ณ ํฌ์ธํธ๋ค.
ํ์ ์ ์ฒด JSON payload๋ฅผ ๋ฃ๋ ๋ฐฉ์๋ ๊ฐ๋ฅํ๋ค. ๊ทธ๋ฐ๋ฐ ์ด ํ๋ก์ ํธ๋ ๊ทธ๋ ๊ฒ ํ์ง ์๋๋ค.
๋์ ๋ค์ ์์๋ฅผ ์ด๋ค.
job_id์์ฑdemo:job:<job_id>์ payload ์ ์ฅdemo:queue์job_id๋ง push
์ด ๋ฐฉ์์ ์ฅ์ :
- payload์ queue๋ฅผ ๋ถ๋ฆฌํ ์ ์๋ค
- ์ํ ์กฐํ ์
job_id๊ธฐ์ค์ผ๋ก ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ฐพ๊ธฐ ์ฝ๋ค - ๊ฒฐ๊ณผ, ์ํ, ์๋ฌ๋ฅผ ๊ฐ์
job_id์ถ์ผ๋ก ๊ด๋ฆฌํ ์ ์๋ค - ํ ๋ฉ์์ง๋ฅผ ๊ฐ๋ณ๊ฒ ์ ์งํ ์ ์๋ค
app/api.py์์ ์ ์ผ ์ค์ํ ์๋ํฌ์ธํธ๋ POST /jobs๋ค.
ํ๋ฆ์ ๊ฑฐ์ ์๋์ ๊ฐ๋ค.
- ์์ฒญ๊ฐ์ ๊ฒ์ฆํ๋ค.
job_id๋ฅผ ๋ง๋ ๋ค.- payload๋ฅผ
demo:job:<id>์ ์ ์ฅํ๋ค. - ์ํ๋ฅผ
waiting์ผ๋ก ๊ธฐ๋กํ๋ค. - ํ์
job_id๋ฅผ ๋ฃ๋๋ค. demo:reply:<id>๋ฅผBLPOP์ผ๋ก ๊ธฐ๋ค๋ฆฐ๋ค.- Worker ๊ฒฐ๊ณผ๊ฐ ์ค๋ฉด ์ฑ๊ณต/์คํจ ์๋ต์ผ๋ก ๋ฐ๊ฟ์ ๋ฐํํ๋ค.
์ฌ๊ธฐ์ ์ค์ํ ์ ์ API๊ฐ ๋น๋๊ธฐ ์์
์ ๋ฑ๋ก๋ง ํ๊ณ ๋๋ด๋ ๊ตฌ์กฐ๊ฐ ์๋๋ผ๋ ์ ์ด๋ค. ์ด ํ๋ก์ ํธ๋ ์์
๋ฑ๋ก ํ ๊ณง๋ฐ๋ก ๊ฒฐ๊ณผ๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค.
์ฆ:
- ๋ด๋ถ ๊ตฌ์กฐ๋ ๋น๋๊ธฐ ๋ถ์ฐ ์ฒ๋ฆฌ
- ์ธ๋ถ ์ฌ์ฉ์ ๊ฒฝํ์ ๋๊ธฐ ์๋ต
์ด ํจํด์ "์์ ์ฒ๋ฆฌ๋ ์์ปค์๊ฒ ๋งก๊ธฐ๊ณ ์ถ์ง๋ง, ํด๋ผ์ด์ธํธ๋ ์ต์ข ์ฑ๊ณต/์คํจ๋ฅผ ๋ฐ๋ก ๋ฐ๊ณ ์ถ๋ค"๋ ์๊ตฌ์ ๋ง๋๋ค.
์ด ์ ์ฅ์๋ฅผ ์ดํดํ๋ ค๋ฉด BLPOP์ ์์์ผ ํ๋ค.
BLPOP์ Redis List์์ ๊ฐ์ ๊บผ๋ด๋, ๊ฐ์ด ์์ผ๋ฉด ๊ธฐ๋ค๋ฆฌ๋ ๋ช
๋ น์ด๋ค.
์ด ํ๋ก์ ํธ๋ ๋ ๊ณณ์์ BLPOP์ ์ด๋ค.
- Worker:
demo:queue๋ฅผ ๊ธฐ๋ค๋ฆผ - API:
demo:reply:<job_id>๋ฅผ ๊ธฐ๋ค๋ฆผ
์ฆ ์์ชฝ ๋ค ํด๋งํ์ง ์๋๋ค. Redis๊ฐ ๊ฐ์ด ๋ค์ด์ฌ ๋๊น์ง block ์ํ๋ก ๋๊ธฐํ๋ค.
์ฅ์ :
- ๋ถํ์ํ while polling์ด ์ค์ด๋ ๋ค
- ๊ตฌํ์ด ๋จ์ํ๋ค
- ์๋ต ๋๊ธฐ ๋ชจ๋ธ์ ์ดํดํ๊ธฐ ์ฝ๋ค
app/worker_demo.py์ ํต์ฌ์ main()๊ณผ _process_job()์ด๋ค.
Worker ๋ฃจํ๋ ์๋์ฒ๋ผ ์๊ฐํ๋ฉด ๋๋ค.
while True:
job_id = BLPOP(queue)
process(job_id)์ค์ ์ฒ๋ฆฌ ์์๋ ์ด๋ ๋ค.
- ํ์์
job_id๋ฅผ ๋ฐ๋๋ค. demo:job:<id>์์ payload๋ฅผ ์ฝ๋๋ค.- ์ํ๋ฅผ
running์ผ๋ก ๋ฐ๊พผ๋ค. work_s๋งํผ sleep ํ๋ฉฐ ์์ ์ ํ๋ด ๋ธ๋ค.- ์ฑ๊ณต ๋๋ ์คํจ ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ ๋ค.
resultkey์replykey์ ๊ธฐ๋กํ๋ค.- ์ํ๋ฅผ
finish๋๋fail๋ก ๋ฐ๊พผ๋ค.
์ด ํ๋ก์ ํธ์ Worker๋ ์ค์ ๋น์ฆ๋์ค ๋ก์ง ๋์ sleep์ผ๋ก ์์
์๊ฐ์ ์๋ฎฌ๋ ์ด์
ํ๋ค. ๊ทธ๋์ ์ํคํ
์ฒ๋ฅผ ๊ณต๋ถํ๊ธฐ์ ์ข๋ค. ๋ณต์กํ ๋๋ฉ์ธ ๋ก์ง ์์ด ํ ํ๋ฆ์๋ง ์ง์คํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
status key๊ฐ ์์ผ๋ฉด ์์
์ด ์ง๊ธ ์ด๋๊น์ง ๊ฐ๋์ง ์ ์ ์๋ค.
์ด ํ๋ก์ ํธ๋ ์ํ๋ฅผ ์ต์ํ ๋ค์ ๊ฐ์ผ๋ก ๋๋๋ค.
waitingrunningfinishfail
์ด ๋๋ถ์ ๋ค์์ด ๊ฐ๋ฅํ๋ค.
- API์์
/jobs/{job_id}/status์ ๊ณต - ๋๋ฒ๊น ์ด ์ฌ์
- Worker๊ฐ ๋ฉ์ท๋์ง ์ถ์ ๊ฐ๋ฅ
- ์ด์ ์ค ํ์ฌ ๋ณ๋ชฉ์ด queue์ธ์ง worker ์ฒ๋ฆฌ์ธ์ง ๋ณด๊ธฐ ์ฌ์
์ด๊ฒ๋ ์ค์ํ ์ค๊ณ ํฌ์ธํธ๋ค.
๊ฒ๋ณด๊ธฐ์๋ ๋ ๋ค ๊ฒฐ๊ณผ ์ ์ฅ์ฒ๋ผ ๋ณด์ด์ง๋ง ๋ชฉ์ ์ด ๋ค๋ฅด๋ค.
result: ๋์ค์ ๋ค์ ์กฐํํ๊ธฐ ์ํ ์ ์ฅ์reply: ์ง๊ธ ๊ธฐ๋ค๋ฆฌ๋ ์์ฒญ์๊ฒ ์ฆ์ ์ ๋ฌํ๊ธฐ ์ํ ์ฑ๋
์ฆ:
reply๋ ์ค์๊ฐ ์๋ต์ฉresult๋ ์กฐํ/๋ณด๊ด์ฉ
๊ทธ๋์ API๋ ๋จผ์ result๊ฐ ์ด๋ฏธ ์์ผ๋ฉด ์ฆ์ ๋ฐํํ๊ณ , ์์ผ๋ฉด reply๋ฅผ ๊ธฐ๋ค๋ฆฐ๋ค.
app/worker_demo.py์์ ์ข์ ๋ถ๋ถ์ "์๋ฌ๊ฐ ๋๋ API๋ฅผ ์์ํ ๊ธฐ๋ค๋ฆฌ๊ฒ ๋์ง ์์ผ๋ ค๋ ์๋"๊ฐ ๋ถ๋ช
ํ๋ค๋ ์ ์ด๋ค.
Worker ์ฒ๋ฆฌ ์ค ์์ธ๊ฐ ๋๋ฉด:
- ์ํ๋ฅผ
fail๋ก ๊ธฐ๋ก - ์คํจ ๊ฒฐ๊ณผ๋ฅผ
result์ ์ ์ฅ - ์คํจ ๊ฒฐ๊ณผ๋ฅผ
reply์๋ push
์ฆ, ์คํจํด๋ ๋ฐ๋์ ์๋ต ๊ฒฝ๋ก๋ฅผ ๋จ๊ธด๋ค.
app/api.py๋ ํ์์์์ ๋๋ค.
timeout = work_s + JOB_TIMEOUT_GRACE_S
์๋ฏธ๋ ๊ฐ๋จํ๋ค.
- ์ ์ ์์ ์๊ฐ๋ณด๋ค ์กฐ๊ธ ๋ ๊ธฐ๋ค๋ฆฐ๋ค
- ๊ทธ๋๋ ์๋ต์ด ์์ผ๋ฉด worker crash ๋๋ hang์ผ๋ก ๋ณด๊ณ ์คํจ ์ฒ๋ฆฌํ๋ค
์ด ์ค๊ณ ๋๋ถ์ API ์์ฒญ์ด ๋ฌดํ์ ๋งค๋ฌ๋ฆฌ์ง ์๋๋ค.
app/config.py์๋ TTL์ด ์ ์๋ผ ์๋ค.
RESULT_TTL_S = 3600REPLY_TTL_S = 600STATUS_TTL_S = 3600
์ ํ์ํ ๊น.
- ๊ฒฐ๊ณผ๊ฐ ์๊ตฌํ ์์ด๋ฉด Redis ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊ณ์ ์ฆ๊ฐํ๋ค
- reply key๋ ์ผํ์ฑ์ด๋ผ ์ค๋ ๋จ๊ธธ ์ด์ ๊ฐ ์๋ค
- status/result๋ ๋๋ฒ๊น ์ ์ํด ์ผ์ ์๊ฐ๋ง ๋จ๊ธฐ๋ฉด ์ถฉ๋ถํ๋ค
์ฆ, ์ด ํ๋ก์ ํธ๋ "๋ฐ๋ชจ์ง๋ง ์ด์ ๊ฐ๊ฐ์ด ์กฐ๊ธ ๋ค์ด๊ฐ ์ค๊ณ"๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
app/producer_demo.py๋ API ์์ด๋ ํ๋ฆ์ ํ์ธํด๋ณด๋ ๋ก์ปฌ CLI ๋๊ตฌ๋ค.
ํ์ต ๊ด์ ์์๋ ์คํ๋ ค ์ด ํ์ผ์ด Redis ํ๋ฆ์ ์ง์ ๋ณด๊ธฐ ์ข๋ค.
๋ณผ๋งํ ํฌ์ธํธ:
- ์์ enqueue
- outstanding ๊ฐ์ ์ถ์
- queue length ์กฐํ
- Redis ๋ฉ๋ชจ๋ฆฌ ํต๊ณ ์ถ๋ ฅ
- reply key ๋๊ธฐ ํ ๊ฒฐ๊ณผ ์ถ๋ ฅ
์ฆ, ๋ธ๋ผ์ฐ์ ๋ HTTP ์์ด๋ "ํ ์์คํ ์ด ์ค์ ๋ก ์ด๋ป๊ฒ ํ๋ฅด๋์ง" ํ์ธํ ์ ์๋ค.
docker-compose.yml์ ๋ณด๋ฉด ์๋น์ค๋ 5๊ฐ๋ค.
redisapiworker-1worker-2locust
ํต์ฌ ํ์ต ํฌ์ธํธ:
- worker๋ฅผ 2๊ฐ ๋์์ ์ํ ํ์ฅ ๊ฐ๋ ์ ๋ณด์ฌ์ค
- API์ Worker๊ฐ ๊ฐ์ ์ด๋ฏธ์ง๋ฅผ ์ฐ๊ณ
command๋ง ๋ค๋ฅด๊ฒ ์ค ์ ์์ - Redis healthcheck๊ฐ ํต๊ณผ๋ ๋ค ๋ค๋ฅธ ์๋น์ค๊ฐ ๋จ๋๋ก ํจ
์ด๊ฑด ์ค๋ฌด์์๋ ์์ฃผ ๋ณด๋ ํจํด์ด๋ค. ๊ฐ์ ์ฝ๋๋ฒ ์ด์ค์์ ์ญํ ๋ง ๋ค๋ฅด๊ฒ ๋ฐฐ์นํ๋ค.
์ฒ์๋ถํฐ ๋ฌธ์ ์ ์ฒด๋ฅผ ๋ค ์ฝ๊ธฐ๋ณด๋ค ์๋ ์์๊ฐ ๋ซ๋ค.
app/config.py์์ key ๊ตฌ์กฐ๋ฅผ ๋จผ์ ๋ณธ๋ค.app/worker_demo.py์์ queue ์๋น ํ๋ฆ์ ๋ณธ๋ค.app/api.py์์ ์์ฒญ์ด ์ด๋ป๊ฒ queue๋ก ์ฐ๊ฒฐ๋๋์ง ๋ณธ๋ค.docker-compose.yml์์ ์๋น์ค ๊ตฌ์ฑ์ ๋ณธ๋ค.- ๋ง์ง๋ง์
app/producer_demo.py๋ฅผ ๋ณด๊ณ ๋ณด์กฐ ๋๊ตฌ ์ญํ ์ ์ดํดํ๋ค.
์ด ์์๊ฐ ์ข์ ์ด์ ๋ ์์คํ
์ ์ค์ฌ์ด UI๊ฐ ์๋๋ผ queue flow์ด๊ธฐ ๋๋ฌธ์ด๋ค.
์๋ ์ง๋ฌธ์ ๋ตํด๋ณด๋ฉด ๊ตฌ์กฐ๊ฐ ๋นจ๋ฆฌ ์กํ๋ค.
- ์ queue์๋ payload๊ฐ ์๋๋ผ
job_id๋ง ๋ฃ์์๊น? - ์
result์reply๋ฅผ ๋ ๋ค ๋ง๋ค์์๊น? - Worker๊ฐ ์ฃฝ์ผ๋ฉด API๋ ์ด๋ป๊ฒ ์คํจ๋ฅผ ํ๋จํ ๊น?
- Worker ์๋ฅผ 1๊ฐ์์ 2๊ฐ๋ก ๋๋ฆฌ๋ฉด ์ด๋ค ์ ์ด ๋ฌ๋ผ์ง๊น?
BLPOP๋์ polling์ผ๋ก ๊ตฌํํ๋ฉด ์ด๋ค ๋นํจ์จ์ด ์๊ธธ๊น?- TTL์ด ์๋ค๋ฉด Redis์๋ ์ด๋ค ๋ฌธ์ ๊ฐ ์๊ธธ๊น?
ํ์ต์ ์ฝ๋๋ฅผ ์ฝ๋ ๊ฒ๋ณด๋ค ์กฐ๊ธ ๋ง์ ธ๋ณด๋ ์ชฝ์ด ๋น ๋ฅด๋ค.
์ถ์ฒ ์คํ:
- Worker๋ฅผ 1๊ฐ๋ง ๋์ฐ๊ณ ์ฌ๋ฌ ์์ฒญ์ ๋ณด๋ด๋ณธ๋ค.
- Worker๋ฅผ 2๊ฐ ๋์ฐ๊ณ ๊ฐ์ ์์ฒญ์ ๋ณด๋ด๋ณธ๋ค.
work_s=1,work_s=5,fail=true๋ฅผ ์์ด์ ์์ฒญํด๋ณธ๋ค.- ์์ ์ค Worker ํ๋ก์ธ์ค๋ฅผ ์ฃฝ์์ ๋ API ์๋ต์ด ์ด๋ป๊ฒ ๋ฐ๋๋์ง ๋ณธ๋ค.
- Redis key๋ฅผ ์ง์ ์กฐํํด๋ณด๋ฉฐ
queue,job,status,result,reply์ ์ฐจ์ด๋ฅผ ๋ณธ๋ค.
์ด ์ ์ฅ์๋ "Redis๋ฅผ ์ค๊ฐ์ ๋ ์์ ๋ถ๋ฐฐ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ฅ ๋จ์ํ ํํ๋ก ๋ณด์ฌ์ฃผ๋ ํ์ต์ฉ ์์ "๋ค.
ํต์ฌ๋ง ๋จ๊ธฐ๋ฉด ์ด ๋ฌธ์ฅ์ด๋ค.
API๋ ์์
์ ๋ฃ๊ณ ๊ธฐ๋ค๋ฆฌ๊ณ , Worker๋ ์์
์ ๊บผ๋ด ์ฒ๋ฆฌํ๊ณ , Redis๋ ๋ ์ฌ์ด์ ์ํ์ ๊ฒฐ๊ณผ๋ฅผ ์ฐ๊ฒฐํ๋ค.
์ด ํ๋ก์ ํธ๋ฅผ ์ฒ์ ์คํํ ๋๋ Podman์ ๋ชจ๋ ๊ธฐ๋ฅ์ ํ ๋ฒ์ ๋ณด๋ ค ํ์ง ์๋ ํธ์ด ๋ซ๋ค.
์ถ์ฒ ์์๋ ์ด๋ ๋ค.
- ๋จผ์
docker compose๋ก ๊ตฌ์กฐ๋ฅผ ์ดํดํ๋ค. - ๊ทธ๋ค์
podman compose๋ก ๊ฐ์ ์คํ์ ์คํํด๋ณธ๋ค. - ๋ง์ง๋ง์ผ๋ก
Quadlet + systemd๋ฅผ ๋ณธ๋ค.
์ด ์์๊ฐ ์ข์ ์ด์ ๋ ์ํคํ ์ฒ ํ์ต๊ณผ Podman ์ด์ ๊ธฐ๋ฅ ํ์ต์ ๋ถ๋ฆฌํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฌธ์์ ์ด ํ๋ก์ ํธ๋ docker-compose.yml์ ๊ธฐ์ค์ผ๋ก ๋ฐ๋ก ์คํํ ์ ์๋ค.
- Git ์ค์น
- Docker Desktop ๋๋ Docker Engine ์ค์น
git clone <your-repo-url>
cd task-dispatcher-demo
git switch developdocker compose up -d --builddocker compose ps
curl http://localhost:8000/health
curl http://localhost:8000/statscurl -X POST http://localhost:8000/jobs \
-H "Content-Type: application/json" \
-d '{"work_s": 3, "fail": false}'docker compose logs -f api
docker compose logs -f worker-1
docker compose logs -f worker-2docker compose down์ฒ์์๋ ์ด ๋จ๊ณ๋ง ํด๋ ์ถฉ๋ถํ๋ค. ์ด๊ฑธ๋ก API -> Redis -> Worker -> ์๋ต ํ๋ฆ์ ๋ชจ๋ ๋ณผ ์ ์๋ค.
ํ ์คํธ ํ ํ ๋ฒ์ ์ ๋ฆฌํ๊ณ ์ถ๋ค๋ฉด ์๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
bash scripts/teardown_all.sh๋ฌธ์ ๊ธฐ์ค์ผ๋ก๋ podman compose๋ ๋ฐ๋ก ์ง์ํ๋ค.
- Podman ์ค์น
podman compose up -d --buildpodman compose ps
curl http://localhost:8000/health
curl http://localhost:8000/statspodman compose downํ์ต ๋ชฉ์ ์ด๋ผ๋ฉด docker compose์ podman compose์ ์ฐจ์ด๋ฅผ ํฌ๊ฒ ์์ํ์ง ์์๋ ๋๋ค. ๋ ๋ค ํ์ฌ ์ ์ฅ์ ๊ตฌ์กฐ๋ฅผ ์ดํดํ๋ ๋ฐ๋ ์ถฉ๋ถํ๋ค.
Podman Compose๋ก ๋์ด ๋ค์๋ ๋์ผํ๊ฒ ์๋ ์คํฌ๋ฆฝํธ๋ก ์ ๋ฆฌํ ์ ์๋ค.
bash scripts/teardown_all.shREADME.md์์๋ Podman์ ์ด์ํ ๊ด๋ฆฌ ๋ฐฉ์์ผ๋ก Quadlet + systemd๋ฅผ ์๋ดํ๋ค.
ํต์ฌ์ Docker ์ปจํ
์ด๋ ์์ Podman์ ๋ฃ๋ ๋ฐฉ์์ด ์๋๋ผ, Podman Machine ์์ผ๋ก ๋ค์ด๊ฐ์ systemd๋ก ๊ด๋ฆฌํ๋ ๋ฐฉ์์ด๋ผ๋ ์ ์ด๋ค.
podman machine init
podman machine start
podman machine ssh์ดํ ๋ช
๋ น์ podman machine ssh ์์์ ์คํํ๋ค.
mkdir -p ~/.config/containers/systemd/๋ฌธ์์ ์๋ ์๋ ํ์ผ๋ค์ ๋ง๋ ๋ค.
dispatcher.networkdispatcher-redis.containerdispatcher-api.containerdispatcher-worker-1.containerdispatcher-worker-2.containerdispatcher-locust.container
์ด ํ์ผ ๋ด์ฉ์ README.md์ ๊ทธ๋๋ก ๋์ ์๋ค.
systemctl --user daemon-reload
systemctl --user start dispatcher-redis.service
systemctl --user start dispatcher-api.service
systemctl --user start dispatcher-worker-1.service
systemctl --user start dispatcher-worker-2.service
systemctl --user start dispatcher-locust.serviceloginctl enable-linger $(whoami)์ด ๋จ๊ณ๋ "๊ทธ๋ฅ ์คํํด๋ณด๊ธฐ"๋ณด๋ค "Podman์์ ์๋ ์ฌ์์๊ณผ systemd ๊ด๋ฆฌ๊น์ง ํ์ธํด๋ณด๊ธฐ"์ ๊ฐ๊น๋ค.
Quadlet๋ก ์ฌ๋ฆฐ ์๋น์ค๊น์ง ์ ๋ฆฌํ๋ ค๋ฉด ์๋ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ฉด ๋๋ค.
bash scripts/teardown_all.sh์ฒ์ ๊ณต๋ถํ ๋ ์ถ์ฒ ๊ฒฝ๋ก๋ ์๋์ ๊ฐ๋ค.
docker compose up -d --buildcurl /health,curl /jobs,curl /statslogs -f api,logs -f worker-1,logs -f worker-2- Worker๋ฅผ ์ผ๋ถ๋ฌ ์ค์งํ๊ฑฐ๋ ์์ฒญ์ ์ฌ๋ฌ ๊ฐ ๋ณด๋ด๋ณด๋ฉฐ ํ ๋์ ํ์ธ
- ์ต์ํด์ง๋ฉด
podman compose - ๋ง์ง๋ง์
podman machine + quadlet
README.md์์๋ ๋ถ๋ช
ํ ๋งํ๋ฏ์ด ๋ค์์ ํผํ๋ ํธ์ด ์ข๋ค.
- Compose์ Quadlet์ ๋์์ ์ฌ์ฉํ์ง ์๊ธฐ
- ๊ฐ์ ํฌํธ์ ๊ฐ์ ์ปจํ ์ด๋ ์ด๋ฆ์ ์ค๋ณต์ผ๋ก ๋์ฐ์ง ์๊ธฐ
- ์ฒ์๋ถํฐ Podman ์ด์ ๊ธฐ๋ฅ๊ณผ ์ํคํ ์ฒ ํ์ต์ ํ ๋ฒ์ ํ๋ ค๊ณ ํ์ง ์๊ธฐ
์ฒ์์ docker compose๋ก ๊ตฌ์กฐ๋ฅผ ์ดํดํ๊ณ , ๊ทธ ๋ค์์ Podman ์ชฝ์ผ๋ก ๋์ด๊ฐ๋ ๊ฒ ๊ฐ์ฅ ๋ ๊ผฌ์ธ๋ค.