Study

[ SJCE ์Šคํ„ฐ๋”” / 4์ฃผ์ฐจ ] Docker, Redis, Nodejs(Async/Await), Coroutines

HUIcode 2025. 4. 29. 17:32

24.09.28(ํ† )

 

[ ๐Ÿ’พ Server Part. ]

1. ์„œ๋ฒ„ ์‹œ์ž‘ํ•˜๊ธฐ(2) - pm2 ์„ค์น˜

2025.04.24 - [Study] - [ SJCE ์Šคํ„ฐ๋”” / 1์ฃผ์ฐจ ] 3-Tier Architecture ๊ธฐ๋ฐ˜ ํด๋ผ์ด์–ธํŠธ, ์„œ๋ฒ„ ๊ฐœ๋ฐœ ์‹œ์ž‘ํ•˜๊ธฐ

 

[ SJCE ์Šคํ„ฐ๋”” / 1์ฃผ์ฐจ ] 3-Tier Architecture ๊ธฐ๋ฐ˜ ํด๋ผ์ด์–ธํŠธ, ์„œ๋ฒ„ ๊ฐœ๋ฐœ ์‹œ์ž‘ํ•˜๊ธฐ

2024.08.24(ํ† )์Šคํ„ฐ๋”” ๋“ค์œผ๋ฉด์„œ ๋…ธ์…˜์— ๋Œ€์ถฉ ์ •๋ฆฌํ•ด ๋†“๊ณ  ๋‹ค์‹œ ์ •๋ฆฌํ•˜๋ฉด์„œ ๋ธ”๋กœ๊ทธ๋กœ ์˜ฎ๊ฒจ์•ผ์ง€ ~ ํ•˜๊ณ  ์ด์ œ ์ƒ๊ฐ๋‚˜์„œ ์ •๋ฆฌ์ค‘ .. ์ด๋ฒˆ ์Šคํ„ฐ๋””๋Š” ํด๋ผ์ด์–ธํŠธ๋ถ€ํ„ฐ ์„œ๋ฒ„, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊นŒ์ง€ 3๊ณ„์ธต ์•„ํ‚คํ…

record-coding53.tistory.com

1์ฃผ์ฐจ์—์„œ Node์™€ Express๋ฅผ ์„ค์น˜ํ–ˆ๋‹ค. ๋ณธ๊ฒฉ์ ์œผ๋กœ ์„œ๋ฒ„ ๊ฐœ๋ฐœ์„ ์‹œ์ž‘ํ•˜๊ธฐ ์œ„ํ•œ ์„ธํŒ…์„ ์ง„ํ–‰ํ•ด ์ฃผ์—ˆ๋‹ค.

 

1. pm2 ์„ค์น˜

 : pm2๋Š” Node.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ด€๋ฆฌํ•˜๊ณ  ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ํ”„๋กœ์„ธ์Šค ๊ด€๋ฆฌ์ž๋กœ, Node.js ์„œ๋ฒ„๋ฅผ ์‰ฝ๊ฒŒ ์‹คํ–‰ํ•˜๊ณ  ์ฃฝ์ง€ ์•Š๊ฒŒ ์œ ์ง€ํ•˜๊ณ  ์ž๋™ ์žฌ์‹œ์ž‘ํ•˜๊ณ  ๋กœ๊ทธ๋„ ๋ณด๊ธฐ ํŽธํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ชจ๋“ˆ์ด๋‹ค.

: node index.js ๋ช…๋ น์–ด๋กœ ์‹คํ–‰ ์‹œ ๋ฐฑ๊ทธ๋ผ์šด๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ ํฌ๊ทธ๋ผ์šด๋“œ(ํ„ฐ๋ฏธ๋„๊ณผ ์ง์ ‘ ์—ฐ๊ฒฐ๋œ ์ฑ„๋กœ ์‹คํ–‰)๋กœ ์‹คํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•  ์ˆ˜ ์—†๋‹ค. ๋ฐฑ๊ทธ๋ผ์šด๋“œ(ํ„ฐ๋ฏธ๋„๊ณผ ๋ณ„๊ฐœ๋กœ ๋”ฐ๋กœ ์‹คํ–‰ → ํ„ฐ๋ฏธ๋„์—์„œ ๋‹ค๋ฅธ ์ž‘์—… ๊ฐ€๋Šฅ) ์‹คํ–‰๊นŒ์ง€ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฒƒ์ด pm2์ด๋‹ค.

