Compilable configuration ntawm ib tug faib system

Nyob rau hauv no ncej peb xav qhia ib tug nthuav txoj kev ntawm kev soj ntsuam nrog configuration ntawm ib tug faib system.
Cov kev teeb tsa tau sawv cev ncaj qha hauv Scala lus hauv hom kev nyab xeeb. Ib qho piv txwv siv tau piav qhia hauv cov ntsiab lus. Ntau yam ntawm cov lus pom zoo tau tham txog, suav nrog kev cuam tshuam rau tag nrho cov txheej txheem kev txhim kho.

Compilable configuration ntawm ib tug faib system

(nyob rau hauv Russia)

Introduction

Kev tsim kom muaj zog faib tshuab xav tau kev siv kom raug thiab sib koom ua ke ntawm txhua qhov nodes. Ib qho kev daws teeb meem yog siv cov lus piav qhia kev xa tawm (terraform, ansible lossis ib yam dab tsi zoo ib yam) thiab tau tsim cov ntaub ntawv teeb tsa (feem ntau - mob siab rau txhua qhov ntawm / lub luag haujlwm). Peb kuj yuav xav siv tib cov kev cai ntawm tib lub versions ntawm txhua qhov kev sib txuas lus (tsis li ntawd peb yuav ntsib teeb meem tsis sib haum). Hauv JVM ntiaj teb no txhais tau hais tias tsawg kawg lub tsev qiv ntawv xa xov yuav tsum yog tib yam ntawm txhua qhov kev sib txuas lus.

Yuav ua li cas rau kev ntsuam xyuas qhov system? Tau kawg, peb yuav tsum muaj kev sim ntsuas rau txhua yam khoom ua ntej tuaj rau kev xeem sib xyaw. Txhawm rau kom muaj peev xwm ntxiv cov txiaj ntsig kev xeem ntawm lub sijhawm ua haujlwm, peb yuav tsum ua kom paub tseeb tias cov qauv ntawm txhua lub tsev qiv ntawv tau khaws cia zoo ib yam nyob rau hauv ob qho tib si runtime thiab kuaj ib puag ncig.

Thaum khiav cov kev xeem sib xyaw ua ke, nws feem ntau yooj yim dua kom muaj tib lub chav kawm ntawm txhua qhov nodes. Peb tsuas yog yuav tsum tau ua kom paub tseeb tias tib chav kawm yog siv rau kev xa tawm. (Nws tuaj yeem siv cov classpaths sib txawv ntawm cov nodes sib txawv, tab sis nws nyuaj dua los sawv cev rau qhov kev teeb tsa no thiab siv nws kom raug.) Yog li txhawm rau ua kom tej yam yooj yim peb tsuas yog xav txog cov classpaths zoo tib yam ntawm txhua qhov nodes.

Configuration zoo li evolve ua ke nrog cov software. Peb feem ntau siv versions los txheeb xyuas ntau yam
theem ntawm software evolution. Nws zoo nkaus li tsim nyog los npog kev teeb tsa raws li kev tswj hwm version thiab txheeb xyuas cov kev teeb tsa sib txawv nrog qee cov ntawv sau. Yog tias tsuas muaj ib qho kev teeb tsa hauv kev tsim khoom, peb tuaj yeem siv ib qho version ua tus cim. Qee zaum peb yuav muaj ntau qhov chaw tsim khoom. Thiab rau txhua qhov chaw peb yuav xav tau ib ceg ntawm kev teeb tsa. Yog li configurations tej zaum yuav tau sau npe nrog ceg thiab version kom paub txog txawv configurations. Txhua ceg daim ntawv lo thiab version sib raug mus rau ib qho kev sib xyaw ua ke ntawm cov kab sib faib, cov chaw nres nkoj, cov peev txheej sab nraud, cov tsev qiv ntawv classpath ntawm txhua qhov. Ntawm no peb tsuas yog npog ib ceg thiab txheeb xyuas cov teeb tsa los ntawm peb feem kaum version (1.2.3), tib yam li lwm yam khoom qub.

Nyob rau hauv ib puag ncig niaj hnub configuration ntaub ntawv tsis hloov manually lawm. Feem ntau peb tsim
config cov ntaub ntawv thaum lub sij hawm xa mus thiab yeej tsis kov lawv tom qab ntawd. Yog li ib tus tuaj yeem nug yog vim li cas peb tseem siv cov ntawv nyeem rau cov ntaub ntawv teeb tsa? Ib qho kev xaiv siv tau yog los tso cov kev teeb tsa hauv ib chav sib sau ua ke thiab tau txais txiaj ntsig los ntawm kev suav sau lub sij hawm configuration validation.

Hauv cov ntawv tshaj tawm no peb yuav tshuaj xyuas lub tswv yim ntawm kev khaws cov kev teeb tsa hauv cov khoom sib sau ua ke.

Compilable configuration

