Konpile sistèm distribiye konfigirasyon

Mwen ta renmen di ou yon mekanis enteresan pou travay ak konfigirasyon yon sistèm distribiye. Konfigirasyon an reprezante dirèkteman nan yon lang konpile (Scala) lè l sèvi avèk kalite ki an sekirite. Pòs sa a bay yon egzanp yon konfigirasyon konsa ak diskite sou divès aspè nan mete ann aplikasyon yon konfigirasyon konpile nan pwosesis devlopman an jeneral.

Konpile sistèm distribiye konfigirasyon

(angle)

Entwodiksyon

Bati yon sistèm distribiye serye vle di ke tout nœuds itilize konfigirasyon kòrèk la, senkronize ak lòt nœuds. Teknoloji DevOps (terraform, ansible oswa yon bagay tankou sa) anjeneral yo itilize otomatikman jenere fichye konfigirasyon (souvan espesifik pou chak ne). Nou ta renmen tou asire w ke tout nœuds kominike yo ap itilize pwotokòl ki idantik (ki gen ladan menm vèsyon an). Sinon, enkonpatibilite pral bati nan sistèm distribiye nou an. Nan mond JVM la, youn nan konsekans egzijans sa a se ke yo dwe itilize menm vèsyon bibliyotèk la ki gen mesaj pwotokòl yo toupatou.

E tès yon sistèm distribiye? Natirèlman, nou sipoze ke tout eleman yo gen tès inite anvan nou ale nan tès entegrasyon. (Nan lòd pou nou ekstrapolasyon rezilta tès yo nan ègzekutabl, nou dwe tou bay yon seri bibliyotèk ki idantik nan etap tès la ak nan ègzekutabl.)

Lè w ap travay ak tès entegrasyon, li souvan pi fasil pou itilize menm classpath toupatou sou tout nœuds. Tout sa nou dwe fè se asire ke yo itilize menm classpath la nan ègzekutabl. (Pandan ke li se antyèman posib yo kouri diferan nœuds ak diferan classpaths, sa ajoute konpleksite nan konfigirasyon an jeneral ak difikilte ak tès deplwaman ak entegrasyon.) Pou rezon pòs sa a, nou sipoze ke tout nœuds pral itilize menm classpath.

Konfigirasyon an evolye ak aplikasyon an. Nou itilize vèsyon pou idantifye diferan etap nan evolisyon pwogram lan. Li sanble lojik pou idantifye tou diferan vèsyon de configurations. Epi mete konfigirasyon an tèt li nan sistèm kontwòl vèsyon an. Si gen yon sèl konfigirasyon nan pwodiksyon, Lè sa a, nou ka tou senpleman itilize nimewo vèsyon an. Si nou itilize anpil ka pwodiksyon, Lè sa a, nou pral bezwen plizyè
branch konfigirasyon ak yon etikèt adisyonèl anplis vèsyon an (pa egzanp, non branch lan). Fason sa a nou ka byen klè idantifye konfigirasyon egzak la. Chak idantifyan konfigirasyon inikman koresponn ak yon konbinezon espesifik nan distribye nœuds, pò, resous ekstèn, ak vèsyon bibliyotèk. Pou rezon pòs sa a, nou pral asime ke gen yon sèl branch epi nou ka idantifye konfigirasyon an nan fason nòmal la lè l sèvi avèk twa nimewo separe pa yon pwen (1.2.3).

Nan anviwònman modèn, fichye konfigirasyon yo raman kreye manyèlman. Pi souvan yo pwodwi pandan deplwaman epi yo pa manyen ankò (konsa pa kraze anyen). Yon kesyon natirèl rive: poukisa nou toujou sèvi ak fòma tèks nan magazen konfigirasyon? Yon altènatif solid sanble se kapasite nan sèvi ak kòd regilye pou konfigirasyon ak benefisye de chèk konpile-tan.

Nan pòs sa a nou pral eksplore lide pou reprezante yon konfigirasyon andedan yon zafè konpile.

Konpile konfigirasyon