npm install -g pm2

์ƒ๋‹จ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ์„ค์น˜ํ•œ๋‹ค

 

 

๐Ÿ“Œ pm2 ์‚ฌ์šฉ๋ฒ•

1. watching ๋ชจ๋“œ ์˜ต์…˜

: ์‹คํ–‰๋œ pm2 ์†Œ์Šค์ฝ”๋“œ, ํ”„๋กœ์ ํŠธ์— ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์žˆ์œผ๋ฉด ์ž๋™ ๋ฐ˜์˜ํ•˜๊ณ  ์žฌ์‹œ์ž‘

pm2 start index.js --name game-server --watch

 

pm2 start PM2๋กœ ์ƒˆ๋กœ์šด ์•ฑ(ํ”„๋กœ์„ธ์Šค)์„ ์‹คํ–‰ํ•˜๊ฒ ๋‹ค๋Š” ๋ช…๋ น์–ด
index.js ์‹คํ–‰ํ•  Node.js ํŒŒ์ผ (๋‹น์‹ ์˜ ์„œ๋ฒ„ ์ง„์ž…์  ํŒŒ์ผ)
--name game-server ์‹คํ–‰ํ•˜๋Š” ์•ฑ์— "game-server" ๋ผ๋Š” ์ด๋ฆ„์„ ๋ถ™์ด๊ฒ ๋‹ค๋Š” ๋œป
--watch ํŒŒ์ผ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ž๋™ ๊ฐ์ง€ํ•ด์„œ ์„œ๋ฒ„๋ฅผ ์ž๋™์œผ๋กœ ์žฌ์‹œ์ž‘ํ•˜๊ฒ ๋‹ค๋Š” ์˜ต์…˜

 

2. ์•ฑ ์‹คํ–‰

pm2 start index.js ๊ธฐ๋ณธ ์‹คํ–‰ (index.js ์‹คํ–‰)
pm2 start index.js --name my-app ์ด๋ฆ„ ์ง€์ •ํ•ด์„œ ์‹คํ–‰
pm2 start index.js --watch ์ฝ”๋“œ ์ˆ˜์ • ๊ฐ์ง€ํ•ด์„œ ์ž๋™ ์žฌ์‹œ์ž‘
pm2 start ecosystem.config.js ์„ค์ •ํŒŒ์ผ(ecosystem) ๊ธฐ๋ฐ˜ ์—ฌ๋Ÿฌ ์•ฑ ์‹คํ–‰

 

3. ์•ฑ ์ค‘์ง€ / ์žฌ์‹œ์ž‘ / ์‚ญ์ œ 

pm2 stop all ๋ชจ๋“  ์•ฑ ์ •์ง€
pm2 stop 0 ID 0๋ฒˆ ์•ฑ๋งŒ ์ •์ง€
pm2 stop app-name ์ด๋ฆ„์ด app-name์ธ ์•ฑ ์ •์ง€
pm2 restart 0 ID 0๋ฒˆ ์•ฑ ์žฌ์‹œ์ž‘
pm2 restart app-name ์ด๋ฆ„์ด app-name์ธ ์•ฑ ์žฌ์‹œ์ž‘
pm2 restart 0 --watch ID 0๋ฒˆ ์•ฑ ์žฌ์‹œ์ž‘ + ๋ณ€๊ฒฝ ๊ฐ์‹œ ์‹œ์ž‘
pm2 delete 0 ID 0๋ฒˆ ์•ฑ ์‚ญ์ œ
pm2 delete app-name ์ด๋ฆ„์ด app-name์ธ ์•ฑ ์‚ญ์ œ
pm2 delete all ๋ชจ๋“  ์•ฑ ์‚ญ์ œ

 

