์ปดํŒŒ์ผ๋œ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ ๊ตฌ์„ฑ

๋ถ„์‚ฐ ์‹œ์Šคํ…œ ๊ตฌ์„ฑ ์ž‘์—…์— ๋Œ€ํ•œ ํฅ๋ฏธ๋กœ์šด ๋ฉ”์ปค๋‹ˆ์ฆ˜ ํ•˜๋‚˜๋ฅผ ๋ง์”€๋“œ๋ฆฌ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ์€ ์•ˆ์ „ํ•œ ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํŒŒ์ผ๋œ ์–ธ์–ด(Scala)๋กœ ์ง์ ‘ ํ‘œํ˜„๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ์˜ ์˜ˆ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ์„ ์ „์ฒด ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค์— ๊ตฌํ˜„ํ•˜๋Š” ๋‹ค์–‘ํ•œ ์ธก๋ฉด์„ ๋…ผ์˜ํ•ฉ๋‹ˆ๋‹ค.

์ปดํŒŒ์ผ๋œ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ ๊ตฌ์„ฑ

(์˜์–ด)

์†Œ๊ฐœ

์•ˆ์ •์ ์ธ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๋ชจ๋“  ๋…ธ๋“œ๊ฐ€ ๋‹ค๋ฅธ ๋…ธ๋“œ์™€ ๋™๊ธฐํ™”๋œ ์˜ฌ๋ฐ”๋ฅธ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. DevOps ๊ธฐ์ˆ (terraform, ansible ๋“ฑ)์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ตฌ์„ฑ ํŒŒ์ผ(์ข…์ข… ๊ฐ ๋…ธ๋“œ์— ํŠน์ •)์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ชจ๋“  ํ†ต์‹  ๋…ธ๋“œ๊ฐ€ ๋™์ผํ•œ ํ”„๋กœํ† ์ฝœ(๋™์ผํ•œ ๋ฒ„์ „ ํฌํ•จ)์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์— ๋น„ํ˜ธํ™˜์„ฑ์ด ๋‚ด์žฅ๋ฉ๋‹ˆ๋‹ค. JVM ์„ธ๊ณ„์—์„œ ์ด ์š”๊ตฌ ์‚ฌํ•ญ์˜ ํ•œ ๊ฐ€์ง€ ๊ฒฐ๊ณผ๋Š” ํ”„๋กœํ† ์ฝœ ๋ฉ”์‹œ์ง€๊ฐ€ ํฌํ•จ๋œ ๋™์ผํ•œ ๋ฒ„์ „์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ชจ๋“  ๊ณณ์—์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ถ„์‚ฐ ์‹œ์Šคํ…œ์„ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์€ ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ๋ฌผ๋ก  ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋กœ ๋„˜์–ด๊ฐ€๊ธฐ ์ „์— ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ์— ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. (ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋ฅผ ๋Ÿฐํƒ€์ž„์— ์ถ”์ •ํ•˜๋ ค๋ฉด ํ…Œ์ŠคํŠธ ๋„์ค‘๊ณผ ๋Ÿฐํƒ€์ž„์— ๋™์ผํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ธํŠธ๋„ ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.)

ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•  ๋•Œ ๋ชจ๋“  ๋…ธ๋“œ์˜ ๋ชจ๋“  ์œ„์น˜์—์„œ ๋™์ผํ•œ ํด๋ž˜์Šค ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์‰ฌ์šด ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ํ•ด์•ผ ํ•  ์ผ์€ ๋Ÿฐํƒ€์ž„์— ๋™์ผํ•œ ํด๋ž˜์Šค ๊ฒฝ๋กœ๊ฐ€ ์‚ฌ์šฉ๋˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ๋ฟ์ž…๋‹ˆ๋‹ค. (๋‹ค๋ฅธ ํด๋ž˜์Šค ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ๋…ธ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์€ ์ „์ ์œผ๋กœ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์ด๋กœ ์ธํ•ด ์ „์ฒด ๊ตฌ์„ฑ์ด ๋ณต์žกํ•ด์ง€๊ณ  ๋ฐฐํฌ ๋ฐ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๊ฐ€ ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค.) ์ด ๊ฒŒ์‹œ๋ฌผ์˜ ๋ชฉ์ ์— ๋”ฐ๋ผ ๋ชจ๋“  ๋…ธ๋“œ๊ฐ€ ๋™์ผํ•œ ํด๋ž˜์Šค ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

๊ตฌ์„ฑ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ํ•จ๊ป˜ ๋ฐœ์ „ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ ๋ฐœ์ „์˜ ๋‹ค์–‘ํ•œ ๋‹จ๊ณ„๋ฅผ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ๋ฒ„์ „์˜ ๊ตฌ์„ฑ์„ ์‹๋ณ„ํ•˜๋Š” ๊ฒƒ๋„ ๋…ผ๋ฆฌ์ ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ตฌ์„ฑ ์ž์ฒด๋ฅผ ๋ฒ„์ „ ์ œ์–ด ์‹œ์Šคํ…œ์— ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ๋•์…˜์— ๊ตฌ์„ฑ์ด ํ•˜๋‚˜๋งŒ ์žˆ๋Š” ๊ฒฝ์šฐ ๊ฐ„๋‹จํžˆ ๋ฒ„์ „ ๋ฒˆํ˜ธ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŽ์€ ํ”„๋กœ๋•์…˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
๋ฒ„์ „ ์™ธ์— ๊ตฌ์„ฑ ๋ถ„๊ธฐ ๋ฐ ์ถ”๊ฐ€ ๋ ˆ์ด๋ธ”(์˜ˆ: ๋ถ„๊ธฐ ์ด๋ฆ„)์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ •ํ™•ํ•œ ๊ตฌ์„ฑ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ๊ตฌ์„ฑ ์‹๋ณ„์ž๋Š” ๋ถ„์‚ฐ ๋…ธ๋“œ, ํฌํŠธ, ์™ธ๋ถ€ ๋ฆฌ์†Œ์Šค ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฒ„์ „์˜ ํŠน์ • ์กฐํ•ฉ์— ๊ณ ์œ ํ•˜๊ฒŒ ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒŒ์‹œ๋ฌผ์˜ ๋ชฉ์ ์„ ์œ„ํ•ด ์šฐ๋ฆฌ๋Š” ๋ถ„๊ธฐ๊ฐ€ ํ•˜๋‚˜๋งŒ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ์ ์œผ๋กœ ๊ตฌ๋ถ„๋œ ์„ธ ๊ฐœ์˜ ์ˆซ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ตฌ์„ฑ์„ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(1.2.3).

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

์ด ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” ์ปดํŒŒ์ผ๋œ ์•„ํ‹ฐํŒฉํŠธ ๋‚ด๋ถ€์˜ ๊ตฌ์„ฑ์„ ํ‘œํ˜„ํ•˜๋Š” ์•„์ด๋””์–ด๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ

์ด ์„น์…˜์—์„œ๋Š” ์ •์  ์ปดํŒŒ์ผ ๊ตฌ์„ฑ์˜ ์˜ˆ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๊ฐ€์ง€ ๊ฐ„๋‹จํ•œ ์„œ๋น„์Šค, ์ฆ‰ ์—์ฝ” ์„œ๋น„์Šค์™€ ์—์ฝ” ์„œ๋น„์Šค ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค. ์ด ๋‘ ๊ฐ€์ง€ ์„œ๋น„์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‘ ๊ฐ€์ง€ ์‹œ์Šคํ…œ ์˜ต์…˜์ด ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ํ•œ ์˜ต์…˜์—์„œ๋Š” ๋‘ ์„œ๋น„์Šค๊ฐ€ ๋ชจ๋‘ ๋™์ผํ•œ ๋…ธ๋“œ์— ์žˆ๊ณ  ๋‹ค๋ฅธ ์˜ต์…˜์—์„œ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋…ธ๋“œ์— ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์—๋Š” ์—ฌ๋Ÿฌ ๋…ธ๋“œ๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ํŠน์ • ์œ ํ˜•์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ๋…ธ๋“œ๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. NodeId:

sealed trait NodeId
case object Backend extends NodeId
case object Frontend extends NodeId

๋˜๋Š”

case class NodeId(hostName: String)

๋˜๋Š”

object Singleton
type NodeId = Singleton.type