Seksyon sa a bay yon egzanp yon konfigirasyon konpile estatik. Yo aplike de sèvis senp - sèvis eko ak kliyan sèvis eko. Dapre de sèvis sa yo, de opsyon sistèm yo reyini. Nan yon opsyon, tou de sèvis yo sitiye sou menm ne, nan yon lòt opsyon - sou diferan ne.

Tipikman yon sistèm distribiye gen plizyè nœuds. Ou ka idantifye nœuds lè l sèvi avèk valè kèk kalite NodeId:

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

oswa

case class NodeId(hostName: String)

oswa menm

object Singleton
type NodeId = Singleton.type

Nœuds fè wòl divès kalite, yo kouri sèvis ak koneksyon TCP / HTTP ka etabli ant yo.

Pou dekri yon koneksyon TCP nou bezwen omwen yon nimewo pò. Nou ta renmen tou reflete pwotokòl ki sipòte sou pò sa a pou asire ke tou de kliyan an ak sèvè yo ap itilize menm pwotokòl la. Nou pral dekri koneksyon an lè l sèvi avèk klas sa a:

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

kote Port - jis yon nonb antye relatif Int endike seri valè akseptab yo:

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

Kalite rafine

Gade bibliyotèk rafine и mwen rapò. Nan ti bout tan, bibliyotèk la pèmèt ou ajoute kontrent nan kalite ke yo tcheke nan tan konpile. Nan ka sa a, valè nimewo pò valab yo se nonb antye relatif 16-bit. Pou yon konfigirasyon konpile, lè l sèvi avèk bibliyotèk la rafine pa obligatwa, men li amelyore kapasite konpilatè a pou tcheke konfigirasyon an.

Pou pwotokòl HTTP (REST), anplis nimewo pò a, nou ka bezwen tou chemen an nan sèvis la:

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

Kalite fantom

Pou idantifye pwotokòl la nan moman konpile, nou itilize yon paramèt kalite ki pa itilize nan klas la. Desizyon sa a se akòz lefèt ke nou pa sèvi ak yon egzanp pwotokòl nan ègzekutabl, men nou ta renmen konpilatè a tcheke konpatibilite pwotokòl. Lè nou espesifye pwotokòl la, nou pa pral kapab pase yon sèvis ki pa apwopriye kòm yon depandans.

Youn nan pwotokòl komen yo se API REST ak seri Json:

sealed trait JsonHttpRestProtocol[RequestMessage, ResponseMessage]

kote RequestMessage - Kalite demann, ResponseMessage - tip repons.
Natirèlman, nou ka itilize lòt deskripsyon pwotokòl ki bay presizyon nan deskripsyon nou mande.

Pou rezon pòs sa a, nou pral itilize yon vèsyon senplifye pwotokòl la:

sealed trait SimpleHttpGetRest[RequestMessage, ResponseMessage]

Isit la demann lan se yon fisèl ajoute nan url la ak repons lan se fisèl ki retounen nan kò a nan repons HTTP an.

Konfigirasyon sèvis la dekri pa non sèvis la, pò, ak depandans. Eleman sa yo ka reprezante nan Scala nan plizyè fason (pa egzanp, HList-s, kalite done aljebrik). Pou rezon pòs sa a, nou pral sèvi ak modèl gato a epi reprezante modil lè l sèvi avèk trait'ov. (Modèl gato a se pa yon eleman obligatwa nan apwòch sa a. Li se tou senpleman yon aplikasyon posib.)

Depandans ant sèvis yo ka reprezante kòm metòd ki retounen pò EndPointlòt nœuds yo:

  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)
  }

Pou kreye yon sèvis eko, tout sa ou bezwen se yon nimewo pò ak yon endikasyon ke pò a sipòte pwotokòl la eko. Nou ta ka pa presize yon pò espesifik, paske... karakteristik pèmèt ou deklare metòd san aplikasyon (metòd abstrè). Nan ka sa a, lè w ap kreye yon konfigirasyon konkrè, du a ta mande pou nou bay yon aplikasyon metòd abstrè a epi bay yon nimewo pò. Depi nou te aplike metòd la, lè nou kreye yon konfigirasyon espesifik, nou ka pa presize yon pò diferan. Valè default la pral itilize.