Hauv seem no peb yuav tham txog ib qho piv txwv ntawm kev teeb tsa zoo li qub. Ob qhov kev pabcuam yooj yim - ncha kev pabcuam thiab cov neeg siv khoom ntawm kev pabcuam ncha tau raug teeb tsa thiab siv. Tom qab ntawd ob qhov sib txawv faib tshuab nrog ob qho kev pabcuam yog instantiated. Ib qho yog rau ib qho kev teeb tsa ib leeg thiab ib qho rau ob qhov kev teeb tsa.

Ib tug raug faib system muaj ob peb nodes. Cov nodes tuaj yeem txheeb xyuas tau siv qee yam:

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

los yog cia li

case class NodeId(hostName: String)

los yog txawm

object Singleton
type NodeId = Singleton.type

Cov nodes ua ntau lub luag haujlwm, khiav qee qhov kev pabcuam thiab yuav tsum muaj peev xwm sib txuas lus nrog lwm cov nodes los ntawm kev sib txuas ntawm TCP / HTTP.

Rau TCP kev txuas yam tsawg kawg yuav tsum muaj tus lej chaw nres nkoj. Peb kuj xav kom paub tseeb tias cov neeg siv khoom thiab cov neeg rau zaub mov tham tib txoj cai. Txhawm rau ua qauv kev sib txuas ntawm cov nodes cia peb tshaj tawm cov hauv qab no:

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

qhov twg Port tsuas yog ib Int nyob rau hauv qhov chaw tso cai:

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

Refined hom

saib ua kom zoo tsev qiv ntawv. Nyob rau hauv luv luv, nws tso cai rau ntxiv compile lub sij hawm txwv rau lwm hom. Hauv qhov no Int tsuas yog tso cai kom muaj 16-ntsis qhov tseem ceeb uas tuaj yeem sawv cev tus lej chaw nres nkoj. Tsis muaj qhov yuav tsum tau siv lub tsev qiv ntawv no rau qhov kev teeb tsa no. Nws cia li zoo li haum zoo heev.

Rau HTTP (REST) ​​​​peb kuj yuav xav tau txoj hauv kev ntawm kev pabcuam:

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

Phantom hom

Txhawm rau txheeb xyuas cov txheej txheem thaum muab tso ua ke peb siv Scala feature ntawm kev tshaj tawm hom kev sib cav Protocol uas tsis siv hauv chav kawm. Nws yog ib tug thiaj li hu ua yam phantom. Thaum runtime peb tsis tshua xav tau ib qho piv txwv ntawm tus txheej txheem tus cim, yog vim li cas peb tsis khaws nws. Thaum muab tso ua ke no hom phantom muab ntxiv yam kev nyab xeeb. Peb tsis tuaj yeem hla qhov chaw nres nkoj nrog cov txheej txheem tsis raug.

Ib qho ntawm feem ntau siv raws tu qauv yog REST API nrog Json serialization:

sealed trait JsonHttpRestProtocol[RequestMessage, ResponseMessage]

qhov twg RequestMessage yog lub hauv paus hom lus uas tus neeg siv yuav xa mus rau server thiab ResponseMessage yog cov lus teb los ntawm server. Tau kawg, peb tuaj yeem tsim lwm cov txheej txheem piav qhia uas qhia meej txog kev sib txuas lus nrog qhov xav tau qhov tseeb.

Rau lub hom phiaj ntawm cov ntawv tshaj tawm no peb yuav siv qhov yooj yim version ntawm cov txheej txheem:

sealed trait SimpleHttpGetRest[RequestMessage, ResponseMessage]

Nyob rau hauv cov txheej txheem thov cov lus no yog ntxiv rau url thiab cov lus teb rov qab los ua txoj hlua dawb.

Ib qho kev pabcuam kev pabcuam tuaj yeem piav qhia los ntawm lub npe pabcuam, sau cov chaw nres nkoj thiab qee qhov kev vam khom. Muaj ob peb txoj hauv kev los sawv cev tag nrho cov ntsiab lus hauv Scala (piv txwv li, HList, algebraic data types). Rau lub hom phiaj ntawm tsab xov xwm no peb yuav siv Cake Pattern thiab sawv cev rau cov khoom sib txuas (modules) ua qhov zoo. (Cov qauv ncuav mog qab zib tsis yog qhov yuav tsum tau ua rau qhov kev sib sau ua ke no. Nws tsuas yog ib qho ua tau raws li lub tswv yim.)

Dependencies tuaj yeem sawv cev siv Cake Pattern raws li qhov kawg ntawm lwm cov nodes:

  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 kev pabcuam tsuas yog xav tau qhov chaw nres nkoj teeb tsa. Thiab peb tshaj tawm tias qhov chaw nres nkoj no txhawb nqa ncha raws tu qauv. Nco ntsoov tias peb tsis tas yuav qhia qhov chaw nres nkoj tshwj xeeb rau lub sijhawm no, vim tias qhov kev zoo nkauj tso cai rau kev tshaj tawm txog kev paub daws teeb meem. Yog tias peb siv cov kev paub daws teeb meem, compiler yuav xav tau kev siv hauv qhov piv txwv teeb tsa. Ntawm no peb tau muab qhov kev siv (8081) thiab nws yuav raug siv los ua tus nqi qub yog tias peb hla nws hauv kev teeb tsa pob zeb.