๋…ธ๋“œ๋Š” ๋‹ค์–‘ํ•œ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์„œ๋น„์Šค๋ฅผ ์‹คํ–‰ํ•˜๋ฉฐ ๋…ธ๋“œ ๊ฐ„์— TCP/HTTP ์—ฐ๊ฒฐ์ด ์„ค์ •๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

TCP ์—ฐ๊ฒฐ์„ ์„ค๋ช…ํ•˜๋ ค๋ฉด ์ตœ์†Œํ•œ ํฌํŠธ ๋ฒˆํ˜ธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ€ ๋ชจ๋‘ ๋™์ผํ•œ ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ํ•ด๋‹น ํฌํŠธ์—์„œ ์ง€์›๋˜๋Š” ํ”„๋กœํ† ์ฝœ์„ ๋ฐ˜์˜ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ฒฐ์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

case class TcpEndPoint[Protocol](node: NodeId, port: Port[Protocol])

์–ด๋””์—์„œ Port - ๊ทธ๋ƒฅ ์ •์ˆ˜ Int ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฐ’์˜ ๋ฒ”์œ„๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

type PortNumber = Refined[Int, Closed[_0, W.`65535`.T]]

์„ธ๋ จ๋œ ์œ ํ˜•

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ณด๊ธฐ ์„ธ๋ จ๋œ ะธ ๋‚ด ๋ณด๊ณ . ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํŒŒ์ผ ํƒ€์ž„์— ํ™•์ธ๋˜๋Š” ์œ ํ˜•์— ์ œ์•ฝ ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์œ ํšจํ•œ ํฌํŠธ๋ฒˆํ˜ธ ๊ฐ’์€ 16๋น„ํŠธ ์ •์ˆ˜์ด๋‹ค. ์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ์˜ ๊ฒฝ์šฐ ๊ฐœ์„ ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ•„์ˆ˜๋Š” ์•„๋‹ˆ์ง€๋งŒ ๊ตฌ์„ฑ์„ ํ™•์ธํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๊ธฐ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

HTTP(REST) โ€‹โ€‹ํ”„๋กœํ† ์ฝœ์˜ ๊ฒฝ์šฐ ํฌํŠธ ๋ฒˆํ˜ธ ์™ธ์—๋„ ์„œ๋น„์Šค ๊ฒฝ๋กœ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

type UrlPathPrefix = Refined[String, MatchesRegex[W.`"[a-zA-Z_0-9/]*"`.T]]
case class PortWithPrefix[Protocol](portNumber: PortNumber, pathPrefix: UrlPathPrefix)

ํŒฌํ…€ ์œ ํ˜•

์ปดํŒŒ์ผ ํƒ€์ž„์— ํ”„๋กœํ† ์ฝœ์„ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด ํด๋ž˜์Šค ๋‚ด์—์„œ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์œ ํ˜• ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฐ์ •์€ ๋Ÿฐํƒ€์ž„์— ํ”„๋กœํ† ์ฝœ ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์ง€๋งŒ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ”„๋กœํ† ์ฝœ ํ˜ธํ™˜์„ฑ์„ ํ™•์ธํ•˜๊ธฐ๋ฅผ ์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ”„๋กœํ† ์ฝœ์„ ์ง€์ •ํ•˜๋ฉด ๋ถ€์ ์ ˆํ•œ ์„œ๋น„์Šค๋ฅผ ์ข…์†์„ฑ์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์ธ ํ”„๋กœํ† ์ฝœ ์ค‘ ํ•˜๋‚˜๋Š” Json ์ง๋ ฌํ™”๊ฐ€ ํฌํ•จ๋œ REST API์ž…๋‹ˆ๋‹ค.

sealed trait JsonHttpRestProtocol[RequestMessage, ResponseMessage]

์–ด๋””์—์„œ RequestMessage โ€” ์š”์ฒญ ์œ ํ˜•, ResponseMessage โ€” ์‘๋‹ต ์œ ํ˜•.
๋ฌผ๋ก  ์šฐ๋ฆฌ๊ฐ€ ์š”๊ตฌํ•˜๋Š” ์„ค๋ช…์˜ ์ •ํ™•์„ฑ์„ ์ œ๊ณตํ•˜๋Š” ๋‹ค๋ฅธ ํ”„๋กœํ† ์ฝœ ์„ค๋ช…์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ฒŒ์‹œ๋ฌผ์˜ ๋ชฉ์ ์„ ์œ„ํ•ด ์šฐ๋ฆฌ๋Š” ํ”„๋กœํ† ์ฝœ์˜ ๋‹จ์ˆœํ™”๋œ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

sealed trait SimpleHttpGetRest[RequestMessage, ResponseMessage]

์—ฌ๊ธฐ์„œ ์š”์ฒญ์€ URL์— ์ถ”๊ฐ€๋œ ๋ฌธ์ž์—ด์ด๊ณ  ์‘๋‹ต์€ HTTP ์‘๋‹ต ๋ณธ๋ฌธ์— ๋ฐ˜ํ™˜๋œ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.

์„œ๋น„์Šค ๊ตฌ์„ฑ์€ ์„œ๋น„์Šค ์ด๋ฆ„, ํฌํŠธ, ์ข…์†์„ฑ์œผ๋กœ ์„ค๋ช…๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์š”์†Œ๋Š” Scala์—์„œ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ‘œํ˜„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: HList-s, ๋Œ€์ˆ˜ ๋ฐ์ดํ„ฐ ์œ ํ˜•). ์ด ๊ฒŒ์‹œ๋ฌผ์˜ ๋ชฉ์ ์„ ์œ„ํ•ด ์ผ€์ดํฌ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๊ณ  ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“ˆ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. trait'ov. (์ผ€์ดํฌ ํŒจํ„ด์€ ์ด ์ ‘๊ทผ ๋ฐฉ์‹์˜ ํ•„์ˆ˜ ์š”์†Œ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ๋‹จ์ง€ ๊ฐ€๋Šฅํ•œ ๊ตฌํ˜„ ์ค‘ ํ•˜๋‚˜์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.)

์„œ๋น„์Šค ๊ฐ„์˜ ์ข…์†์„ฑ์€ ํฌํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋กœ ํ‘œํ˜„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. EndPoint๋‹ค๋ฅธ ๋…ธ๋“œ์˜ ๊ฒƒ:

  type EchoProtocol[A] = SimpleHttpGetRest[A, A]

  trait EchoConfig[A] extends ServiceConfig {
    def portNumber: PortNumber = 8081
    def echoPort: PortWithPrefix[EchoProtocol[A]] = PortWithPrefix[EchoProtocol[A]](portNumber, "echo")
    def echoService: HttpSimpleGetEndPoint[NodeId, EchoProtocol[A]] = providedSimpleService(echoPort)
  }

์—์ฝ” ์„œ๋น„์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด ํฌํŠธ ๋ฒˆํ˜ธ์™€ ํ•ด๋‹น ํฌํŠธ๊ฐ€ ์—์ฝ” ํ”„๋กœํ† ์ฝœ์„ ์ง€์›ํ•œ๋‹ค๋Š” ํ‘œ์‹œ๋งŒ ์žˆ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ํŠน์ • ํฌํŠธ๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด... ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ตฌํ˜„ ์—†์ด ๋ฉ”์„œ๋“œ(์ถ”์ƒ ๋ฉ”์„œ๋“œ)๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ๊ตฌ์ฒด์ ์ธ ๊ตฌ์„ฑ์„ ์ƒ์„ฑํ•  ๋•Œ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ถ”์ƒ ๋ฉ”์„œ๋“œ์˜ ๊ตฌํ˜„์„ ์ œ๊ณตํ•˜๊ณ  ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ์ œ๊ณตํ•˜๋„๋ก ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํŠน์ • ๊ตฌ์„ฑ์„ ์ƒ์„ฑํ•  ๋•Œ ๋‹ค๋ฅธ ํฌํŠธ๋ฅผ ์ง€์ •ํ•˜์ง€ ๋ชปํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ ๊ตฌ์„ฑ์—์„œ echo ์„œ๋น„์Šค์— ๋Œ€ํ•œ ์ข…์†์„ฑ์„ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.

  trait EchoClientConfig[A] {
    def testMessage: String = "test"
    def pollInterval: FiniteDuration
    def echoServiceDependency: HttpSimpleGetEndPoint[_, EchoProtocol[A]]
  }