Nan konfigirasyon kliyan an nou deklare yon depandans sou sèvis la eko:

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

Depandans lan se nan menm kalite ak sèvis la ekspòte echoService. An patikilye, nan kliyan an eko nou mande pou menm pwotokòl la. Se poutèt sa, lè konekte de sèvis, nou ka asire w ke tout bagay ap travay kòrèkteman.

Aplikasyon sèvis yo

Yon fonksyon oblije kòmanse epi sispann sèvis la. (Kapasite pou sispann sèvis la enpòtan pou tès la.) Yon fwa ankò, gen plizyè opsyon pou mete ann aplikasyon yon karakteristik (pa egzanp, nou ta ka itilize kalite klas ki baze sou kalite konfigirasyon an). Pou rezon pòs sa a nou pral sèvi ak modèl gato a. Nou pral reprezante sèvis la lè l sèvi avèk yon klas cats.Resource, paske Klas sa a deja bay mwayen pou garanti san danje liberasyon resous yo nan ka ta gen pwoblèm. Pou jwenn yon resous, nou bezwen bay konfigirasyon ak yon kontèks ègzekutabl pare. Fonksyon demaraj sèvis la ka sanble sa a:

  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]
  }

kote

  • Config — kalite konfigirasyon pou sèvis sa a
  • AddressResolver - yon objè ègzekutabl ki pèmèt ou chèche konnen adrès lòt nœuds (gade anba a)

ak lòt kalite nan bibliyotèk la cats:

  • F[_] - kalite efè (nan ka ki pi senp la F[A] ta ka jis yon fonksyon () => A. Nan pòs sa a nou pral itilize cats.IO.)
  • Reader[A,B] - plis oswa mwens sinonim ak fonksyon A => B
  • cats.Resource - yon resous ki ka jwenn ak lage
  • Timer - revèy (pèmèt ou tonbe nan dòmi pou yon ti tan epi mezire entèval tan)
  • ContextShift - analòg ExecutionContext
  • Applicative — yon klas kalite efè ki pèmèt ou konbine efè endividyèl (prèske yon monad). Nan aplikasyon ki pi konplèks li sanble pi bon pou itilize Monad/ConcurrentEffect.

Sèvi ak siyati fonksyon sa a nou ka aplike plizyè sèvis. Pou egzanp, yon sèvis ki pa fè anyen:

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

(Cm. sous, kote lòt sèvis yo aplike - sèvis eko, kliyan eko
и kontwolè pou tout lavi.)

Yon ne se yon objè ki ka lanse plizyè sèvis (lansman yon chèn resous asire pa modèl gato a):

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

Tanpri sonje ke nou ap presize kalite egzak la nan konfigirasyon ki nesesè pou ne sa a. Si nou bliye presize youn nan kalite konfigirasyon yo mande pou yon sèvis patikilye, pral gen yon erè konpilasyon. Epitou, nou pa pral kapab kòmanse yon ne sof si nou bay kèk objè nan kalite ki apwopriye a ak tout done ki nesesè yo.

Rezolisyon non lame

Pou konekte ak yon lame aleka, nou bezwen yon adrès IP reyèl. Li posib ke adrès la pral vin konnen pita pase rès la nan konfigirasyon an. Se konsa, nou bezwen yon fonksyon ki kat ID ne a nan yon adrès:

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

Gen plizyè fason pou aplike fonksyon sa a:

  1. Si adrès yo vin konnen nou anvan deplwaman, Lè sa a, nou ka jenere kòd Scala ak
    adrès ak Lè sa a, kouri bati a. Sa a pral konpile epi kouri tès yo.
    Nan ka sa a, yo pral konnen fonksyon an statikman epi yo ka reprezante nan kòd kòm yon kat Map[NodeId, NodeAddress].
  2. Nan kèk ka, adrès aktyèl la se sèlman li te ye apre ne la te kòmanse.
    Nan ka sa a, nou ka aplike yon "sèvis dekouvèt" ki kouri anvan lòt nœuds ak tout nœuds pral anrejistre ak sèvis sa a epi mande adrès yo nan lòt nœuds.
  3. Si nou ka modifye /etc/hosts, Lè sa a, ou ka itilize non host predefini (tankou my-project-main-node и echo-backend) epi tou senpleman lyen non sa yo
    ak adrès IP pandan deplwaman.