Peb tuaj yeem tshaj tawm qhov kev vam khom nyob rau hauv kev teeb tsa ntawm tus neeg siv khoom siv ncho:

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

Dependency muaj tib yam li cov echoService. Tshwj xeeb, nws xav tau tib txoj cai. Yog li, peb tuaj yeem paub tseeb tias yog tias peb txuas ob qhov kev cia siab no lawv yuav ua haujlwm raug.

Kev siv cov kev pabcuam

Ib qho kev pabcuam xav tau kev ua haujlwm los pib thiab kaw kom zoo. (Lub peev xwm kaw qhov kev pabcuam yog qhov tseem ceeb rau kev sim.) Ib zaug ntxiv, muaj qee qhov kev xaiv ntawm kev qhia txog cov haujlwm no rau ib qho kev teeb tsa (piv txwv li, peb tuaj yeem siv hom chav kawm). Rau cov ncej no peb mam li siv ncuav mog qab zib qauv dua. Peb tuaj yeem sawv cev rau kev pabcuam siv cats.Resource uas twb muab bracketing thiab kev tso tawm. Txhawm rau kom tau txais cov peev txheej peb yuav tsum muab cov kev teeb tsa thiab qee lub sijhawm ua haujlwm. Yog li qhov kev pabcuam pib ua haujlwm yuav zoo li:

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

qhov twg

  • Config - hom kev teeb tsa uas xav tau los ntawm qhov kev pabcuam no pib
  • AddressResolver - cov khoom siv sijhawm ua haujlwm uas muaj peev xwm tau txais qhov chaw nyob ntawm lwm cov nodes (kom nyeem kom paub meej).

lwm hom los ntawm cats:

  • F[_] - hom nyhuv (hauv qhov yooj yim tshaj plaws F[A] tuaj yeem yog () => A. Hauv tsab ntawv no peb yuav siv cats.IO.)
  • Reader[A,B] - yog ntau dua los yog tsawg dua lub ntsiab lus rau kev ua haujlwm A => B
  • cats.Resource - muaj txoj hauv kev kom tau txais thiab tso tawm
  • Timer - tso cai rau pw / ntsuas lub sijhawm
  • ContextShift - analog ntawm ExecutionContext
  • Applicative - qhwv ntawm kev ua haujlwm hauv cov txiaj ntsig (yuav luag ib qho monad) (peb zaum kawg hloov nws nrog lwm yam)

Siv qhov interface no peb tuaj yeem siv qee qhov kev pabcuam. Piv txwv li, ib qho kev pabcuam uas tsis muaj dab tsi:

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

(Saib Qhov chaws code rau kev siv lwm yam kev pabcuam - kev pabcuam,
echo tus neeg siv khoom thiab cov tswj lub neej.)

Ib lub node yog ib yam khoom uas khiav ob peb cov kev pab cuam (pib ib txoj saw ntawm kev pab yog enabled los ntawm ncuav mog qab zib qauv):

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

Nco ntsoov tias hauv node peb qhia meej hom kev teeb tsa uas xav tau los ntawm node. Compiler yuav tsis cia peb tsim cov khoom (Cake) nrog hom tsis txaus, vim tias txhua qhov kev pabcuam zoo tshaj tawm qhov txwv ntawm Config hom. Tsis tas li ntawd peb yuav tsis tuaj yeem pib node yam tsis muaj kev teeb tsa tiav.

Node chaw nyob daws teeb meem

Txhawm rau tsim kev sib txuas peb xav tau qhov chaw nyob tiag tiag rau txhua qhov ntawm. Tej zaum nws yuav paub tom qab lwm qhov chaw ntawm kev teeb tsa. Li no, peb xav tau ib txoj hauv kev los muab ib daim ntawv qhia ntawm node id thiab nws qhov chaw nyob. Daim ntawv qhia no yog ib txoj haujlwm:

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

Muaj ob peb txoj hauv kev los siv cov haujlwm no.

  1. Yog tias peb paub qhov chaw nyob tiag tiag ua ntej xa mus, thaum lub sijhawm node hosts instantiation, tom qab ntawd peb tuaj yeem tsim Scala code nrog cov chaw nyob tiag tiag thiab khiav qhov tsim tom qab (uas ua tiav cov sijhawm kuaj xyuas thiab tom qab ntawd sau cov ntawv xeem sib xyaw). Nyob rau hauv cov ntaub ntawv no peb daim ntawv qhia muaj nuj nqi yog paub statically thiab yuav ua tau yooj yim rau tej yam zoo li a Map[NodeId, NodeAddress].
  2. Qee lub sij hawm peb tau txais qhov chaw nyob tsuas yog tom qab ntawd thaum lub node pib tiag tiag, lossis peb tsis muaj qhov chaw nyob ntawm nodes uas tseem tsis tau pib. Nyob rau hauv rooj plaub no peb yuav muaj ib qho kev tshawb nrhiav uas tau pib ua ntej tag nrho lwm cov nodes thiab txhua lub node yuav tshaj tawm nws qhov chaw nyob hauv qhov kev pabcuam ntawd thiab sau npe rau kev vam khom.
  3. Yog peb hloov tau /etc/hosts, peb tuaj yeem siv cov npe tswv tsev ua ntej (xws li my-project-main-node thiab echo-backend) thiab tsuas yog koom nrog lub npe no nrog ip chaw nyob ntawm lub sijhawm xa tawm.