์ข…์†์„ฑ์€ ๋‚ด๋ณด๋‚ธ ์„œ๋น„์Šค์™€ ๋™์ผํ•œ ์œ ํ˜•์ž…๋‹ˆ๋‹ค. echoService. ํŠนํžˆ, ์—์ฝ” ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” ๋™์ผํ•œ ํ”„๋กœํ† ์ฝœ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‘ ์„œ๋น„์Šค๋ฅผ ์—ฐ๊ฒฐํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์„œ๋น„์Šค ๊ตฌํ˜„

์„œ๋น„์Šค๋ฅผ ์‹œ์ž‘ํ•˜๊ณ  ์ค‘์ง€ํ•˜๋ ค๋ฉด ํ•จ์ˆ˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. (์„œ๋น„์Šค๋ฅผ ์ค‘์ง€ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ํ…Œ์ŠคํŠธ์— ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.) ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ๊ตฌ์„ฑ ์œ ํ˜•์— ๋”ฐ๋ผ ์œ ํ˜• ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ). ์ด ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” ์ผ€์ดํฌ ํŒจํ„ด์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋น„์Šค๋ฅผ ํ‘œํ˜„ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. cats.Resource, ์™œ๋ƒํ•˜๋ฉด ์ด ํด๋ž˜์Šค๋Š” ๋ฌธ์ œ ๋ฐœ์ƒ ์‹œ ๋ฆฌ์†Œ์Šค ํ•ด์ œ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด์žฅํ•˜๋Š” ์ˆ˜๋‹จ์„ ์ด๋ฏธ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ์†Œ์Šค๋ฅผ ์–ป์œผ๋ ค๋ฉด ๊ตฌ์„ฑ๊ณผ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด์ง„ ๋Ÿฐํƒ€์ž„ ์ปจํ…์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋น„์Šค ์‹œ์ž‘ ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  type ResourceReader[F[_], Config, A] = Reader[Config, Resource[F, A]]

  trait ServiceImpl[F[_]] {
    type Config
    def resource(
      implicit
      resolver: AddressResolver[F],
      timer: Timer[F],
      contextShift: ContextShift[F],
      ec: ExecutionContext,
      applicative: Applicative[F]
    ): ResourceReader[F, Config, Unit]
  }

์–ด๋””์—์„œ

  • Config โ€” ์ด ์„œ๋น„์Šค์˜ ๊ตฌ์„ฑ ์œ ํ˜•
  • AddressResolver โ€” ๋‹ค๋ฅธ ๋…ธ๋“œ์˜ ์ฃผ์†Œ๋ฅผ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ๋Š” ๋Ÿฐํƒ€์ž„ ๊ฐ์ฒด(์•„๋ž˜ ์ฐธ์กฐ)

๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋‹ค๋ฅธ ์œ ํ˜• cats:

  • F[_] โ€” ํšจ๊ณผ ์œ ํ˜•(๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ F[A] ๊ทธ๋ƒฅ ํ•จ์ˆ˜์ผ ์ˆ˜๋„ ์žˆ์–ด์š” () => A. ์ด ๊ฒŒ์‹œ๋ฌผ์—์„œ ์šฐ๋ฆฌ๋Š” cats.IO.)
  • Reader[A,B] - ๊ธฐ๋Šฅ๊ณผ ๊ฑฐ์˜ ๋™์˜์–ด A => B
  • cats.Resource - ํš๋“ํ•˜๊ณ  ๊ณต๊ฐœํ•  ์ˆ˜ ์žˆ๋Š” ์ž์›
  • Timer โ€” ํƒ€์ด๋จธ(์ž ์‹œ ์ž ๋“ค๊ณ  ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์„ ์ธก์ •ํ•  ์ˆ˜ ์žˆ์Œ)
  • ContextShift - ์•„๋‚ ๋กœ๊ทธ ExecutionContext
  • Applicative โ€” ๊ฐœ๋ณ„ ํšจ๊ณผ๋ฅผ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ๋Š” ํšจ๊ณผ ์œ ํ˜• ํด๋ž˜์Šค(๊ฑฐ์˜ ๋ชจ๋‚˜๋“œ) ๋” ๋ณต์žกํ•œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. Monad/ConcurrentEffect.

์ด ํ•จ์ˆ˜ ์„œ๋ช…์„ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ์„œ๋น„์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š” ์„œ๋น„์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  trait ZeroServiceImpl[F[_]] extends ServiceImpl[F] {
    type Config <: Any
    def resource(...): ResourceReader[F, Config, Unit] =
      Reader(_ => Resource.pure[F, Unit](()))
  }

(์„ผํ‹ฐ๋ฏธํ„ฐ. ์ถœ์ฒ˜, ๋‹ค๋ฅธ ์„œ๋น„์Šค๊ฐ€ ๊ตฌํ˜„๋˜๋Š” ๊ฒฝ์šฐ - ์—์ฝ” ์„œ๋น„์Šค, ์—์ฝ” ํด๋ผ์ด์–ธํŠธ
ะธ ์ˆ˜๋ช… ์ปจํŠธ๋กค๋Ÿฌ.)

๋…ธ๋“œ๋Š” ์—ฌ๋Ÿฌ ์„œ๋น„์Šค๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค(๋ฆฌ์†Œ์Šค ์ฒด์ธ์˜ ์‹œ์ž‘์€ ์ผ€์ดํฌ ํŒจํ„ด์— ์˜ํ•ด ๋ณด์žฅ๋ฉ๋‹ˆ๋‹ค).

object SingleNodeImpl extends ZeroServiceImpl[IO]
  with EchoServiceService
  with EchoClientService
  with FiniteDurationLifecycleServiceImpl
{
  type Config = EchoConfig[String] with EchoClientConfig[String] with FiniteDurationLifecycleConfig
}

์ด ๋…ธ๋“œ์— ํ•„์š”ํ•œ ์ •ํ™•ํ•œ ๊ตฌ์„ฑ ์œ ํ˜•์„ ์ง€์ •ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํŠน์ • ์„œ๋น„์Šค์— ํ•„์š”ํ•œ ๊ตฌ์„ฑ ์œ ํ˜• ์ค‘ ํ•˜๋‚˜๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์–ด๋ฒ„๋ฆฌ๋ฉด ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ํ•„์š”ํ•œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ ์ ์ ˆํ•œ ์œ ํ˜•์˜ ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์œผ๋ฉด ๋…ธ๋“œ๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

ํ˜ธ์ŠคํŠธ ์ด๋ฆ„ ํ™•์ธ

์›๊ฒฉ ํ˜ธ์ŠคํŠธ์— ์—ฐ๊ฒฐํ•˜๋ ค๋ฉด ์‹ค์ œ IP ์ฃผ์†Œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์†Œ๋Š” ๋‚˜๋จธ์ง€ ๊ตฌ์„ฑ๋ณด๋‹ค ๋‚˜์ค‘์— ์•Œ๋ ค์งˆ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋…ธ๋“œ ID๋ฅผ ์ฃผ์†Œ์— ๋งคํ•‘ํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

case class NodeAddress[NodeId](host: Uri.Host)
trait AddressResolver[F[_]] {
  def resolve[NodeId](nodeId: NodeId): F[NodeAddress[NodeId]]
}

์ด ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋ฐฐํฌ ์ „์— ์ฃผ์†Œ๊ฐ€ ์•Œ๋ ค์ง€๋ฉด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ Scala ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ์ฃผ์†Œ๋ฅผ ์ž…๋ ฅํ•œ ๋‹ค์Œ ๋นŒ๋“œ๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”. ๊ทธ๋Ÿฌ๋ฉด ํ…Œ์ŠคํŠธ๊ฐ€ ์ปดํŒŒ์ผ๋˜๊ณ  ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
    ์ด ๊ฒฝ์šฐ ํ•จ์ˆ˜๋Š” ์ •์ ์œผ๋กœ ์•Œ๋ ค์ง€๋ฉฐ ์ฝ”๋“œ์—์„œ ๋งคํ•‘์œผ๋กœ ํ‘œํ˜„๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Map[NodeId, NodeAddress].
  2. ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ์‹ค์ œ ์ฃผ์†Œ๋Š” ๋…ธ๋“œ๊ฐ€ ์‹œ์ž‘๋œ ํ›„์—๋งŒ ์•Œ๋ ค์ง‘๋‹ˆ๋‹ค.
    ์ด ๊ฒฝ์šฐ ๋‹ค๋ฅธ ๋…ธ๋“œ๋ณด๋‹ค ๋จผ์ € ์‹คํ–‰๋˜๋Š” "๊ฒ€์ƒ‰ ์„œ๋น„์Šค"๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ชจ๋“  ๋…ธ๋“œ๋Š” ์ด ์„œ๋น„์Šค์— ๋“ฑ๋กํ•˜๊ณ  ๋‹ค๋ฅธ ๋…ธ๋“œ์˜ ์ฃผ์†Œ๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
  3. ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด /etc/hosts, ๊ทธ๋Ÿฐ ๋‹ค์Œ ์‚ฌ์ „ ์ •์˜๋œ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„(์˜ˆ: my-project-main-node ะธ echo-backend) ๊ฐ„๋‹จํžˆ ์ด ์ด๋ฆ„์„ ์—ฐ๊ฒฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
    ๋ฐฐํฌ ์ค‘์— IP ์ฃผ์†Œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ๋ฅผ ๋” ์ž์„ธํžˆ ๊ณ ๋ คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋ฅผ ์œ„ํ•ด
