μ΄ κ²μλ¬Όμμ μ°λ¦¬λ λΆμ° μμ€ν
ꡬμ±μ μ²λ¦¬νλ ν₯λ―Έλ‘μ΄ λ°©λ²μ 곡μ νκ³ μΆμ΅λλ€.
ꡬμ±μ μ νμ΄ μμ ν λ°©μμΌλ‘ Scala μΈμ΄λ‘ μ§μ ννλ©λλ€. ꡬν μκ° μμΈν μ€λͺ
λμ΄ μμ΅λλ€. μ 체 κ°λ° νλ‘μΈμ€μ λν μν₯μ ν¬ν¨νμ¬ μ μμ λ€μν μΈ‘λ©΄μ΄ λ
Όμλ©λλ€.
κ°μ
κ°λ ₯ν λΆμ° μμ€ν μ ꡬμΆνλ €λ©΄ λͺ¨λ λ Έλμμ μ ννκ³ μΌκ΄λ ꡬμ±μ μ¬μ©ν΄μΌ ν©λλ€. μΌλ°μ μΈ μ루μ μ ν μ€νΈ λ°°ν¬ μ€λͺ (terraform, ansible λ±)κ³Ό μλμΌλ‘ μμ±λ κ΅¬μ± νμΌ(μ’ μ’ κ° λ Έλ/μν μ μ©)μ μ¬μ©νλ κ²μ λλ€. λν κ° ν΅μ λ Έλμμ λμΌν λ²μ μ λμΌν νλ‘ν μ½μ μ¬μ©νκ³ μΆμ μλ μμ΅λλ€(κ·Έλ μ§ μμΌλ©΄ λΉνΈνμ± λ¬Έμ κ° λ°μνκ² λ©λλ€). JVM μΈκ³μμ μ΄λ μ΅μν λ©μμ§ λΌμ΄λΈλ¬λ¦¬κ° λͺ¨λ ν΅μ λ Έλμμ λμΌν λ²μ μ΄μ΄μΌ ν¨μ μλ―Έν©λλ€.
μμ€ν ν μ€νΈλ μ΄λ»μ΅λκΉ? λ¬Όλ‘ ν΅ν© ν μ€νΈμ μμ λͺ¨λ κ΅¬μ± μμμ λν λ¨μ ν μ€νΈλ₯Ό κ±°μ³μΌ ν©λλ€. λ°νμ μ ν μ€νΈ κ²°κ³Όλ₯Ό μΆμ νλ €λ©΄ λͺ¨λ λΌμ΄λΈλ¬λ¦¬μ λ²μ μ΄ λ°νμκ³Ό ν μ€νΈ νκ²½ λͺ¨λμμ λμΌνκ² μ μ§λλμ§ νμΈν΄μΌ ν©λλ€.
ν΅ν© ν μ€νΈλ₯Ό μ€νν λ λͺ¨λ λ Έλμμ λμΌν ν΄λμ€ κ²½λ‘λ₯Ό κ°λ κ²μ΄ ν¨μ¬ μ¬μ΄ κ²½μ°κ° λ§μ΅λλ€. λ°°ν¬ μ λμΌν ν΄λμ€ κ²½λ‘κ° μ¬μ©λλμ§ νμΈνλ©΄ λ©λλ€. (λ€λ₯Έ λ Έλμμ λ€λ₯Έ ν΄λμ€ κ²½λ‘λ₯Ό μ¬μ©ν μ μμ§λ§ μ΄ κ΅¬μ±μ νννκ³ μ¬λ°λ₯΄κ² λ°°ν¬νλ κ²μ΄ λ μ΄λ ΅μ΅λλ€.) λ°λΌμ μμ μ λ¨μνκ² μ μ§νκΈ° μν΄ λͺ¨λ λ Έλμμ λμΌν ν΄λμ€ κ²½λ‘λ§ κ³ λ €ν©λλ€.
ꡬμ±μ μννΈμ¨μ΄μ ν¨κ» λ°μ νλ κ²½ν₯μ΄ μμ΅λλ€. μ°λ¦¬λ μΌλ°μ μΌλ‘ λ€μν λ²μ μ μλ³νκΈ° μν΄ λ²μ μ μ¬μ©ν©λλ€.
μννΈμ¨μ΄ μ§νμ λ¨κ³. λ²μ κ΄λ¦¬μμ ꡬμ±μ λ€λ£¨κ³ μΌλΆ λ μ΄λΈμ μ¬μ©νμ¬ λ€μν ꡬμ±μ μλ³νλ κ²μ΄ ν©λ¦¬μ μΌλ‘ 보μ
λλ€. νλ‘λμ
μ ꡬμ±μ΄ νλλ§ μλ κ²½μ° λ¨μΌ λ²μ μ μλ³μλ‘ μ¬μ©ν μ μμ΅λλ€. λλ‘λ μ¬λ¬ νλ‘λμ
νκ²½μ΄ μμ μ μμ΅λλ€. κ·Έλ¦¬κ³ κ° νκ²½λ§λ€ λ³λμ κ΅¬μ± λΆκΈ°κ° νμν μ μμ΅λλ€. λ°λΌμ λ€μν ꡬμ±μ κ³ μ νκ² μλ³νκΈ° μν΄ κ΅¬μ±μ λΆκΈ° λ° λ²μ λ μ΄λΈμ΄ μ§μ λ μ μμ΅λλ€. κ° λΆκΈ° λ μ΄λΈ λ° λ²μ μ λΆμ° λ
Έλ, ν¬νΈ, μΈλΆ 리μμ€, κ° λ
Έλμ ν΄λμ€ κ²½λ‘ λΌμ΄λΈλ¬λ¦¬ λ²μ μ λ¨μΌ μ‘°ν©μ ν΄λΉν©λλ€. μ¬κΈ°μλ λ€λ₯Έ μν°ν©νΈμ λμΌν λ°©μμΌλ‘ λ¨μΌ λΆκΈ°λ§ λ€λ£¨κ³ ꡬμ±μ 1.2.3κ° κ΅¬μ± μμ XNUMXμ§μ λ²μ (XNUMX)μΌλ‘ μλ³ν©λλ€.
μ΅μ νκ²½μμλ κ΅¬μ± νμΌμ΄ λ μ΄μ μλμΌλ‘ μμ λμ§ μμ΅λλ€. μΌλ°μ μΌλ‘ μ°λ¦¬λ
λ°°ν¬ μ κ΅¬μ± νμΌ λ°
μ΄λ² ν¬μ€ν μμλ μ»΄νμΌλ μν°ν©νΈμ ꡬμ±μ μ μ§νλ μμ΄λμ΄λ₯Ό μ΄ν΄λ³΄κ² μ΅λλ€.
μ»΄νμΌ κ°λ₯ν ꡬμ±
μ΄ μΉμ μμλ μ μ ꡬμ±μ μλ₯Ό μ€λͺ ν©λλ€. λ κ°μ§ κ°λ¨ν μλΉμ€μΈ μμ½ μλΉμ€μ μμ½ μλΉμ€ ν΄λΌμ΄μΈνΈκ° κ΅¬μ± λ° κ΅¬νλ©λλ€. κ·Έλ° λ€μ λ μλΉμ€κ° λͺ¨λ ν¬ν¨λ λ κ°μ μλ‘ λ€λ₯Έ λΆμ° μμ€ν μ΄ μΈμ€ν΄μ€νλ©λλ€. νλλ λ¨μΌ λ Έλ ꡬμ±μ©μ΄κ³ λ€λ₯Έ νλλ XNUMXκ° λ Έλ ꡬμ±μ©μ λλ€.
μΌλ°μ μΈ λΆμ° μμ€ν μ λͺ κ°μ λ Έλλ‘ κ΅¬μ±λ©λλ€. λ Έλλ λ€μκ³Ό κ°μ μ νμ μ¬μ©νμ¬ μλ³ν μ μμ΅λλ€.
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]]
μΈλ ¨λ μ ν
λ§λλ€ Int
ν¬νΈ λ²νΈλ₯Ό λνλΌ μ μλ 16λΉνΈ κ°λ§ νμ©λ©λλ€. μ΄ κ΅¬μ± μ κ·Ό λ°©μμλ μ΄ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©ν νμκ° μμ΅λλ€. κ·Έλ₯ λ무 μ μ΄μΈλ¦¬λ κ² κ°μμ.
HTTP(REST)μ κ²½μ° μλΉμ€ κ²½λ‘κ° νμν μλ μμ΅λλ€.
type UrlPathPrefix = Refined[String, MatchesRegex[W.`"[a-zA-Z_0-9/]*"`.T]]
case class PortWithPrefix[Protocol](portNumber: PortNumber, pathPrefix: UrlPathPrefix)
ν¬ν ν
μ»΄νμΌ μ€μ νλ‘ν μ½μ μλ³νκΈ° μν΄ μ°λ¦¬λ μ ν μΈμλ₯Ό μ μΈνλ Scala κΈ°λ₯μ μ¬μ©ν©λλ€. Protocol
μμ
μμλ μ¬μ©νμ§ μλ κ²μ
λλ€. μμ λ§νλκ±°λ€ ν¬ν
μ ν. λ°νμμλ νλ‘ν μ½ μλ³μ μΈμ€ν΄μ€κ° κ±°μ νμνμ§ μμΌλ―λ‘ μ μ₯νμ§ μμ΅λλ€. μ»΄νμΌνλ λμ μ΄ ν¬ν
μ νμ μΆκ°μ μΈ μ ν μμ μ±μ μ 곡ν©λλ€. μλͺ»λ νλ‘ν μ½λ‘ ν¬νΈλ₯Ό μ λ¬ν μ μμ΅λλ€.
κ°μ₯ λ리 μ¬μ©λλ νλ‘ν μ½ μ€ νλλ Json μ§λ ¬νλ₯Ό μ¬μ©νλ REST APIμ λλ€.
sealed trait JsonHttpRestProtocol[RequestMessage, ResponseMessage]
μ΄λμ RequestMessage
ν΄λΌμ΄μΈνΈκ° μλ²μ λ³΄λΌ μ μλ κΈ°λ³Έ λ©μμ§ μ νμ
λλ€. ResponseMessage
μλ²λ‘λΆν°μ μλ΅ λ©μμ§μ
λλ€. λ¬Όλ‘ μνλ μ λ°λλ‘ ν΅μ νλ‘ν μ½μ μ§μ νλ λ€λ₯Έ νλ‘ν μ½ μ€λͺ
μ λ§λ€ μλ μμ΅λλ€.
μ΄ κ²μλ¬Όμ λͺ©μ μ μν΄ μ°λ¦¬λ νλ‘ν μ½μ λ κ°λ¨ν λ²μ μ μ¬μ©ν κ²μ λλ€:
sealed trait SimpleHttpGetRest[RequestMessage, ResponseMessage]
μ΄ νλ‘ν μ½μμλ μμ² λ©μμ§κ° URLμ μΆκ°λκ³ μλ΅ λ©μμ§κ° μΌλ° λ¬Έμμ΄λ‘ λ°νλ©λλ€.
μλΉμ€ ꡬμ±μ μλΉμ€ μ΄λ¦, ν¬νΈ λͺ¨μ λ° μΌλΆ μ’
μμ±μΌλ‘ μ€λͺ
λ μ μμ΅λλ€. Scalaμμ μ΄λ¬ν λͺ¨λ μμλ₯Ό ββνννλ λ°©λ²μλ λͺ κ°μ§ λ°©λ²μ΄ μμ΅λλ€(μ: HList
, λμ λ°μ΄ν° μ ν). μ΄ κ²μλ¬Όμ λͺ©μ μ μν΄ μ°λ¦¬λ μΌμ΄ν¬ ν¨ν΄μ μ¬μ©νκ³ κ²°ν© κ°λ₯ν μ‘°κ°(λͺ¨λ)μ νΉμ±μΌλ‘ λνλΌ κ²μ
λλ€. (μΌμ΄ν¬ ν¨ν΄μ μ΄ μ»΄νμΌ κ°λ₯ν κ΅¬μ± μ κ·Ό λ°©μμ μꡬ μ¬νμ΄ μλλλ€. μ΄λ μμ΄λμ΄μ κ°λ₯ν ꡬν μ€ νλμΌ λΏμ
λλ€.)
μΌμ΄ν¬ ν¨ν΄μ λ€λ₯Έ λ Έλμ λμ μΌλ‘ μ¬μ©νμ¬ μ’ μμ±μ ννν μ μμ΅λλ€.
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)
}
μμ½ μλΉμ€μλ ν¬νΈλ§ ꡬμ±νλ©΄ λ©λλ€. κ·Έλ¦¬κ³ μ΄ ν¬νΈκ° μμ½ νλ‘ν μ½μ μ§μν¨μ μ μΈν©λλ€. νΉμ±μ΄ μΆμ λ©μλ μ μΈμ νμ©νκΈ° λλ¬Έμ μ§κΈμ νΉμ ν¬νΈλ₯Ό μ§μ ν νμκ° μμ΅λλ€. μΆμ λ©μλλ₯Ό μ¬μ©νλ κ²½μ° μ»΄νμΌλ¬λ κ΅¬μ± μΈμ€ν΄μ€μμ ꡬνμ μꡬν©λλ€. μ¬κΈ°μλ ꡬνμ μ 곡νμ΅λλ€(8081
) ꡬ체μ μΈ κ΅¬μ±μμ 건λλ°λ©΄ κΈ°λ³Έκ°μΌλ‘ μ¬μ©λ©λλ€.
μμ½ μλΉμ€ ν΄λΌμ΄μΈνΈ ꡬμ±μμ μ’ μμ±μ μ μΈν μ μμ΅λλ€.
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
β μ€μ ν¨μ λνΌ(κ±°μ λͺ¨λλ)(κ²°κ΅ λ€λ₯Έ κ²μΌλ‘ λ체ν μ μμ)
μ΄ μΈν°νμ΄μ€λ₯Ό μ¬μ©νμ¬ λͺ κ°μ§ μλΉμ€λ₯Ό ꡬνν μ μμ΅λλ€. μλ₯Ό λ€μ΄, μ무κ²λ νμ§ μλ μλΉμ€λ λ€μκ³Ό κ°μ΅λλ€.
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
}
λ
Έλμμλ μ΄ λ
Έλμ νμν μ νν κ΅¬μ± μ νμ μ§μ ν©λλ€. μ»΄νμΌλ¬λ μ°λ¦¬κ° λΆμΆ©λΆν μ νμΌλ‘ κ°μ²΄(μΌμ΄ν¬)λ₯Ό λ§λλ κ²μ νμ©νμ§ μμ΅λλ€. Config
μ ν. λν μμ ν ꡬμ±μ μ 곡νμ§ μμΌλ©΄ λ
Έλλ₯Ό μμν μ μμ΅λλ€.
λ Έλ μ£Όμ νμΈ
μ°κ²°μ μ€μ νλ €λ©΄ κ° λ Έλμ λν μ€μ νΈμ€νΈ μ£Όμκ° νμν©λλ€. ꡬμ±μ λ€λ₯Έ λΆλΆλ³΄λ€ λμ€μ μλ €μ§ μλ μμ΅λλ€. λ°λΌμ λ Έλ IDμ μ€μ μ£Όμ κ°μ 맀νμ μ 곡νλ λ°©λ²μ΄ νμν©λλ€. μ΄ λ§€νμ λ€μκ³Ό κ°μ ν¨μμ λλ€.
case class NodeAddress[NodeId](host: Uri.Host)
trait AddressResolver[F[_]] {
def resolve[NodeId](nodeId: NodeId): F[NodeAddress[NodeId]]
}
μ΄λ¬ν κΈ°λ₯μ ꡬννλ λ°©λ²μλ λͺ κ°μ§κ° μμ΅λλ€.
- λ°°ν¬ μ μ μ€μ μ£Όμλ₯Ό μκ³ μμΌλ©΄ λ
Έλ νΈμ€νΈ μΈμ€ν΄μ€ν μ€μ μ€μ μ£Όμλ‘ Scala μ½λλ₯Ό μμ±νκ³ λμ€μ λΉλλ₯Ό μ€νν μ μμ΅λλ€(μ»΄νμΌ μκ° νμΈμ μνν λ€μ ν΅ν© ν
μ€νΈ λꡬ λͺ¨μ μ€ν). μ΄ κ²½μ° λ§€ν κΈ°λ₯μ μ μ μΌλ‘ μλ €μ Έ μμΌλ©° λ€μκ³Ό κ°μ΄ λ¨μνλ μ μμ΅λλ€.
Map[NodeId, NodeAddress]
. - λλ‘λ λ Έλκ° μ€μ λ‘ μμλ λ λμ€μ μ€μ μ£Όμλ₯Ό μ»κ±°λ μμ§ μμλμ§ μμ λ Έλμ μ£Όμκ° μλ κ²½μ°λ μμ΅λλ€. μ΄ κ²½μ° λ€λ₯Έ λͺ¨λ λ Έλλ³΄λ€ λ¨Όμ μμλλ κ²μ μλΉμ€κ° μμ μ μμΌλ©° κ° λ Έλλ ν΄λΉ μλΉμ€μμ μμ μ μ£Όμλ₯Ό μλ¦¬κ³ μ’ μμ±μ ꡬλ ν μ μμ΅λλ€.
- μμ ν μ μλ€λ©΄
/etc/hosts
, μ¬μ μ μλ νΈμ€νΈ μ΄λ¦(μ:my-project-main-node
λ°echo-backend
) λ°°ν¬ μ μ΄ μ΄λ¦μ IP μ£Όμμ μ°κ²°νλ©΄ λ©λλ€.
μ΄ κ²μλ¬Όμμλ μ΄λ¬ν μ¬λ‘λ₯Ό λ μμΈν λ€λ£¨μ§ μμ΅λλ€. μ€μ λ‘ μ°λ¦¬μ μ₯λκ° μμμλ λͺ¨λ λ
Έλκ° λμΌν IP μ£Όμλ₯Ό κ°μ΅λλ€. 127.0.0.1
.
μ΄ κ²μλ¬Όμμλ λ κ°μ§ λΆμ° μμ€ν λ μ΄μμμ κ³ λ €ν΄ λ³΄κ² μ΅λλ€.
- λͺ¨λ μλΉμ€κ° λ¨μΌ λ Έλμ λ°°μΉλλ λ¨μΌ λ Έλ λ μ΄μμ.
- μλΉμ€μ ν΄λΌμ΄μΈνΈκ° μλ‘ λ€λ₯Έ λ Έλμ μλ λ κ°μ λ Έλ λ μ΄μμ.
μ λν ꡬμ±
λ¨μΌ λ Έλ ꡬμ±
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.
}
μ¬κΈ°μλ μλ²μ ν΄λΌμ΄μΈνΈ ꡬμ±μ λͺ¨λ νμ₯νλ λ¨μΌ ꡬμ±μ λ§λλλ€. λν μΌλ°μ μΌλ‘ ν΄λΌμ΄μΈνΈμ μλ²λ₯Ό μ’
λ£νλ λΌμ΄νμ¬μ΄ν΄ 컨νΈλ‘€λ¬λ₯Ό ꡬμ±ν©λλ€. lifetime
κ°κ²©μ΄ μ§λκ°λλ€.
λμΌν μλΉμ€ ꡬν λ° κ΅¬μ± μΈνΈλ₯Ό μ¬μ©νμ¬ λ κ°μ κ°λ³ λ
Έλκ° μλ μμ€ν
λ μ΄μμμ μμ±ν μ μμ΅λλ€. μ°λ¦¬λ λ¨μ§ μ°½μ‘°νκΈ°λ§ νλ©΄ λλ€
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
, μμ½ ν΄λΌμ΄μΈνΈλ ꡬμ±λ μ ν κΈ°κ° νμ μ’
λ£λ©λλ€. μ°Έμ‘°
μ λ°μ μΈ κ°λ° κ³Όμ
μ΄ μ κ·Ό λ°©μμ΄ κ΅¬μ± μμ λ°©μμ μ΄λ»κ² λ³κ²½νλμ§ μ΄ν΄λ³΄κ² μ΅λλ€.
μ½λλ‘μμ ꡬμ±μ΄ μ»΄νμΌλμ΄ μν°ν©νΈλ₯Ό μμ±ν©λλ€. κ΅¬μ± μν°ν©νΈλ₯Ό λ€λ₯Έ μ½λ μν°ν©νΈμ λΆλ¦¬νλ κ²μ΄ ν©λ¦¬μ μΌλ‘ 보μ λλ€. λμΌν μ½λ κΈ°λ°μ λ€μν ꡬμ±μ κ°μ§ μ μλ κ²½μ°κ° λ§μ΅λλ€. λ¬Όλ‘ λ€μν κ΅¬μ± λΆκΈ°μ μ¬λ¬ λ²μ μ΄ μμ μλ μμ΅λλ€. ꡬμ±μμ νΉμ λ²μ μ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ νν μ μμΌλ©° μ΄λ μ΄ κ΅¬μ±μ λ°°ν¬ν λλ§λ€ μΌμ νκ² μ μ§λ©λλ€.
κ΅¬μ± λ³κ²½μ μ½λ λ³κ²½μ΄ λ©λλ€. λ°λΌμ λμΌν νμ§ λ³΄μ¦ νλ‘μΈμ€κ° μ μ©λμ΄μΌ ν©λλ€.
ν°μΌ -> ν보 -> κ²ν -> λ³ν© -> μ§μμ ν΅ν© -> μ§μμ λ°°ν¬
μ κ·Ό λ°©μμλ λ€μκ³Ό κ°μ κ²°κ³Όκ° μμ΅λλ€.
- ꡬμ±μ νΉμ μμ€ν μ μΈμ€ν΄μ€μ λν΄ μΌκ΄μ±μ΄ μμ΅λλ€. λ Έλ κ° μ°κ²°μ΄ μλͺ»λ μ μλ λ°©λ²μ μλ κ² κ°μ΅λλ€.
- νλμ λ Έλμμλ§ κ΅¬μ±μ λ³κ²½νλ κ²μ μ½μ§ μμ΅λλ€. λ‘κ·ΈμΈν΄μ μΌλΆ ν μ€νΈ νμΌμ λ³κ²½νλ κ²μ λ¬΄λ¦¬μΈ κ² κ°μ΅λλ€. λ°λΌμ κ΅¬μ± λ리ννΈ κ°λ₯μ±μ΄ μ€μ΄λλλ€.
- μμ κ΅¬μ± λ³κ²½μ μ½μ§ μμ΅λλ€.
- λλΆλΆμ κ΅¬μ± λ³κ²½ μ¬νμ λμΌν κ°λ° νλ‘μΈμ€λ₯Ό λ°λ₯΄λ©° μΌλΆ κ²ν λ₯Ό ν΅κ³Όν©λλ€.
νλ‘λμ ꡬμ±μ μν΄ λ³λμ μ μ₯μκ° νμν©λκΉ? νλ‘λμ ꡬμ±μλ λ§μ μ¬λμ μμ΄ λΏμ§ μλ κ³³μ 보κ΄νκ³ μΆμ λ―Όκ°ν μ λ³΄κ° ν¬ν¨λ μ μμ΅λλ€. λ°λΌμ νλ‘λμ ꡬμ±μ ν¬ν¨νκ³ μ‘μΈμ€κ° μ νλ λ³λμ μ μ₯μλ₯Ό μ μ§νλ κ²μ΄ μ’μ΅λλ€. ꡬμ±μ λ λΆλΆμΌλ‘ λλ μ μμ΅λλ€. νλλ νλ‘λμ μ κ°μ₯ κ°λ°©μ μΈ λ§€κ°λ³μλ₯Ό ν¬ν¨νκ³ λ€λ₯Έ νλλ ꡬμ±μ λΉλ° λΆλΆμ ν¬ν¨ν©λλ€. μ΄λ₯Ό ν΅ν΄ λλΆλΆμ κ°λ°μλ λ§€μ° λ―Όκ°ν νλͺ©μ λν μ‘μΈμ€λ₯Ό μ ννλ©΄μ λλ€μμ 맀κ°λ³μμ μ‘μΈμ€ν μ μμ΅λλ€. κΈ°λ³Έ 맀κ°λ³μ κ°μ΄ μλ μ€κ° νΉμ±μ μ¬μ©νλ©΄ μ΄λ₯Ό μ½κ² μνν μ μμ΅λλ€.
λ³ν
λ€λ₯Έ κ΅¬μ± κ΄λ¦¬ κΈ°μ κ³Ό λΉκ΅νμ¬ μ μλ μ κ·Ό λ°©μμ μ₯λ¨μ μ μ΄ν΄λ³΄κ² μ΅λλ€.
μ°μ , μ μλ κ΅¬μ± μ²λ¦¬ λ°©λ²μ λ€μν μΈ‘λ©΄μ λν λͺ κ°μ§ λμμ λμ΄νκ² μ΅λλ€.
- λμ μ»΄ν¨ν°μ ν μ€νΈ νμΌμ λλ€.
- μ€μ μ§μ€μ ν€-κ° μ μ₯μ(μ:
etcd
/zookeeper
). - νλ‘μΈμ€λ₯Ό λ€μ μμνμ§ μκ³ λ μ¬κ΅¬μ±/λ€μ μμν μ μλ νμ νλ‘μΈμ€ κ΅¬μ± μμμ λλ€.
- μν°ν©νΈ λ° λ²μ μ μ΄ μΈλΆ ꡬμ±μ λλ€.
ν μ€νΈ νμΌμ μμ μμ μΈ‘λ©΄μμ μ΄λ μ λ μ μ°μ±μ μ 곡ν©λλ€. μμ€ν κ΄λ¦¬μλ λμ λ Έλμ λ‘κ·ΈμΈνμ¬ λ³κ²½ν ν κ°λ¨ν μλΉμ€λ₯Ό λ€μ μμν μ μμ΅λλ€. μ΄λ λ ν° μμ€ν μλ μ’μ§ μμ μ μμ΅λλ€. λ³κ²½ μ¬ν λ€μ νμ μ΄ λ¨μ§ μμ΅λλ€. λ³κ²½ μ¬νμ λ€λ₯Έ μ¬λμ λμΌλ‘ κ²ν λμ§ μμ΅λλ€. λ³νμ μμΈμ΄ 무μμΈμ§ μμλ΄λ κ²μ μ΄λ €μΈ μ μμ΅λλ€. ν μ€νΈλμ§ μμμ΅λλ€. λΆμ° μμ€ν μ κ΄μ μμ κ΄λ¦¬μλ λ€λ₯Έ λ Έλ μ€ νλμ ꡬμ±μ μ λ°μ΄νΈνλ κ²μ μμ΄λ²λ¦΄ μ μμ΅λλ€.
(κ·Έλ°λ° κ²°κ΅ ν
μ€νΈ κ΅¬μ± νμΌμ μ¬μ©νκΈ° μμν΄μΌ νλ€λ©΄ λμΌν κ²°κ³Όλ₯Ό μμ±ν μ μλ νμ + μ ν¨μ± κ²μ¬κΈ°λ§ μΆκ°νλ©΄ λ©λλ€. Config
μ νμ μ
λ ₯νλ©΄ ν
μ€νΈ ꡬμ±μ μ¬μ©νκΈ°μ μΆ©λΆν©λλ€. μ΄λ λν μ»΄νμΌ μκ° κ΅¬μ±μ 볡μ‘μ±μ΄ ν
μ€νΈ κΈ°λ° κ΅¬μ±μ 볡μ‘μ±λ³΄λ€ μ‘°κΈ λ μλ€λ κ²μ 보μ¬μ€λλ€. μλνλ©΄ ν
μ€νΈ κΈ°λ° λ²μ μμλ λͺ κ°μ§ μΆκ° μ½λκ° νμνκΈ° λλ¬Έμ
λλ€.)
μ€μ μ§μ€μ ν€-κ° μ μ₯μλ μ ν리μΌμ΄μ
λ©ν 맀κ°λ³μλ₯Ό λ°°ν¬νλ λ° μ’μ λ©μ»€λμ¦μ
λλ€. μ¬κΈ°μ μ°λ¦¬λ κ΅¬μ± κ°μΌλ‘ κ°μ£Όνλ κ²μ΄ 무μμΈμ§, λ°μ΄ν°λ§ 무μμΈμ§ μκ°ν΄ λ³Ό νμκ° μμ΅λλ€. μ£Όμ΄μ§ ν¨μ C => A => B
μ°λ¦¬λ μΌλ°μ μΌλ‘ κ±°μ λ³νμ§ μλ κ°μ νΈμΆν©λλ€. C
"ꡬμ±", μμ£Ό λ³κ²½λλ λ°μ΄ν° A
- λ°μ΄ν°λ₯Ό μ
λ ₯νλ©΄ λ©λλ€. ꡬμ±μ λ°μ΄ν°λ³΄λ€ λ¨Όμ κΈ°λ₯μ μ 곡λμ΄μΌ ν©λλ€. A
. μ΄ μμ΄λμ΄λ₯Ό κ³ λ €νλ©΄ κ΅¬μ± λ°μ΄ν°μ λ¨μν λ°μ΄ν°λ₯Ό ꡬλ³νλ λ° μ¬μ©ν μ μλ λ³κ²½ λΉλκ° μμλλ€κ³ λ§ν μ μμ΅λλ€. λν λ°μ΄ν°λ μΌλ°μ μΌλ‘ νλμ μμ€(μ¬μ©μ)μμ κ°μ Έμ€κ³ ꡬμ±μ λ€λ₯Έ μμ€(κ΄λ¦¬μ)μμ κ°μ Έμ΅λλ€. μ΄κΈ°ν κ³Όμ μ΄νμ λ³κ²½λ μ μλ 맀κ°λ³μλ₯Ό μ²λ¦¬νλ κ²μ μ ν리μΌμ΄μ
μ 볡μ‘μ±μ μ¦κ°μν΅λλ€. μ΄λ¬ν 맀κ°λ³μμ κ²½μ° μ λ¬ λ©μ»€λμ¦, ꡬ문 λΆμ λ° μ ν¨μ± κ²μ¬, μλͺ»λ κ° μ²λ¦¬λ₯Ό μ²λ¦¬ν΄μΌ ν©λλ€. λ°λΌμ νλ‘κ·Έλ¨ λ³΅μ‘μ±μ μ€μ΄λ €λ©΄ λ°νμ μ λ³κ²½λ μ μλ 맀κ°λ³μ μλ₯Ό μ€μ΄λ κ²μ΄ μ’μ΅λλ€(λλ μμ μ κ±°νλ κ²λ μ’μ΅λλ€).
μ΄ κ²μλ¬Όμ κ΄μ μμ μ°λ¦¬λ μ μ 맀κ°λ³μμ λμ 맀κ°λ³μλ₯Ό ꡬλ³ν΄μΌ ν©λλ€. μλΉμ€ λ‘μ§μ΄ λ°νμ μ μΌλΆ 맀κ°λ³μλ₯Ό λλ¬Όκ² λ³κ²½ν΄μΌ νλ κ²½μ° μ΄λ₯Ό λμ 맀κ°λ³μλΌκ³ λΆλ₯Ό μ μμ΅λλ€. κ·Έλ μ§ μμΌλ©΄ μ μ μ΄λ©° μ μλ μ κ·Ό λ°©μμ μ¬μ©νμ¬ κ΅¬μ±ν μ μμ΅λλ€. λμ μ¬κ΅¬μ±μ μν΄μλ λ€λ₯Έ μ κ·Ό λ°©μμ΄ νμν μ μμ΅λλ€. μλ₯Ό λ€μ΄, λΆμ° μμ€ν
μ κ°λ³ νλ‘μΈμ€λ₯Ό λ€μ μμνλ κ²κ³Ό μ μ¬ν λ°©μμΌλ‘ μμ€ν
μ μΌλΆκ° μ κ΅¬μ± λ§€κ°λ³μλ₯Ό μ¬μ©νμ¬ λ€μ μμλ μ μμ΅λλ€.
(μ μ κ²Έμν μ견μ μμ€ν
μ 볡μ‘μ±μ μ¦κ°μν€κΈ° λλ¬Έμ λ°νμ μ¬κ΅¬μ±μ νΌνλ κ²μ
λλ€.
νλ‘μΈμ€ μ¬μμμ λν OS μ§μμ μμ‘΄νλ κ²μ΄ λ κ°λ¨ν μ μμ΅λλ€. νμ§λ§ νμ κ°λ₯νμ§λ μμ μλ μμ΅λλ€.)
λλλ‘ μ¬λλ€μ΄ (λ€λ₯Έ μ΄μ μμ΄) λμ ꡬμ±μ κ³ λ €νκ² λ§λλ μ μ κ΅¬μ± μ¬μ©μ μ€μν μΈ‘λ©΄ μ€ νλλ κ΅¬μ± μ
λ°μ΄νΈ μ€ μλΉμ€ κ°λ μ€μ§ μκ°μ
λλ€. μ€μ λ‘ μ μ ꡬμ±μ λ³κ²½ν΄μΌ νλ κ²½μ° μ κ°μ΄ μ μ©λλλ‘ μμ€ν
μ λ€μ μμν΄μΌ ν©λλ€. κ°λ μ€μ§ μκ°μ λν μꡬ μ¬νμ μμ€ν
λ§λ€ λ€λ₯΄λ―λ‘ κ·Έλ€μ§ μ€μνμ§ μμ μλ μμ΅λλ€. μ€μν κ²½μ°μλ μμ€ν
μ λ€μ μμν μ μλλ‘ λ―Έλ¦¬ κ³νμ μΈμμΌ ν©λλ€. μλ₯Ό λ€μ΄ λ€μμ ꡬνν μ μμ΅λλ€.
λ²μ μ΄ μ§μ λ μν°ν©νΈ λ΄λΆ λλ μΈλΆμμ ꡬμ±μ μ μ§νλ κ²μ μ΄λ»μ΅λκΉ? μν°ν©νΈ λ΄λΆμ ꡬμ±μ μ μ§νλ€λ κ²μ λλΆλΆμ κ²½μ° μ΄ κ΅¬μ±μ΄ λ€λ₯Έ μν°ν©νΈμ λμΌν νμ§ λ³΄μ¦ νλ‘μΈμ€λ₯Ό ν΅κ³Όνμμ μλ―Έν©λλ€. λ°λΌμ ꡬμ±μ νμ§μ΄ μ’κ³ μ λ’°ν μ μλ€κ³ νμ ν μ μμ΅λλ€. λ°λλ‘ λ³λμ νμΌμ ꡬμ±νλ©΄ ν΄λΉ νμΌμ λ³κ²½ν μ¬λκ³Ό μ΄μ μ λν μΆμ μ΄ μμμ μλ―Έν©λλ€. μ΄κ²μ΄ μ€μν©λκΉ? μ°λ¦¬λ λλΆλΆμ μμ° μμ€ν μμ μμ μ μ΄κ³ κ³ νμ§ κ΅¬μ±μ κ°λ κ²μ΄ λ λ«λ€κ³ λ―Ώμ΅λλ€.
μν°ν©νΈ λ²μ μ ν΅ν΄ μμ± μκΈ°, ν¬ν¨λ κ°, νμ±ν/λΉνμ±νλλ κΈ°λ₯, ꡬμ±μ κ° λ³κ²½μ λ΄λΉν μ¬λμ νμΈν μ μμ΅λλ€. μν°ν©νΈ λ΄λΆμ ꡬμ±μ μ μ§νλ €λ©΄ μ½κ°μ λ Έλ ₯μ΄ νμν μ μμΌλ©° μ΄λ λμμΈ μ νμ λλ€.
μ₯λ¨μ
μ¬κΈ°μ μ°λ¦¬λ μ μλ μ κ·Ό λ°©μμ λͺ κ°μ§ μ₯μ μ κ°μ‘°νκ³ λͺ κ°μ§ λ¨μ μ λ Όμνκ³ μΆμ΅λλ€.
μ₯μ
μμ ν λΆμ° μμ€ν μ μ»΄νμΌ κ°λ₯ν κ΅¬μ± κΈ°λ₯:
- ꡬμ±μ μ μ νμΈ. μ΄λ μ ν μ μ½ μ‘°κ±΄μ λ°λΌ ꡬμ±μ΄ μ ννλ€λ λμ μμ€μ νμ μ μ 곡ν©λλ€.
- νλΆν κ΅¬μ± μΈμ΄. μΌλ°μ μΌλ‘ λ€λ₯Έ κ΅¬μ± μ κ·Ό λ°©μμ μ΅λ λ³μ λ체μΌλ‘ μ νλ©λλ€.
Scalaλ₯Ό μ¬μ©νλ©΄ κ΄λ²μν μΈμ΄ κΈ°λ₯μ μ¬μ©νμ¬ κ΅¬μ±μ λ μ’κ² λ§λ€ μ μμ΅λλ€. μλ₯Ό λ€μ΄ νΉμ±μ μ¬μ©νμ¬ κΈ°λ³Έκ°μ μ 곡νκ³ κ°μ²΄λ₯Ό μ¬μ©νμ¬ λ€λ₯Έ λ²μλ₯Ό μ€μ ν μ μμ΅λλ€.val
sλ μΈλΆ λ²μ(DRY)μμ ν λ²λ§ μ μλ©λλ€. 리ν°λ΄ μνμ€λ νΉμ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μ¬μ©νλ κ²μ΄ κ°λ₯ν©λλ€(Seq
,Map
λ±). - DSL. Scalaλ DSL μμ±μλ₯Ό μ μ νκ² μ§μν©λλ€. μ΄λ¬ν κΈ°λ₯μ μ¬μ©νλ©΄ λ³΄λ€ νΈλ¦¬νκ³ μ΅μ’ μ¬μ©μμκ² μΉμν κ΅¬μ± μΈμ΄λ₯Ό μ€μ ν μ μμΌλ―λ‘ μ΅μν λλ©μΈ μ¬μ©μλ μ΅μ’ ꡬμ±μ μ½μ μ μμ΅λλ€.
- λ Έλ μ 체μ 무결μ±κ³Ό μΌκ΄μ±. μ 체 λΆμ° μμ€ν μ ν κ³³μμ ꡬμ±ν λμ μ΄μ μ€ νλλ λͺ¨λ κ°μ΄ μ격νκ² ν λ² μ μλ λ€μ νμν λͺ¨λ κ³³μμ μ¬μ¬μ©λλ€λ κ²μ λλ€. λν μμ ν ν¬νΈ μ μΈμ μ λ ₯νλ©΄ κ°λ₯ν λͺ¨λ μ¬λ°λ₯Έ ꡬμ±μμ μμ€ν λ Έλκ° λμΌν μΈμ΄λ₯Ό μ¬μ©νλλ‘ ν μ μμ΅λλ€. λ Έλ κ°μλ λͺ μμ μΈ μ’ μμ±μ΄ μμΌλ―λ‘ μΌλΆ μλΉμ€λ₯Ό μ 곡νλ κ²μ μκΈ° μ΄λ ΅μ΅λλ€.
- λμ νμ§μ λ³κ²½. μΌλ°μ μΈ PR νλ‘μΈμ€λ₯Ό ν΅ν΄ κ΅¬μ± λ³κ²½ μ¬νμ μ λ¬νλ μ λ°μ μΈ μ κ·Ό λ°©μμ ꡬμ±μμλ λμ νμ§ νμ€μ μ€μ ν©λλ€.
- λμ κ΅¬μ± λ³κ²½. κ΅¬μ± μλ λ°°ν¬λ₯Ό λ³κ²½ν λλ§λ€ λͺ¨λ λ Έλκ° μ λ°μ΄νΈλλλ‘ ν©λλ€.
- μ ν리μΌμ΄μ λ¨μν. μ ν리μΌμ΄μ μ ꡬμ±μ ꡬ문 λΆμ λ° κ²μ¦νκ³ μλͺ»λ κ΅¬μ± κ°μ μ²λ¦¬ν νμκ° μμ΅λλ€. μ΄λ μ 체 μ ν리μΌμ΄μ μ λ¨μνν©λλ€. (κ΅¬μ± μ체μ μ½κ°μ 볡μ‘μ± μ¦κ°κ° μμ§λ§ μ΄λ μμ μ λν μμμ μΈ μ μΆ©μ λλ€.) μΌλ°μ μΈ κ΅¬μ±μΌλ‘ λμκ°λ κ²μ λ§€μ° κ°λ¨ν©λλ€. λλ½λ λΆλΆμ μΆκ°νκΈ°λ§ νλ©΄ λ©λλ€. μ»΄νμΌλ ꡬμ±μΌλ‘ μμνκ³ μΆκ° λΆλΆμ ꡬνμ λμ€μ μ°κΈ°νλ κ²μ΄ λ μ½μ΅λλ€.
- λ²μ μ΄ μ§μ λ ꡬμ±. κ΅¬μ± λ³κ²½μ΄ λμΌν κ°λ° νλ‘μΈμ€λ₯Ό λ°λ₯΄κΈ° λλ¬Έμ κ²°κ³Όμ μΌλ‘ κ³ μ ν λ²μ μ μν°ν©νΈλ₯Ό μ»κ² λ©λλ€. νμν κ²½μ° κ΅¬μ±μ λ€μ μ νν μ μμ΅λλ€. XNUMXλ μ μ μ¬μ©νλ ꡬμ±μ λ°°ν¬ν μλ μμΌλ©° μ΄λ μ νν λμΌν λ°©μμΌλ‘ μλν©λλ€. μμ μ μΈ κ΅¬μ±μ λΆμ° μμ€ν μ μμΈ‘ κ°λ₯μ±κ³Ό μ λ’°μ±μ ν₯μμν΅λλ€. ꡬμ±μ μ»΄νμΌ νμμ μμ λλ©° νλ‘λμ μμ€ν μμλ μ½κ² λ³μ‘°λ μ μμ΅λλ€.
- λͺ¨λμ±. μ μλ νλ μμν¬λ λͺ¨λμμ΄λ©° λͺ¨λμ λ€μν λ°©μμΌλ‘ κ²°ν©λ μ μμ΅λλ€.
λ€μν ꡬμ±(μ€μ /λ μ΄μμ)μ μ§μν©λλ€. νΉν μκ·λͺ¨ λ¨μΌ λ Έλ λ μ΄μμκ³Ό λκ·λͺ¨ λ€μ€ λ Έλ μ€μ μ΄ κ°λ₯ν©λλ€. μ¬λ¬ μμ° λ μ΄μμμ κ°λ κ²μ΄ ν©λ¦¬μ μ λλ€. - ν μ€νΈ. ν μ€νΈ λͺ©μ μΌλ‘ λͺ¨μ μλΉμ€λ₯Ό ꡬννκ³ μ΄λ₯Ό μ ν μμ λ°©μμ μ’ μμ±μΌλ‘ μ¬μ©ν μ μμ΅λλ€. λͺ¨μνμΌλ‘ κ΅μ²΄λ λ€μν λΆνμ κ°μΆ λͺ κ°μ§ λ€λ₯Έ ν μ€νΈ λ μ΄μμμ λμμ μ μ§ κ΄λ¦¬ν μ μμ΅λλ€.
- ν΅ν© ν
μ€νΈ. λλλ‘ λΆμ° μμ€ν
μμλ ν΅ν© ν
μ€νΈλ₯Ό μ€ννκΈ°κ° μ΄λ ΅μ΅λλ€. μ 체 λΆμ° μμ€ν
μ μμ ν ꡬμ±μ μ
λ ₯νκΈ° μν΄ μ€λͺ
λ μ κ·Ό λ°©μμ μ¬μ©νλ©΄ λ¨μΌ μλ²μμ λͺ¨λ λΆμ° λΆλΆμ μ μ΄ κ°λ₯ν λ°©μμΌλ‘ μ€νν μ μμ΅λλ€. μν©μ νλ΄λ΄λ κ²μ μ½μ΅λλ€
μλΉμ€ μ€ νλλ₯Ό μ¬μ©ν μ μκ² λ κ²½μ°.
λ¨μ
μ»΄νμΌλ κ΅¬μ± μ κ·Ό λ°©μμ "μΌλ°" ꡬμ±κ³Ό λ€λ₯΄λ©° λͺ¨λ μꡬ μ¬νμ μ ν©νμ§ μμ μ μμ΅λλ€. μ»΄νμΌλ ꡬμ±μ λͺ κ°μ§ λ¨μ μ λ€μκ³Ό κ°μ΅λλ€.
- μ μ ꡬμ±. λͺ¨λ μμ© νλ‘κ·Έλ¨μ μ ν©νμ§ μμ μλ μμ΅λλ€. μ΄λ€ κ²½μ°μλ λͺ¨λ μμ μ‘°μΉλ₯Ό μ°ννμ¬ μμ° μ ꡬμ±μ μ μνκ² μμ ν΄μΌ ν νμκ° μμ΅λλ€. μ΄ μ κ·Ό λ°©μμ λ μ΄λ ΅μ΅λλ€. ꡬμ±μ λ³κ²½ν νμλ μ»΄νμΌ λ° μ¬λ°°ν¬κ° νμν©λλ€. μ΄κ²μ΄ νΉμ§μ΄κΈ°λ νκ³ λΆλ΄μ΄κΈ°λ νλ€.
- κ΅¬μ± μμ±. μΌλΆ μλν λꡬμμ ꡬμ±μ μμ±νλ κ²½μ° μ΄ μ κ·Ό λ°©μμλ νμ μ»΄νμΌμ΄ νμν©λλ€(κ²°κ³Όμ μΌλ‘ μ€ν¨ν μ μμ). μ΄ μΆκ° λ¨κ³λ₯Ό λΉλ μμ€ν μ ν΅ν©νλ €λ©΄ μΆκ° λ Έλ ₯μ΄ νμν μ μμ΅λλ€.
- μ
κΈ°. μ€λλ ν
μ€νΈ κΈ°λ° κ΅¬μ±μ μμ‘΄νλ λκ΅¬κ° λ§μ΄ μ¬μ©λκ³ μμ΅λλ€. κ·Έλ€ μ€ μΌλΆ
ꡬμ±μ΄ μ»΄νμΌλλ©΄ μ μ©λμ§ μμ΅λλ€. - μ¬κ³ λ°©μμ μ νμ΄ νμν©λλ€. κ°λ°μμ DevOpsλ ν μ€νΈ κ΅¬μ± νμΌμ μ΅μν©λλ€. ꡬμ±μ μ»΄νμΌνλ€λ μμ΄λμ΄κ° κ·Έλ€μκ²λ μ΄μνκ² λ³΄μΌ μλ μμ΅λλ€.
- μ»΄νμΌ κ°λ₯ν ꡬμ±μ λμ νκΈ° μ μ κ³ νμ§ μννΈμ¨μ΄ κ°λ° νλ‘μΈμ€κ° νμν©λλ€.
ꡬνλ μμ μλ λͺ κ°μ§ μ ν μ¬νμ΄ μμ΅λλ€.
- λ
Έλ ꡬνμμ μꡬνμ§ μλ μΆκ° ꡬμ±μ μ 곡νλ κ²½μ° μ»΄νμΌλ¬λ λλ½λ ꡬνμ κ°μ§νλ λ° λμμ΄ λμ§ μμ΅λλ€. μ΄ λ¬Έμ λ λ€μμ μ¬μ©νμ¬ ν΄κ²°ν μ μμ΅λλ€.
HList
λλ νΉμ± λ° μΌμ΄ν¬ ν¨ν΄ λμ λ Έλ ꡬμ±μ μν ADT(μΌμ΄μ€ ν΄λμ€). - κ΅¬μ± νμΌμ λͺ κ°μ§ μμ©κ΅¬λ₯Ό μ 곡ν΄μΌ ν©λλ€. (
package
,import
,object
μ μΈ;
override def
κΈ°λ³Έκ°μ΄ μλ 맀κ°λ³μμ κ²½μ°). μ΄ λ¬Έμ λ DSLμ μ¬μ©νμ¬ λΆλΆμ μΌλ‘ ν΄κ²°λ μ μμ΅λλ€. - μ΄ κ²μλ¬Όμμλ μ μ¬ν λ Έλ ν΄λ¬μ€ν°μ λμ μ¬κ΅¬μ±μ λ€λ£¨μ§ μμ΅λλ€.
κ²°λ‘
μ΄ κ²μλ¬Όμμ μ°λ¦¬λ μ νμ΄ μμ ν λ°©μμΌλ‘ μμ€ μ½λμμ μ§μ ꡬμ±μ νννλ μμ΄λμ΄μ λν΄ λ Όμνμ΅λλ€. μ΄ μ κ·Ό λ°©μμ XML λ° κΈ°ν ν μ€νΈ κΈ°λ° κ΅¬μ±μ λ체νμ¬ λ§μ μ ν리μΌμ΄μ μμ μ¬μ©λ μ μμ΅λλ€. μ°λ¦¬ μμ κ° Scalaλ‘ κ΅¬νλμμμλ λΆκ΅¬νκ³ λ€λ₯Έ μ»΄νμΌ κ°λ₯ν μΈμ΄(Kotlin, C#, Swift λ±)λ‘ λ²μλ μλ μμ΅λλ€. μ νλ‘μ νΈμμ μ΄ μ κ·Ό λ°©μμ μλν΄ λ³Ό μ μμΌλ©°, μ λ§μ§ μλ κ²½μ° κΈ°μ‘΄ λ°©μμΌλ‘ μ νν μ μμ΅λλ€.
λ¬Όλ‘ μ»΄νμΌ κ°λ₯ν ꡬμ±μλ κ³ νμ§ κ°λ° νλ‘μΈμ€κ° νμν©λλ€. κ·Έ λκ°λ‘ κ³ νμ§μ κ²¬κ³ ν ꡬμ±μ μ 곡ν κ²μ μ½μν©λλ€.
μ΄ μ κ·Ό λ°©μμ λ€μν λ°©μμΌλ‘ νμ₯λ μ μμ΅λλ€.
- 맀ν¬λ‘λ₯Ό μ¬μ©νμ¬ κ΅¬μ± μ ν¨μ± κ²μ¬λ₯Ό μννκ³ λΉμ¦λμ€ λ Όλ¦¬ μ μ½ μ‘°κ±΄μ΄ μ€ν¨νλ κ²½μ° μ»΄νμΌ νμμ μ€ν¨ν μ μμ΅λλ€.
- λλ©μΈ μ¬μ©μ μΉνμ μΈ λ°©μμΌλ‘ ꡬμ±μ λνλ΄κΈ° μν΄ DSLμ ꡬνν μ μμ΅λλ€.
- μλ κ΅¬μ± μ‘°μ μ ν΅ν λμ 리μμ€ κ΄λ¦¬. μλ₯Ό λ€μ΄, ν΄λ¬μ€ν° λ Έλ μλ₯Ό μ‘°μ ν λ (1) λ Έλκ° μ½κ° μμ λ ꡬμ±μ μ»λλ‘ νκ³ ; (2) ν΄λ¬μ€ν° κ΄λ¦¬μλ μ λ Έλ μ 보λ₯Ό μμ ν©λλ€.
κ°μ¬
μ΄ κ²μλ¬Όμ μ΄μμ λ³΄λ€ λͺ ννκ² λ§λλ λ° λμμ΄ λλ μκ°μ μ£Όλ νΌλλ°±μ μ£Όμ Andrey Saksonov, Pavel Popov, Anton Nehaevμκ² κ°μ¬μ λ§μμ μ νκ³ μΆμ΅λλ€.
μΆμ² : habr.com