Hauv tsab xov xwm no peb tsis hais txog cov xwm txheej no hauv cov ntsiab lus ntxiv. Qhov tseeb hauv peb cov khoom ua si piv txwv tag nrho cov nodes yuav muaj tib qhov chaw nyob IP - 127.0.0.1.

Hauv tsab xov xwm no peb yuav xav txog ob qhov kev faib tawm qhov system:

  1. Ib leeg layout, qhov twg tag nrho cov kev pab cuam muab tso rau ntawm ib leeg.
  2. Ob qhov kev teeb tsa, qhov kev pabcuam thiab cov neeg siv khoom nyob ntawm qhov sib txawv.

Configuration rau a ib node layout yog raws li nram no:

Ib leeg node configuration

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

Ntawm no peb tsim ib qho kev teeb tsa uas txuas ntxiv ob qho tib si server thiab cov neeg siv khoom teeb tsa. Tsis tas li ntawd peb teeb tsa lub voj voog lub neej tswj uas feem ntau yuav txiav cov neeg siv khoom thiab cov neeg rau zaub mov tom qab lifetime lub caij hla dhau.

Tib txheej kev pabcuam kev siv thiab kev teeb tsa tuaj yeem siv los tsim cov txheej txheem kev teeb tsa nrog ob qhov sib cais. Peb tsuas yog yuav tsum tau tsim ob cais node configs nrog cov kev pabcuam tsim nyog:

Ob lub nodes configuration

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

Saib seb peb qhia qhov kev vam meej li cas. Peb hais txog lwm qhov ntawm qhov muab kev pabcuam raws li kev vam khom ntawm cov node tam sim no. Hom kev vam khom raug tshuaj xyuas vim tias nws muaj hom phantom uas piav txog cov txheej txheem. Thiab ntawm runtime peb yuav muaj qhov tseeb node ID. Qhov no yog ib qho tseem ceeb ntawm cov txheej txheem kev teeb tsa. Nws muab peb lub peev xwm los teeb tsa chaw nres nkoj ib zaug thiab xyuas kom meej tias peb tau xa mus rau qhov chaw nres nkoj raug.

Ob qhov nodes kev siv

Rau qhov kev teeb tsa no peb siv raws nraim tib yam kev pabcuam. Tsis muaj kev hloov pauv kiag li. Txawm li cas los xij, peb tsim ob qhov sib txawv ntawm qhov kev siv uas muaj cov kev pabcuam sib txawv:

  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
  }

Thawj node siv server thiab nws tsuas yog xav tau server sab config. Qhov thib ob node siv cov neeg siv khoom thiab xav tau lwm qhov ntawm config. Ob lub nodes xav tau qee qhov kev qhia lub neej. Rau lub hom phiaj ntawm no ncej kev pab cuam node yuav muaj infinite lifetime uas yuav raug txiav siv SIGTERM, thaum tus neeg siv echo yuav xaus tom qab lub sijhawm teem sijhawm kawg. Saib cov pib daim ntawv thov kom paub meej.

Txheej txheem kev loj hlob

Cia wb mus saib yuav ua li cas txoj kev no hloov txoj kev uas peb ua hauj lwm nrog configuration.

Lub configuration raws li code yuav muab tso ua ke thiab tsim ib tug artifact. Nws zoo nkaus li tsim nyog los cais cov duab kos duab los ntawm lwm cov khoom kos duab kos duab. Feem ntau peb tuaj yeem muaj ntau qhov kev teeb tsa ntawm tib lub hauv paus code. Thiab ntawm chav kawm, peb muaj peev xwm muaj ntau yam versions ntawm ntau yam configuration ceg. Hauv kev teeb tsa peb tuaj yeem xaiv cov ntawv tshwj xeeb ntawm cov tsev qiv ntawv thiab qhov no yuav nyob tas li thaum twg peb siv qhov kev teeb tsa no.

Ib tug configuration hloov ua code hloov. Yog li nws yuav tsum tau them los ntawm tib txheej txheem kev lees paub zoo:

Daim pib -> PR -> tshuaj xyuas -> sib koom ua ke -> kev sib koom ua ke tsis tu ncua -> kev xa mus tas li