4. ์•ฑ ์ƒํƒœ / ๋กœ๊ทธ ๋ณด๊ธฐ

โญ๏ธ pm2 list ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ๋ชจ๋“  ์•ฑ ๋ชฉ๋ก ํ™•์ธ
pm2 show 0 ID 0๋ฒˆ ์•ฑ์˜ ์ƒ์„ธ์ •๋ณด ๋ณด๊ธฐ
pm2 show app-name ์ด๋ฆ„์ด app-name์ธ ์•ฑ ์ƒ์„ธ์ •๋ณด ๋ณด๊ธฐ
pm2 monit ์‹ค์‹œ๊ฐ„ ๋ชจ๋‹ˆํ„ฐ๋ง ๋Œ€์‹œ๋ณด๋“œ
โญ๏ธ pm2 logs ์ „์ฒด ๋กœ๊ทธ ๋ณด๊ธฐ (์‹ค์‹œ๊ฐ„)
pm2 logs app-name ํŠน์ • ์•ฑ ๋กœ๊ทธ๋งŒ ๋ณด๊ธฐ
pm2 flush ์ €์žฅ๋œ ๋กœ๊ทธ ์ดˆ๊ธฐํ™” (๋น„์šฐ๊ธฐ)

 

5. ์„œ๋ฒ„ ์žฌ๋ถ€ํŒ… ๋Œ€๋น„ ์ž๋™ ์žฌ์‹œ์ž‘ ์„ค์ •

pm2 startup ๋ถ€ํŒ… ์‹œ PM2 ์ž๋™ ์‹คํ–‰ ์Šคํฌ๋ฆฝํŠธ ์ƒ์„ฑ
pm2 save ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ์•ฑ ์ƒํƒœ ์ €์žฅ (startup ํ›„ ํ•„์ˆ˜)
pm2 resurrect ๋งˆ์ง€๋ง‰ ์ €์žฅ๋œ ์ƒํƒœ๋กœ ๋ณต๊ตฌ
pm2 reset app-name ์•ฑ์˜ ์ƒํƒœ (์žฌ์‹œ์ž‘ ํšŸ์ˆ˜ ๋“ฑ) ์ดˆ๊ธฐํ™”

 

+ index.js ์—์„œ port๋ฅผ 80์œผ๋กœ ๋ฐ”๊พธ๋ฉด uptime์ด 5์ดˆ์ •๋„๋กœ ์žกํž˜(๊ทธ ์‚ฌ์ด์— restart๋œ ๊ฒƒ). ์ดํ›„ 80ํฌํŠธ ๊ฒฝ๋กœ๋กœ ์ ‘์†ํ•˜๋ฉด ์ž˜ ๋œ๋‹ค. ๋ฆฌ๋ˆ…์Šค ๊ณ„์—ด์˜ ์„œ๋ฒ„๋Š” 1000๋ฒˆ ์ดํ•˜์˜ ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์„ ํ•„์š”๋กœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ถŒํ•œ์„ ๋ฌผ์–ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

2. ์„œ๋ฒ„ ์‹œ์ž‘ํ•˜๊ธฐ(2) - Docker, Redis ์‹œ์ž‘ํ•˜๊ธฐ

OS์˜ ๊ตฌ์กฐ ์ฐจ์ด(Mac,Linux vs Windows)์— ๋”ฐ๋ฅธ ์„ค์น˜ ํŒŒ์ผ์˜ ์ฐจ์ด๊ฐ€ ์กด์žฌํ•œ๋‹ค. OS๋งˆ๋‹ค ๋‹ค ๋”ฐ๋กœ ์„ค์น˜ํ•˜๊ธฐ ๋ฒˆ๊ฑฐ๋กญ๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๋Š” Docker๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๋”๋ณด๊ธฐ

๐ŸŒ 1. Client Device์™€ ๋นŒ๋“œ ๋‹ค์–‘์„ฑ

Client device๋Š” ์‚ฌ์šฉ์ž์˜ ๋ฌผ๋ฆฌ์ ์ธ ํ•˜๋“œ์›จ์–ด/OS๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

 