์žฅ๋‚œ๊ฐ ์˜ˆ์—์„œ๋Š” ๋ชจ๋“  ๋…ธ๋“œ๊ฐ€ ๋™์ผํ•œ IP ์ฃผ์†Œ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค. 127.0.0.1.

๋‹ค์Œ์œผ๋กœ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์„ ๊ณ ๋ คํ•ฉ๋‹ˆ๋‹ค.

  1. ๋ชจ๋“  ์„œ๋น„์Šค๋ฅผ ํ•˜๋‚˜์˜ ๋…ธ๋“œ์— ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ทธ๋ฆฌ๊ณ  ์—์ฝ” ์„œ๋น„์Šค์™€ ์—์ฝ” ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋‹ค๋ฅธ ๋…ธ๋“œ์—์„œ ํ˜ธ์ŠคํŒ…ํ•ฉ๋‹ˆ๋‹ค.

๊ตฌ์„ฑ ๋…ธ๋“œ XNUMX๊ฐœ:

๋‹จ์ผ ๋…ธ๋“œ ๊ตฌ์„ฑ

object SingleNodeConfig extends EchoConfig[String] 
  with EchoClientConfig[String] with FiniteDurationLifecycleConfig
{
  case object Singleton // identifier of the single node 
  // configuration of server
  type NodeId = Singleton.type
  def nodeId = Singleton

  /** Type safe service port specification. */
  override def portNumber: PortNumber = 8088

  // configuration of client

  /** We'll use the service provided by the same host. */
  def echoServiceDependency = echoService

  override def testMessage: UrlPathElement = "hello"

  def pollInterval: FiniteDuration = 1.second

  // lifecycle controller configuration
  def lifetime: FiniteDuration = 10500.milliseconds // additional 0.5 seconds so that there are 10 requests, not 9.
}

๊ฐœ์ฒด๋Š” ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๋ชจ๋‘์˜ ๊ตฌ์„ฑ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. TTL(Time-To-Live) ๊ตฌ์„ฑ๋„ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ ๊ฐ„๊ฒฉ์ด ์ง€๋‚˜๋ฉด lifetime ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. (Ctrl-C๋„ ์ž‘๋™ํ•˜์—ฌ ๋ชจ๋“  ๋ฆฌ์†Œ์Šค๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.)

๋™์ผํ•œ ๊ตฌ์„ฑ ๋ฐ ๊ตฌํ˜„ ํŠน์„ฑ ์„ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ์œผ๋กœ ๊ตฌ์„ฑ๋œ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ๊ฐœ์˜ ๋ณ„๋„ ๋…ธ๋“œ:

XNUMX๋…ธ๋“œ ๊ตฌ์„ฑ

  object NodeServerConfig extends EchoConfig[String] with SigTermLifecycleConfig
  {
    type NodeId = NodeIdImpl

    def nodeId = NodeServer

    override def portNumber: PortNumber = 8080
  }

  object NodeClientConfig extends EchoClientConfig[String] with FiniteDurationLifecycleConfig
  {
    // NB! dependency specification
    def echoServiceDependency = NodeServerConfig.echoService

    def pollInterval: FiniteDuration = 1.second

    def lifetime: FiniteDuration = 10500.milliseconds // additional 0.5 seconds so that there are 10 request, not 9.

    def testMessage: String = "dolly"
  }

์ค‘์š”ํ•œ! ์„œ๋น„์Šค๊ฐ€ ์–ด๋–ป๊ฒŒ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. ์šฐ๋ฆฌ๋Š” ํ•œ ๋…ธ๋“œ๊ฐ€ ๊ตฌํ˜„ํ•˜๋Š” ์„œ๋น„์Šค๋ฅผ ๋‹ค๋ฅธ ๋…ธ๋“œ์˜ ์ข…์†์„ฑ ๋ฐฉ๋ฒ• ๊ตฌํ˜„์œผ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ข…์†์„ฑ ์œ ํ˜•์€ ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ ํ™•์ธ๋ฉ๋‹ˆ๋‹ค. ํ”„๋กœํ† ์ฝœ ์œ ํ˜•์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์‹คํ–‰ํ•˜๋ฉด ์ข…์†์„ฑ์— ์˜ฌ๋ฐ”๋ฅธ ๋Œ€์ƒ ๋…ธ๋“œ ID๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ด ์ฒด๊ณ„ ๋•๋ถ„์— ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ์ •ํ™•ํžˆ ํ•œ ๋ฒˆ ์ง€์ •ํ•˜๊ณ  ํ•ญ์ƒ ์˜ฌ๋ฐ”๋ฅธ ํฌํŠธ๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ๋ณด์žฅ๋ฉ๋‹ˆ๋‹ค.

๋‘ ๊ฐœ์˜ ์‹œ์Šคํ…œ ๋…ธ๋“œ ๊ตฌํ˜„

์ด ๊ตฌ์„ฑ์—์„œ๋Š” ๋ณ€๊ฒฝ ์—†์ด ๋™์ผํ•œ ์„œ๋น„์Šค ๊ตฌํ˜„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์œ ์ผํ•œ ์ฐจ์ด์ ์€ ์ด์ œ ์„œ๋กœ ๋‹ค๋ฅธ ์„œ๋น„์Šค ์„ธํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋‘ ๊ฐœ์˜ ๊ฐ์ฒด๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  object TwoJvmNodeServerImpl extends ZeroServiceImpl[IO] with EchoServiceService with SigIntLifecycleServiceImpl {
    type Config = EchoConfig[String] with SigTermLifecycleConfig
  }

  object TwoJvmNodeClientImpl extends ZeroServiceImpl[IO] with EchoClientService with FiniteDurationLifecycleServiceImpl {
    type Config = EchoClientConfig[String] with FiniteDurationLifecycleConfig
  }

์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋Š” ์„œ๋ฒ„๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉฐ ์„œ๋ฒ„ ๊ตฌ์„ฑ๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ๋…ธ๋“œ๋Š” ํด๋ผ์ด์–ธํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ๊ตฌ์„ฑ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋‘ ๋…ธ๋“œ ๋ชจ๋‘ ์ˆ˜๋ช… ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„ ๋…ธ๋“œ๋Š” ์ค‘์ง€๋  ๋•Œ๊นŒ์ง€ ๋ฌด๊ธฐํ•œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. SIGTERM'om, ํด๋ผ์ด์–ธํŠธ ๋…ธ๋“œ๋Š” ์ผ์ • ์‹œ๊ฐ„ ํ›„์— ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ์„ผํ‹ฐ๋ฏธํ„ฐ. ๋Ÿฐ์ฒ˜ ์•ฑ.

์ผ๋ฐ˜์ ์ธ ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค

์ด ๊ตฌ์„ฑ ์ ‘๊ทผ ๋ฐฉ์‹์ด ์ „์ฒด ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค์— ์–ด๋–ค ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ตฌ์„ฑ์€ ๋‚˜๋จธ์ง€ ์ฝ”๋“œ์™€ ํ•จ๊ป˜ ์ปดํŒŒ์ผ๋˜๊ณ  ์•„ํ‹ฐํŒฉํŠธ(.jar)๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๊ตฌ์„ฑ์„ ๋ณ„๋„์˜ ์•„ํ‹ฐํŒฉํŠธ์— ๋„ฃ๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ผ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋™์ผํ•œ ์ฝ”๋“œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์—ฌ๋Ÿฌ ๊ตฌ์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ, ๋‹ค์–‘ํ•œ ๊ตฌ์„ฑ ๋ถ„๊ธฐ์— ํ•ด๋‹นํ•˜๋Š” ์•„ํ‹ฐํŒฉํŠธ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠน์ • ๋ฒ„์ „์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์ข…์†์„ฑ์€ ๊ตฌ์„ฑ๊ณผ ํ•จ๊ป˜ ์ €์žฅ๋˜๋ฉฐ ํ•ด๋‹น ๋ฒ„์ „์€ ํ•ด๋‹น ๋ฒ„์ „์˜ ๊ตฌ์„ฑ์„ ๋ฐฐํฌํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•  ๋•Œ๋งˆ๋‹ค ์˜์›ํžˆ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ๊ตฌ์„ฑ ๋ณ€๊ฒฝ์€ ์ฝ”๋“œ ๋ณ€๊ฒฝ์œผ๋กœ ์ด์–ด์ง‘๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ๊ฐ
๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์ผ๋ฐ˜์ ์ธ ํ’ˆ์งˆ ๋ณด์ฆ ํ”„๋กœ์„ธ์Šค์— ๋”ฐ๋ผ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

๋ฒ„๊ทธ ํŠธ๋ž˜์ปค ํ‹ฐ์ผ“ -> ํ™๋ณด -> ๊ฒ€ํ†  -> ๊ด€๋ จ ๋ธŒ๋žœ์น˜์™€ ๋ณ‘ํ•ฉ ->
ํ†ตํ•ฉ -> ๋ฐฐํฌ

์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ ๊ตฌํ˜„์˜ ์ฃผ์š” ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ๊ตฌ์„ฑ์€ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์˜ ๋ชจ๋“  ๋…ธ๋“œ์—์„œ ์ผ๊ด€๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๋…ธ๋“œ๊ฐ€ ๋‹จ์ผ ์†Œ์Šค๋กœ๋ถ€ํ„ฐ ๋™์ผํ•œ ๊ตฌ์„ฑ์„ ์ˆ˜์‹ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

  2. ๋…ธ๋“œ ์ค‘ ํ•˜๋‚˜๋งŒ ๊ตฌ์„ฑ์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ "๊ตฌ์„ฑ ๋“œ๋ฆฌํ”„ํŠธ"๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.

  3. ์ž‘์€ ๊ตฌ์„ฑ ๋ณ€๊ฒฝ์ด ๋” ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค.

  4. ๋Œ€๋ถ€๋ถ„์˜ ๊ตฌ์„ฑ ๋ณ€๊ฒฝ์€ ์ „์ฒด ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค์˜ ์ผ๋ถ€๋กœ ๋ฐœ์ƒํ•˜๋ฉฐ ๊ฒ€ํ†  ๋Œ€์ƒ์ด ๋ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ๋•์…˜ ๊ตฌ์„ฑ์„ ์ €์žฅํ•˜๋ ค๋ฉด ๋ณ„๋„์˜ ์ €์žฅ์†Œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๊นŒ? ์ด ๊ตฌ์„ฑ์—๋Š” ์•ก์„ธ์Šค๋ฅผ ์ œํ•œํ•˜๋ ค๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ฐ ๊ธฐํƒ€ ๋ฏผ๊ฐํ•œ ์ •๋ณด๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ† ๋Œ€๋กœ ์ตœ์ข… ๊ตฌ์„ฑ์„ ๋ณ„๋„์˜ ์ €์žฅ์†Œ์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ํƒ€๋‹นํ•  ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ๊ตฌ์„ฑ์„ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋ถ„ํ• ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜๋Š” ๊ณต๊ฐœ์ ์œผ๋กœ ์•ก์„ธ์Šค ๊ฐ€๋Šฅํ•œ ๊ตฌ์„ฑ ์„ค์ •์„ ํฌํ•จํ•˜๊ณ  ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ์ œํ•œ๋œ ์„ค์ •์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ์ž๋Š” ์ผ๋ฐ˜ ์„ค์ •์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ถ„๋ฆฌ๋Š” ๊ธฐ๋ณธ๊ฐ’์ด ํฌํ•จ๋œ ์ค‘๊ฐ„ ํŠน์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‰ฝ๊ฒŒ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€๋Šฅํ•œ ๋ณ€ํ˜•

์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ์„ ๋ช‡ ๊ฐ€์ง€ ์ผ๋ฐ˜์ ์ธ ๋Œ€์•ˆ๊ณผ ๋น„๊ตํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. ๋Œ€์ƒ ์ปดํ“จํ„ฐ์˜ ํ…์ŠคํŠธ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.
  2. ์ค‘์•™ ์ง‘์ค‘์‹ ํ‚ค-๊ฐ’ ์ €์žฅ์†Œ(etcd/zookeeper).
  3. ํ”„๋กœ์„ธ์Šค๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜์ง€ ์•Š๊ณ ๋„ ์žฌ๊ตฌ์„ฑ/๋‹ค์‹œ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ์„ธ์Šค ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๋‹ค.
  4. ์•„ํ‹ฐํŒฉํŠธ ๋ฐ ๋ฒ„์ „ ์ œ์–ด ์™ธ๋ถ€์— ๊ตฌ์„ฑ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

ํ…์ŠคํŠธ ํŒŒ์ผ์€ ์ž‘์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์—๋„ ์ƒ๋‹นํ•œ ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ ๊ด€๋ฆฌ์ž๋Š” ์›๊ฒฉ ๋…ธ๋“œ์— ๋กœ๊ทธ์ธํ•˜์—ฌ ์ ์ ˆํ•œ ํŒŒ์ผ์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์„œ๋น„์Šค๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋Œ€๊ทœ๋ชจ ์‹œ์Šคํ…œ์˜ ๊ฒฝ์šฐ ์ด๋Ÿฌํ•œ ์œ ์—ฐ์„ฑ์€ ๋ฐ”๋žŒ์งํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ๋‹ค๋ฅธ ์‹œ์Šคํ…œ์— ํ”์ ์„ ๋‚จ๊ธฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋ฌด๋„ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฒ€ํ† ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ •ํ™•ํžˆ ๋ˆ„๊ฐ€ ์–ด๋–ค ์ด์œ ๋กœ ๋ณ€๊ฒฝ์„ ํ–ˆ๋Š”์ง€ ํŒŒ์•…ํ•˜๊ธฐ๋Š” ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ํ…Œ์ŠคํŠธ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ์ด ๋ถ„์‚ฐ๋œ ๊ฒฝ์šฐ ๊ด€๋ฆฌ์ž๋Š” ๋‹ค๋ฅธ ๋…ธ๋“œ์—์„œ ํ•ด๋‹น ๋ณ€๊ฒฝ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ์žŠ์–ด๋ฒ„๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(๋˜ํ•œ ์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ด์„œ ๋‚˜์ค‘์— ํ…์ŠคํŠธ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋‹ซํžˆ๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ถœ๋ ฅ๊ณผ ๋™์ผํ•œ ์œ ํ˜•์„ ์ƒ์„ฑํ•˜๋Š” ํŒŒ์„œ ๋ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ธฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. Config, ํ…์ŠคํŠธ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ์‹œ์Šคํ…œ์˜ ๋ณต์žก์„ฑ์€ ํ…์ŠคํŠธ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ์‹œ์Šคํ…œ์˜ ๋ณต์žก์„ฑ๋ณด๋‹ค ๋‹ค์†Œ ์ ์Šต๋‹ˆ๋‹ค. ํ…์ŠคํŠธ ํŒŒ์ผ์—๋Š” ์ถ”๊ฐ€ ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.)

์ค‘์•™ ์ง‘์ค‘์‹ ํ‚ค-๊ฐ’ ์ €์žฅ์†Œ๋Š” ๋ถ„์‚ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฉ”ํƒ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐฐํฌํ•˜๊ธฐ ์œ„ํ•œ ์ข‹์€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋ฌด์—‡์ธ์ง€, ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๊ฒฐ์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋ฅผ ํ•˜๋‚˜ ๊ฐ€์ง€์ž C => A => B๋ฐ ๋งค๊ฐœ๋ณ€์ˆ˜ C ๊ฑฐ์˜ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์œผ๋ฉฐ ๋ฐ์ดํ„ฐ A - ์ž์ฃผ. ์ด ๊ฒฝ์šฐ์— ์šฐ๋ฆฌ๋Š” ์ด๋ ‡๊ฒŒ ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. C - ๊ตฌ์„ฑ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐ A - ๋ฐ์ดํ„ฐ. ๊ตฌ์„ฑ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ณด๋‹ค ๋œ ์ž์ฃผ ๋ณ€๊ฒฝ๋œ๋‹ค๋Š” ์ ์—์„œ ๋ฐ์ดํ„ฐ์™€ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ฐ์ดํ„ฐ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํ•œ ์†Œ์Šค(์‚ฌ์šฉ์ž)์—์„œ ๊ฐ€์ ธ์˜ค๊ณ  ๊ตฌ์„ฑ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋‹ค๋ฅธ ์†Œ์Šค(์‹œ์Šคํ…œ ๊ด€๋ฆฌ์ž)์—์„œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