Muaj cov txiaj ntsig hauv qab no ntawm txoj hauv kev:

  1. Lub configuration yog coherent rau ib qho system qhov piv txwv. Nws zoo nkaus li tias tsis muaj txoj hauv kev kom muaj kev sib txuas tsis raug ntawm cov nodes.
  2. Nws tsis yooj yim los hloov kev teeb tsa hauv ib qho xwb. Nws zoo nkaus li tsis tsim nyog nkag mus thiab hloov qee cov ntawv nyeem. Yog li configuration drift ua tau tsawg dua.
  3. Kev hloov pauv me me tsis yooj yim ua.
  4. Feem ntau ntawm cov kev hloov pauv yuav ua raws li tib txoj kev txhim kho, thiab nws yuav dhau qee qhov kev tshuaj xyuas.

Peb puas xav tau ib lub repository cais rau kev tsim khoom? Cov txheej txheem tsim khoom yuav muaj cov ntaub ntawv rhiab heev uas peb xav kom tsis txhob ncav cuag ntau tus neeg. Yog li nws yuav tsim nyog khaws ib qho chaw khaws cia cais nrog kev txwv tsis pub nkag uas yuav muaj cov txheej txheem tsim khoom. Peb tuaj yeem faib cov kev teeb tsa ua ob ntu - ib qho uas muaj qhov qhib tsis tau ntau lawm thiab ib qho uas muaj qhov zais cia ntawm kev teeb tsa. Qhov no yuav ua rau kev nkag mus rau feem ntau ntawm cov neeg tsim khoom mus rau feem ntau ntawm cov kev txwv thaum txwv kev nkag mus rau cov khoom rhiab heev. Nws yog ib qho yooj yim los ua kom tiav qhov no siv cov yam ntxwv nruab nrab nrog cov nqi tsis raug.

variations

Cia peb pom qhov zoo thiab qhov tsis zoo ntawm txoj hauv kev tau muab piv rau lwm cov txheej txheem tswj kev teeb tsa.

Ua ntej tshaj plaws, peb yuav sau ob peb txoj hauv kev rau qhov sib txawv ntawm txoj kev npaj los ntawm kev teeb tsa:

  1. Cov ntawv nyeem ntawm lub hom phiaj tshuab.
  2. Centralized tseem ceeb-tus nqi cia (xws li etcd/zookeeper).
  3. Subprocess Cheebtsam uas yuav reconfigured/restarted yam tsis muaj restarting txheej txheem.
  4. Configuration sab nraum artifact thiab version tswj.

Cov ntawv nyeem muab qee qhov yooj yim ntawm kev kho ad-hoc. Tus thawj tswj hwm lub cev tuaj yeem nkag mus rau lub hom phiaj node, hloov pauv thiab tsuas yog rov pib qhov kev pabcuam. Qhov no yuav tsis zoo rau cov tshuab loj dua. Tsis muaj ib yam dab tsi nyob hauv qab qhov kev hloov pauv. Qhov kev hloov no tsis raug tshuaj xyuas los ntawm lwm ob lub qhov muag. Tej zaum nws yuav nyuaj kom paub seb dab tsi tau ua rau muaj kev hloov pauv. Nws tsis tau sim. Los ntawm kev faib tawm qhov kev xav ib tus thawj coj tuaj yeem tsuas tsis nco qab hloov kho cov teeb tsa hauv ib qho ntawm lwm cov nodes.

(Btw, yog tias thaum kawg yuav muaj qhov xav tau pib siv cov ntawv teeb tsa cov ntaub ntawv, peb tsuas yog yuav tsum tau ntxiv parser + validator uas tuaj yeem tsim tau tib yam. Config hom thiab qhov ntawd yuav txaus los pib siv cov ntawv teeb tsa. Qhov no kuj qhia tau hais tias qhov nyuaj ntawm compile-time configuration yog me me uas qhov nyuaj ntawm cov ntawv nyeem raws li configs, vim hais tias nyob rau hauv cov ntawv nyeem-raws li version peb xav tau ib co ntxiv code.)

Centralized qhov tseem ceeb-tus nqi cia yog ib qho zoo rau kev faib cov ntawv thov meta tsis. Ntawm no peb yuav tsum xav txog dab tsi peb xav tias yog configuration values ​​thiab dab tsi yog cov ntaub ntawv xwb. Muab ib txoj haujlwm C => A => B peb feem ntau hu tsis tshua hloov qhov tseem ceeb C "configuration", thaum nquag hloov cov ntaub ntawv A - tsuas yog sau cov ntaub ntawv. Configuration yuav tsum tau muab rau cov haujlwm ua ntej tshaj cov ntaub ntawv A. Muab lub tswv yim no peb tuaj yeem hais tias nws xav tau ntau zaus ntawm kev hloov pauv dab tsi tuaj yeem siv los txheeb xyuas cov ntaub ntawv teeb tsa los ntawm cov ntaub ntawv xwb. Tsis tas li cov ntaub ntawv feem ntau yog los ntawm ib qhov chaw (neeg siv) thiab kev teeb tsa los ntawm lwm qhov chaw (admin). Kev cuam tshuam nrog cov kev txwv uas tuaj yeem hloov pauv tom qab pib txheej txheem ua rau muaj qhov nce ntawm daim ntawv thov nyuaj. Rau cov kev txwv no peb yuav tsum tau ua raws lawv cov txheej txheem xa khoom, txheeb xyuas thiab siv tau, tuav cov nqi tsis raug. Li no, txhawm rau txo qhov kev ua haujlwm nyuaj, peb yuav zoo dua txo tus lej ntawm qhov tsis tuaj yeem hloov pauv thaum lub sijhawm ua haujlwm (lossis txawm tias tshem tawm lawv tag nrho).