Device OS ์˜ˆ์‹œ
PC Windows, macOS
๋ชจ๋ฐ”์ผ iOS (iPhone, iPad), Android (AOS, Android OS)

โžก ๊ฐ๊ฐ ์šด์˜์ฒด์ œ๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์—,
๊ฐ ๋””๋ฐ”์ด์Šค์— ๋งž๊ฒŒ ๋”ฐ๋กœ ๋นŒ๋“œ(์ปดํŒŒ์ผ)ํ•ด์„œ ๋ฐฐํฌํ•ด์•ผ ํ•œ๋‹ค.

  • Windows์šฉ ์•ฑ → .exe
  • macOS์šฉ ์•ฑ → .app
  • iOS ์•ฑ → .ipa
  • Android ์•ฑ → .apk

์ฆ‰, ํ•˜๋‚˜์˜ ์†Œ์Šค ์ฝ”๋“œ๋ผ๋„ ๊ธฐ๊ธฐ๋ณ„๋กœ "ํฌ๋งท"๊ณผ "ํ™˜๊ฒฝ"์„ ๋‹ค๋ฅด๊ฒŒ ๋งž์ถฐ์•ผ ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.


๐Ÿ› ๏ธ 2. Docker๋ž€?

Docker๋Š” ๋‹ค์–‘ํ•œ ์šด์˜์ฒด์ œ(OS) ํ™˜๊ฒฝ์— ๊ด€๊ณ„์—†์ด, ์ปจํ…Œ์ด๋„ˆ๋ผ๋Š” ๊ฐ€๋ฒผ์šด ๊ฐ€์ƒํ™˜๊ฒฝ ์œ„์—์„œ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค.

โœ… ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด:

  • "์šด์˜์ฒด์ œ ์ข…๋ฅ˜๊ฐ€ ๋ญ๋“  ์ƒ๊ด€์—†์ด,
    Docker๋งŒ ๊น”๋ ค ์žˆ์œผ๋ฉด ์„œ๋ฒ„ ์„ธํŒ…์„ ๋˜‘๊ฐ™์ด ํ•  ์ˆ˜ ์žˆ๋‹ค!"
์„œ๋ฒ„ OS Docker ์„ค์น˜ ๊ฐ€๋Šฅ ์—ฌ๋ถ€
Linux (Ubuntu, RedHat, Rocky, CentOS) ๊ฐ€๋Šฅ โœ…
Windows Server ๊ฐ€๋Šฅ โœ…
macOS (๊ฐœ๋ฐœ์šฉ) ๊ฐ€๋Šฅ โœ…

โžก ์ฆ‰, ์„œ๋ฒ„๋งˆ๋‹ค ๋‹ค๋ฅด๊ฒŒ ์ง์ ‘ ์„ธํŒ…ํ•  ํ•„์š” ์—†์ด, Docker ์ปจํ…Œ์ด๋„ˆ ์•ˆ์— ๋ชจ๋“  ์„ธํŒ…์„ ํ†ต์ผํ•  ์ˆ˜ ์žˆ๋‹ค.


๐Ÿณ 3. Docker์—์„œ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค

  • Node.js
  • MongoDB
  • Redis
  • Nginx
  • MySQL
  • PostgreSQL

โžก ์ด๋Ÿฐ ํ”„๋กœ๊ทธ๋žจ๋“ค๋„ Docker ์ด๋ฏธ์ง€๋ฅผ ํ†ตํ•ด ์‰ฝ๊ฒŒ ์„ค์น˜/์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

docker pull redis
docker pull mongo
docker pull node
docker pull nginx

(๊ณต์‹ ์ธ์ฆ ๋งˆํฌ ์žˆ๋Š” ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์•ˆ์ „ํ•˜๋‹ค)


๐Ÿ“ฆ 4. Containers, Port, Files, Exec

โœ… Containers ์ฐฝ

  • ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ Docker ์ปจํ…Œ์ด๋„ˆ๋“ค์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ณณ
  • ๊ฐ ์ปจํ…Œ์ด๋„ˆ๋ณ„๋กœ Port ์„ค์ •, ํŒŒ์ผ ์‹œ์Šคํ…œ, ์‹คํ–‰ ์ƒํƒœ ๋“ฑ์„ ํ™•์ธ ๊ฐ€๋Šฅ