ํ”„๋กœ๊ทธ๋žจ์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜์ง€ ์•Š๊ณ  ๊ฑฐ์˜ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, ์–ด๋–ป๊ฒŒ๋“  ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๊ณ , ์ž˜๋ชป๋œ ๊ฐ’์„ ์ €์žฅํ•˜๊ณ , ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๊ณ  ํ™•์ธํ•˜๊ณ , ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋กœ๊ทธ๋žจ์ด ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ํ”„๋กœ๊ทธ๋žจ์˜ ๋ณต์žก๋„๋ฅผ ์ค„์ด๋Š” ๊ด€์ ์—์„œ๋Š”, ํ”„๋กœ๊ทธ๋žจ ๋™์ž‘ ์ค‘์— ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ˆ˜๋ฅผ ์ค„์ด๋Š” ๊ฒƒ(ํ˜น์€ ๊ทธ๋Ÿฌํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „ํ˜€ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ)์ด ํ•ฉ๋ฆฌ์ ์ด๋‹ค.

์ด ๊ฒŒ์‹œ๋ฌผ์˜ ๋ชฉ์ ์— ๋”ฐ๋ผ ์ •์  ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๋™์  ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์„œ๋น„์Šค ๋…ผ๋ฆฌ๋กœ ์ธํ•ด ํ”„๋กœ๊ทธ๋žจ ์ž‘๋™ ์ค‘์— ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋™์ ์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์˜ต์…˜์€ ์ •์ ์ด๋ฉฐ ์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋™์  ์žฌ๊ตฌ์„ฑ์˜ ๊ฒฝ์šฐ ์šด์˜ ์ฒด์ œ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ์ƒˆ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์˜ ์ผ๋ถ€๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์‹ค์‹œ๊ฐ„ ์žฌ๊ตฌ์„ฑ์€ ์‹œ์Šคํ…œ์˜ ๋ณต์žก์„ฑ์„ ์ฆ๊ฐ€์‹œํ‚ค๋ฏ€๋กœ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ํ”„๋กœ์„ธ์Šค๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด ํ‘œ์ค€ OS ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.)

์‚ฌ๋žŒ๋“ค์ด ๋™์  ์žฌ๊ตฌ์„ฑ์„ ๊ณ ๋ คํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ์ •์  ๊ตฌ์„ฑ ์‚ฌ์šฉ์˜ ์ค‘์š”ํ•œ ์ธก๋ฉด ์ค‘ ํ•˜๋‚˜๋Š” ๊ตฌ์„ฑ ์—…๋ฐ์ดํŠธ(๋‹ค์šดํƒ€์ž„) ํ›„ ์‹œ์Šคํ…œ์„ ์žฌ๋ถ€ํŒ…ํ•˜๋Š” ๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ •์  ๊ตฌ์„ฑ์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์ƒˆ ๊ฐ’์„ ์ ์šฉํ•˜๋ ค๋ฉด ์‹œ์Šคํ…œ์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€๋™ ์ค‘์ง€ ์‹œ๊ฐ„ ๋ฌธ์ œ๋Š” ์‹œ์Šคํ…œ๋งˆ๋‹ค ์‹ฌ๊ฐ๋„๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ๋กœ๋“œ๊ฐ€ ์ตœ์†Œ์ผ ๋•Œ ์žฌ๋ถ€ํŒ…์„ ์˜ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€์†์ ์ธ ์„œ๋น„์Šค ์ œ๊ณต์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. AWS ELB ์—ฐ๊ฒฐ ๋“œ๋ ˆ์ด๋‹. ๋™์‹œ์— ์‹œ์Šคํ…œ์„ ์žฌ๋ถ€ํŒ…ํ•ด์•ผ ํ•  ๋•Œ ์ด ์‹œ์Šคํ…œ์˜ ๋ณ‘๋ ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์‹œ์ž‘ํ•˜๊ณ  ๋ฐธ๋Ÿฐ์„œ๋ฅผ ์ด ์‹œ์Šคํ…œ์œผ๋กœ ์ „ํ™˜ํ•œ ๋‹ค์Œ ์ด์ „ ์—ฐ๊ฒฐ์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ์ด์ „ ์—ฐ๊ฒฐ์ด ๋ชจ๋‘ ์ข…๋ฃŒ๋œ ํ›„ ์‹œ์Šคํ…œ์˜ ์ด์ „ ์ธ์Šคํ„ด์Šค๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ์•„ํ‹ฐํŒฉํŠธ ๋‚ด๋ถ€ ๋˜๋Š” ์™ธ๋ถ€์— ๊ตฌ์„ฑ์„ ์ €์žฅํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ๊ณ ๋ คํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ์„ ์•„ํ‹ฐํŒฉํŠธ ๋‚ด๋ถ€์— ์ €์žฅํ–ˆ๋‹ค๋ฉด ์ ์–ด๋„ ์•„ํ‹ฐํŒฉํŠธ๋ฅผ ์กฐ๋ฆฝํ•˜๋Š” ๋™์•ˆ ๊ตฌ์„ฑ์˜ ์ •ํ™•์„ฑ์„ ํ™•์ธํ•  ๊ธฐํšŒ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ์ด ์ œ์–ด๋œ ์•„ํ‹ฐํŒฉํŠธ ์™ธ๋ถ€์— ์žˆ๋Š” ๊ฒฝ์šฐ ์ด ํŒŒ์ผ์„ ๋ณ€๊ฒฝํ•œ ์‚ฌ๋žŒ๊ณผ ๊ทธ ์ด์œ ๋ฅผ ์ถ”์ ํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ์–ผ๋งˆ๋‚˜ ์ค‘์š”ํ•ฉ๋‹ˆ๊นŒ? ์šฐ๋ฆฌ์˜ ์˜๊ฒฌ์œผ๋กœ๋Š” ๋งŽ์€ ์ƒ์‚ฐ ์‹œ์Šคํ…œ์—์„œ ์•ˆ์ •์ ์ด๊ณ  ๊ณ ํ’ˆ์งˆ์˜ ๊ตฌ์„ฑ์„ ๊ฐ–๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

์•„ํ‹ฐํŒฉํŠธ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋ฉด ์ƒ์„ฑ ์‹œ๊ธฐ, ํฌํ•จ๋œ ๊ฐ’, ํ™œ์„ฑํ™”/๋น„ํ™œ์„ฑํ™”๋˜๋Š” ๊ธฐ๋Šฅ, ๊ตฌ์„ฑ ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์ฑ…์ž„์ด ์žˆ๋Š” ์‚ฌ๋žŒ์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ๊ตฌ์„ฑ์„ ์•„ํ‹ฐํŒฉํŠธ ๋‚ด๋ถ€์— ์ €์žฅํ•˜๋ ค๋ฉด ์•ฝ๊ฐ„์˜ ๋…ธ๋ ฅ์ด ํ•„์š”ํ•˜๋ฏ€๋กœ ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๊ฒฐ์ •์„ ๋‚ด๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฐฌ๋ฐ˜ ์–‘๋ก 

์ œ์•ˆ๋œ ๊ธฐ์ˆ ์˜ ์žฅ๋‹จ์ ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์žฅ์ 

