á€ááá¯á·á
áºááœáẠáá»áœááºá¯ááºááá¯á·ááẠááŒáá·áºáá±ááŸá¯á
áá
áºá ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááŸáá·áº áááºáááºááá·áº á
áááºáááºá
á¬ážááœááºáááºážáááºážáá
áºáá¯ááᯠáá»áŸáá±áá±ážáá»ááºáá«áááºá
ááœá²á·á
ááºážááŸá¯á¡á¬áž á¡áá»áá¯ážá¡á
á¬áž áá±ážáááºážáá±á¬áá¯á¶á
á¶ááŒáá·áº Scala áá¬áá¬á
áá¬ážááŒáá·áº ááá¯ááºááá¯ááºááá¯ááºá
á¬ážááŒá¯áááºá á¥ááᬠá¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááᯠá¡áá±ážá
áááºáá±á¬áºááŒáá¬ážáááºá á¡áá¯á¶ážá
á¯á¶ ááœá¶á·ááŒáá¯ážááá¯ážáááºáá±áž áá¯ááºáááºážá
ááºá¡áá±á«áº ááœáŸááºážááá¯ážááŸá¯ á¡áá«á¡ááẠá¡ááá¯ááŒá¯áá»ááºá ááŸá¯áá±á¬áá·áºá¡áá»áá¯ážáá»áá¯ážááᯠááœá±ážááœá±ážááŒáááºá
áááá«áá¹áž
ááá¯ááºáá¬áá±á¬ ááŒáá·áºáá±ááŸá¯á áá áºáá»á¬ážááᯠáááºáá±á¬ááºááŒááºážááẠnode á¡á¬ážáá¯á¶ážááœáẠááŸááºáááºááŒá®áž áá±á«ááºážá ááºááœá²á·á ááºážááŸá¯ááᯠá¡áá¯á¶ážááŒá¯áááºááá¯á¡ááºáááºá áá¯á¶ááŸááºááŒá±ááŸááºážáá»ááºáá áºáá¯ááẠá á¬áá¬ážááŒáá·áºáá»ááºááŸá¯áá±á¬áºááŒáá»áẠ(terraformá ansible ááá¯á·ááá¯áẠá¡áá¬ážáá°áá áºáá¯áá¯) ááŸáá·áº á¡ááá¯á¡áá»á±á¬ááºáá¯ááºáá±ážáá±á¬ configuration files (áááŒá¬áá â node/role áá áºáá¯á á®á¡ááœááºáá®ážááá·áº) ááá¯á¡áá¯á¶ážááŒá¯áááºááŒá áºáááºá áááºááœááºááŸá¯ áá¯á¶ááŸááºáá áºáá¯á á®ááœáẠáá°áá®áá±á¬áá¬ážááŸááºážáá»á¬ážá áá°áá®áá±á¬áááá¯ááá¯áá±á¬áá»á¬ážááá¯áááºáž á¡áá¯á¶ážááŒá¯ááá¯áááá·áºááẠ(ááá¯ááºáá«á ááá¯ááºáááºáá®ááŸá¯ááŒá¿áá¬áá»á¬áž ááŒá¯á¶ááœá±á·áááá¯ááºáááº)á JVM ááá¹áá¬ááœááºá á¡áááºážáá¯á¶áž á á¬ááá¯áá±ážááá¯á·áá±áž áá áºáá»á áºááá¯ááºááẠáááºááœááºáá±áž áááºážááŒá±á¬ááºážá¡á¬ážáá¯á¶ážááœáẠáá°áá®áá±á¬áá¬ážááŸááºážááŒá áºááá·áºáááºáᯠááá¯ááá¯áááºá
á áá áºááᯠá ááºážáááºááá¯á·áá±á¬á áá±á«ááºážá ááºá á áºáá±ážááŸá¯áá»á¬ážáááŒá¯áá¯ááºáá® á¡á áááºá¡ááá¯ááºážá¡á¬ážáá¯á¶ážá¡ááœáẠáá°áá áºá á áºáá±ážááŸá¯áá»á¬áž ááŒá¯áá¯ááºááá·áºáá«áááºá runtime ááœáẠá ááºážáááºááŸá¯ááááºáá»á¬ážááᯠá¡ááá¯áá¯ááºááá¯ááºá á±áááºá áá»áœááºá¯ááºááá¯á·ááẠáá áºáá»á áºááá¯ááºá¡á¬ážáá¯á¶ážááá¬ážááŸááºážáá»á¬ážááᯠruntime ááŸáá·áº testing environment ááŸá áºáá¯áá¯á¶ážááœáẠáá°áá®áá±á á±ááẠáá±áá»á¬á á±ááá·áºáá«áááºá
áá±á«ááºážá ááºá á áºáá±ážááŸá¯áá»á¬ážááᯠáá¯ááºáá±á¬ááºáá±á¬á¡áá«á node á¡á¬ážáá¯á¶ážááœáẠáá°áá®áá±á¬ classpath ááŸáááẠááá¯ááá¯ááœááºáá°áááºá á¡áá¯á¶ážáá»ááŸá¯ááœáẠáá°áá®áá±á¬ classpath ááᯠá¡áá¯á¶ážááŒá¯ááŒá±á¬ááºáž áá±áá»á¬ááẠááá¯á¡ááºáá«áááºá (ááœá²ááŒá¬ážááŒá¬ážáá¬ážáá±á¬ node áá»á¬ážááœáẠááá°áá®áá±á¬ classpaths áá»á¬ážááᯠá¡áá¯á¶ážááŒá¯ááẠááŒá áºááá¯ááºáá±á¬áºáááºážá á€ááœá²á·á ááºážáá¯á¶á¡á¬áž ááá¯ááºá á¬ážááŒá¯ááŒá®áž áááºážááᯠááŸááºáááºá áœá¬ á¡áá¯á¶ážáá»ááẠááá¯áááºáá²áá«áááºá) ááá¯á·ááŒá±á¬áá·áº á¡áá¬áá»á¬ážááᯠááá¯ážááŸááºážáá±á á±áááºá¡ááœáẠnode á¡á¬ážáá¯á¶ážááœáẠáááºáá°áááºáá»áŸáá±á¬ classpath áá»á¬ážááá¯áᬠá ááºážá á¬ážáá«áááºá
ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááẠáá±á¬á·ááºáá²ááºááŸáá·áºá¡áá° ááá¯ážáááºáá¬áááºá á¡áá»áá¯ážáá»áá¯ážááœá²ááŒá¬ážáááºááŸááºááẠáá»áœááºá¯ááºááá¯á·ááẠáá»á¬ážáá±á¬á¡á¬ážááŒáá·áº áá¬ážááŸááºážáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯ááŒáááºá
áá±á¬á·ááºáá²ááºááá·áºáá²ááŒá
áºá
ááºá¡ááá·áºááá·áºá áá¬ážááŸááºážá
á®áá¶ááá·áºááœá²ááŸá¯á¡á±á¬ááºááœáẠááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááᯠáá¬ááá
á±áááºááŸáá·áº á¡áá»áá¯á·áá±á¬ á¡ááœáŸááºážáá»á¬ážááŒáá·áº ááá°áá®áá±á¬áá¯á¶á
á¶áá»á¬ážááᯠááœá²ááŒá¬ážáááºááŸááºááẠáá»áá¯ážááŒá±á¬ááºážáá®áá»á±á¬áºáá¯á¶ááááºá áá¯ááºáá¯ááºáá±ážááœáẠááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶áá
áºáá¯áááºážáá¬ááŸááá«áá áá
áºáá¯áááºážáá±á¬áá¬ážááŸááºážááᯠááœá²ááŒá¬ážáááºááŸááºááŸá¯á¡ááŒá
Ạáá»áœááºá¯ááºááá¯á·á¡áá¯á¶ážááŒá¯ááá¯ááºáá«áááºá áá
áºáá«áá
áºáá¶ááœáẠáá»áœááºá¯ááºááá¯á·ááẠáá¯ááºáá¯ááºááŸá¯áááºáááºážáá»ááºáá»á¬ážá
áœá¬ ááŸááá±á¬ááºážááŸáááá¯ááºáááºá áááºáááºážáá»ááºáá
áºáá¯á
á®á¡ááœáẠáá®ážááŒá¬ážááœá²á·á
ááºážáá¯á¶ááœá²á·á
ááºážáá¯á¶á¡ááœá²áá
áºáᯠááá¯á¡ááºááá¯ááºáááºá ááá¯á·ááŒá±á¬áá·áº ááœá²ááŒá¬ážáá±á¬ ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶áá»á¬ážááᯠáá®ážááŒá¬ážááœá²ááŒá¬ážáááºááŸááºááẠá¡ááœá²ááŸáá·áº áá¬ážááŸááºážááŒáá·áº áá¶ááááºáááºáá¬ážááá¯ááºáááºá áá¬áááœá²áá¶ááááºááŸáá·áº áá¬ážááŸááºážáá
áºáá¯á
á®ááẠnode áá
áºáá¯á
á®ááŸá ááŒáá·áºáá±áá¬ážáá±á¬ nodeáá»á¬ážá ááááºáááºážáá»á¬ážá ááŒááºáá¡áááºážá¡ááŒá
áºáá»á¬ážá classpath á
á¬ááŒáá·áºááá¯ááºáá¬ážááŸááºážáá»á¬áž áá±á«ááºážá
ááºááŸá¯áá
áºáá¯ááŸáá·áº áááºááá¯ááºáá«áááºá á€áá±áá¬ááœáẠáá»áœááºá¯ááºááá¯á·ááẠá¡ááá¯ááºážá¡áááºáá
áºáá¯áááºážááá¯áᬠááŒá¯á¶áá¯á¶ááŒá®áž á¡ááŒá¬ážá¡áá¬áá»á¬ážáá²á·ááá¯á·ááẠá¡á
áááºá¡ááá¯ááºáž ááááá¬ážááŸááºáž (1.2.3) ááŒáá·áº ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶áá»á¬ážááᯠááœá²ááŒá¬ážáááºááŸááºáá«áááºá
áá±ááºáá®áá±á¬áááºáááºážáá»ááºáá»á¬ážááœáẠconfiguration ááá¯ááºáá»á¬ážááᯠááá¯ááºááá¯ááºáááŒááºááá¯ááºáá±á¬á·áá«á áá¯á¶ááŸááºá¡á¬ážááŒáá·áº áá»áœááºá¯ááºááá¯á· áá¯ááºáá¯ááºáááºá
ááŒáá·áºáá»ááºáá»áááºááŸáá·áº config ááá¯ááºáá»á¬áž
ဠpost ááœáẠá á¯á ááºážáá¬ážáá±á¬ artifact ááœáẠconfiguration ááᯠááááºážááááºážááŒááºážááá¯ááºáᬠá¡áá°á¡áááᯠáá±á·áá¬áá«áááºá
á á¯á ááºážááá¯ááºáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶
á€á¡ááá¯ááºážááœáẠstatic configuration á á¥ááá¬ááᯠááœá±ážááœá±ážáá«áááºá ááá¯ážááŸááºážáá±á¬áááºáá±á¬ááºááŸá¯ááŸá áºáᯠ- áá²á·áááºáá¶áááºáá±á¬ááºááŸá¯ááŸáá·áº áá²á·áááºáá¶áááºáá±á¬ááºááŸá¯á áá±á¬ááºáááºá¡á¬áž ááŒááºáááºáááºááŸááºááŒá®áž á¡áá±á¬ááºá¡áááºáá±á¬áºáá±áá«áááºá ááá¯á·áá±á¬áẠáááºáá±á¬ááºááŸá¯ááŸá áºáá¯á áá¯á¶ážááŒáá·áº ááá°áá®áá±á¬ ááŒáá·áºáá±ááŸá¯á áá áºááŸá áºáá¯ááᯠáá»ááºáá»ááºážáá¯ááºáá±á¬ááºáááºá áá áºáá¯ááẠnode configuration áá áºáá¯á¡ááœááºááŒá áºááŒá®áž áá±á¬ááºáá áºáá¯ááẠnode configuration ááŸá áºáá¯á¡ááœááºááŒá áºáááºá
áá¯á¶ááŸááºááŒáá·áºáá±ááá·áºá áá áºááœáẠnode á¡áááºážáááºáá«áááºáááºá á¡áá»áá¯ážá¡á á¬ážá¡áá»áá¯á·ááá¯á¡áá¯á¶ážááŒá¯á node áá»á¬ážááá¯áá±á¬áºáá¯ááºááá¯ááºáááº-
sealed trait NodeId
case object Backend extends NodeId
case object Frontend extends NodeId
ááá¯á·ááá¯ááºáá²
case class NodeId(hostName: String)
ááá¯á·ááá¯ááºáááº
object Singleton
type NodeId = Singleton.type
ဠnode áá»á¬ážááẠá¡áá»áá¯ážáá»áá¯ážáá±á¬ á¡áááºážááá¹ááá»á¬ážááᯠáá¯ááºáá±á¬ááºáááºá á¡áá»áá¯á·áá±á¬ áááºáá±á¬ááºááŸá¯áá»á¬ážááᯠáá¯ááºáá±á¬ááºááŒá®áž TCP/HTTP áá»áááºáááºááŸá¯áá»á¬ážááŒáá·áº á¡ááŒá¬áž node áá»á¬ážááŸáá·áº áááºááœááºááá¯ááºááá·áºáá«áááºá
TCP áá»áááºáááºááŸá¯á¡ááœáẠá¡áááºážáá¯á¶áž port áá¶áá«ááºáá áºáᯠááá¯á¡ááºáá«áááºá client ááŸáá·áº server ááá¯á·ááẠáá°áá®áá±á¬ áááá¯ááá¯áá±á¬ááᯠááŒá±á¬ááá¯áá±ááŒááŒá±á¬ááºážááá¯áááºáž áá±áá»á¬á á±ááá¯áá«áááºá node áá»á¬ážááŒá¬áž áá»áááºáááºááŸá¯ááᯠááá°áá¬áá°áááºá¡ááœáẠá¡á±á¬ááºáá« class ááᯠááŒá±áá¬ááŒáá«á áá¯á·á
case class TcpEndPoint[Protocol](node: NodeId, port: Port[Protocol])
áááºááŸá¬ Port
áá
áºáá¯áá¬ááŒá
áºáááºá Int
ááœáá·áºááŒá¯áá¬ážáá±á¬ á¡ááá¯ááºážá¡áá¬á¡ááœááºáž-
type PortNumber = Refined[Int, Closed[_0, W.`65535`.T]]
ááá·áºá ááºáá±á¬á¡áá»áá¯ážá¡á á¬ážáá»á¬áž
ááŒáẠInt
port áá¶áá«ááºáá»á¬ážááá¯ááá¯ááºá
á¬ážááŒá¯ááá¯ááºáá±á¬ 16-bit áááºááá¯ážáá»á¬ážáá¬ááŸááááºááœáá·áºááŒá¯áá¬ážáááºá á€ááœá²á·á
ááºážáá¯á¶áááºážáááºážá¡ááœáẠá€á
á¬ááŒáá·áºááá¯ááºááᯠá¡áá¯á¶ážááŒá¯ááẠáááá¯á¡ááºáá«á áá±á¬áºáá±á¬á·áºááᯠá¡áááºááŒá±áá¯á¶ááá«áááºá
HTTP (REST) ââá¡ááœáẠáá»áœááºá¯ááºááá¯á·ááẠáááºáá±á¬ááºááŸá¯á áááºážááŒá±á¬ááºážáá áºáá¯áááºáž ááá¯á¡ááºááá¯ááºáááº-
type UrlPathPrefix = Refined[String, MatchesRegex[W.`"[a-zA-Z_0-9/]*"`.T]]
case class PortWithPrefix[Protocol](portNumber: PortNumber, pathPrefix: UrlPathPrefix)
Phantom á¡áá»áá¯ážá¡á á¬áž
á
á¯á
ááºážááŸá¯á¡ááœááºáž áááá¯ááá¯áá±á¬ááᯠááœá²ááŒá¬ážáááºááŸááºáááºá¡ááœáẠáá»áœááºá¯ááºááá¯á·ááẠá¡áá»áá¯ážá¡á
á¬ážá¡ááŒááºážááœá¬ážááŸá¯ááᯠááŒá±áá¬ááŒááºážá Scala á¡ááºá¹áá«áááºááᯠá¡áá¯á¶ážááŒá¯áá±áááºá Protocol
á¡á²áá«ááᯠá¡áááºážáá²ááŸá¬ á¡áá¯á¶ážááá»áá°ážá á¡á²áá«ááᯠáá±á«áºáá¬á phantom á¡áá»áá¯ážá¡á
á¬áž. runtime ááœáẠprotocol identifier áá¥ááá¬áá
áºáá¯ááá¯á¡ááºáá²áá±á¬ááŒá±á¬áá·áºáááºážááá¯áá»áœááºá¯ááºááá¯á·áááááºážáááºážáá«á á
á¯á
ááºážááŸá¯á¡ááœááºáž ဠPhantom á¡áá»áá¯ážá¡á
á¬ážááẠáá±á¬ááºáááºá¡áá»áá¯ážá¡á
á¬áž áá±ážáááºážááŸá¯ááᯠáá±ážáááºá áááŸááºáááºáá±á¬ áááá¯ááá¯áá±á¬ááŒáá·áº ááááºáááºážááᯠáá»áœááºá¯ááºááá¯á· áááŒááºáááºážááá¯ááºáá«á
á¡áá¯á¶ážáá»á¬ážáá¯á¶áž áááá¯ááá¯áá±á¬áá»á¬ážáá²á០áá áºáá¯ááẠJson áá¶áá«ááºá ááºá¡ááá¯áẠREST API ááŒá áºáááºá
sealed trait JsonHttpRestProtocol[RequestMessage, ResponseMessage]
áááºááŸá¬ RequestMessage
client ááẠserver ááá¯á·áá±ážááá¯á·ááá¯ááºáá±á¬ á¡ááŒá±áá¶á
á¬á¡áá»áá¯ážá¡á
á¬ážááŒá
áºáááºá ResponseMessage
áá¬áá¬á០áá¯á¶á·ááŒááºááá·áº áááºáá±á·áá»áºááŒá
áºáááºá áá¯ááºáá«áááºá áá»áœááºá¯ááºááá¯á·ááẠáááºááœááºáá±ážáááá¯ááá¯áá±á¬ááᯠá¡ááá¯ááŸááá±á¬ áááá»ááŸá¯ááŒáá·áº áááºááŸááºáá±ážááá·áº á¡ááŒá¬ážáá±á¬ áááá¯ááá¯áá±á¬ áá±á¬áºááŒáá»ááºáá»á¬ážááᯠáááºáá®ážááá¯ááºáá«áááºá
á€ááá¯á·á áºááááºááœááºáá»ááºáá»á¬ážá¡ááœáẠáá»áœááºá¯ááºááá¯á·ááẠááá¯ááá¯ááá¯ážááŸááºážáá±á¬ áááá¯ááá¯áá±á¬áá¬ážááŸááºážááᯠá¡áá¯á¶ážááŒá¯áá«áááº-
sealed trait SimpleHttpGetRest[RequestMessage, ResponseMessage]
á€áááá¯ááá¯áá±á¬ááœáẠáá±á¬ááºážááá¯áá»ááºáááºáá±á·áá»áºááᯠurl ááœáẠáá±á«ááºážááá·áºáá¬ážááŒá®áž áá¯á¶á·ááŒááºáá»ááºáááºáá±á·áá»áºááᯠááá¯ážááá¯ážá á¬ááŒá±á¬ááºážá¡ááŒá ẠááŒááºáá±ážáááºá
áááºáá±á¬ááºááŸá¯ááœá²á·á
ááºážáá¯á¶áá
áºáá¯á¡á¬áž áááºáá±á¬ááºááŸá¯á¡áááºá ááááºáááºážáá»á¬ážá
á¯á
ááºážááŸá¯ááŸáá·áº ááŸá®ááá¯ááŸá¯á¡áá»áá¯á·ááŒáá·áº áá±á¬áºááŒááá¯ááºáááºá Scala ááœáẠá€ááŒááºá
ááºáá»á¬ážá¡á¬ážáá¯á¶ážááᯠááá¯ááºá
á¬ážááŒá¯áá¯á¶ ááŒá
áºááá¯ááºááá·áº áááºážáááºážá¡áááºážáááºááŸáááẠ(á¥ááá¬á HList
á¡áá¹ááá¬áááºá¹áá»á¬ áá±áá¬á¡áá»áá¯ážá¡á
á¬ážáá»á¬áž)á á€ááá¯á·á
áºááááºááœááºáá»ááºá¡ááœáẠáá»áœááºá¯ááºááá¯á·ááẠCake Pattern ááá¯á¡áá¯á¶ážááŒá¯ááŒá®áž áá±á«ááºážá
ááºááá¯ááºáá±á¬á¡ááá¯ááºážáá»á¬áž (modules) ááᯠá
ááá¯ááºááá¹ááá¬áá»á¬ážá¡ááŒá
Ạááá¯ááºá
á¬ážááŒá¯áá«áááºá (Cake Pattern ááẠá€á
á¯á
ááºážááá¯ááºáá±á¬ ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶á¡ááœáẠááá¯á¡ááºáá»ááºááá¯ááºáá«á áááºážááẠá
áááºáá°ážá ááŒá
áºááá¯ááºáá»á±ááŸááá±á¬ á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯áá
áºáá¯áá»áŸáá¬ááŒá
áºáááºá)
ááŸá®ááá¯ááŸá¯áá»á¬ážá¡á¬áž á¡ááŒá¬áž node áá»á¬ážá á¡áá¯á¶ážááŸááºáá»á¬ážá¡ááŒá Ạááááºáá¯áá·áºáá¯á¶á á¶ááᯠá¡áá¯á¶ážááŒá¯á ááá¯ááºá á¬ážááŒá¯ááá¯ááºáááº-
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 áááºáá±á¬ááºááŸá¯ááẠááŒááºáááºáááºááŸááºáá¬ážáá±á¬ ááááºáááºážáá
áºáá¯áᬠááá¯á¡ááºáááºá ááŒá®ážáá±á¬á· áá® port á echo protocol ááᯠáá¶á·ááá¯ážáá±ážááŒá±á¬ááºáž ááŒá±áá¬áá«áááºá trait ááẠabstract method declarations áá»á¬ážááᯠááœáá·áºááŒá¯áá¬ážáá±á¬ááŒá±á¬áá·áº ááá¯á¡áá»áááºááœáẠáá®ážááŒá¬áž port áá
áºáá¯ááᯠáááºááŸááºááẠáááá¯á¡ááºááŒá±á¬ááºáž áááááŒá¯áá«á áá»áœááºá¯ááºááá¯á·ááẠabstract áááºážáááºážáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯áá«áá á
á¯á
ááºážáá°ááẠááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶áá
áºáá¯ááœáẠá¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯áá
áºáᯠááá¯á¡ááºáááºááŒá
áºáááºá á€áá±áá¬ááœáẠáá»áœááºá¯ááºááá¯á·ááẠá¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááᯠáá¶á·ááá¯ážáá±ážááẠ(8081
) áááºážááᯠááœááºááá
áºáá¯á¶á
á¶ááŒáá·áº áá»á±á¬áºááœá¬ážáá«á áááºážááᯠáá°áááºážáááºááá¯ážá¡ááŒá
Ạá¡áá¯á¶ážááŒá¯áááºááŒá
áºáááºá
echo áááºáá±á¬ááºááŸá¯ áááá¯ááºážááá·áºá ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááœáẠááŸá®ááá¯ááŸá¯ááᯠáá»áœááºá¯ááºááá¯á· ááŒá±áá¬ááá¯ááºáááº-
trait EchoClientConfig[A] {
def testMessage: String = "test"
def pollInterval: FiniteDuration
def echoServiceDependency: HttpSimpleGetEndPoint[_, EchoProtocol[A]]
}
ááŸá®ááá¯ááŸá¯ááœáẠá¡áá»áá¯ážá¡á
á¬ážáá°áááºá echoService
. á¡áá°ážáááŒáá·áºá áááºážááẠáá°áá®áá±á¬ áááá¯ááá¯áá±á¬ááᯠáá±á¬ááºážááá¯áááºá ááá¯á·ááŒá±á¬áá·áº á€ááŸá®ááá¯ááŸá¯ááŸá
áºáá¯ááᯠáá»áááºáááºáááá«á áááºážááá¯á· ááŸááºáááºá
áœá¬ áá¯ááºáá±á¬ááºááá¯ááºáááºáᯠáá»áœááºá¯ááºááá¯á· á
áááºáá»ááá¯ááºáá«áááºá
áááºáá±á¬ááºááŸá¯áá»á¬áž á¡áá±á¬ááºá¡áááºáá±á¬áºááŒááºážá
áááºáá±á¬ááºááŸá¯áá
áºáᯠá
áááºáááºááŸáá·áº áá»á±á¬ááœá±á·á
áœá¬ ááááºááẠáá¯ááºáá±á¬ááºáá»ááºáá
áºáᯠááá¯á¡ááºáá«áááºá (á
ááºážáááºááŒááºážá¡ááœáẠáááºáá±á¬ááºááŸá¯áá
áºáá¯á¡á¬áž ááááºááá¯ááºááŸá¯ááẠá¡áá±ážááŒá®ážáá«áááºá) áááºáá¶á áá±ážáá¬ážááá·áº config áá
áºáá¯á¡ááœáẠááá¯ááá¯á·áá±á¬áá¯ááºáá±á¬ááºáá»ááºááᯠáááºááŸááºááŒááºážá¡ááœáẠááœá±ážáá»ááºá
áá¬á¡áá»áá¯á·ááŸááá«áááºá á€ááá¯á·á
áºá¡ááœáẠáá»áœááºá¯ááºááá¯á·ááẠCake Pattern ááᯠáááºáá¶á¡áá¯á¶ážááŒá¯áá«áááºá áá»áœááºá¯ááºááá¯á·ááẠáááºáá±á¬ááºááŸá¯ááᯠá¡áá¯á¶ážááŒá¯á ááá¯ááºá
á¬ážááŒá¯ááá¯ááºáááºá cats.Resource
áááºážááẠbracketing ááŸáá·áº resource release ááᯠáá±á¬ááºáá¶á·áá±ážááŒá®ážááŒá
áºáááºá á¡áááºážá¡ááŒá
áºáá
áºáá¯ááá°áááºá¡ááœáẠáá»áœááºá¯ááºááá¯á·ááẠááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶áá
áºáá¯ááŸáá·áº runtime á¡ááŒá±á¬ááºážá¡áá¬á¡áá»áá¯á·ááᯠáá±ážááá·áºáááºá ááá¯á·ááŒá±á¬áá·áº áááºáá±á¬ááºááŸá¯á
áááºááá·áºáá¯ááºáá±á¬ááºáá»ááºááẠá¡á±á¬ááºáá«á¡ááá¯ááºážááŒá
áºááá¯ááºáááº-
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
â á¡ááŒá¬áž node áá»á¬ážá ááááºá á¬á¡á á áºá¡ááŸááºáá»á¬ážááᯠááá°ááá¯ááºá áœááºážááŸáááá·áº runtime object áá áºáᯠ(á¡áá±ážá áááºá¡áá»ááºá¡áááºáá»á¬ážááᯠáááºáááºáááºááŸá¯áááº)á
á¡ááŒá¬ážá¡áá»áá¯ážá¡á
á¬ážáá»á¬ážá០áá¬áá«áááºá cats
:
F[_]
- á¡áá»áá¯ážáááºáá±á¬ááºááŸá¯á¡áá»áá¯ážá¡á á¬áž (á¡ááá¯ážááŸááºážáá¯á¶ážááá á¹á ááœááºF[A]
áááºáááºááŒá áºááá¯ááºáááºá() => A
. áá® post ááŸá¬ áá¯á¶ážáá«áááºácats.IO
.)Reader[A,B]
â ááẠáá¯ááºáá±á¬ááºáá»ááºáá áºáá¯á¡ááœáẠá¡áááá¹áá«ááºáá° ááá¯á·ááá¯áẠá¡áááºážá¡áá»á¬ážááŒá áºáááºáA => B
cats.Resource
- ááá°áááºááŸáá·áº ááœááºááŒá±á¬ááºááẠáááºážáááºážáá»á¬ážááŸááááºáTimer
- á¡áááºáá»ááẠ/ ááá¯ááºážáá¬áááºááœáá·áºááŒá¯áááºáContextShift
- analog ofExecutionContext
Applicative
- á¡áá»áá¯ážáááºáá±á¬ááºááŸá¯ááŸááá±á¬ áá¯ááºáá±á¬ááºáá»ááºáá»á¬áž (monad áá áºáá¯áá®ážáá«áž) (áá±á¬ááºáá¯á¶ážááœáẠáááºážááᯠá¡ááŒá¬ážá¡áá¬áá áºáá¯ááŒáá·áº á¡á á¬ážááá¯ážááá¯ááºáááº)
á€á¡ááºáá¬áá±á·á áºááá¯á¡áá¯á¶ážááŒá¯ááŒááºážááŒáá·áº áá»áœááºá¯ááºááá¯á·ááẠáááºáá±á¬ááºááŸá¯á¡áááºážáááºááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááá¯ááºáá«áááºá á¥ááá¬á áá¬ááŸááá¯ááºáá²á· áááºáá±á¬ááºááŸá¯áá áºáá¯á
trait ZeroServiceImpl[F[_]] extends ServiceImpl[F] {
type Config <: Any
def resource(...): ResourceReader[F, Config, Unit] =
Reader(_ => Resource.pure[F, Unit](()))
}
(ááŒááºá·ááŸá¯áá«
node ááẠáááºáá±á¬ááºááŸá¯á¡áááºážáááºááᯠáá¯ááºáá±á¬ááºááá·áº á¡áá¬ááá¹áá¯áá áºáá¯ááŒá áºááẠ(á¡áááºážá¡ááŒá áºáá»á¬ážá ááœááºážáááºáá áºáá¯á áááºááŒááºážááᯠCake Pattern ááŒáá·áº ááœáá·áºáá¬ážáááº)á
object SingleNodeImpl extends ZeroServiceImpl[IO]
with EchoServiceService
with EchoClientService
with FiniteDurationLifecycleServiceImpl
{
type Config = EchoConfig[String] with EchoClientConfig[String] with FiniteDurationLifecycleConfig
}
ဠnode ááœáẠááá¯á¡ááºáá±á¬ configuration á¡áá»áá¯ážá¡á
á¬ážá¡ááá¡áá»ááᯠáá»áœááºá¯ááºááá¯á·áááºááŸááºáá¬ážááŒá±á¬ááºáž áááááŒá¯áá«á áááºáá±á¬ááºááŸá¯á
ááá¯ááºáá
áºáá¯á
á®ááẠááá·áºáááºáá»ááºáá
áºáá¯á
á®ááᯠááŒá±ááŒá¬áá¬ážáá±á¬ááŒá±á¬áá·áº ááá¯á¶áá±á¬ááºáá±á¬á¡áá»áá¯ážá¡á
á¬ážááŒáá·áº á¡áá¬ááá¹áᯠ(Cake) ááᯠCompiler á០áááºáá±á¬ááºááœáá·áºáááŒá¯áá«á Config
á¡áá»áá¯ážá¡á
á¬ážá ááŒá®ážááŒáá·áºá
á¯á¶áá±á¬ ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááᯠááá¶á·ááá¯ážáá² áá»áœááºá¯ááºááá¯á·ááẠnode ááᯠá
áááºááá¯ááºáááºááá¯ááºáá±á
Node ááááºá ᬠááŒááºáááºááŒááºáá¬ážááŸá¯
áá»áááºáááºááŸá¯áá áºáá¯áááºáá±á¬ááºáááºá¡ááœáẠnode áá áºáá¯á á®á¡ááœáẠá¡ááŸááºáááẠhost ááááºá á¬áá áºáᯠááá¯á¡ááºáá«áááºá ááœá²á·á ááºážááŸá¯áá¯á¶á á¶á á¡ááŒá¬ážá¡á áááºá¡ááá¯ááºážáá»á¬ážááẠáá±á¬ááºáá»á០ááááá¯ááºáááºá ááá¯á·ááŒá±á¬áá·áºá node id ááŸáá·áº áááºážáá¡ááŸááºááááºááááºá á¬ááŒá¬ážááœáẠááŒá±áá¯á¶ááœá²ááẠáááºážáááºážáá áºáᯠááá¯á¡ááºáá«áááºá á€ááŒá±áá¯á¶ááœá²ááŒááºážááŸá¬ áá¯ááºáá±á¬ááºáá»ááºáá áºáá¯ááŒá áºáááºá
case class NodeAddress[NodeId](host: Uri.Host)
trait AddressResolver[F[_]] {
def resolve[NodeId](nodeId: NodeId): F[NodeAddress[NodeId]]
}
ááá¯ááá¯á·áá±á¬áá¯ááºáá±á¬ááºáá»ááºááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááẠááŒá áºááá¯ááºááá·áºáááºážáááºážá¡áááºážáááºááŸááá«áááºá
- á¡áááºá áá»áœááºá¯ááºááá¯á·ááẠáááºááœá±á·ááá¯ááºáá±á¬ááºáá® ááááºá
á¬á¡ááŸááºáá»á¬ážááᯠááááŸááá«áá node hosts instantiation áá¬áá¡ááœááºážá áá»áœááºá¯ááºááá¯á·ááẠá¡ááŸááºáááẠááááºá
á¬áá»á¬ážááŸáá·áºá¡áá° Scala áá¯ááºááᯠáá¯ááºáá¯ááºááŒá®áž áá±á¬ááºááá¯ááºážááœáẠáááºáá±á¬ááºááŸá¯ááᯠáá¯ááºáá±á¬ááºááá¯ááºááẠ(áááºážááẠá¡áá»áááºá
á
áºáá±ážááŸá¯áá»á¬ážááᯠáá¯ááºáá±á¬ááºááŒá®áž áá±á«ááºážá
ááºá
ááºážáááºááŸá¯á¡á
á¯á¶ááᯠáá¯ááºáá±á¬ááºáááº)á á€á¡ááŒá±á¡áá±ááœáẠáá»áœááºá¯ááºááá¯á·áááŒá±áá¯á¶ááœá²ááŒááºážáá¯ááºáá±á¬ááºáá»ááºááᯠáááºááŒáááºá
áœá¬ááááŸáááŒá®áž áá
áºáá»áá¯ážáá²á·ááá¯á· ááá¯ážááŸááºážá¡á±á¬ááºááŒá¯áá¯ááºááá¯ááºáááºá
Map[NodeId, NodeAddress]
. - áá áºáá«áá áºáá¶ááœáẠnode ááᯠá¡ááŸááºááááºá áááºááá·áºá¡áá« áá±á¬ááºááá¯ááºážááœááºáᬠáá»áœááºá¯ááºááá¯á·ááẠá¡ááŸááºáááẠááááºá á¬áá»á¬ážááᯠáááŸáááẠááá¯á·ááá¯áẠáá»áœááºá¯ááºááá¯á·ááœáẠáá áááºááá±ážááá·áº node ááááºá á¬áá»á¬áž áááŸááá«á á€á¡ááŒá±á¡áá±ááœáẠáá»áœááºá¯ááºááá¯á·ááẠá¡ááŒá¬áž node áá»á¬ážá¡á¬ážáá¯á¶ážááŸá±á·ááœáẠá áááºáá¬ážáá±á¬ ááŸá¬ááœá±ááœá±á·ááŸáááŸá¯áááºáá±á¬ááºááŸá¯áá áºáá¯ááŸáááá¯ááºááŒá®áž node áá áºáá¯á á®ááẠáááºážáááºáá±á¬ááºááŸá¯ááœáẠáááºážáááááºá á¬ááᯠááŒá±á¬áºááŒá¬ááŒá®áž ááŸá®ááá¯ááŸá¯á á¬áááºážááœááºážááẠá á¬áááºážááœááºážááá¯ááºáá«áááºá
- ááŒá¯ááŒááºááá¯á· ááááºá
/etc/hosts
ááŒáá¯áááºáááºááŸááºáá¬ážáá±á¬á¡áááºááŸááºá¡áááºáá»á¬áž (áá²á·ááá¯á·áá±á¬my-project-main-node
ááŸáá·áºecho-backend
) ááŸáá·áº á¡áá¯á¶ážáá»áá»áááºá á€á¡áááºááᯠip ááááºá á¬ááŒáá·áº áá»áááºáááºáá«á
á€ááá¯á·á
áºááœáẠáá»áœááºá¯ááºááá¯á·ááẠá€ááá
á¹á
áá»á¬ážááᯠá¡áá±ážá
áááºááá±á¬áºááŒáá«á ááááºáá±á¬á· áá»áœááºá¯ááºááá¯á·á á¡áá¯ááºá¥ááá¬ááœáẠnode áá»á¬ážá¡á¬ážáá¯á¶ážááẠáá°áá®áá±á¬ IP address ááŸááááá·áºááẠâ 127.0.0.1
.
á€ááá¯á·á áºááœáẠáá»áœááºá¯ááºááá¯á·ááẠááŒáá·áºáá±ááŸá¯á áá Ạlayout ááŸá áºáá¯ááᯠáá¯á¶ážáááºáá«áááºá
- áááºáá±á¬ááºááŸá¯á¡á¬ážáá¯á¶ážááẠnode áá áºáá¯áááºážáá±á«áºááœáẠáá±áá¬áá»áá¬ážááá·áº Single node á¡ááŒááºá¡áááºá
- áááºáá±á¬ááºááŸá¯ááŸáá·áº áááá¯ááºážááá·áº ááá°áá®áá±á¬ node áá»á¬ážáá±á«áºááœáẠááŸááá±ááá·áº node layout ááŸá áºáá¯á
ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶áá
áºáá¯
Single node ááœá²á·á ááºážááŸá¯
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.
}
á€ááœáẠáá»áœááºá¯ááºááá¯á·ááẠáá¬áá¬ááŸáá·áº áááá¯ááºážááá·áºááœá²á·á
ááºážááŸá¯ááŸá
áºáá¯áá¯á¶ážááᯠááá¯ážáá»á²á·ááá¯ááºáá±á¬ áá
áºáá¯áááºážáá±á¬ ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááᯠáááºáá®ážáááºá ááá¯á·á¡ááŒáẠáá»áœááºá¯ááºááá¯á·ááẠáá±á¬ááºááá¯ááºážááœáẠáá¯á¶ááŸááºá¡á¬ážááŒáá·áº client ááŸáá·áº server ááᯠáááºá
á²ááœá¬ážááá·áº lifecycle controller ááᯠconfigure áá¯ááºáá«áááºá lifetime
ááŒá¬ážáá¬áááŒááºáááºážááŸá¯áá»á¬ážá
áá°áá®áá±á¬ áááºáá±á¬ááºááŸá¯ á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯áá»á¬ážááŸáá·áº ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶áá»á¬ážááᯠáá®ážááŒá¬áž node ááŸá
áºáá¯ááŒáá·áº á
áá
áºá á¡ááŒááºá¡áááºááᯠáááºáá®ážááẠá¡áá¯á¶ážááŒá¯ááá¯ááºáááºá áááºáá®ážááá¯á·áá²ááá¯áááºá
áá¯á¶ááŸááºááŸá áºáᯠááœá²á·á ááºážááŸá¯
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"
}
ááŸá®ááá¯ááŸá¯ááᯠáá»áœááºá¯ááºááá¯á· áááºááá¯á·áááºááŸááºáááºááᯠááŒáá·áºáá«á áááºááŸá node á ááŸá®ááá¯ááŸá¯á¡ááŒá Ạá¡ááŒá¬áž node á áá¶á·ááá¯ážáá±ážáá¬ážáá±á¬ áááºáá±á¬ááºááŸá¯ááᯠáá»áœááºá¯ááºááá¯á·áá±á¬áºááŒáá¬ážáááºá áááá¯ááá¯áá±á¬ááá¯áá±á¬áºááŒááá·áº áááºáááºá¡áá»áá¯ážá¡á á¬ážáá«áááºáá±á¬ááŒá±á¬áá·áº ááŸá®ááá¯ááŸá¯á¡áá»áá¯ážá¡á á¬ážááᯠá á áºáá±ážáá¬ážáááºá ááŒá®ážáá±á¬á· runtime ááŸá¬ ááŸááºáááºáá²á· node id ááŸááá«áááá·áºáááºá á€áááºááŸá¬ á¡ááá¯ááŒá¯áá¬ážáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶áá»ááºážáááºááŸá¯á á¡áá±ážááŒá®ážáá±á¬ááá¹ááá»á¬ážáá²á០áá áºáá¯ááŒá áºáááºá áááºážááẠáá»áœááºá¯ááºááá¯á·á¡á¬áž ááááºáááºážááᯠáá áºááŒáááºáᬠáááºááŸááºááá¯ááºá áœááºážááŸáááŒá®áž áá»áœááºá¯ááºááá¯á·ááẠááŸááºáááºáá±á¬ port ááᯠááá¯ážáá¬ážááŒá±á¬ááºáž áá±áá»á¬á á±áá«áááºá
node ááŸá áºáá¯á¡áá±á¬ááºá¡áááºáá±á¬áºááŒááºážá
á€ááœá²á·á ááºážáá¯á¶á¡ááœáẠáá»áœááºá¯ááºááá¯á·ááẠá¡ááá¡áá»áá°áá®áá±á¬ áááºáá±á¬ááºááŸá¯áá»á¬ážááᯠá¡áá¯á¶ážááŒá¯áá«áááºá á¡ááŒá±á¬ááºážá¡áá² áá¯á¶ážááááŸááá«á ááá¯á·áá±á¬áºáááºážá áá»áœááºá¯ááºááá¯á·ááẠááá°áá®áá±á¬ áááºáá±á¬ááºááŸá¯á¡á á¯á¶áá«áááºáá±á¬ ááá°áá®áá±á¬ node ááŸá áºáá¯ááᯠáááºáá®ážáááº-
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
}
ááááá¯á¶áž node ááẠserver ááá¯á¡áá±á¬ááºá¡áááºáá±á¬áºááŒá®áž áááºážááẠserver side config áá¬ááá¯á¡ááºáááºá áá¯ááá Node ááẠclient ááá¯á¡áá±á¬ááºá¡áááºáá±á¬áºááŒá®áž config áá¡ááŒá¬ážá¡á
áááºá¡ááá¯ááºážáá
áºáá¯ááá¯á¡ááºáááºá node ááŸá
áºáá¯áá¯á¶ážááẠáá
áºáááºáá¬áááºááŸááºáá»ááºá¡áá»áá¯á· ááá¯á¡ááºáá«áááºá ဠpost service node ááááºááœááºáá»ááºáá»á¬ážá¡ááœááºá¡áá¯á¶ážááŒá¯ááŒááºážááá¯áááºá
á²ááá¯ááºááá·áºá¡áá¯á¶ážáá²á·áá
áºáááºáá¬ááŸááááá·áºáááºá SIGTERM
áá²á·áááºáá¶áá±á¬ááºáááºááẠááŒááºáááºáááºááŸááºáá¬ážáá±á¬ ááá·áºáááºááŒá¬áá»áááºááŒá®ážáá±á¬áẠáááºááá·áºááœá¬ážáááá·áºáááºá ááŒáá·áºáá«á
á¡áá¯á¶ážá á¯á¶ ááœá¶á·ááŒáá¯ážááá¯ážáááºáá±áž áá¯ááºáááºážá ááº
á€áá»ááºážáááºáá¯á¶ááẠáá»áœááºá¯ááºááá¯á·áááœá²á·á ááºážáá¯á¶ááŸáá·áºáá¯ááºáá±á¬ááºáá¯á¶á¡á¬áž áááºááá¯á·ááŒá±á¬ááºážáá²á á±áááºááᯠááŒáá·áºááŒáá«á áá¯á·á
áá¯ááºá¡ááŒá Ạááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠá á¯á ááºážááŒá®áž ááŸá±ážáá±á¬ááºážáá á¹á ááºážáá áºáᯠáá¯ááºáá¯ááºáááºááŒá áºáááºá á¡ááŒá¬áž áá¯ááºá¡áá¯á¶ážá¡áá±á¬ááºáá»á¬áž ááŸáá·áº ááœá²á·á ááºážááŸá¯ááá¯ááºáᬠáá á¹á ááºážááᯠááœá²ááŒá¬ážááẠáá»áá¯ážááŒá±á¬ááºážáá®áá»á±á¬áºáá¯á¶ááááºá áááŒá¬ááááá¯áááᯠáá»áœááºá¯ááºááá¯á·ááẠáá°áá®áá±á¬áá¯ááºá¡ááŒá±áá¶áá±á«áºááœáẠááœá²á·á ááºážááŸá¯á¡áá»á¬ážá¡ááŒá¬ážááŸáááá¯ááºáááºá ááá¯á·á¡ááŒááºá áá»áœááºá¯ááºááá¯á·ááẠá¡áá»áá¯ážáá»áá¯ážáá±á¬ááœá²á·á ááºážáá¯á¶á¡ááá¯ááºážá¡áááºáá»á¬ážá áá¬ážááŸááºážáá»á¬ážá áœá¬ááᯠáááŸáááá¯ááºáá«áááºá á á®á ááºááœá²á·á ááºážááŸá¯áá áºáá¯ááœáẠáá»áœááºá¯ááºááá¯á·ááẠá á¬ááŒáá·áºááá¯ááºáá»á¬ážá áá®ážááŒá¬ážáá¬ážááŸááºážáá»á¬ážááᯠááœá±ážáá»ááºááá¯ááºááŒá®áž á€ááœá²á·á ááºážáá¯á¶ááᯠáá»áœááºá¯ááºááá¯á·á¡áá¯á¶ážááŒá¯ááá·áºá¡áá«ááá¯ááºáž áááºážááẠá¡ááŒá²áááºáá±áááºááŒá áºáááºá
ááœá²á·á ááºážááŸá¯ááŒá±á¬ááºážáá²ááŸá¯ááẠáá¯ááºááŒá±á¬ááºážáá²ááŸá¯ááŒá áºáá¬áááºá ááá¯á·ááŒá±á¬áá·áº áááºážááᯠáá°áá®áá±á¬ á¡áááºá¡ááœá±áž á¡á¬ááá¶ááŸá¯ áá¯ááºáááºážá ááºááŒáá·áº á¡áá»á¯á¶ážáááºááá·áºáááº-
áááºááŸáẠ-> PR -> ááŒááºáááºáá¯á¶ážáááºááŒááºáž -> áá±á«ááºážá ááºážááŒááºáž -> á ááºáááºáááŒáẠáá±á«ááºážá ááºážááŒááºáž -> á ááºáááºáááŒáẠááŒáá·áºáá»ááºááŒááºážá
áá»ááºážáááºááŸá¯áá¡á±á¬ááºáá«á¡áá»áá¯ážáááºáá»á¬ážááŸááááºá
- á áá áºáá áºáá¯á á á¶ááá°áá¬á¡ááœáẠááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááẠáá®ááœááºáááºá node áá»á¬ážááŒá¬ážááœáẠááŸá¬ážááœááºážáá±á¬áá»áááºáááºááŸá¯ááŸáááẠáááºážáááºážáááŸááá¯á¶ááááºá
- node áá áºáá¯ááœáẠconfiguration ááá¯ááŒá±á¬ááºážáááºáááœááºáá°áá«á áá±á¬á·ááºá¡ááºáááºááŒá®áž á á¬áá¬ážááá¯ááºá¡áá»áá¯á·ááᯠááŒá±á¬ááºážáá²ááŒááºážááẠáá»áá¯ážááŒá±á¬ááºážáá®áá»á±á¬áºááŸá¯áááŸááá¯á¶ááááºá ááá¯á·ááŒá±á¬áá·áº configuration drift ááẠááŒá áºááá¯ááºáá»á±áááºážáááºá
- áá±ážáááºáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á ᶠá¡ááŒá±á¬ááºážá¡áá²áá»á¬ážááẠááŒá¯áá¯ááºááẠáááœááºáá°áá«á
- ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááŒá±á¬ááºážáá²ááŸá¯á¡áá»á¬ážá á¯ááẠáá°áá®áá±á¬ááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯áá¯ááºáááºážá ááºá¡ááá¯ááºáž áá¯ááºáá±á¬ááºáááºááŒá áºááŒá®áž ááŒááºáááºáá¯á¶ážáááºááŸá¯á¡áá»áá¯á·ááᯠáá»á±á¬áºááœááºááœá¬ážáááºááŒá áºáááºá
áá¯ááºáá¯ááºááŸá¯ááœá²á·á ááºážááŸá¯áá¯á¶á á¶á¡ááœáẠáá®ážááŒá¬ážááá¯ááŸá±á¬ááºááŸá¯áá áºáᯠááá¯á¡ááºáá«ááá¬ážá áá¯ááºáá¯ááºááŸá¯ááœá²á·á ááºážáá¯á¶ááœáẠáá»áœááºá¯ááºááá¯á·ááẠáá°áá»á¬ážá áœá¬ááááºááŸááºážááá®ááŸá¯ááᯠááááºážáááºážáá¬ážááá¯ááá·áº á¡áá±ážááŒá®ážáá±á¬á¡áá»ááºá¡áááºáá»á¬áž áá«áááºááá¯ááºáááºá ááá¯á·ááŒá±á¬áá·áº áá¯ááºáá¯ááºááœá²á·á ááºážááŸá¯áá¯á¶á á¶áá«áááºááá·áº ááá·áºáááºáááºáá±á¬ááºááœáá·áºááŒáá·áº áá®ážááŒá¬ážááá¯ááŸá±á¬ááºáááºážááᯠáá¬ážááŸáááá»áá¯ážáááºáá±áááºá áá»áœááºá¯ááºááá¯á·ááẠááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠá¡ááá¯ááºážááŸá áºááá¯ááºážááœá²ááá¯ááºááẠ- áá¯ááºáá¯ááºááŸá¯á á¡ááœáá·áºáááºááŸááºáá»ááºáá»á¬áž á¡áá»á¬ážáá¯á¶ážáá«áááºááá·áºáá áºáá¯ááŸáá·áº ááœá²á·á ááºážááŸá¯áá¯á¶á á¶á áá»áŸáá¯á·ááŸááºá¡á áááºá¡ááá¯ááºážáá»á¬ážáá«ááŸááá±á¬ áá áºáá¯ááá¯á·áá«áááºáá«áááºá áááºážááẠá¡ááŸááºáááẠááááœááºááŸááœáẠá¡áá¬áá»á¬ážááᯠáááºáá±á¬ááºááœáá·áºááᯠááá·áºáááºáá¬ážá ááºááœáẠdeveloper á¡áá»á¬ážá á¯á¡á¬áž ááá·áºáááºáá»ááºáá»á¬áž á¡áá»á¬ážá á¯ááá¯á· áááºáá±á¬ááºááá¯ááºá á±áááºááŒá áºáááºá áá¯á¶áá±áá«áá¬áá®áá¬áááºááá¯ážáá»á¬ážááŸáá·áºá¡áá° á¡áááºá¡áááºá ááá¯ááºáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯á áááºážááᯠááŒá®ážááŒá±á¬ááºááẠááœááºáá°áááºá
á¡ááŒá±á¬ááºážá¡áá²ááœá±áá¬
á¡ááá¯ááŒá¯áá¬ážáá±á¬áá»ááºážáááºááŸá¯á á¡á¬ážáá¬áá»ááºáá»á¬ážááŸáá·áº á¡á¬ážáááºážáá»ááºáá»á¬ážááᯠá¡ááŒá¬ážááœá²á·á ááºážáá¯á¶á á®áá¶ááá·áºááœá²ááŸá¯áááºážá áá áºáá»á¬ážááŸáá·áº ááŸáá¯ááºážááŸááºááŒáá·áºááŒáá«á áá¯á·á
ááááŠážá áœá¬á ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠááá¯ááºááœááºááŒá±ááŸááºážááẠá¡ááá¯ááŒá¯áá¬ážááá·áº ááá°áá®áá±á¬ááŸá¯áá±á¬áá·áºáá»á¬ážá¡ááœáẠá¡ááŒá¬ážááœá±ážáá»ááºá áá¬á¡áá»áá¯á·ááᯠáá»áœááºá¯ááºááá¯á· á á¬áááºážááŒá¯á á¯áá¬ážáá«áááºá
- áá áºááŸááºá ááºáá±á«áºááŸá á á¬áá¬ážááá¯ááºá
- áááá¯áá»á¯ááºááá¯ááºáá¬ážáá±á¬ áá±á¬á·áááºááá¯ážááá¯ááŸá±á¬ááºááŸá¯ (áá²á·ááá¯á·áá±á¬
etcd
/zookeeper
). - áá¯ááºáááºážá ááºááᯠááŒááºáááºá áááºááŒááºážáááŸááá² ááŒááºáááºááœá²á·á ááºážááŒááºáž/ááŒááºáááºá áááºááá¯ááºááá·áº áá¯ááºáááºážá ááºááœá²á¡á áááºá¡ááá¯ááºážáá»á¬ážá
- ááŸá±ážáá±á¬ááºážáá á¹á ááºážááŸáá·áº áá¬ážááŸááºážááááºážáá»á¯ááºááŸá¯ááŒááºáááœáẠááœá²á·á ááºážááŸá¯á
á á¬áá¬ážááá¯ááºááẠad-hoc ááŒá¯ááŒááºááŸá¯áá»á¬ážáá ááºážáááºážáá»ááºáá»á¬ážáá¡áá»áá¯á·áá±á¬ááŒá±á¬ááºážááœááºááŒááºááœááºáá±ážáááºá á áá áºáá á®áá¶ááá·áºááœá²áá°ááẠáá áºááŸáẠnode ááá¯á·áááºáá±á¬ááºááá¯ááºááŒá®ážá á¡ááŒá±á¬ááºážá¡áá²áá áºáá¯ááŒá¯áá¯ááºáᬠáááºáá±á¬ááºááŸá¯ááá¯ááá¯ážááŸááºážá áœá¬ááŒááºáááºá áááºááá¯ááºáááºá áááºážááẠááá¯ááá¯ááŒá®ážáá¬ážáá±á¬ á áá áºáá»á¬ážá¡ááœáẠáá±á¬ááºážááœááºáááºááá¯ááºáá±á ááŒá±á¬ááºážáá²ááŸá¯áá±á¬ááºááœááºááŸá¬ ááŒá±áá¬ááœá± ááá»ááºáá±á¬á·áá°ážá á¡ááŒá±á¬ááºážá¡áá²ááᯠá¡ááŒá¬ážáá»ááºáá¯á¶ážáá áºá á¯á¶á ááá¯á¶ážáááºáá«á á¡ááŒá±á¬ááºážá¡áá²ááᯠááŒá áºáá±á«áºá á±ááá·áº á¡ááŒá±á¬ááºážá¡áááºážááᯠááŸá¬ááœá±ááẠáááºáá²áá±áááºá áá ááºážáááºááá±ážáá«á ááŒáá·áºáá±ááá·áºá áá áºáááŸá¯áá±á¬áá·áºááŸááŒáá·áºáá»áŸáẠá¡ááºááááºáá áºáŠážááẠá¡ááŒá¬áž node áá áºáá¯ááŸá configuration ááᯠupdate áá¯ááºááẠáá±á·ááœá¬ážááá¯ááºáááºá
(Btwá áá±á¬ááºáá¯á¶ážááœáẠtext config ááá¯ááºáá»á¬ážááᯠá
áááºá¡áá¯á¶ážááŒá¯ááẠááá¯á¡ááºáá¬áá«áá áá»áœááºá¯ááºááá¯á·ááẠáá°áá®áá±á¬ parser + validator ááᯠááá·áºááœááºážááẠááá¯á¡ááºáá«áááºá Config
type áá¯ááºááŒá®áž text configs ááá¯á
áá¯á¶ážááá¯á· áá¯á¶áá±á¬ááºáá«áááá·áºáááºá á
á¬áá¬ážá¡ááŒá±áá¶áá¬ážááŸááºážááœáẠáá»áœááºá¯ááºááá¯á·ááẠáááºáá±á¬ááºážáá¯ááºá¡áá»áá¯á· ááá¯á¡ááºáá±á¬ááŒá±á¬áá·áº á
á¬áá¬ážá¡ááŒá±áá¶ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶á ááŸá¯ááºááœá±ážááŸá¯ááẠá
á¯á
ááºážá¡áá»áááºááœá²á·á
ááºážááŸá¯á ááŸá¯ááºááœá±ážááŸá¯ááẠá¡áááºážáááºáá±ážáááºááŒá±á¬ááºážáááºáž áááºážááŸááŒááááºá)
Centralized key-value storage ááẠapplication meta parameters áá»á¬ážááᯠááŒáá·áºáá±áááºá¡ááœáẠáá±á¬ááºážááœááºáá±á¬ ááá¹ááá¬ážáá
áºáá¯ááŒá
áºáááºá á€áá±áá¬ááœáẠáá»áœááºá¯ááºááá¯á·ááẠconfiguration values ââááŸáá·áº data áá»áŸáá¬áá¯áá»áœááºá¯ááºááá¯á·áá°ááá±á¬á¡áá¬ááá¯á
ááºážá
á¬ážáááºááá¯á¡ááºáááºá áá¯ááºáá±á¬ááºáá»ááºáá
áºáᯠáá±ážáá¬ážáááºá C => A => B
ááŒá±á¬ááºážáá²áá²áá±á¬ áááºááá¯ážáá»á¬ážááᯠáá»áœááºá¯ááºááá¯á· áá±á«áºááá¯áá±á·ááŸááá«áááºá C
"configuration" áááŒá¬áá data ááá¯ááŒá±á¬ááºážáá²áá±á
áẠA
- áá±áá¬ááá·áºáá¯á¶áá«áá²á áá±áá¬áááºá
á±á¬áá±á¬ áá¯ááºáá±á¬ááºáá»ááºááᯠááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááᯠáá±ážááá·áºáááºá A
. á€á¡ááŒá¶á¡á
ááºááŒá±á¬áá·áº áááºážááẠáá±áá¬áá
áºáá¯áááºážá០configuration data ááᯠááœá²ááŒá¬ážáá¬ááœáẠá¡áá¯á¶ážááŒá¯ááá¯ááºááá·áº ááŒáááºááŸá¯ááºážá¡ááŒá±á¬ááºážá¡áá²áá»á¬ážáᯠáá»áœááºá¯ááºááá¯á·ááŒá±á¬ááá¯ááºáááºá ááá¯á·á¡ááŒáẠáá±áá¬ááẠáá¯á¶ááŸááºá¡á¬ážááŒáá·áº á¡áááºážá¡ááŒá
áºáá
áºáᯠ(á¡áá¯á¶ážááŒá¯áá°) á០áá¬ááŒá®áž ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááẠááá°áá®áá±á¬ á¡áááºážá¡ááŒá
Ạ(á
á®áá¶ááá·áºááœá²áá°) á០áá¬áá«áááºá á¡á
ááŒá¯ááŒááºážáá¯ááºáááºážá
ááºááŒá®ážáá±á¬áẠááŒá±á¬ááºážáá²ááá¯ááºáá±á¬ ááá·áºáááºáá»ááºáá»á¬ážááᯠááá¯ááºááœááºááŒá±ááŸááºážááŒááºážá á¡ááºááºáá®áá±ážááŸááºážááŸá¯ááºááœá±ážááŸá¯ááᯠááá¯ážáá¬á
á±áá«áááºá ááá¯ááá¯á·áá±á¬ ááá·áºáááºáá»ááºáá»á¬áž á¡ááœáẠáá»áœááºá¯ááºááá¯á·ááẠáááºážááá¯á·á áá±ážááá¯á·ááŸá¯ ááá¹ááá¬ážá ááœá²ááŒááºážá
áááºááŒá¬ááŒááºážááŸáá·áº á¡áááºááŒá¯ááŒááºážá áááŸááºáááºáá±á¬ áááºááá¯ážáá»á¬ážááᯠááá¯ááºááœááºááŒá±ááŸááºážááẠááá¯á¡ááºáá«áááºá ááá¯á·ááŒá±á¬áá·áºá áááá¯ááááºáááŸá¯ááºááœá±ážááŸá¯ááá¯áá»áŸá±á¬á·áá»áááºá¡ááœááºá áá»áœááºá¯ááºááá¯á·ááẠruntime ááœááºááŒá±á¬ááºážáá²ááá¯ááºáá±á¬ parameters á¡áá±á¡ááœááºááá¯áá»áŸá±á¬á·áá»ááá¯ááºááẠ(ááá¯á·ááá¯ááºáááºážááá¯á·ááá¯áá¯á¶ážááááºááŸá¬ážáá
áºáááº) á
á€ááá¯á·á
áºáááŸá¯áá±á¬áá·áºá០áá»áœááºá¯ááºááá¯á·ááẠstatic ááŸáá·áº dynamic parameters áá»á¬ážá¡ááŒá¬áž ááœá²ááŒá¬ážááŸá¯ááᯠááŒá¯áá¯ááºááá·áºáááºá á¡áááºá service logic ááẠruntime ááœáẠá¡áá»áá¯á·áá±á¬ parameter áá»á¬ážááᯠááŸá¬ážáá«ážáá±á¬ááŒá±á¬ááºážáá²ááŸá¯ ááá¯á¡ááºáá«áá áááºážááá¯á·ááᯠdynamic parameters áá¯áá±á«áºááá¯ááºáááºá ááá¯ááºáá«á áááºážááá¯á·ááẠáááºááŒáááºáá±ááŒá®áž á¡ááá¯ááŒá¯áá¬ážáá±á¬ áá»ááºážáááºááŸá¯ááᯠá¡áá¯á¶ážááŒá¯á ááŒááºáááºááá¯ááºáááºá ááŒá±á¬ááºážáá²áá±áá±á¬ ááŒááºáááºááœá²á·á
ááºážááŸá¯á¡ááœáẠá¡ááŒá¬ážáááºážáááºážáá»á¬áž ááá¯á¡ááºááá¯ááºáááºá á¥ááá¬á¡á¬ážááŒáá·áºá ááŒáá·áºáá±áá¬ážáá±á¬á
áá
áºá áá®ážááŒá¬ážáá¯ááºáááºážá
ááºáá»á¬ážááᯠááŒááºáááºá
áááºááẠá¡áá¬ážáá°áá¯á¶á
á¶ááŒáá·áº á
áá
áºáá¡á
áááºá¡ááá¯ááºážáá»á¬ážááᯠá¡áá
áºááœá²á·á
ááºážááŸá¯ááá·áºáááºáá»ááºáá»á¬ážááŒáá·áº ááŒááºáááºá
áááºááá¯ááºáááºá
(áá»áœááºá¯ááºá ááŸááá·áºáá»áá±á¬ á¡ááŒááºááŸá¬ áááºážááẠá
áá
áºá ááŸá¯ááºááœá±ážááŸá¯ááᯠááá¯ážááœá¬ážá
á±áá±á¬ááŒá±á¬áá·áº runtime ááŒááºáááºááŒááºáááºááŒááºážááᯠááŸá±á¬ááºááŒááºáááºááŒá
áºáááºá
áá¯ááºáááºážá
ááºáá»á¬áž ááŒááºáááºá
áááºááŒááºážá¡ááœáẠOS áá¶á·ááá¯ážááŸá¯ááá¯áᬠá¡á¬ážááá¯ážáááºááŸá¬ ááá¯ááá¯ááá¯ážááŸááºážáá«áááºá áá«áá±á¬áẠá¡ááŒá²áááºážáááŒá
áºááá¯ááºáá°ážáá±á)
áá
áºáá«áá
áºáá¶ááœáẠáá°áá»á¬ážááᯠááŒá±á¬ááºážáá²áá±áá±á¬ ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááᯠ(á¡ááŒá¬ážá¡ááŒá±á¬ááºážááŒáá»ááºáááŸááá²) ááá·áºááœááºážá
ááºážá
á¬ážá
á±ááá·áº static configuration ááá¯á¡áá¯á¶ážááŒá¯ááŒááºážá á¡áá±ážááŒá®ážáá±á¬á¡áá»ááºáá
áºáá¯ááŸá¬ configuration update áá¯ááºá
ááºááœáẠáááºáá±á¬ááºááŸá¯áááºáá¬ážáá»áááºááŒá
áºáááºá á¡ááŸááºááŸá¬á áá»áœááºá¯ááºááá¯á·ááẠstatic configuration ááᯠá¡ááŒá±á¬ááºážá¡áá²áá¯ááºááááºááá¯áá»áŸááºá áááºááá¯ážá¡áá
áºáá»á¬áž áááá±á¬ááºáá¬á
á±ááẠá
áá
áºá¡á¬áž ááŒááºáááºá
áááºááááºááŒá
áºáááºá á
ááºáááºáá»áááºá¡ááœáẠááá¯á¡ááºáá»ááºáá»á¬ážááẠááá°áá®áá±á¬á
áá
áºáá»á¬ážá¡ááœáẠááœá²ááŒá¬ážáá±á¬ááŒá±á¬áá·áº áááºážááẠá¡ááœááºá¡áá±ážááŒá®ážáááºááá¯ááºáá«á á¡áá±ážááŒá®ážáá«á áááºááá·áºá
áá
ẠááŒááºáááºá
áááºááŒááºážá¡ááœáẠááŒáá¯áááºá
á®á
ááºáá¬ážááááºáááºážá á¥ááá¬á¡áá±áá²á· á¡áá±á¬ááºá¡áááºáá±á¬áºááá¯á·ááááºá
áá¯á¶á á¶ááœá²áá¬ážáá±á¬ ááŸá±ážáá±á¬ááºážáá á¹á ááºážá¡ááœááºáž ááá¯á·ááá¯áẠá¡ááŒááºááœáẠááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠáá¬ážááŸáááŒááºážááŸáá·áºáááºáááºááá±á¬á á€ááœá²á·á ááºážáá¯á¶ááẠá¡ááŒá¬ážááŸá±ážáá±á¬ááºážáá á¹á ááºážáá»á¬ážáá²á·ááá¯á· áá°áá®áá±á¬ á¡áááºá¡ááœá±ážá¡á¬ááá¶ááŸá¯áá¯ááºáááºážá ááºááᯠáá»á±á¬áºááŒááºááŒá®áž á¡áá»á¬ážá á¯ááœáẠááŸá±ážáá±á¬ááºážáá á¹á ááºážáá áºáá¯á¡ááœááºáž áá¯á¶á á¶ááá·áºááœááºážááŒááºážááᯠááá¯ááá¯áááºá ááá¯á·ááŒá±á¬áá·áº ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááẠá¡áááºá¡ááœá±ážáá±á¬ááºážááœááºááŒá®áž áá¯á¶ááŒááºá áááºáá»áááŒá±á¬ááºáž áá±áá»á¬á á±ááá¯ááºáá«áááºá áá®ážááŒá¬ážááá¯ááºáá áºáá¯ááŸá ááá·áºáá»ááºáááºáá¯á¶á á¶ááœá²á·á ááºážááŸá¯ááœáẠáááºáá°á á€ááá¯ááºááᯠá¡áááºááŒá±á¬áá·áº á¡ááŒá±á¬ááºážá¡áá²ááŒá¯áá¯ááºáá²á·áááºááᯠááŒá±áá¬áá¬áááŸááᯠááá¯ááá¯áááºá áá«á á¡áá±ážááŒá®ážááá¬ážá áá¯ááºáá¯ááºááŸá¯á áá áºá¡áá»á¬ážá á¯á¡ááœáẠáááºááŒáááºááŒá®áž á¡áááºá¡ááœá±ážááŒáá·áº ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááŸáááŒááºážá ááá¯áá±á¬ááºážáááºáᯠáá»áœááºá¯ááºááá¯á·áá¯á¶ááŒááºáá«áááºá
áááºáá®ážáá¬ážááá·áºá¡áá»áááºá áááºážááœáẠáááºááá·áºáááºááá¯ážáá»á¬ážáá«áááºáááºá áááºááá·áºá¡ááºá¹áá«áááºáá»á¬ážááᯠááœáá·áºáá¬ážáááº/ááááºáá¬ážáááºá ááŒá¯ááŒááºááŸá¯áá áºáá¯á á®ááœáẠá¡ááŒá±á¬ááºážá¡áá²áá áºáá¯á á®á¡ááœáẠáá¬áááºááŸáááá·áºá¡áá¬áá»á¬ážááᯠááŸá¬ááœá±ááœá±á·ááŸáááá¯ááºá á±ááá·áº ááŸá±ážáá±á¬ááºážáá á¹á ááºážáá¬ážááŸááºážáá¬ážááŸááºážá ááŸá±ážáá±á¬ááºážáá á¹á ááºážáá áºáá¯á¡ááœááºáž áá¯á¶á á¶ááœá²á·á ááºážááŸá¯ááᯠááááºážááááºážáá¬ážááẠá¡á¬ážáá¯ááºááŸá¯á¡áá»áá¯á· ááá¯á¡ááºááá¯ááºááŒá®áž áááºážááẠáá®ááá¯ááºážááœá±ážáá»ááºááŸá¯áá áºáá¯ááŒá áºáááºá
áá±á¬ááºážáá»áá¯ážááŸáá·áºááá¯ážáá»áá¯ážáá»á¬áž
á€áá±áá¬ááœáẠáá»áœááºá¯ááºááá¯á·ááẠá¡á¬ážáá¬áá»ááºá¡áá»áá¯á·ááᯠáá®ážáá±á¬ááºážááá¯ážááŒááŒá®áž á¡ááá¯ááŒá¯áá¬ážáá±á¬áá»ááºážáááºááŸá¯á á¡á¬ážáááºážáá»ááºá¡áá»áá¯á·ááᯠááœá±ážááœá±ážáááºááŒááá¯áá«áááºá
á¡á¬ážáá¬áá»ááºáá»á¬áž
ááŒá®ážááŒáá·áºá á¯á¶áá±á¬ ááŒáá·áºáá±ááŸá¯á áá áºá á á¯á ááºážááá¯ááºáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶á á¡ááºá¹áá«áááºáá»á¬áž-
- ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠáááºááŒáááºá áœá¬á á áºáá±ážáá«á áááºážááẠáá±ážáá¬ážáá±á¬ á¡áá»áá¯ážá¡á á¬áž ááá·áºáááºáá»ááºáá»á¬áž ááŸááºáááºááŒá±á¬ááºáž ááŒáá·áºáá¬ážáá±á¬ áá¯á¶ááŒááºááŸá¯ááᯠáá±ážáááºá
- ááŒáœááºááá±á¬áá¬áá¬á
áá¬ážááœá²á·á
ááºážááŸá¯á áá¯á¶ááŸááºá¡á¬ážááŒáá·áº á¡ááŒá¬ážááœá²á·á
ááºážáá¯á¶áááºážáááºážáá»á¬ážááᯠááŒá±á¬ááºážáá²ááá¯ááºáá±á¬ á¡á
á¬ážááá¯ážááŸá¯á¡áá»á¬ážá
á¯ááœáẠááá·áºáááºáá¬ážáááºá
Scala ááá¯á¡áá¯á¶ážááŒá¯ááŒááºážááŒáá·áº configuration ááá¯ááá¯áá±á¬ááºážááœááºá á±áááºá¡ááœáẠáá»ááºááŒáá·áºáá±á¬áá¬áá¬á áá¬ážá¡ááºá¹áá«áááºáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯ááá¯ááºáááºá á¥ááá¬á¡á¬ážááŒáá·áºá áá»áœááºá¯ááºááá¯á·ááẠáá¯á¶áá±áááºááá¯ážáá»á¬ážá ááá°áá®áá±á¬áááºáááºááᯠáááºááŸááºááẠá¡áá¬ááá¹áá¯áá»á¬ážááᯠáá±ážáá±á¬ááºááẠá ááá¯ááºááá¹ááá¬áá»á¬ážááᯠá¡áá¯á¶ážááŒá¯ááá¯ááºááŒá®ážá áá»áœááºá¯ááºááá¯á·á¡á¬áž ááá¯ážáá¬ážááá¯ááºáááºával
s ááẠááŒááºááááºááẠ(DRY) ááœáẠáá áºááŒáááºáᬠáááºááŸááºáá¬ážáááºá ááááá¡á á®á¡á á¥áºáá»á¬áž ááá¯á·ááá¯áẠá¡áá»áá¯á·áá±á¬á¡áááºážáá»á¬ážá á¥ááá¬áá»á¬ážááᯠá¡áá¯á¶ážááŒá¯ááẠááŒá áºááá¯ááºááẠ(Seq
,Map
, etc) á - DSL Scala ááẠDSL á á¬áá±ážááá¬áá»á¬ážá¡ááœáẠááá·áºáá»á±á¬áºáá±á¬áá¶á·ááá¯ážááŸá¯ááŸááá«áááºá ááá¯ááá¯á¡áááºááŒá±ááŒá®áž á¡áá¯á¶ážá¡áá¯á¶ážááŒá¯áá°áá±á¬áºááœá±áá±á¬ ááœá²á·á ááºážááŸá¯áá¬áá¬á áá¬ážáá áºáá¯ááᯠáááºáá±á¬ááºááẠá€á¡ááºá¹áá«áááºáá»á¬ážááᯠá¡áá¯á¶ážááŒá¯ááá¯ááºááŒá®ážá ááá¯á·ááŸáᬠáá±á¬ááºáá¯á¶ážááœá²á·á ááºážáá¯á¶ááẠááá¯ááááºážá¡áá¯á¶ážááŒá¯áá°áá»á¬áž á¡áááºážáá¯á¶ážáááºááŸá¯ááá¯ááºáááºááŒá áºáááºá
- node áá»á¬ážáá áºáá»áŸá±á¬áẠááá¬ááááŸáá·áº áá±á«ááºážá ááºááŸá¯á áá áºáá±áá¬áááºážááœáẠááŒáá·áºáá±ááŸá¯á áá áºáá áºáá¯áá¯á¶ážá¡ááœáẠáá¯á¶á á¶ááœá²á·á ááºážááŸá¯áá¬ážááŸáááŒááºážá á¡áá»áá¯ážáá»á±ážáá°ážáá áºáá¯ááŸá¬ áááºááá¯ážáá»á¬ážá¡á¬ážáá¯á¶ážááᯠáá áºááŒáááºáááºážááŒáá·áº áááºážáááºážáá»ááºáá»áẠáááºááŸááºááŒá®áž áá»áœááºá¯ááºááá¯á· ááá¯á¡ááºááá·áºáá±áá¬á¡á¬ážáá¯á¶ážááœáẠááŒááºáááºá¡áá¯á¶ážááŒá¯ááŒááºážááŒá áºáá«áááºá áá¯á¶ááŒá¯á¶áá±á¬ ááá¯á·ááºááŒá±ááŒá¬áá»ááºáá»á¬ážááá¯áááºáž ááá¯ááºááá·áºáá« ááŒá áºááá¯ááºáá»á± ááŸááºáááºáá±á¬ ááœá²á·á ááºážááŸá¯á áá áºá¡á¬ážáá¯á¶ážááœáẠá áá áºá node áá»á¬ážááẠáá°áá®áá±á¬áá¬áá¬á áá¬ážááᯠááŒá±á¬ááá¯ááá¯ááºá á±ááẠáá±áá»á¬á á±áá«áááºá á¡áá»áá¯á·áá±á¬ áááºáá±á¬ááºááŸá¯áá»á¬ážááᯠáá±ážáá±á¬ááºááẠáá±á·áá áºááẠáááºáá²á á±áá±á¬ node áá»á¬ážááŒá¬ážááœáẠááŒááºáá¬ážá áœá¬ ááŸá®ááá¯ááŸá¯ááŸááá«áááºá
- á¡ááŒá±á¬ááºážá¡áá²áá»á¬ážáá¡áááºá¡ááœá±ážááŒáá·áºáá¬ážá áá¯á¶ááŸáẠPR áá¯ááºáááºážá ááºááŸáááá·áº ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážááᯠááŒááºáá»á±á¬áºááŒááºážá á¡áá¯á¶ážá á¯á¶áá»ááºážáááºááŸá¯ááẠááœá²á·á ááºážááœá²á·á ááºážáá¯á¶ááœáẠá¡áááºá¡ááœá±ážááŒáá·áºá á¶ááŸá¯ááºážáá»á¬ážááᯠáá»ááŸááºáá±ážáááºá
- áááŒáá¯ááºáááºáááºáž ááœá²á·á ááºážááŸá¯áá¯á¶á ᶠá¡ááŒá±á¬ááºážá¡áá²áá»á¬ážá ááŒááºáááºáááºááŸááºááŸá¯ááœáẠáá»áœááºá¯ááºááá¯á·ááẠá¡ááá¯á¡áá»á±á¬áẠááŒáá·áºáá»ááºááŸá¯ááœáẠá¡ááŒá±á¬ááºážá¡áá²áá»á¬áž ááŒá¯áá¯ááºááá·áºá¡áá«ááá¯ááºáž node á¡á¬ážáá¯á¶ážááᯠááœááºážáá¶áá¬ážááŒá±á¬ááºáž áá±áá»á¬á á±áááºá
- áá»áŸá±á¬ááºááœáŸá¬ááá¯ážááŸááºážá á¡ááá®áá±ážááŸááºážááẠááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠááœá²ááŒááºážá áááºááŒá¬ááŒá®áž á¡áááºááŒá¯áááºááŸáá·áº ááŸá¬ážááœááºážáá±á¬ ááœá²á·á ááºážááŸá¯áááºááá¯ážáá»á¬ážááᯠááá¯ááºááœááºááẠáááá¯á¡ááºáá«á áááºážááẠá¡áá¯á¶ážá á¯á¶á¡ááá®áá±ážááŸááºážááᯠááá¯ážááŸááºážá á±áááºá (á¡áá»áá¯á·áá±á¬ ááŸá¯ááºááœá±ážááŸá¯áá»á¬áž ááá¯ážáá¬ááŒááºážááẠconfiguration áá°á·áá¬áá¬áá° ááŒá áºáááºá ááá¯á·áá±á¬áº áááºážááẠáá±ážáááºážáá±áž á¡ááœáẠáááááŸáááŸá á¡áá±ážá¡áá°áá áºáᯠááŒá áºáááºá) áá¬áááºááœá²á·á ááºážáá¯á¶ááá¯á· ááŒááºááœá¬ážááẠá¡ááœááºááá¯ážááŸááºážáá«ááẠâ áá»á±á¬ááºáá¯á¶ážáá±áá±á¬ á¡ááá¯ááºážáá»á¬ážááᯠááá·áºááá¯ááºáá¯á¶áááºá á á¯á ááºážááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááŒáá·áº á áááºááẠááá¯ááá¯ááœááºáá°ááŒá®áž á¡ááá¯á¡ááá¯ááºážá¡á áá»á¬áž á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááᯠáá±á¬ááºááá¯ááºážá¡áá»áááºá¡áá»áá¯á·á¡áá ááœáŸá±á·ááá¯ááºážááẠááá¯ááá¯ááœááºáá°áááºá
- áá¬ážááŸááºážáá¯á¶á ᶠááœá²á·á ááºážááŸá¯á ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááŒá±á¬ááºážáá²ááŸá¯áá»á¬ážááẠáá°áá®áá±á¬ááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯áá¯ááºáááºážá ááºá¡ááá¯ááºážáá¯ááºáá±á¬ááºáá±á¬ááŒá±á¬áá·áºá ááááºá¡áá±ááŒáá·áº áá»áœááºá¯ááºááá¯á·ááẠáá°ážááŒá¬ážáá±á¬áá¬ážááŸááºážááŒáá·áº ááŸá±ážáá±á¬ááºážáá á¹á ááºážáá áºáá¯ááᯠáááŸááá«áááºá áááºážááẠáá»áœááºá¯ááºááá¯á·á¡á¬áž ááá¯á¡ááºáá«á configuration ááᯠááŒááºááŒá±á¬ááºážááá¯ááºá á±áá«áááºá áá»áœááºá¯ááºááá¯á·ááẠááœááºáá²á·áá±á¬ áá áºááŸá áºá á¡áá¯á¶ážááŒá¯áá²á·ááá·áº ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááá¯ááẠá¡áá¯á¶ážáá»ááá¯ááºááŒá®áž áááºážááẠáá°áá®áá±á¬áá¯á¶á á¶á¡ááá¯ááºáž áá¯ááºáá±á¬ááºááá¯ááºáááºááŒá áºáááºá áááºááŒáááºáá±á¬ááœá²á·á ááºážáá¯á¶ááẠááŒáá·áºáá±ááŸá¯á áá áºá ááŒáá¯áááºááá·áºááŸááºážááá¯ááºááŸá¯ááŸáá·áº áá¯á¶ááŒááºá áááºáá»áááŸá¯ááᯠááá¯ážáááºá á±áááºá ááœá²á·á ááºážááŸá¯á¡á¬áž á á¯á ááºážáá»áááºá ááŒááºáááºááŒá®áž áá¯ááºáá¯ááºááŸá¯á áá áºááœáẠá¡ááœááºááá° ááœá²áá»á±á¬áºááááá«á
- ááœá±á·áá»á¬ážááŸá¯á á¡ááá¯ááŒá¯áá¬ážáá±á¬ framework ááẠmodular ááŒá
áºááŒá®áž module áá»á¬ážááᯠáááºážáááºážá¡áá»áá¯ážáá»áá¯ážááŒáá·áº áá±á«ááºážá
ááºááá¯ááºáááºá
ááá°áá®áá±á¬ááœá²á·á ááºážáá¯á¶áá»á¬ážááᯠáá¶á·ááá¯ážáá±ážááẠ(áááºáááºáá»á¬áž/ á¡ááŒááºá¡áááºáá»á¬áž)á á¡áá°ážáááŒáá·áºá áá±ážáááºáá±á¬á áá±ážáá áºáá¯áááºáž node á¡ááŒááºá¡áááºááŸáá·áº ááŒá®ážáá¬ážáá±á¬á áá±ážáá»á¬ážá áœá¬áá±á¬ node áááºáááºááŸáááẠááŒá áºááá¯ááºáááºá áá¯ááºáá¯ááºááŸá¯á¡ááŒááºá¡áááºáá»á¬ážá áœá¬ááŸáááẠááá·áºáá»á±á¬áºáá«áááºá - á ááºážáááºááŒááºážá á ááºážáááºááŒááºáž áááºááœááºáá»ááºá¡ááœáẠáá áºáŠážááẠáá¯á¶á á¶áá° áááºáá±á¬ááºááŸá¯ááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºáᬠá¡áá»áá¯ážá¡á á¬áž áá±ážáááºážáá±á¬ áááºážáááºážááŒáá·áº ááŸá®ááá¯ááŸá¯á¡ááŒá Ạá¡áá¯á¶ážááŒá¯ááá¯ááºáááºá áá¯á¶ááá¹áá¬ááºáá»á¬ážááŒáá·áº á¡á á¬ážááá¯ážáá¬ážáá±á¬ á¡áá»áá¯ážáá»áá¯ážáá±á¬ á¡á áááºá¡ááá¯ááºážáá»á¬ážááŒáá·áº ááá°áá®áá±á¬ á ááºážáááºááŸá¯ á¡ááŒááºá¡ááẠá¡áááºážáááºááᯠáá áºááŒáá¯ááºááẠááááºážááááºážáá¬ážááá¯ááºáááºá
- áá±á«ááºážá
ááºá
ááºážáááºááŒááºážá áá
áºáá«áá
áºáá¶ááœáẠááŒáá·áºáá±ááá·áºá
áá
áºáá»á¬ážááœáẠáá±á«ááºážá
ááºá
á
áºáá±ážááŸá¯áá»á¬ážááᯠáá¯ááºáá±á¬ááºááẠáááºáá²áááºá ááŒá®ážááŒáá·áºá
á¯á¶áá±á¬ ááŒáá·áºáá±ááŸá¯á
áá
áºá áá±ážáááºážáá±á¬ ááœá²á·á
ááºážááŸá¯áá¯á¶á
á¶ááᯠááá¯ááºááá·áºááẠáá±á¬áºááŒáá¬ážááá·áº áá»ááºážáááºáááºážááᯠá¡áá¯á¶ážááŒá¯ááŒááºážááŒáá·áºá áá»áœááºá¯ááºááá¯á·ááẠááááºážáá»á¯ááºááá¯ááºáá±á¬ áááºážáááºážááŒáá·áº áá¬áá¬áá
áºáá¯áááºážááœáẠááŒáá·áºáá±áá¬ážáá±á¬ á¡á
áááºá¡ááá¯ááºážá¡á¬ážáá¯á¶ážááᯠáá¯ááºáá±á¬ááºááá¯ááºáááºá á¡ááŒá±á¡áá±ááᯠá¡áá¯áá°ááá¯á· ááœááºáá«áááºá
áááºáá±á¬ááºááŸá¯áá»á¬ážáá²á០áá áºáá¯ááᯠááááá¯ááºáá±á¬á¡áá«á
á¡á¬ážáááºážáá»ááºáá»á¬áž
á á¯á ááºážáá¬ážáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááẠ"áá¬áááº" ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááŸáá·áº ááœá²ááŒá¬ážááŒá®áž ááá¯á¡ááºáá»ááºá¡á¬ážáá¯á¶ážááŸáá·áº áááá¯ááºáá®áá«á á€áááºááŸá¬ compiled config áá¡á¬ážáááºážáá»ááºá¡áá»áá¯á·ááŒá áºáááº-
- Static configuration áááºážááẠá¡ááá®áá±ážááŸááºážá¡á¬ážáá¯á¶ážá¡ááœáẠááá·áºáá»á±á¬áºáááºááá¯ááºáá±á á¡áá»áá¯á·áá±á¬ááá á¹á áá»á¬ážááœáẠáá±ážáááºážáá±ážá¡á á®á¡áá¶á¡á¬ážáá¯á¶ážááᯠáá»á±á¬áºááŒááºááŒá®áž áá¯ááºáá¯ááºááŸá¯ááœáẠááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠá¡ááŒááºááŒááºáááºááẠááá¯á¡ááºáááºá áá®áááºážáááºážá ááá¯áááºáá²á á±áááºá ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠááŒá±á¬ááºážáá²ááŒá®ážáá±á¬áẠá á¯á ááºážááŒááºážááŸáá·áº ááŒááºáááºáá±áá¬áá»áá¬ážááŒááºážááá¯á·ááᯠááá¯á¡ááºáá«áááºá á€áááºááŸá¬ á¡ááºá¹áá«áááºááŸáá·áº áááºáá¯ááºáááºááá¯áž ááŸá áºáá¯áá¯á¶ážááŒá áºáááºá
- ááœá²á·á ááºážááŸá¯áá»áá¯ážáááºá config ááᯠautomation tool á¡áá»áá¯á·ááŸáá¯ááºáá±ážáá±á¬á¡áá«á á€áá»ááºážáááºááŸá¯ááẠáá±á¬ááºáááºááœá²á á¯á ááºážááŸá¯ ááá¯á¡ááºááẠ(á¡ááŸáá·áºáá»ááŒá áºááá¯ááºáááº)á á€áá±á¬ááºáááºá¡ááá·áºááᯠáááºáá±á¬ááºááŸá¯á áá áºááœáẠáá±á«ááºážá ááºážááẠáááºáá±á¬ááºážá¡á¬ážáá¯ááºááŸá¯ ááá¯á¡ááºááá¯ááºáááºá
- áá°áááá¬á á
á¬áá¬ážá¡ááŒá±áᶠconfigs ááá¯á¡á¬ážááá¯ážááá·áºááá±á·á¡áá¯á¶ážááŒá¯áá±áá±á¬áááááá¬áá»á¬ážá
áœá¬ááŸááááºá ááá»áá¯á·á
ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠááŒá¯á á¯áá±á¬á¡áá«ááœáẠáááºáá±á¬ááºááŸá¯ááŸááááºááá¯ááºáá«á - á¡ááœá±ážá¡ááŒááºááŒá±á¬ááºážááá¯á· ááá¯áááºá áá±á¬á·ááºáá²áá±ážáá¬ážáá°áá»á¬ážááŸáá·áº DevOps ááá¯á·ááẠá á¬áá¬ážááœá²á·á ááºážááŸá¯ááá¯ááºáá»á¬ážááŸáá·áº áááºážááŸá®ážááŒáááºá ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠá á¯á ááºážááẠá áááºáá°ážááẠáááºážááá¯á·á¡ááœáẠáá°ážáááºážáá±áá±áááºá
- compilable configuration ááᯠáááááºáááºáá® á¡áááºá¡ááœá±ážááŒáá·áº áá±á¬á·ááºáá² ááœá¶á·ááŒáá¯ážááá¯ážáááºáá±áž áá¯ááºáááºážá ááºáá áºáᯠááá¯á¡ááºáá«áááºá
á¡áá±á¬ááºá¡áááºáá±á¬áºáá²á·ááá·áº á¥ááá¬á ááá·áºáááºáá»ááºá¡áá»áá¯á·ááŸááááºá
- á¡áááºá áá»áœááºá¯ááºááá¯á·ááẠnode á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯á០áá±á¬ááºážááá¯ááŒááºážáááŸááá±á¬ á¡ááᯠconfig ááᯠáá±ážáá±á¬ááºáá«áá compiler ááẠáá»ááºááœááºáá±áá±á¬á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááᯠááŸá¬ááœá±ááœá±á·ááŸáááẠáá»áœááºá¯ááºááá¯á·á¡á¬áž áá°áá®áá±ážáááá·áºáááºááá¯ááºáá«á áá«ááᯠá¡áá¯á¶ážááŒá¯ááŒá®áž ááŒá±ááŸááºážááá¯ááºáá«áááºá
HList
ááá¯á·ááá¯áẠá ááá¯ááºáá»á¬ážááŸáá·áº Cake Pattern á¡á á¬áž node ááœá²á·á ááºážááŸá¯áá¯á¶á á¶á¡ááœáẠADTs (case classes)á - config file ááœáẠboilerplate á¡áá»áá¯á·ááᯠáá±ážáá±á¬ááºááá«áááº: (
package
,import
,object
ááŒá±ááŒá¬áá»ááºáá»á¬ážá
override def
áá¯á¶áá±áááºááá¯ážáá»á¬ážááŸááá±á¬ áá±á¬ááºáá»á¬ážá¡ááœáẠ's)á áááºážááᯠDSL áá¯á¶ážááŒá®áž áá áºá áááºáá áºááá¯ááºáž ááá¯ááºááœááºááŒá±ááŸááºážááá¯ááºáá«áááºá - á€ááá¯á·á áºááœáẠá¡áá¬ážáá° node á¡á á¯á¡áá±ážáá»á¬ážá áááºááŒáœáá±á¬ ááŒááºáááºááœá²á·á ááºážááŒááºážááᯠá¡áá»á¯á¶ážááááºáá«á
áá±á¬ááºáá»ááº
á€ááá¯á·á áºááœáẠáá»áœááºá¯ááºááá¯á·ááẠá¡áá»áá¯ážá¡á á¬ážáá¯á¶ááŒá¯á¶áá±á¬áááºážáááºážááŒáá·áº á¡áááºážá¡ááŒá áºáá¯ááºááᯠááá¯ááºááá¯ááºááœá²á·á ááºážááŒááºážá¡á¬áž ááá¯ááºá á¬ážááŒá¯ááŒááºážá¡ááŒá±á¬ááºáž ááœá±ážááœá±ážáá¬ážáá«áááºá áá»ááºážáááºááŸá¯ááᯠxml- ááŸáá·áº á¡ááŒá¬ážáá±á¬ á á¬áá¬ážá¡ááŒá±áᶠconfigs áá»á¬ážááᯠá¡á á¬ážááá¯ážá¡ááŒá Ạá¡ááá®áá±ážááŸááºážáá»á¬ážá áœá¬ááœáẠá¡áá¯á¶ážááŒá¯ááá¯ááºáááºá áá»áœááºá¯ááºááá¯á·áááá°áá¬ááᯠScala ááœáẠá¡áá±á¬ááºá¡áááºáá±á¬áºáá¬ážáá±á¬áºáááºážá áááºážááᯠá¡ááŒá¬ážá á¯á ááºážááá¯ááºáá±á¬áá¬áá¬á áá¬ážáá»á¬áž (Kotliná C#á Swift á áááºááŒáá·áº) ááá¯á·áááºáž áá¬áá¬ááŒááºááá¯ááá¯ááºáá«áááºá á€áá»ááºážáááºáááºážááᯠááá±á¬áá»ááºá¡áá áºááœáẠá ááºážááŒáá·áºááá¯ááºááŒá®ážá á¡áááºáááŒá±áá«á áá±ááºáá±á¬ááºážáá¯á¶á á¶ááá¯á· ááŒá±á¬ááºážááá¯ááºáááºá
ááŸááºáá«áááºá á á¯á ááºážááá¯ááºáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááẠá¡áááºá¡ááœá±ážááŒáá·áº ááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯áá¯ááºáááºážá áẠááá¯á¡ááºáá«áááºá á¡ááŒááºá¡ááŸááºá¡á¬ážááŒáá·áº á¡áá®á¡áá»áŸ á¡áááºá¡ááœá±ážááŒáá·áºáá¬ážáá±á¬ ááŒá¶á·ááá¯ááºááœá²á·á ááºážááŸá¯ááᯠáá¶á·ááá¯ážáá±ážáááºáᯠáááááŒá¯áá«áááºá
á€áá»ááºážáááºáááºážááᯠáááºážá¡áá»áá¯ážáá»áá¯ážááŒáá·áº áá»á²á·ááœááºááá¯ááºáááºá
- áá áºáá¯á áááºáááá¯ááᯠá¡áá¯á¶ážááŒá¯á áá¯ááºáááºážááá¯ááºáᬠáá¯áá¹áááá±áááá¯ááºáᬠááá·áºáááºáá»ááºáá»á¬áž áá¡á±á¬ááºááŒááºáá«á á á¯á ááºážááŸá¯á¡áá»áááºá áá»ááºááœááºááá¯ááºáááºá
- domain-user-friendly áááºážáááºážááŒáá·áº configuration ááá¯ááá¯ááºá á¬ážááŒá¯ááẠDSL ááá¯á¡áá±á¬ááºá¡áááºáá±á¬áºááá¯ááºáááºá
- á¡ááá¯á¡áá»á±á¬ááºááœá²á·á ááºážáá¯á¶ áá»áááºááŸáááŸá¯áá»á¬ážááŒáá·áº áááºááŒáœáá±á¬ á¡áááºážá¡ááŒá áºá á®áá¶ááá·áºááœá²ááŸá¯á á¥ááá¬á¡á¬ážááŒáá·áºá áá»áœááºá¯ááºááá¯á·ááẠá¡á á¯á¡áá±ážááá¶áá«ááºáá»á¬ážááᯠáá»áááºááŸááá±á¬á¡áá«ááœáẠáá»áœááºá¯ááºááá¯á·ááẠ(á) á¡áááºážáááºááŒá¯ááŒááºáá¬ážáá±á¬ ááœá²á·á ááºážááŸá¯áá¯á¶á á¶ááᯠáááŸáááẠnode áá»á¬ážááᯠááá¯áá»ááºáá±áááºá (1) node info á¡áá áºáá»á¬ážááá¯áááºáá¶áááŸáááẠcluster manager á
ááŒá±ážáá°ážááá»á áá¬áž
áá®ááá¯á·á áºáá°ááŒááºážá¡ááœáẠá áááºá¡á¬ážáááºáááºáá²á· á¡ááŒá¶ááŒá¯áá»ááºáá±ážáá²á·á¡ááœáẠAndrey Saksonová Pavel Popová Anton Nehaev ááá¯á·ááᯠáá»á±ážáá°ážáááºááŒá±á¬ááºáž ááŒá±á¬ááá¯áá«áááºá
source: www.habr.com