โœ… Port

  • ํ˜ธ์ŠคํŠธ(์„œ๋ฒ„)์™€ ์ปจํ…Œ์ด๋„ˆ ๊ฐ„ ํ†ต์‹ ์„ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฌธ.
  • ์˜ˆ: localhost:6379 → redis ์—ฐ๊ฒฐ

โœ… Files

  • ์ปจํ…Œ์ด๋„ˆ ์•ˆ์˜ ํŒŒ์ผ ์‹œ์Šคํ…œ ํ™•์ธ ๊ฐ€๋Šฅ.
  • Linux๋‚˜ macOS์˜ ํด๋” ๊ตฌ์กฐ์™€ ๊ฑฐ์˜ ๋น„์Šทํ•จ (ex. /etc, /var, /usr ๋“ฑ)

โœ… Exec

  • ์ปจํ…Œ์ด๋„ˆ ์•ˆ์œผ๋กœ "๋“ค์–ด๊ฐ€์„œ" ๋ฆฌ๋ˆ…์Šค ๋ช…๋ น์–ด๋ฅผ ์ง์ ‘ ์น  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ.
docker exec -it container_name bash
  • ์ด๊ฑธ๋กœ ์‹ค์ œ ๋ฆฌ๋ˆ…์Šค ์„œ๋ฒ„์ฒ˜๋Ÿผ ๋ช…๋ น์–ด ์ž…๋ ฅ ๊ฐ€๋Šฅ.

๐Ÿ”— 5. Bind Mounts vs Volume

๊ตฌ๋ถ„ ํŠน์ง•
Bind Mounts ์„œ๋ฒ„์˜ ํŠน์ • ํด๋”์™€ ์ปจํ…Œ์ด๋„ˆ์˜ ํด๋”๋ฅผ ์ง์ ‘ ์—ฐ๊ฒฐ→ ์„œ๋ฒ„ ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜๋ฉด ์ปจํ…Œ์ด๋„ˆ์—๋„ ๋ฐ”๋กœ ๋ฐ˜์˜
Volumes Docker๊ฐ€ ์ž์ฒด์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ์ €์žฅ๊ณต๊ฐ„→ ์ปจํ…Œ์ด๋„ˆ ์‚ญ์ œํ•ด๋„ ๋ฐ์ดํ„ฐ ์œ ์ง€ ๊ฐ€๋Šฅ (๋ฐฑ์—…, ์ด๊ด€ ์šฉ์ด)

โžก ๊ฐœ๋ฐœ ์ดˆ๋ฐ˜์—๋Š” Bind Mounts ์‚ฌ์šฉํ•ด์„œ ๋น ๋ฅด๊ฒŒ ์ˆ˜์ •ํ•˜๊ณ ,
์šด์˜(์šด์˜ ์„œ๋ฒ„)์—์„œ๋Š” ์•ˆ์ •์„ฑ๊ณผ ๋ฐฑ์—…์„ ์œ„ํ•ด Volume์„ ๋งŽ์ด ์”๋‹ˆ๋‹ค.


๐Ÿ“š 6. CommonJS vs ES6 ๋ชจ๋“ˆ ์‹œ์Šคํ…œ

โœ… CommonJS (cjs)

  • 2016๋…„ ์ด์ „ Node.js ํ‘œ์ค€
  • ๋ชจ๋“ˆ ๊ฐ€์ ธ์˜ค๊ธฐ/๋‚ด๋ณด๋‚ด๊ธฐ ๋ฐฉ์‹:
// ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
const express = require('express');

// ๋‚ด๋ณด๋‚ด๊ธฐ
module.exports = someFunction;

โžก ์„œ๋ฒ„ ์‚ฌ์ด๋“œ(Node.js)์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ๋์Œ.