Nan pòs sa a nou pa pral konsidere ka sa yo an plis detay. Pou nou
nan yon egzanp jwèt, tout nœuds pral gen menm adrès IP - 127.0.0.1.

Apre sa, nou konsidere de opsyon pou yon sistèm distribiye:

  1. Mete tout sèvis sou yon sèl ne.
  2. Ak hosting sèvis la eko ak kliyan eko sou nœuds diferan.

Konfigirasyon pou yon sèl ne:

Konfigirasyon sèl ne

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.
}

Objè a aplike konfigirasyon tou de kliyan an ak sèvè. Yon konfigirasyon tan-a-viv tou itilize pou ke apre entèval la lifetime mete fen nan pwogram nan. (Ctrl-C tou travay epi libere tout resous kòrèkteman.)

Menm seri konfigirasyon ak karakteristik aplikasyon yo ka itilize pou kreye yon sistèm ki gen ladann de nœuds separe:

De konfigirasyon ne

  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"
  }

Enpòtan! Remake kijan sèvis yo lye. Nou presize yon sèvis aplike pa yon sèl ne kòm yon aplikasyon metòd depandans yon lòt ne. Kalite depandans la tcheke pa du a, paske gen kalite pwotokòl la. Lè kouri, depandans la pral genyen ID kòrèk sib la. Mèsi a konplo sa a, nou presize nimewo pò a egzakteman yon fwa epi yo toujou garanti pou refere a pò ki kòrèk la.

Aplikasyon de nœuds sistèm

Pou konfigirasyon sa a, nou itilize menm aplikasyon sèvis yo san chanjman. Sèl diferans lan se ke nou kounye a gen de objè ki aplike diferan seri sèvis:

  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
  }

Premye ne a aplike sèvè a epi li sèlman bezwen konfigirasyon sèvè. Dezyèm ne aplike kliyan an epi sèvi ak yon pati diferan nan konfigirasyon an. Epitou tou de nœuds bezwen jesyon pou tout lavi. Ne sèvè a kouri endefini jiskaske li sispann SIGTERM'om, ak ne kliyan an fini apre kèk tan. Cm. aplikasyon lans.

Pwosesis devlopman jeneral

Ann wè ki jan apwòch konfigirasyon sa a afekte pwosesis devlopman an jeneral.

Konfigirasyon an pral konpile ansanm ak rès la nan kòd la epi yo pral pwodwi yon asosye (.jar). Li sanble gen sans yo mete konfigirasyon an nan yon asosye separe. Sa a se paske nou ka gen plizyè konfigirasyon ki baze sou menm kòd la. Ankò, li posib pou jenere zafè ki koresponn ak diferan branch konfigirasyon. Depandans sou vèsyon espesifik bibliyotèk yo sove ansanm ak konfigirasyon an, epi vèsyon sa yo sove pou tout tan chak fwa nou deside deplwaye vèsyon sa a nan konfigirasyon an.

Nenpòt chanjman konfigirasyon vin tounen yon chanjman kòd. Se poutèt sa, chak
chanjman an pral kouvri pa pwosesis asirans kalite nòmal la:

Tikè nan tracker ensèk -> PR -> revizyon -> rantre ak branch ki enpòtan ->
entegrasyon -> deplwaman

Konsekans prensipal yo nan aplikasyon yon konfigirasyon konpile yo se:

  1. Konfigirasyon an pral konsistan atravè tout nœuds nan sistèm distribiye a. Akòz lefèt ke tout nœuds resevwa menm konfigirasyon nan yon sèl sous.

  2. Li se pwoblèm chanje konfigirasyon an nan sèlman youn nan nœuds yo. Se poutèt sa, "drift konfigirasyon" se fasil.

  3. Li vin pi difisil pou fè ti chanjman nan konfigirasyon an.

  4. Pifò chanjman konfigirasyon yo pral fèt nan kad pwosesis devlopman an jeneral epi yo pral sijè a revize.