๋‹ค์Œ์€ ์ปดํŒŒ์ผ๋œ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ ๊ตฌ์„ฑ์˜ ์ฃผ์š” ๊ธฐ๋Šฅ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

  1. ์ •์  ๊ตฌ์„ฑ ํ™•์ธ. ํ™•์‹ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค
    ๊ตฌ์„ฑ์ด ์ •ํ™•ํ•ฉ๋‹ˆ๋‹ค.
  2. ํ’๋ถ€ํ•œ ๊ตฌ์„ฑ ์–ธ์–ด. ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ๋ฐฉ๋ฒ•์€ ์ตœ๋Œ€ ๋ฌธ์ž์—ด ๋ณ€์ˆ˜ ๋Œ€์ฒด์œผ๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. Scala๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ตฌ์„ฑ์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์–‘ํ•œ ์–ธ์–ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ๊ธฐ๋ณธ๊ฐ’์— ๋Œ€ํ•œ ํŠน์„ฑ, ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๋ฉด ๋‘˜๋Ÿฌ์‹ธ๋Š” ๋ฒ”์œ„์—์„œ ํ•œ ๋ฒˆ๋งŒ ์„ ์–ธ๋œ(DRY) ๊ฐ’์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ๋‚ด์—์„œ ์ง์ ‘ ๋ชจ๋“  ํด๋ž˜์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(Seq, Map, ์‚ฌ์šฉ์ž ์ •์˜ ํด๋ž˜์Šค).
  3. DSL. Scala์—๋Š” DSL์„ ๋” ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ์–ธ์–ด ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜๊ณ  ๋Œ€์ƒ ์‚ฌ์šฉ์ž ๊ทธ๋ฃน์— ๋ณด๋‹ค ํŽธ๋ฆฌํ•œ ๊ตฌ์„ฑ ์–ธ์–ด๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ์ตœ์†Œํ•œ ๋„๋ฉ”์ธ ์ „๋ฌธ๊ฐ€๊ฐ€ ๊ตฌ์„ฑ์„ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ „๋ฌธ๊ฐ€๋Š” ๊ตฌ์„ฑ ๊ฒ€ํ†  ํ”„๋กœ์„ธ์Šค์— ์ฐธ์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  4. ๋…ธ๋“œ ๊ฐ„ ๋ฌด๊ฒฐ์„ฑ ๋ฐ ๋™๊ธฐํ™”. ์ „์ฒด ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์˜ ๊ตฌ์„ฑ์„ ๋‹จ์ผ ์ง€์ ์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์˜ ์žฅ์  ์ค‘ ํ•˜๋‚˜๋Š” ๋ชจ๋“  ๊ฐ’์ด ์ •ํ™•ํžˆ ํ•œ ๋ฒˆ ์„ ์–ธ๋œ ๋‹ค์Œ ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ์žฌ์‚ฌ์šฉ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŒฌํ…€ ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜์—ฌ ํฌํŠธ๋ฅผ ์„ ์–ธํ•˜๋ฉด ๋…ธ๋“œ๊ฐ€ ๋ชจ๋“  ์˜ฌ๋ฐ”๋ฅธ ์‹œ์Šคํ…œ ๊ตฌ์„ฑ์—์„œ ํ˜ธํ™˜ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Œ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ๋…ธ๋“œ ๊ฐ„์— ๋ช…์‹œ์ ์ธ ํ•„์ˆ˜ ์ข…์†์„ฑ์ด ์žˆ์œผ๋ฉด ๋ชจ๋“  ์„œ๋น„์Šค๊ฐ€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.
  5. ๊ณ ํ’ˆ์งˆ์˜ ๋ณ€ํ™”. ๊ณตํ†ต ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์„ฑ์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๊ตฌ์„ฑ์— ๋Œ€ํ•œ ๋†’์€ ํ’ˆ์งˆ ํ‘œ์ค€์„ ๋‹ฌ์„ฑํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  6. ๋™์‹œ ๊ตฌ์„ฑ ์—…๋ฐ์ดํŠธ. ๊ตฌ์„ฑ ๋ณ€๊ฒฝ ํ›„ ์ž๋™ ์‹œ์Šคํ…œ ๋ฐฐํฌ๋ฅผ ํ†ตํ•ด ๋ชจ๋“  ๋…ธ๋“œ๊ฐ€ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.
  7. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‹จ์ˆœํ™”. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ๊ตฌ๋ฌธ ๋ถ„์„, ๊ตฌ์„ฑ ํ™•์ธ ๋˜๋Š” ์ž˜๋ชป๋œ ๊ฐ’ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ณต์žก์„ฑ์ด ์ค„์–ด๋“ญ๋‹ˆ๋‹ค. (์ด ์˜ˆ์ œ์—์„œ ๊ด€์ฐฐ๋œ ๊ตฌ์„ฑ ๋ณต์žก์„ฑ ์ค‘ ์ผ๋ถ€๋Š” ์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ์˜ ์†์„ฑ์ด ์•„๋‹ˆ๋ผ ๋” ํฐ ์œ ํ˜• ์•ˆ์ „์„ฑ์„ ์ œ๊ณตํ•˜๋ ค๋Š” ์š•๊ตฌ์— ๋”ฐ๋ฅธ ์˜์‹์ ์ธ ๊ฒฐ์ •์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.) ์ผ๋ฐ˜์ ์ธ ๊ตฌ์„ฑ์œผ๋กœ ๋Œ์•„๊ฐ€๋Š” ๊ฒƒ์€ ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. ๋ˆ„๋ฝ๋œ ๋ถ€๋ถ„์„ ๊ตฌํ˜„ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋ถ€์†. ๋”ฐ๋ผ์„œ ์˜ˆ๋ฅผ ๋“ค์–ด ์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ์œผ๋กœ ์‹œ์ž‘ํ•˜์—ฌ ์‹ค์ œ๋กœ ํ•„์š”ํ•  ๋•Œ๊นŒ์ง€ ๋ถˆํ•„์š”ํ•œ ๋ถ€๋ถ„์˜ ๊ตฌํ˜„์„ ์—ฐ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  8. ํ™•์ธ๋œ ๊ตฌ์„ฑ. ๊ตฌ์„ฑ ๋ณ€๊ฒฝ์€ ๋‹ค๋ฅธ ๋ณ€๊ฒฝ์˜ ์ผ๋ฐ˜์ ์ธ ์šด๋ช…์„ ๋”ฐ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ๊ฐ€ ์–ป๋Š” ์ถœ๋ ฅ์€ ๊ณ ์œ ํ•œ ๋ฒ„์ „์˜ ์•„ํ‹ฐํŒฉํŠธ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ด๋ฅผ ํ†ตํ•ด ์ด์ „ ๋ฒ„์ „์˜ ๊ตฌ์„ฑ์œผ๋กœ ๋Œ์•„๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. XNUMX๋…„ ์ „์˜ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ ์‹œ์Šคํ…œ์€ ์ •ํ™•ํžˆ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์•ˆ์ •์ ์ธ ๊ตฌ์„ฑ์€ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์˜ ์˜ˆ์ธก ๊ฐ€๋Šฅ์„ฑ๊ณผ ์‹ ๋ขฐ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ์€ ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ๊ณ ์ •๋˜๋ฏ€๋กœ ํ”„๋กœ๋•์…˜์—์„œ ์ด๋ฅผ ์œ„์กฐํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
  9. ๋ชจ๋“ˆ์„ฑ. ์ œ์•ˆ๋œ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ๋ชจ๋“ˆ์‹์ด๋ฉฐ ๋ชจ๋“ˆ์„ ๋‹ค์–‘ํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ฒฐํ•ฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์‹œ์Šคํ…œ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, ํ•œ ์‹ค์‹œ์˜ˆ์—์„œ๋Š” ๋‹จ์ผ ๋…ธ๋“œ์—์„œ ์‹คํ–‰๋˜๊ณ  ๋‹ค๋ฅธ ์‹ค์‹œ์˜ˆ์—์„œ๋Š” ์—ฌ๋Ÿฌ ๋…ธ๋“œ์—์„œ ์‹คํ–‰๋˜๋„๋ก ์‹œ์Šคํ…œ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ์˜ ํ”„๋กœ๋•์…˜ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๊ตฌ์„ฑ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  10. ํ…Œ์ŠคํŠธ. ๊ฐœ๋ณ„ ์„œ๋น„์Šค๋ฅผ ๋ชจ์˜ ๊ฐœ์ฒด๋กœ ๋Œ€์ฒดํ•˜๋ฉด ํ…Œ์ŠคํŠธ์— ํŽธ๋ฆฌํ•œ ์—ฌ๋Ÿฌ ๋ฒ„์ „์˜ ์‹œ์Šคํ…œ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  11. ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ. ์ „์ฒด ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์— ๋Œ€ํ•ด ๋‹จ์ผ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜๋ฉด ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ์˜ ์ผ๋ถ€๋กœ ํ†ต์ œ๋œ ํ™˜๊ฒฝ์—์„œ ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ผ๋ถ€ ๋…ธ๋“œ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์„ ์—๋ฎฌ๋ ˆ์ดํŠธํ•˜๋Š” ๊ฒƒ์€ ์‰ฝ์Šต๋‹ˆ๋‹ค.