โœ… ES6 Modules (esm)

  • ์ตœ์‹  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ‘œ์ค€ (ECMAScript 2015)
  • ๋ธŒ๋ผ์šฐ์ €/Node.js ๋‘˜ ๋‹ค ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
// ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
import express from 'express';

// ๋‚ด๋ณด๋‚ด๊ธฐ
export default someFunction;

โžก ํ”„๋ก ํŠธ์—”๋“œ(Vue, React ๋“ฑ)์—์„œ๋Š” ์ฃผ๋กœ ES6 ๋ชจ๋“ˆ์„ ์‚ฌ์šฉ.


๐Ÿ”ฅ cjs vs es6 ์ •๋ฆฌ

๊ตฌ๋ถ„ CommonJS (cjs) ES6 Modules (esm)
์‚ฌ์šฉ๋ฒ• require / module.exports import / export
๊ธฐ๋ณธ ์ ์šฉ ์˜ˆ์ „ Node.js ์ตœ์‹  Node.js, ๋ธŒ๋ผ์šฐ์ €
ํŠน์ง• ๋™๊ธฐ ๋กœ๋”ฉ ๋น„๋™๊ธฐ ๋กœ๋”ฉ ์ง€์›
ํŒŒ์ผ ํ™•์žฅ์ž .js (๊ธฐ๋ณธ) .mjs ๋˜๋Š” package.json ์„ค์ • ํ•„์š”

 

์–ด๋–ค ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๋Š”์ง€์— ๋”ฐ๋ผ (๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋”ฐ๋ผ) cjs ๋ฐฉ์‹์ด๋‚˜ esm ๋ฐฉ์‹ ์ค‘ ํ•˜๋‚˜๋ฅผ ๋งž์ถฐ์•ผ ํ•ฉ๋‹ˆ๋‹ค!

 

์šฐ์„  ๋„์ปค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์„ค์น˜ํ•ด ์ค€๋‹ค.

์ฐธ๊ณ ๋กœ, ๋„์ปค์— ๊ด€๋ จ๋œ ์„œ๋น„์Šค๋“ค์€ ๋ชจ๋‘ Linux ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค์น˜๋œ๋‹ค. (containers ์ฐฝ์˜ port > files๋ฅผ ์—ด๋žŒํ•ด๋ณด๋ฉด Linux๋‚˜ mac์˜ ๊ตฌ์กฐ์™€ ํŒŒ์ผ ๊ตฌ์กฐ๊ฐ€ ๊ฑฐ์˜ ๋™์ผํ•จ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค) 

 

 

Step 1. Docker Desktop Install

-       mac : https://docs.docker.com/desktop/install/mac-install/

-       windows : https://docs.docker.com/desktop/install/windows-install/

์ƒ๋‹จ ๋งํฌ์—์„œ Docker.dmg๋ฅผ ๋‹ค์šด๋ฐ›๊ณ  ๋“œ๋ž˜๊ทธ์•ค ๋“œ๋กญํ•˜๋Š” GUI ๋ฐฉ์‹์œผ๋กœ ์„ค์น˜๋ฅผ ์ง„ํ–‰ํ–ˆ๋”๋‹ˆ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๊ฝค ์žˆ๋‹ค..
ํ•˜๋‹จ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด, CLI ๋ฐฉ์‹์œผ๋กœ ์„ค์น˜๋ฅผ ์ง„ํ–‰ํ•˜์ž.
sudo hdiutil attach Docker.dmg
sudo /Volumes/Docker/Docker.app/Contents/MacOS/install
sudo hdiutil detach /Volumes/Dockerโ€‹

์ฐธ๊ณ  โžก๏ธ https://docs.docker.com/desktop/setup/install/mac-install/

 

Step 2. Redis, Mongo ์ด๋ฏธ์ง€ ์„ค์น˜

: ์ธ์ฆ ํ‘œ์‹œ๋ฅผ ์ž˜ ํ™•์ธํ•ด์„œ ์„ค์น˜ํ•  ๊ฒƒ

 