Los ntawm qhov kev xav ntawm cov ncej no peb yuav tsum ua kom muaj qhov sib txawv ntawm qhov tsis zoo li qub thiab dynamic. Yog tias kev pabcuam logic xav tau qhov tsis tshua muaj kev hloov pauv ntawm qee qhov tsis sib xws ntawm lub sijhawm ua haujlwm, peb tuaj yeem hu rau lawv qhov tsis muaj zog. Txwv tsis pub lawv yog cov zoo li qub thiab tuaj yeem teeb tsa siv qhov kev xav tau. Rau dynamic reconfiguration lwm txoj kev yuav xav tau. Piv txwv li, qee qhov ntawm lub kaw lus yuav rov pib dua nrog cov kev teeb tsa tshiab tsis zoo ib yam li rov pib dua cov txheej txheem cais ntawm ib qho kev faib tawm.
(Kuv lub tswv yim txo hwj chim yog kom tsis txhob runtime reconfiguration vim hais tias nws nce complexity ntawm lub system.
Tej zaum nws yuav yooj yim dua rau cia siab rau OS kev txhawb nqa ntawm kev rov pib txheej txheem. Txawm li cas los xij, nws yuav tsis yog ib txwm ua tau.)

Ib qho tseem ceeb ntawm kev siv cov kev teeb tsa zoo li qub uas qee zaum ua rau tib neeg xav txog kev teeb tsa dynamic (tsis muaj lwm yam laj thawj) yog kev pabcuam poob haujlwm thaum lub sijhawm hloov kho. Tseeb tiag, yog tias peb yuav tsum tau hloov pauv mus rau qhov kev teeb tsa zoo li qub, peb yuav tsum rov pib lub kaw lus kom cov txiaj ntsig tshiab ua tau zoo. Cov kev cai rau downtime sib txawv rau cov tshuab sib txawv, yog li nws yuav tsis yog qhov tseem ceeb. Yog tias nws yog qhov tseem ceeb, ces peb yuav tsum npaj ua ntej rau txhua qhov system rov pib dua. Piv txwv li, peb tuaj yeem siv tau AWS ELB connection draining. Hauv qhov xwm txheej no thaum twg peb yuav tsum rov pib lub kaw lus, peb pib qhov piv txwv tshiab ntawm lub kaw lus nyob rau tib lub sijhawm, tom qab ntawd hloov ELB rau nws, thaum cia cov txheej txheem qub los ua kom tiav kev pabcuam kev sib txuas uas twb muaj lawm.

Yuav ua li cas rau khaws configuration nyob rau hauv versioned artifact los yog sab nraum? Khaws kev teeb tsa hauv ib qho khoom cuav txhais tau hais tias feem ntau ntawm cov teeb meem no tau dhau los ntawm cov txheej txheem kev lees paub zoo ib yam li lwm yam khoom cuav. Yog li ib tus yuav paub tseeb tias qhov kev teeb tsa yog qhov zoo thiab muaj kev ntseeg siab. Ntawm qhov tsis sib xws configuration nyob rau hauv ib tug nyias muaj nyias ntaub ntawv txhais tau hais tias tsis muaj ib tug kab ntawm leej twg thiab vim li cas thiaj li hloov rau cov ntaub ntawv ntawd. Qhov no puas tseem ceeb? Peb ntseeg hais tias rau feem ntau cov tshuab ntau lawm nws yog qhov zoo dua kom muaj kev ruaj ntseg thiab zoo configuration.

Version ntawm artifact tso cai rau kom paub seb thaum twg nws tau tsim, dab tsi muaj nuj nqis nws muaj, dab tsi nta yog enabled / neeg xiam oob qhab, leej twg yog lub luag hauj lwm rau ua txhua yam kev hloov nyob rau hauv lub configuration. Tej zaum nws yuav xav tau qee qhov kev siv zog los khaws cov teeb tsa hauv cov khoom qub thiab nws yog qhov kev xaiv tsim los ua.

Pros & cons

Ntawm no peb xav hais txog qee qhov zoo thiab sib tham txog qee qhov tsis zoo ntawm txoj kev npaj.

zoo