Èske mwen bezwen yon depo separe pou sere konfigirasyon pwodiksyon an? Konfigirasyon sa a ka genyen modpas ak lòt enfòmasyon sansib kote nou ta renmen mete restriksyon sou aksè. Ki baze sou sa a, li sanble gen sans pou estoke konfigirasyon final la nan yon depo separe. Ou ka divize konfigirasyon an an de pati—yon sèl ki gen paramèt konfigirasyon aksesib piblikman ak yon lòt ki gen paramèt ki genyen restriksyon. Sa a pral pèmèt pifò devlopè yo gen aksè a anviwònman komen. Separasyon sa a fasil pou reyalize lè l sèvi avèk karakteristik entèmedyè ki gen valè default.

Varyasyon posib

Ann eseye konpare konfigirasyon konpile a ak kèk altènativ komen:

  1. Fichye tèks sou machin nan sib.
  2. Magazen kle-valè santralize (etcd/zookeeper).
  3. Pwosesis konpozan ki ka rekonfigire/rekòmanse san rekòmanse pwosesis la.
  4. Estoke konfigirasyon deyò nan zafè ak kontwòl vèsyon.

Fichye tèks yo bay fleksibilite enpòtan an tèm de ti chanjman. Administratè sistèm lan ka konekte nan ne a aleka, fè chanjman nan dosye ki apwopriye yo epi rekòmanse sèvis la. Pou gwo sistèm, sepandan, fleksibilite sa yo ka pa dezirab. Chanjman ki fèt yo pa kite okenn tras nan lòt sistèm yo. Pa gen moun ki revize chanjman yo. Li difisil pou detèmine ki moun ki fè chanjman yo egzakteman ak pou ki rezon. Chanjman yo pa teste. Si sistèm nan distribye, Lè sa a, administratè a ka bliye fè chanjman ki koresponn lan sou lòt nœuds.

(Li ta dwe remake tou ke lè l sèvi avèk yon konfigirasyon konpile pa fèmen posibilite pou itilize dosye tèks nan tan kap vini an. Li pral ase yo ajoute yon analizeur ak validateur ki pwodui menm kalite ak pwodiksyon an. Config, epi ou ka itilize dosye tèks yo. Li imedyatman swiv ke konpleksite a nan yon sistèm ak yon konfigirasyon konpile se yon ti jan mwens pase konpleksite a nan yon sistèm lè l sèvi avèk dosye tèks, paske dosye tèks yo mande pou kòd adisyonèl.)

Yon magazen kle-valè santralize se yon bon mekanis pou distribye paramèt meta nan yon aplikasyon distribiye. Nou bezwen deside ki sa ki paramèt konfigirasyon ak sa ki jis done. Se pou nou gen yon fonksyon C => A => B, ak paramèt yo C raman chanjman, ak done A - souvan. Nan ka sa a nou ka di sa C - paramèt konfigirasyon, ak A - done. Li parèt ke paramèt konfigirasyon diferan de done yo ke yo jeneralman chanje mwens souvan pase done yo. Epitou, done anjeneral soti nan yon sous (ki soti nan itilizatè a), ak paramèt konfigirasyon soti nan yon lòt (soti nan administratè a sistèm).

Si raman chanje paramèt yo bezwen mete ajou san yo pa rekòmanse pwogram nan, Lè sa a, sa a ka souvan mennen nan konplikasyon nan pwogram nan, paske nou pral bezwen yon jan kanmenm delivre paramèt, magazen, analize ak tcheke, ak trete valè kòrèk. Se poutèt sa, nan pwen de vi nan diminye konpleksite nan pwogram nan, li fè sans diminye kantite paramèt ki ka chanje pandan operasyon pwogram nan (oswa pa sipòte paramèt sa yo ditou).