์šฐ์„  ์„ค์น˜๊นŒ์ง€๋งŒ ํ•ด๋‘๊ณ  optional settings ์„ค์ •๊ณผ ๋„์šฐ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ๋Š” ํ›„์„คํ•˜๊ฒ ๋‹ค.

 

 

 

 

 

3. ๋™๊ธฐ / ๋น„๋™๊ธฐ

๋™๊ธฐ : ํ•˜๋‚˜์˜ ์ž‘์—…์ด ๋๋‚˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๋‹ค์Œ ์ž‘์—…์„ ์‹คํ–‰

๋น„๋™๊ธฐ : ์„ ํ–‰ ์ž‘์—…์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋ณ‘๋ ฌ์ ์œผ๋กœ ์ž‘์—… ์ฒ˜๋ฆฌ

 

Await : ๊ธฐ๋‹ค๋ ค๋ผ! <- ๋™๊ธฐ ๋ฐฉ์‹

Async/Await : ๋น„๋™๊ธฐ ์ž‘์—…์˜ ๋™๊ธฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹

cf) ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ํŒจํ„ด Promise

 

์‚ฌ์šฉํ•˜๋Š” ์ด์œ ?

 

Redis์™€ ๊ฐ™์€ DB์— ์—ฐ๊ฒฐ(connect)์ด ์™„๋ฃŒ๋œ ์ดํ›„์— ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์กฐํšŒ ์‹œ์ ์— DB ์—ฐ๊ฒฐ์ด ๋˜์ง€ ์•Š์•„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ await๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด DB ์—ฐ๊ฒฐ์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๊ทธ ๋‹ค์Œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

-       await ๊ตฌ๋ฌธ์˜ ๋งˆ์ง€๋ง‰๊นŒ์ง€ ๋‹ค ์ˆ˜ํ–‰ํ•˜๊ณ  ๋‚œ ๋’ค ๋‹ค์Œ ์ฝ”๋“œ ์ˆ˜ํ–‰

-       ๋น„๋™๊ธฐ๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ถ„๋ฆฌ๊ฐ€ ๋จ

 

 

์‹œ๊ฐ„ ์ง€์—ฐ ํ•จ์ˆ˜ setTimeout์œผ๋กœ delay ํ•จ์ˆ˜ ๊ตฌํ˜„
function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function fetchUserInfo() {
  await delay(1000); // 1์ดˆ ๋Œ€๊ธฐ
  console.log("์œ ์ € ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค.");
}

 

 

Node express์˜ get ์š”์ฒญ๊ณผ Redis Client์˜ set์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ •๋ณด ๋„˜๊ฒจ์ฃผ๊ธฐ
app.get("/user", async (req, res) => {
  await redisClient.set("user", JSON.stringify({ name: "ํฌ" }));
  const user = await redisClient.get("user");
  res.send(user);
});

 

 

 

[ ๐Ÿ–ฅ๏ธClient Part. ]

1. ์ฝ”๋ฃจํ‹ด(Coroutines) ๋ฐ ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„ ์—ฐ๊ฒฐ

 

๐Ÿ’ก ์ฝ”๋ฃจํ‹ด์ด๋ž€?

: ์ฝ”๋ฃจํ‹ด์€ ์œ ๋‹ˆํ‹ฐ์—์„œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ(ํ˜น์€ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ ์ฒ˜๋ฆฌ)๋ฅผ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ํŠน์ˆ˜ํ•œ ํ•จ์ˆ˜์ด๋‹ค. ์ผ๋ฐ˜ ํ•จ์ˆ˜์™€๋Š” ๋‹ฌ๋ฆฌ ์ค‘๊ฐ„์— ๋ฉˆ์ท„๋‹ค๊ฐ€(yield) ๋‚˜์ค‘์— ๋‹ค์‹œ ์ด์–ด์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