Cov yam ntxwv ntawm compilable configuration ntawm ib tug ua tiav faib system:

  1. Static check ntawm configuration. Qhov no ua rau muaj kev ntseeg siab siab, tias qhov kev teeb tsa yog raug muab hom txwv.
  2. Cov lus nplua nuj ntawm kev teeb tsa. Feem ntau lwm txoj hauv kev teeb tsa tau txwv rau ntawm qhov hloov pauv hloov pauv.
    Siv Scala ib qho tuaj yeem siv ntau hom lus los ua kom zoo dua. Piv txwv li, peb tuaj yeem siv qhov zoo los muab qhov tseem ceeb, cov khoom los teeb tsa qhov txawv, peb tuaj yeem xa mus rau vals txhais tsuas yog ib zaug nyob rau hauv lub sab nrauv (DRY). Nws muaj peev xwm siv cov lus qhia ua ntu zus, lossis piv txwv ntawm qee cov chav kawm (Seq, Map, thiab lwm yam).
  3. DSL. Scala muaj kev txhawb nqa zoo rau cov kws sau ntawv DSL. Ib tus tuaj yeem siv cov yam ntxwv no los tsim cov lus teeb tsa uas yooj yim dua thiab cov neeg siv kawg tus phooj ywg, yog li qhov kev teeb tsa zaum kawg yog qhov tsawg kawg nyeem tau los ntawm cov neeg siv sau npe.
  4. Kev ncaj ncees thiab kev sib koom ua ke ntawm cov nodes. Ib qho txiaj ntsig ntawm kev muaj kev teeb tsa rau tag nrho cov kev faib tawm hauv ib qho chaw yog tias tag nrho cov txiaj ntsig tau txhais nruj me ntsis ib zaug thiab rov qab siv dua hauv txhua qhov chaw uas peb xav tau. Kuj ntaus cov ntawv tshaj tawm chaw nyab xeeb kom ntseeg tau tias nyob rau hauv txhua qhov kev teeb tsa kom raug lub kaw lus yuav hais tib hom lus. Muaj kev vam meej ntawm cov nodes uas ua rau nws nyuaj rau tsis nco qab muab qee qhov kev pabcuam.
  5. Kev hloov pauv tau zoo. Tag nrho txoj hauv kev ntawm kev hloov pauv kev hloov pauv los ntawm cov txheej txheem PR ib txwm tsim kom muaj cov qauv zoo hauv kev teeb tsa.
  6. Ib txhij configuration hloov. Thaum twg peb ua ib qho kev hloov pauv hauv kev teeb tsa tsis siv neeg xa mus ua kom ntseeg tau tias tag nrho cov nodes tau hloov kho.
  7. Kev siv yooj yim. Daim ntawv thov tsis tas yuav parse thiab validate configuration thiab lis cov nqi configuration tsis raug. Qhov no simplifies tag nrho daim ntawv thov. (Qee qhov nyuaj nce yog nyob rau hauv kev teeb tsa nws tus kheej, tab sis nws yog ib qho kev paub txog kev lag luam tawm ntawm kev nyab xeeb.) Nws yog qhov yooj yim zoo nkauj kom rov qab mus rau qhov kev teeb tsa zoo tib yam - tsuas yog ntxiv cov khoom ploj lawm. Nws yooj yim dua los pib nrog kev teeb tsa ua ke thiab ncua kev siv cov khoom ntxiv rau qee lub sijhawm tom qab.
  8. Versioned configuration. Vim lub fact tias configuration hloov raws li tib txoj kev loj hlob, vim li ntawd peb tau txais ib tug artifact nrog tshwj xeeb version. Nws tso cai rau peb hloov configuration rov qab yog tias xav tau. Peb tseem tuaj yeem xa ib qho kev teeb tsa uas tau siv ib xyoos dhau los thiab nws yuav ua haujlwm zoo ib yam. Stable configuration txhim kho kev kwv yees thiab kev ntseeg siab ntawm kev faib tawm. Lub configuration yog tsau nyob rau hauv compile lub sij hawm thiab yuav tsis yooj yim tampered ntawm ib tug ntau lawm system.
  9. Modularity. Lub moj khaum uas tau thov yog modular thiab modules tuaj yeem ua ke hauv ntau txoj hauv kev
    txhawb cov configurations sib txawv (setups/layouts). Tshwj xeeb, nws muaj peev xwm ua kom muaj qhov me me ntawm ib qho ntawm qhov kev teeb tsa thiab qhov loj teev ntau qhov chaw teeb tsa. Nws yog qhov tsim nyog kom muaj ntau qhov kev tsim khoom.
  10. Kev sim. Rau kev sim lub hom phiaj ib qho yuav siv cov kev pab cuam thuam thiab siv nws ua qhov kev vam khom rau hauv hom kev nyab xeeb. Ob peb qhov kev sim sib txawv nrog ntau qhov chaw hloov los ntawm kev thuam tuaj yeem khaws cia ib txhij.
  11. Kev sib xyaw ua ke. Qee lub sij hawm hauv cov kab ke faib nws nyuaj rau kev sim kev sib koom ua ke. Siv txoj hauv kev piav qhia rau hom kev teeb tsa muaj kev nyab xeeb ntawm kev xa tawm tag nrho, peb tuaj yeem khiav txhua qhov faib ntawm ib tus neeg rau zaub mov hauv txoj kev tswj tau. Nws yooj yim los ua raws li qhov xwm txheej
    thaum ib qho ntawm cov kev pabcuam yuav tsis muaj.