๋‹จ์  ๋ฐ ์ œํ•œ ์‚ฌํ•ญ

์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ์€ ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์ ‘๊ทผ ๋ฐฉ์‹๊ณผ ๋‹ค๋ฅด๋ฉฐ ์ผ๋ถ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๋ช‡ ๊ฐ€์ง€ ๋‹จ์ ์ž…๋‹ˆ๋‹ค.

  1. ์ •์  ๊ตฌ์„ฑ. ๋•Œ๋กœ๋Š” ๋ชจ๋“  ๋ณดํ˜ธ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์šฐํšŒํ•˜์—ฌ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ ๊ตฌ์„ฑ์„ ์‹ ์†ํ•˜๊ฒŒ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ๋” ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์†Œํ•œ ์ปดํŒŒ์ผ๊ณผ ์ž๋™ ๋ฐฐํฌ๋Š” ์—ฌ์ „ํžˆ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ ‘๊ทผ ๋ฐฉ์‹์˜ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์ธ ๋™์‹œ์— ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ๋‹จ์ ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
  2. ๊ตฌ์„ฑ ์ƒ์„ฑ. ์ž๋™ ๋„๊ตฌ๋กœ ๊ตฌ์„ฑ ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ ๊ฒฝ์šฐ ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ฉํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ ๋…ธ๋ ฅ์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. ๋„๊ตฌ. ํ˜„์žฌ ๊ตฌ์„ฑ ์ž‘์—…์„ ์œ„ํ•ด ์„ค๊ณ„๋œ ์œ ํ‹ธ๋ฆฌํ‹ฐ์™€ ๊ธฐ์ˆ ์€ ํ…์ŠคํŠธ ํŒŒ์ผ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ/๊ธฐ์ˆ  ์ค‘ ์ผ๋ถ€๋Š” ์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  4. ํƒœ๋„์˜ ๋ณ€ํ™”๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž์™€ DevOps๋Š” ํ…์ŠคํŠธ ํŒŒ์ผ์— ์ต์ˆ™ํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์„ฑ์„ ์ปดํŒŒ์ผํ•œ๋‹ค๋Š” ์•„์ด๋””์–ด๋Š” ๋‹ค์†Œ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์ด๋ก€์ ์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฑฐ๋ถ€๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  5. ๊ณ ํ’ˆ์งˆ์˜ ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ์„ ํŽธ์•ˆํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(CI/CD) ๊ตฌ์ถ• ๋ฐ ๋ฐฐํฌ ํ”„๋กœ์„ธ์Šค์˜ ์ „์ฒด ์ž๋™ํ™”๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ƒ๋‹นํžˆ ๋ถˆํŽธํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ์˜ ์•„์ด๋””์–ด์™€ ๊ด€๋ จ์ด ์—†๋Š” ๊ณ ๋ ค๋œ ์˜ˆ์˜ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ œํ•œ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. ๋…ธ๋“œ์—์„œ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋ถˆํ•„์š”ํ•œ ๊ตฌ์„ฑ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ˆ„๋ฝ๋œ ๊ตฌํ˜„์„ ๊ฐ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋Š” ์ผ€์ดํฌ ํŒจํ„ด์„ ๋ฒ„๋ฆฌ๊ณ  ๋ณด๋‹ค ์—„๊ฒฉํ•œ ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, HList ๋˜๋Š” ๊ตฌ์„ฑ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋Œ€์ˆ˜์  ๋ฐ์ดํ„ฐ ์œ ํ˜•(์ผ€์ด์Šค ํด๋ž˜์Šค)์ž…๋‹ˆ๋‹ค.
  2. ๊ตฌ์„ฑ ํŒŒ์ผ์—๋Š” ๊ตฌ์„ฑ ์ž์ฒด์™€ ๊ด€๋ จ๋˜์ง€ ์•Š์€ ์ค„์ด ์žˆ์Šต๋‹ˆ๋‹ค. (package, import,๊ฐ์ฒด ์„ ์–ธ; override def๊ธฐ๋ณธ๊ฐ’์ด ์žˆ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ฒฝ์šฐ). ์ž์ฒด DSL์„ ๊ตฌํ˜„ํ•˜๋ฉด ์ด ๋ฌธ์ œ๋ฅผ ๋ถ€๋ถ„์ ์œผ๋กœ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋‹ค๋ฅธ ์œ ํ˜•์˜ ๊ตฌ์„ฑ(์˜ˆ: XML)๋„ ํŒŒ์ผ ๊ตฌ์กฐ์— ํŠน์ • ์ œํ•œ์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  3. ์ด ๊ฒŒ์‹œ๋ฌผ์˜ ๋ชฉ์ ์— ๋”ฐ๋ผ ์œ ์‚ฌํ•œ ๋…ธ๋“œ ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋™์  ์žฌ๊ตฌ์„ฑ์„ ๊ณ ๋ คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก 

์ด ๊ฒŒ์‹œ๋ฌผ์—์„œ ์šฐ๋ฆฌ๋Š” Scala ์œ ํ˜• ์‹œ์Šคํ…œ์˜ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ์†Œ์Šค ์ฝ”๋“œ์—์„œ ๊ตฌ์„ฑ์„ ํ‘œํ˜„ํ•˜๋Š” ์•„์ด๋””์–ด๋ฅผ ํƒ๊ตฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ ‘๊ทผ ๋ฐฉ์‹์€ XML ๋˜๋Š” ํ…์ŠคํŠธ ํŒŒ์ผ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ๊ธฐ์กด ๊ตฌ์„ฑ ๋ฐฉ๋ฒ•์„ ๋Œ€์ฒดํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ์˜ˆ์ œ๋Š” Scala๋กœ ๊ตฌํ˜„๋˜์—ˆ์ง€๋งŒ ๋™์ผํ•œ ์•„์ด๋””์–ด๊ฐ€ ๋‹ค๋ฅธ ์ปดํŒŒ์ผ๋œ ์–ธ์–ด(์˜ˆ: Kotlin, C#, Swift ๋“ฑ)๋กœ ์˜ฎ๊ฒจ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ํ”„๋กœ์ ํŠธ ์ค‘ ํ•˜๋‚˜์—์„œ ์ด ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ž‘๋™ํ•˜์ง€ ์•Š์œผ๋ฉด ํ…์ŠคํŠธ ํŒŒ์ผ๋กœ ์ด๋™ํ•˜์—ฌ ๋ˆ„๋ฝ๋œ ๋ถ€๋ถ„์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.

๋‹น์—ฐํžˆ ์ปดํŒŒ์ผ๋œ ๊ตฌ์„ฑ์—๋Š” ๊ณ ํ’ˆ์งˆ ๊ฐœ๋ฐœ ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ๋Œ€๊ฐ€๋กœ ๊ตฌ์„ฑ์˜ ๋†’์€ ํ’ˆ์งˆ๊ณผ ์‹ ๋ขฐ์„ฑ์ด ๋ณด์žฅ๋ฉ๋‹ˆ๋‹ค.

๊ณ ๋ ค๋œ ์ ‘๊ทผ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ™•์žฅ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋งคํฌ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํŒŒ์ผ ํƒ€์ž„ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. DSL์„ ๊ตฌํ˜„ํ•˜์—ฌ ์ตœ์ข… ์‚ฌ์šฉ์ž๊ฐ€ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌ์„ฑ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. ์ž๋™ ๊ตฌ์„ฑ ์กฐ์ •์„ ํ†ตํ•ด ๋™์  ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋…ธ๋“œ ์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด (1) ๊ฐ ๋…ธ๋“œ๊ฐ€ ์•ฝ๊ฐ„ ๋‹ค๋ฅธ ๊ตฌ์„ฑ์„ ๋ฐ›์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. (2) ํด๋Ÿฌ์Šคํ„ฐ ๊ด€๋ฆฌ์ž๋Š” ์ƒˆ ๋…ธ๋“œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌ์˜ ๋ง

๋‚˜๋Š” ์ดˆ์•ˆ ๊ธฐ์‚ฌ์— ๋Œ€ํ•œ ๊ฑด์„ค์ ์ธ ๋น„ํŒ์— ๋Œ€ํ•ด Andrei Saksonov, Pavel Popov ๋ฐ Anton Nekhaev์—๊ฒŒ ๊ฐ์‚ฌ๋ฅผ ํ‘œํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€