IEnumerator MyCoroutine() {
    for (int i = 0; i < 10; i++) {
        Debug.Log($"๋กœ๊ทธ ์ถœ๋ ฅ {i + 1}");
        yield return new WaitForSeconds(1f); // 1์ดˆ ๋Œ€๊ธฐ
    }
}
  • IEnumerator: ์ฝ”๋ฃจํ‹ด ํ•จ์ˆ˜๋Š” ๋ฐ˜๋“œ์‹œ ์ด ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด์•ผ ํ•จ
  • yield return: ์ค‘๊ฐ„์— ์ž ์‹œ ๋ฉˆ์ท„๋‹ค๊ฐ€ ๋‹ค์‹œ ์ด์–ด์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ํ‚ค์›Œ๋“œ
  • StartCoroutine(MyCoroutine()): ์ฝ”๋ฃจํ‹ด์„ ์‹œ์ž‘ํ•  ๋•Œ ์‚ฌ์šฉ

 

 

๐Ÿ“Œ ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„ ์—ฐ๊ฒฐ ์‹ค์Šต

์œ ๋‹ˆํ‹ฐ์—์„œ ์™ธ๋ถ€ ์„œ๋ฒ„(Redis ๋“ฑ)์™€ ์—ฐ๋™ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ๊ธฐ๋ณธ ํ๋ฆ„์ด๋‹ค.

  1. ๋กœ๊ณ  ์”ฌ์— ๋ฒ„ํŠผ ์ƒ์„ฑ
    • ์„œ๋ฒ„ ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ UI ๋ฒ„ํŠผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    • UI → Button ์„ ํƒ ํ›„ ์ ์ ˆํ•œ ์œ„์น˜์— ๋ฐฐ์น˜.
  2. ๋„คํŠธ์›Œํฌ ๋งค๋‹ˆ์ € ์˜ค๋ธŒ์ ํŠธ ์ƒ์„ฑ
    • ๋นˆ GameObject๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ด๋ฆ„์„ NetworkManager๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  3. ๋„คํŠธ์›Œํฌ ๋งค๋‹ˆ์ € ์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ
    • NetworkManager.cs๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ C# ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ ์ž‘์„ฑ
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class NetworkManager : MonoBehaviour {
    public void OnConnectButtonClicked() {
        StartCoroutine(GetDataFromServer());
    }

    IEnumerator GetDataFromServer() {
        string url = "http://<์„œ๋ฒ„์ฃผ์†Œ>/api/test"; // ์‹ค์ œ ์„œ๋ฒ„ ์ฃผ์†Œ๋กœ ๋ณ€๊ฒฝ
        UnityWebRequest request = UnityWebRequest.Get(url);
        yield return request.SendWebRequest();

        if (request.result == UnityWebRequest.Result.Success) {
            Debug.Log("์„œ๋ฒ„ ์‘๋‹ต: " + request.downloadHandler.text);
        } else {
            Debug.LogError("์„œ๋ฒ„ ์—ฐ๊ฒฐ ์‹คํŒจ: " + request.error);
        }
    }
}

 

4. ๋ฒ„ํŠผ๊ณผ ์Šคํฌ๋ฆฝํŠธ ์—ฐ๊ฒฐ

  • ๋ฒ„ํŠผ์˜ OnClick() ์ด๋ฒคํŠธ์— NetworkManager ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋“ฑ๋กํ•œ ๋’ค, OnConnectButtonClicked ํ•จ์ˆ˜๋ฅผ ์—ฐ๊ฒฐ

5. ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ ํ™•์ธ

  • ์„œ๋ฒ„๊ฐ€ ๋„์›Œ์ ธ ์žˆ๋Š” ์ƒํƒœ์—์„œ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ Redis์— ์ €์žฅ๋œ ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธ

 

๊ทธ๋ฆฌ๊ณ  ์ง€๋‚œ ์ฃผ ๊ณผ์ œ์˜€๋˜ ์บ๋ฆญํ„ฐ์™€ ๋ชฌ์Šคํ„ฐ๊ฐ€ ์ถฉ๋Œ ์‹œ ์ผ์ • ํšŸ์ˆ˜ ๊ณต๊ฒฉ ์ดํ›„ ๋‹ค์‹œ ์ง€๋‚˜๊ฐ€๊ฒŒ๋” ๊ตฌํ˜„๋„ ๋งˆ๋ฌด๋ฆฌํ–ˆ๋‹ค โœŒ๐Ÿป