Pou rezon pòs sa a, nou pral fè diferans ant paramèt estatik ak dinamik. Si lojik sèvis la mande pou chanje paramèt pandan operasyon an nan pwogram nan, Lè sa a, nou pral rele paramèt sa yo dinamik. Sinon opsyon yo se estatik epi yo ka konfigirasyon lè l sèvi avèk konfigirasyon an konpile. Pou rekonfigirasyon dinamik, nou ka bezwen yon mekanis pou rekòmanse pati nan pwogram nan ak nouvo paramèt, menm jan ak fason pwosesis sistèm opere yo rekòmanse. (Nan opinyon nou, li rekòmande pou evite rekonfigirasyon an tan reyèl, paske sa ogmante konpleksite sistèm lan. Si sa posib, li pi bon pou itilize kapasite estanda OS yo pou rekòmanse pwosesis yo.)

Youn nan aspè enpòtan nan itilize konfigirasyon estatik ki fè moun konsidere rekonfigirasyon dinamik se tan li pran pou sistèm nan rdemare apre yon aktyalizasyon konfigirasyon (Dann). An reyalite, si nou bezwen fè chanjman nan konfigirasyon estatik la, nou pral oblije rekòmanse sistèm nan pou nouvo valè yo pran efè. Pwoblèm tan an varye nan severite pou diferan sistèm. Nan kèk ka, ou ka pwograme yon rdemare nan yon moman lè chaj la minim. Si ou bezwen bay sèvis kontinyèl, ou ka aplike AWS ELB koneksyon drenaj. An menm tan an, lè nou bezwen rdemare sistèm nan, nou lanse yon egzanp paralèl nan sistèm sa a, chanje balans lan nan li, epi tann pou koneksyon yo fin vye granmoun fini. Apre tout ansyen koneksyon yo fini, nou fèmen ansyen egzanp sistèm lan.

Se pou nou kounye a konsidere pwoblèm nan nan estoke konfigirasyon an andedan oswa deyò asosye a. Si nou estoke konfigirasyon an andedan yon zafè, Lè sa a, omwen nou te gen opòtinite pou verifye kòrèkteman nan konfigirasyon an pandan asanble a nan zafè a. Si konfigirasyon an se andeyò zafè kontwole a, li difisil pou swiv ki moun ki fè chanjman nan dosye sa a ak poukisa. Ki jan li enpòtan? Nan opinyon nou an, pou anpil sistèm pwodiksyon li enpòtan pou gen yon konfigirasyon ki estab ak-wo kalite.

Vèsyon an nan yon zafè pèmèt ou detèmine ki lè li te kreye, ki valè li genyen, ki fonksyon yo aktive / enfim, ak ki moun ki responsab pou nenpòt chanjman nan konfigirasyon an. Natirèlman, estoke konfigirasyon an andedan yon zafè mande pou kèk efò, kidonk ou bezwen pran yon desizyon enfòme.

Les ak inconvénients

Mwen ta renmen rete sou avantaj ak dezavantaj teknoloji yo pwopoze a.

Avantaj