tsis zoo

Txoj kev sib sau ua ke sib txawv ntawm "ib txwm" configuration thiab nws yuav tsis haum txhua qhov kev xav tau. Nov yog qee qhov tsis zoo ntawm qhov kev sib sau ua ke:

  1. Static configuration. Tej zaum nws yuav tsis haum rau txhua daim ntawv thov. Qee qhov xwm txheej yuav tsum tau kho sai sai ntawm kev teeb tsa hauv kev tsim khoom hla dhau txhua qhov kev ntsuas kev nyab xeeb. Txoj kev no ua rau nws nyuaj dua. Kev muab tso ua ke thiab rov ua haujlwm rov qab yuav tsum tau ua tom qab hloov pauv hauv kev teeb tsa. Qhov no yog ob qho tib si feature thiab lub nra.
  2. Configuration tiam. Thaum config yog tsim los ntawm qee qhov cuab yeej automation no txoj hauv kev yuav tsum tau muab tso ua ke tom ntej (uas yuav ua tsis tau). Tej zaum nws yuav xav tau kev siv zog ntxiv los koom ua ke cov kauj ruam ntxiv no rau hauv kev tsim kho.
  3. Cov cuab yeej. Muaj ntau cov cuab yeej siv niaj hnub no uas tso siab rau cov ntawv nyeem raws li kev teeb tsa. Ib txhia ntawm lawv
    yuav tsis siv tau thaum configuration yog compiled.
  4. Yuav tsum muaj kev hloov pauv hauv kev xav. Cov neeg tsim khoom thiab DevOps tau paub txog cov ntaub ntawv teeb tsa. Lub tswv yim ntawm kev sau configuration tej zaum yuav tshwm sim coj txawv txawv rau lawv.
  5. Ua ntej tshaj tawm cov kev teeb tsa sib sau ua ke yuav tsum muaj cov txheej txheem txhim kho software zoo.

Muaj qee qhov kev txwv ntawm qhov ua piv txwv:

  1. Yog tias peb muab cov config ntxiv uas tsis xav tau los ntawm kev siv node, compiler yuav tsis pab peb txhawm rau txheeb xyuas qhov tsis siv. Qhov no tuaj yeem daws tau los ntawm kev siv HList los yog ADTs (cov ntaub ntawv chav kawm) rau kev teeb tsa ntawm node es tsis txhob ntawm qhov zoo thiab Cake Pattern.
  2. Peb yuav tsum muab qee qhov boilerplate hauv cov ntaub ntawv config: (package, import, object tshaj tawm;
    override def's rau parameters uas muaj qhov tseem ceeb). Qhov no tej zaum yuav yog ib feem ntawm kev siv DSL.
  3. Nyob rau hauv no ncej peb tsis npog dynamic reconfiguration ntawm pawg ntawm zoo sib xws nodes.

xaus

Nyob rau hauv no ncej peb tau tham txog lub tswv yim ntawm kev sawv cev configuration ncaj qha nyob rau hauv lub qhov chaws code nyob rau hauv ib hom kev nyab xeeb txoj kev. Txoj hauv kev tuaj yeem siv rau hauv ntau daim ntawv thov hloov pauv rau xml- thiab lwm yam ntawv-raws li kev teeb tsa. Txawm hais tias peb qhov piv txwv tau raug coj los siv hauv Scala, nws kuj tseem tuaj yeem muab txhais ua lwm hom lus (xws li Kotlin, C#, Swift, thiab lwm yam). Ib tus tuaj yeem sim ua qhov no hauv qhov project tshiab thiab, yog tias nws tsis haum zoo, hloov mus rau txoj kev qub qub.

Ntawm chav kawm, compilable configuration yuav tsum muaj kev loj hlob zoo. Nyob rau hauv rov qab nws cog lus tias yuav muab sib npaug zoo zoo robust configuration.

Txoj kev no tuaj yeem txuas ntxiv mus rau ntau txoj hauv kev:

  1. Ib tus tuaj yeem siv macros los ua qhov kev teeb tsa validation thiab ua tsis tiav thaum sau lub sijhawm nyob rau hauv rooj plaub ntawm kev lag luam-logic txwv tsis ua haujlwm.
  2. Lub DSL tuaj yeem siv los sawv cev rau kev teeb tsa hauv kev sau npe-tus neeg siv-phooj ywg.
  3. Kev tswj cov peev txheej dynamic nrog kev hloov kho tsis siv neeg. Piv txwv li, thaum peb kho tus naj npawb ntawm pawg nodes peb yuav xav tau (1) cov nodes kom tau txais kev hloov kho me ntsis; (2) pawg thawj tswj hwm kom tau txais cov ntaub ntawv nodes tshiab.

tsaug

Kuv xav hais ua tsaug rau Andrey Saksonov, Pavel Popov, Anton Nehaev uas tau muab kev tshoov siab tawm tswv yim ntawm cov ntawv sau no uas tau pab kuv ua kom pom tseeb.

Tau qhov twg los: www.hab.com