Anba a se yon lis karakteristik prensipal yo nan yon konfigirasyon sistèm distribiye konpile:

  1. Tcheke konfigirasyon estatik. Pèmèt ou asire w ke
    konfigirasyon an kòrèk.
  2. Lang konfigirasyon rich. Tipikman, lòt metòd konfigirasyon yo limite a sibstitisyon varyab fisèl nan pi plis. Lè w ap itilize Scala, gen yon pakèt karakteristik lang ki disponib pou amelyore konfigirasyon w la. Pou egzanp nou ka itilize
    karakteristik pou valè default, lè l sèvi avèk objè nan paramèt gwoup, nou ka refere a vals te deklare sèlman yon fwa (SEK) nan sijè ki abòde lan. Ou ka enstansye nenpòt klas dirèkteman andedan konfigirasyon an (Seq, Map, klas koutim).
  3. DSL. Scala gen yon kantite karakteristik lang ki fè li pi fasil pou kreye yon DSL. Li posib pou pran avantaj de karakteristik sa yo epi aplike yon lang konfigirasyon ki pi pratik pou gwoup itilizatè yo sib, pou konfigirasyon an omwen lizib pa ekspè domèn. Espesyalis yo ka, pou egzanp, patisipe nan pwosesis revizyon konfigirasyon an.
  4. Entegrite ak synchrony ant nœuds. Youn nan avantaj ki genyen nan genyen konfigirasyon an nan yon sistèm distribye antye ki estoke nan yon sèl pwen se ke tout valè yo deklare egzakteman yon fwa ak Lè sa a, reyitilize nenpòt kote yo bezwen. Sèvi ak kalite fantom pou deklare pò asire ke nœuds yo ap itilize pwotokòl konpatib nan tout konfigirasyon sistèm kòrèk. Gen depandans obligatwa klè ant nœuds asire ke tout sèvis yo konekte.
  5. Chanjman kalite siperyè. Fè chanjman nan konfigirasyon an lè l sèvi avèk yon pwosesis devlopman komen fè li posib reyalize estanda kalite siperyè pou konfigirasyon an tou.
  6. Mizajou konfigirasyon similtane. Otomatik deplwaman sistèm apre chanjman konfigirasyon asire ke tout nœuds yo mete ajou.
  7. Senplifye aplikasyon an. Aplikasyon an pa bezwen analiz, konfigirasyon tcheke, oswa manyen valè ki pa kòrèk. Sa a diminye konpleksite aplikasyon an. (Gen kèk nan konpleksite nan konfigirasyon obsève nan egzanp nou an se pa yon atribi nan konfigirasyon an konpile, men se sèlman yon desizyon konsyan kondwi pa dezi a bay pi gwo sekirite kalite.) Li se byen fasil pou retounen nan konfigirasyon abityèl la - jis aplike ki manke a. pati. Se poutèt sa, ou ka, pou egzanp, kòmanse ak yon konfigirasyon konpile, ranvwaye aplikasyon an nan pati nesesè jiskaske li se reyèlman nesesè.
  8. Konfigirasyon verifye. Depi chanjman konfigirasyon swiv sò abityèl nenpòt lòt chanjman, pwodiksyon an nou jwenn se yon zafè ak yon vèsyon inik. Sa a pèmèt nou, pou egzanp, retounen nan yon vèsyon anvan konfigirasyon an si sa nesesè. Nou ka menm itilize konfigirasyon an soti nan yon ane de sa ak sistèm nan ap travay egzakteman menm jan an. Yon konfigirasyon ki estab amelyore previzibilite ak fyab nan yon sistèm distribiye. Depi konfigirasyon an fiks nan etap konpilasyon an, li se byen difisil pou fo li nan pwodiksyon an.
  9. Modularite. Fondasyon yo pwopoze a se modilè ak modil yo ka konbine nan diferan fason yo kreye diferan sistèm. An patikilye, ou ka konfigirasyon sistèm nan kouri sou yon sèl ne nan yon reyalizasyon, ak sou plizyè ne nan yon lòt. Ou ka kreye plizyè konfigirasyon pou ka pwodiksyon sistèm lan.
  10. Tès. Lè w ranplase sèvis endividyèl yo ak mok objè, ou ka jwenn plizyè vèsyon nan sistèm nan ki bon pou tès.
  11. Tès entegrasyon. Èske w gen yon sèl konfigirasyon pou tout sistèm distribye a fè li posib pou kouri tout eleman nan yon anviwònman kontwole kòm yon pati nan tès entegrasyon. Li fasil pou imite, pou egzanp, yon sitiyasyon kote kèk nœuds vin aksesib.

Dezavantaj ak limit

Konpile konfigirasyon diferan de lòt apwòch konfigirasyon epi li ka pa apwopriye pou kèk aplikasyon. Anba a gen kèk dezavantaj:

  1. Konfigirasyon estatik. Pafwa ou bezwen byen vit korije konfigirasyon an nan pwodiksyon, contournement tout mekanis pwoteksyon. Avèk apwòch sa a li ka pi difisil. Omwen, konpilasyon ak deplwaman otomatik yo ap toujou obligatwa. Sa a se tou de yon karakteristik itil nan apwòch la ak yon dezavantaj nan kèk ka.
  2. Jenerasyon konfigirasyon. Nan ka se yon zouti otomatik ki pwodui fichye konfigirasyon an, yo ka mande plis efò pou entegre script bati a.
  3. Zouti. Kounye a, sèvis piblik ak teknik ki fèt pou travay ak konfigirasyon yo baze sou dosye tèks. Se pa tout sèvis piblik/teknik sa yo ap disponib nan yon konfigirasyon konpile.
  4. Yon chanjman nan atitid nesesè. Devlopè ak DevOps yo abitye dosye tèks yo. Lide a anpil nan konpile yon konfigirasyon ka yon ti jan inatandi ak etranj ak lakòz rejè.
  5. Yon pwosesis devlopman kalite siperyè obligatwa. Yo nan lòd yo alèz itilize konfigirasyon an konpile, automatisation konplè nan pwosesis la nan bati ak deplwaye aplikasyon an (CI/CD) nesesè. Sinon li pral byen konvenyan.

Se pou nou rete tou sou yon kantite limit nan egzanp konsidere a ki pa gen rapò ak lide nan yon konfigirasyon konpile:

  1. Si nou bay enfòmasyon konfigirasyon ki pa nesesè ki pa itilize pa ne a, Lè sa a, du a pa pral ede nou detekte aplikasyon ki manke a. Pwoblèm sa a ka rezoud pa abandone modèl gato a epi sèvi ak kalite ki pi rijid, pou egzanp, HList oswa kalite done aljebrik (klas ka) pou reprezante konfigirasyon.
  2. Gen liy nan dosye konfigirasyon an ki pa gen rapò ak konfigirasyon an li menm: (package, import,deklarasyon objè; override def's pou paramèt ki gen valè default). Sa a ka pasyèlman evite si ou aplike pwòp DSL ou. Anplis de sa, lòt kalite konfigirasyon (pa egzanp, XML) tou enpoze sèten restriksyon sou estrikti nan dosye.
  3. Pou rezon pòs sa a, nou pa konsidere rekonfigirasyon dinamik nan yon gwoup nœuds menm jan an.

Konklizyon

Nan pòs sa a, nou eksplore lide pou reprezante konfigirasyon nan kòd sous lè l sèvi avèk kapasite avanse nan sistèm nan kalite Scala. Apwòch sa a ka itilize nan divès aplikasyon kòm yon ranplasman pou metòd konfigirasyon tradisyonèl ki baze sou xml oswa dosye tèks. Menmsi egzanp nou an aplike nan Scala, menm lide yo ka transfere nan lòt lang konpile (tankou Kotlin, C#, Swift, ...). Ou ka eseye apwòch sa a nan youn nan pwojè sa yo, epi, si li pa travay, ale nan dosye tèks la, ajoute pati ki manke yo.

Natirèlman, yon konfigirasyon konpile mande pou yon pwosesis devlopman kalite siperyè. An retou, se bon jan kalite segondè ak fyab nan konfigirasyon asire.

Apwòch konsidere a ka elaji:

  1. Ou ka itilize makro pou fè chèk tan konpile.
  2. Ou ka aplike yon DSL pou prezante konfigirasyon an nan yon fason ki aksesib pou itilizatè fen yo.
  3. Ou ka aplike jesyon resous dinamik ak ajisteman konfigirasyon otomatik. Pa egzanp, chanje kantite nœuds nan yon grap mande pou (1) chak nœuds resevwa yon konfigirasyon yon ti kras diferan; (2) manadjè gwoup la te resevwa enfòmasyon sou nouvo nœuds.

Remèsiman

Mwen ta renmen remèsye Andrei Saksonov, Pavel Popov ak Anton Nekhaev pou kritik konstriktif yo sou bouyon atik la.

Sous: www.habr.com

Add nouvo kòmantè