Usanidi unaoweza kuunganishwa wa mfumo uliosambazwa

Katika chapisho hili tungependa kushiriki njia ya kuvutia ya kushughulika na usanidi wa mfumo uliosambazwa.
Usanidi unawakilishwa moja kwa moja katika lugha ya Scala kwa njia salama ya aina. Mfano wa utekelezaji umeelezewa kwa undani. Vipengele mbalimbali vya pendekezo vinajadiliwa, ikiwa ni pamoja na ushawishi katika mchakato mzima wa maendeleo.

Usanidi unaoweza kuunganishwa wa mfumo uliosambazwa

(kwa Kirusi)

kuanzishwa

Kujenga mifumo thabiti iliyosambazwa inahitaji matumizi ya usanidi sahihi na madhubuti kwenye nodi zote. Suluhisho la kawaida ni kutumia maelezo ya uwekaji wa maandishi (terraform, ansible au kitu sawa) na faili za usanidi zinazozalishwa kiotomatiki (mara nyingi - zinazotolewa kwa kila nodi/jukumu). Tungetaka pia kutumia itifaki zile zile za matoleo yale yale kwenye kila nodi za mawasiliano (la sivyo tungekumbana na matatizo ya kutopatana). Katika ulimwengu wa JVM hii inamaanisha kuwa angalau maktaba ya ujumbe inapaswa kuwa ya toleo sawa kwenye nodi zote za mawasiliano.

Vipi kuhusu kupima mfumo? Bila shaka, tunapaswa kuwa na majaribio ya vitengo kwa vipengele vyote kabla ya kuja kwenye majaribio ya ujumuishaji. Ili kuweza kuongeza matokeo ya majaribio wakati wa utekelezaji, tunapaswa kuhakikisha kuwa matoleo ya maktaba yote yanawekwa sawa katika mazingira ya muda wa kufanya kazi na majaribio.

Wakati wa kufanya majaribio ya ujumuishaji, mara nyingi ni rahisi zaidi kuwa na njia sawa ya darasa kwenye nodi zote. Tunahitaji tu kuhakikisha kuwa njia sawa ya darasa inatumika kwenye upelekaji. (Inawezekana kutumia njia tofauti za darasa kwenye nodi tofauti, lakini ni ngumu zaidi kuwakilisha usanidi huu na kuupeleka kwa usahihi.) Kwa hivyo ili kuweka mambo rahisi tutazingatia tu njia za darasa zinazofanana kwenye nodi zote.

Usanidi huelekea kubadilika pamoja na programu. Kwa kawaida sisi hutumia matoleo kutambua anuwai
hatua za maendeleo ya programu. Inaonekana ni sawa kushughulikia usanidi chini ya usimamizi wa toleo na kutambua usanidi tofauti na baadhi ya lebo. Ikiwa kuna usanidi mmoja tu katika toleo la umma, tunaweza kutumia toleo moja kama kitambulisho. Wakati mwingine tunaweza kuwa na mazingira mengi ya uzalishaji. Na kwa kila mazingira tunaweza kuhitaji tawi tofauti la usanidi. Kwa hivyo usanidi unaweza kuwekewa lebo ya tawi na toleo ili kutambua usanidi tofauti. Kila lebo ya tawi na toleo linalingana na mchanganyiko mmoja wa nodi zilizosambazwa, bandari, rasilimali za nje, matoleo ya maktaba ya njia ya darasa kwenye kila nodi. Hapa tutashughulikia tawi moja pekee na kutambua usanidi kwa toleo la desimali la sehemu tatu (1.2.3), kwa njia sawa na vizalia vya programu vingine.

Katika mazingira ya kisasa faili za usanidi hazirekebishwi kwa mikono tena. Kwa kawaida tunazalisha
config faili wakati wa kupeleka na usiwahi kuwagusa baadaye. Kwa hivyo mtu anaweza kuuliza kwa nini bado tunatumia umbizo la maandishi kwa faili za usanidi? Chaguo linalowezekana ni kuweka usanidi ndani ya kitengo cha mkusanyiko na kufaidika na uthibitishaji wa usanidi wa wakati.

Katika chapisho hili tutachunguza wazo la kuweka usanidi katika mabaki yaliyokusanywa.

Usanidi unaoweza kuunganishwa

Katika sehemu hii tutajadili mfano wa usanidi tuli. Huduma mbili rahisi - huduma ya echo na mteja wa huduma ya echo inasanidiwa na kutekelezwa. Kisha mifumo miwili tofauti iliyosambazwa na huduma zote mbili inasisitizwa. Moja ni ya usanidi wa nodi moja na nyingine kwa usanidi wa nodi mbili.

Mfumo wa kawaida uliosambazwa una nodi chache. Nodi zinaweza kutambuliwa kwa kutumia aina fulani:

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

au tu

case class NodeId(hostName: String)

au hata

object Singleton
type NodeId = Singleton.type

Nodi hizi hutekeleza majukumu mbalimbali, huendesha baadhi ya huduma na zinapaswa kuwa na uwezo wa kuwasiliana na nodi nyingine kwa njia ya miunganisho ya TCP/HTTP.

Kwa muunganisho wa TCP angalau nambari ya mlango inahitajika. Pia tunataka kuhakikisha kuwa mteja na seva wanazungumza itifaki sawa. Ili kuiga muunganisho kati ya nodi wacha tutangaze darasa lifuatalo:

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

ambapo Port ni tu Int ndani ya safu inayoruhusiwa:

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

Aina zilizosafishwa

Kuona iliyosafishwa maktaba. Kwa kifupi, inaruhusu kuongeza vikwazo vya wakati wa kukusanya kwa aina nyingine. Kwa kesi hii Int inaruhusiwa tu kuwa na thamani za biti 16 zinazoweza kuwakilisha nambari ya mlango. Hakuna sharti la kutumia maktaba hii kwa mbinu hii ya usanidi. Inaonekana tu inafaa sana.

Kwa HTTP (REST) ​​​​tunaweza pia kuhitaji njia ya huduma:

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

Aina ya Phantom

Ili kutambua itifaki wakati wa ujumuishaji tunatumia kipengele cha Scala cha kutangaza hoja ya aina Protocol ambayo haitumiki darasani. Inaitwa hivyo aina ya phantom. Wakati wa utekelezaji, hatuhitaji mfano wa kitambulisho cha itifaki mara chache sana, ndiyo maana hatukihifadhi. Wakati wa kukusanya aina hii ya phantom inatoa usalama wa aina ya ziada. Hatuwezi kupitisha mlango na itifaki isiyo sahihi.

Mojawapo ya itifaki zinazotumiwa sana ni REST API na usanifu wa Json:

sealed trait JsonHttpRestProtocol[RequestMessage, ResponseMessage]

ambapo RequestMessage ni aina ya msingi ya ujumbe ambao mteja anaweza kutuma kwa seva na ResponseMessage ni ujumbe wa majibu kutoka kwa seva. Bila shaka, tunaweza kuunda maelezo mengine ya itifaki ambayo yanabainisha itifaki ya mawasiliano kwa usahihi unaotaka.

Kwa madhumuni ya chapisho hili tutatumia toleo rahisi la itifaki:

sealed trait SimpleHttpGetRest[RequestMessage, ResponseMessage]

Katika ujumbe huu wa ombi la itifaki huongezwa kwa url na ujumbe wa majibu unarudishwa kama mfuatano mtupu.

Usanidi wa huduma unaweza kuelezewa kwa jina la huduma, mkusanyiko wa bandari na baadhi ya vitegemezi. Kuna njia chache zinazowezekana za jinsi ya kuwakilisha vitu hivi vyote katika Scala (kwa mfano, HList, aina za data za aljebra). Kwa madhumuni ya chapisho hili tutatumia Muundo wa Keki na kuwakilisha vipande vinavyoweza kuunganishwa (moduli) kama sifa. (Mchoro wa Keki sio hitaji la mbinu hii ya usanidi inayoweza kuunganishwa. Ni utekelezaji mmoja tu unaowezekana wa wazo.)

Utegemezi unaweza kuwakilishwa kwa kutumia Mchoro wa Keki kama miisho ya nodi zingine:

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

Huduma ya Echo inahitaji tu bandari iliyosanidiwa. Na tunatangaza kwamba bandari hii inasaidia itifaki ya mwangwi. Kumbuka kuwa hatuhitaji kubainisha lango fulani kwa wakati huu, kwa sababu sifa inaruhusu utangazaji wa mbinu dhahania. Ikiwa tutatumia njia za kufikirika, mkusanyaji atahitaji utekelezaji katika mfano wa usanidi. Hapa tumetoa utekelezaji (8081) na itatumika kama dhamana chaguo-msingi ikiwa tutairuka katika usanidi thabiti.

Tunaweza kutangaza utegemezi katika usanidi wa mteja wa huduma ya mwangwi:

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

Utegemezi una aina sawa na echoService. Hasa, inadai itifaki sawa. Kwa hivyo, tunaweza kuwa na uhakika kwamba ikiwa tutaunganisha tegemezi hizi mbili zitafanya kazi kwa usahihi.

Utekelezaji wa huduma

Huduma inahitaji chaguo la kukokotoa ili kuanza na kuzima kwa njia nzuri. (Uwezo wa kuzima huduma ni muhimu kwa majaribio.) Tena kuna chaguo chache za kubainisha chaguo za kukokotoa kama hizo kwa usanidi fulani (kwa mfano, tunaweza kutumia aina za madarasa). Kwa chapisho hili tutatumia Muundo wa Keki tena. Tunaweza kuwakilisha huduma kwa kutumia cats.Resource ambayo tayari inatoa mabano na kutolewa kwa rasilimali. Ili kupata rasilimali tunapaswa kutoa usanidi na muktadha fulani wa wakati wa utekelezaji. Kwa hivyo kazi ya kuanza huduma inaweza kuonekana kama:

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

ambapo

  • Config β€” aina ya usanidi unaohitajika na kianzisha huduma hiki
  • AddressResolver β€” kitu cha wakati wa kukimbia ambacho kina uwezo wa kupata anwani halisi za nodi zingine (endelea kusoma kwa maelezo).

aina nyingine zinatoka cats:

  • F[_] - aina ya athari (Katika hali rahisi F[A] inaweza kuwa tu () => A. Katika chapisho hili tutatumia cats.IO.)
  • Reader[A,B] - ni zaidi au chini ya kisawe cha chaguo la kukokotoa A => B
  • cats.Resource - ina njia za kupata na kutolewa
  • Timer - Huruhusu kulala/kupima muda
  • ContextShift - analog ya ExecutionContext
  • Applicative - mpangilio wa utendaji kazi (karibu monad) (hatimaye tunaweza kuibadilisha na kitu kingine)

Kwa kutumia kiolesura hiki tunaweza kutekeleza huduma chache. Kwa mfano, huduma ambayo haifanyi chochote:

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

(Angalia Chanzo code kwa utekelezaji wa huduma zingine - huduma ya mwangwi,
mteja echo na watawala wa maisha.)

Nodi ni kitu kimoja ambacho huendesha huduma chache (kuanzisha msururu wa rasilimali kunawezeshwa na Muundo wa Keki):

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

Kumbuka kwamba katika node tunataja aina halisi ya usanidi ambayo inahitajika na node hii. Mkusanyaji hataturuhusu kuunda kitu (Keki) na aina isiyo ya kutosha, kwa sababu kila sifa ya huduma inatangaza kizuizi kwenye Config aina. Pia hatutaweza kuanza nodi bila kutoa usanidi kamili.

Azimio la anwani ya nodi

Ili kuanzisha muunganisho tunahitaji anwani halisi ya mwenyeji kwa kila nodi. Inaweza kujulikana baadaye kuliko sehemu zingine za usanidi. Kwa hivyo, tunahitaji njia ya kusambaza ramani kati ya kitambulisho cha nodi na anwani yake halisi. Kuchora ramani hii ni kazi:

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

Kuna njia chache zinazowezekana za kutekeleza kazi kama hiyo.

  1. Iwapo tunajua anwani halisi kabla ya kupelekwa, wakati wa kupangisha nodi za upangishaji, basi tunaweza kutoa msimbo wa Scala na anwani halisi na kuendesha muundo baadaye (ambao hufanya ukaguzi wa wakati na kisha kuendesha kitengo cha jaribio la ujumuishaji). Katika hali hii utendakazi wetu wa uchoraji ramani unajulikana kitakwimu na unaweza kurahisishwa kwa kitu kama a Map[NodeId, NodeAddress].
  2. Wakati mwingine tunapata anwani halisi baadaye tu wakati nodi imeanzishwa, au hatuna anwani za nodi ambazo bado hazijaanzishwa. Katika hali hii tunaweza kuwa na huduma ya ugunduzi ambayo imeanzishwa kabla ya nodi zingine zote na kila nodi inaweza kutangaza anwani yake katika huduma hiyo na kujiandikisha kwa utegemezi.
  3. Ikiwa tunaweza kurekebisha /etc/hosts, tunaweza kutumia majina ya mwenyeji yaliyofafanuliwa (kama my-project-main-node na echo-backend) na husisha tu jina hili na anwani ya ip wakati wa kupeleka.

Katika chapisho hili hatuangazii kesi hizi kwa maelezo zaidi. Kwa kweli katika mfano wetu wa toy nodi zote zitakuwa na anwani sawa ya IP - 127.0.0.1.

Katika chapisho hili tutazingatia mipangilio miwili ya mfumo uliosambazwa:

  1. Mpangilio wa nodi moja, ambapo huduma zote zimewekwa kwenye node moja.
  2. Mpangilio wa nodi mbili, ambapo huduma na mteja ziko kwenye nodi tofauti.

Mpangilio wa a nodi moja mpangilio ni kama ifuatavyo:

Usanidi wa nodi moja

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

Hapa tunaunda usanidi mmoja unaopanua usanidi wa seva na mteja. Pia tunasanidi kidhibiti cha mzunguko wa maisha ambacho kitasimamisha mteja na seva baada ya hapo lifetime kupita muda.

Seti sawa ya utekelezaji na usanidi wa huduma inaweza kutumika kuunda mpangilio wa mfumo na nodi mbili tofauti. Tunahitaji tu kuunda usanidi wa nodi mbili tofauti na huduma zinazofaa:

Usanidi wa nodi mbili

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

Tazama jinsi tunavyobainisha utegemezi. Tunataja huduma nyingine iliyotolewa na nodi kama utegemezi wa nodi ya sasa. Aina ya utegemezi imeangaliwa kwa sababu ina aina ya phantom inayoelezea itifaki. Na wakati wa kukimbia tutakuwa na kitambulisho sahihi cha nodi. Hii ni moja ya vipengele muhimu vya mbinu iliyopendekezwa ya usanidi. Inatupa uwezo wa kuweka mlango mara moja pekee na kuhakikisha kuwa tunarejelea mlango sahihi.

Utekelezaji wa nodi mbili

Kwa usanidi huu tunatumia utekelezwaji wa huduma sawa. Hakuna mabadiliko hata kidogo. Walakini, tunaunda utekelezaji wa nodi mbili tofauti ambazo zina seti tofauti za huduma:

  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
  }

Njia ya kwanza hutumia seva na inahitaji tu usanidi wa upande wa seva. Nodi ya pili inatekelezea mteja na inahitaji sehemu nyingine ya usanidi. Nodi zote mbili zinahitaji vipimo fulani vya maisha. Kwa madhumuni ya nodi hii ya huduma ya posta itakuwa na maisha yasiyo na kikomo ambayo yanaweza kusitishwa kwa kutumia SIGTERM, huku mteja wa mwangwi atakoma baada ya muda wa kikomo uliowekwa. Angalia programu ya kuanza kwa maelezo.

Mchakato wa maendeleo ya jumla

Wacha tuone jinsi mbinu hii inavyobadilisha jinsi tunavyofanya kazi na usanidi.

Usanidi kama msimbo utakusanywa na kutoa vizalia vya programu. Inaonekana ni sawa kutenganisha vizalia vya programu vya usanidi kutoka kwa vizalia vya programu vingine vya msimbo. Mara nyingi tunaweza kuwa na usanidi mwingi kwenye msingi sawa wa nambari. Na bila shaka, tunaweza kuwa na matoleo mengi ya matawi mbalimbali ya usanidi. Katika usanidi tunaweza kuchagua matoleo fulani ya maktaba na hii itasalia mara kwa mara wakati wowote tunapoweka usanidi huu.

Mabadiliko ya usanidi huwa mabadiliko ya nambari. Kwa hivyo inapaswa kufunikwa na mchakato sawa wa uhakikisho wa ubora:

Tikiti -> PR -> hakiki -> unganisha -> ujumuishaji endelevu -> utumaji unaoendelea

Kuna matokeo yafuatayo ya mbinu:

  1. Usanidi ni madhubuti kwa mfano wa mfumo fulani. Inaonekana kwamba hakuna njia ya kuwa na muunganisho usio sahihi kati ya nodi.
  2. Si rahisi kubadilisha usanidi katika nodi moja. Inaonekana sio busara kuingia na kubadilisha faili kadhaa za maandishi. Kwa hivyo kuteleza kwa usanidi kunakuwa chini iwezekanavyo.
  3. Mabadiliko madogo ya usanidi si rahisi kufanya.
  4. Mabadiliko mengi ya usanidi yatafuata mchakato sawa wa usanidi, na itapitisha ukaguzi fulani.

Je, tunahitaji hifadhi tofauti kwa usanidi wa uzalishaji? Mipangilio ya toleo la umma inaweza kuwa na maelezo nyeti ambayo tungependa kuweka mbali na watu wengi. Kwa hivyo inaweza kufaa kuweka hazina tofauti na ufikiaji uliozuiliwa ambao utakuwa na usanidi wa uzalishaji. Tunaweza kugawanya usanidi katika sehemu mbili - moja ambayo ina vigezo vya wazi zaidi vya uzalishaji na moja ambayo ina sehemu ya siri ya usanidi. Hii itawezesha ufikiaji kwa wasanidi wengi kwa idadi kubwa ya vigezo huku ikizuia ufikiaji wa vitu nyeti sana. Ni rahisi kukamilisha hili kwa kutumia sifa za kati na maadili ya kigezo chaguo-msingi.

Tofauti

Wacha tuone faida na hasara za mbinu iliyopendekezwa ikilinganishwa na mbinu zingine za usimamizi wa usanidi.

Kwanza kabisa, tutaorodhesha njia mbadala chache kwa vipengele tofauti vya njia iliyopendekezwa ya kushughulika na usanidi:

  1. Faili ya maandishi kwenye mashine inayolengwa.
  2. Hifadhi ya thamani kuu ya kati (kama etcd/zookeeper).
  3. Vipengee vya mchakato mdogo ambavyo vinaweza kusanidiwa upya/kuanzishwa upya bila kuanzisha upya mchakato.
  4. Usanidi wa nje ya vizalia vya programu na udhibiti wa toleo.

Faili ya maandishi hutoa unyumbufu fulani katika suala la marekebisho ya ad-hoc. Msimamizi wa mfumo anaweza kuingia kwenye nodi inayolengwa, kufanya mabadiliko na kuanza tena huduma. Hii inaweza kuwa sio nzuri kwa mifumo mikubwa zaidi. Hakuna athari zilizoachwa nyuma ya mabadiliko. Mabadiliko hayapitiwi na jozi nyingine ya macho. Inaweza kuwa ngumu kujua ni nini kimesababisha mabadiliko. Haijajaribiwa. Kutoka kwa mtazamo wa mfumo uliosambazwa msimamizi anaweza kusahau tu kusasisha usanidi katika mojawapo ya nodi nyingine.

(Btw, ikiwa hatimaye kutakuwa na hitaji la kuanza kutumia faili za usanidi wa maandishi, itabidi tu kuongeza kichanganuzi + kithibitishaji ambacho kinaweza kutoa sawa. Config type na hiyo ingetosha kuanza kutumia usanidi wa maandishi. Hii pia inaonyesha kwamba uchangamano wa usanidi wa wakati wa kukusanya ni mdogo kidogo kuliko ugumu wa usanidi unaotegemea maandishi, kwa sababu katika toleo linalotegemea maandishi tunahitaji msimbo wa ziada.)

Uhifadhi wa thamani ya ufunguo wa kati ni utaratibu mzuri wa kusambaza vigezo vya meta ya programu. Hapa tunahitaji kufikiria juu ya kile tunachokiona kuwa maadili ya usanidi na ni nini data tu. Imepewa kazi C => A => B kwa kawaida tunaita maadili yanayobadilika mara chache C "usanidi", wakati data iliyobadilishwa mara kwa mara A - Ingiza data tu. Usanidi unapaswa kutolewa kwa chaguo za kukokotoa mapema kuliko data A. Kwa kuzingatia wazo hili tunaweza kusema kwamba frequency inayotarajiwa ya mabadiliko ambayo inaweza kutumika kutofautisha data ya usanidi kutoka kwa data pekee. Pia data kawaida hutoka kwa chanzo kimoja (mtumiaji) na usanidi hutoka kwa chanzo tofauti (admin). Kushughulika na vigezo vinavyoweza kubadilishwa baada ya mchakato wa uanzishaji husababisha ongezeko la utata wa maombi. Kwa vigezo kama hivyo itabidi kushughulikia utaratibu wao wa uwasilishaji, uchanganuzi na uthibitishaji, kushughulikia maadili yasiyo sahihi. Kwa hivyo, ili kupunguza ugumu wa programu, ni bora kupunguza idadi ya vigezo vinavyoweza kubadilika wakati wa utekelezaji (au hata kuviondoa kabisa).

Kutoka kwa mtazamo wa chapisho hili tunapaswa kufanya tofauti kati ya vigezo vya tuli na vya nguvu. Ikiwa mantiki ya huduma inahitaji mabadiliko machache ya baadhi ya vigezo wakati wa utekelezaji, basi tunaweza kuviita vigezo vinavyobadilika. Vinginevyo ni tuli na zinaweza kusanidiwa kwa kutumia mbinu iliyopendekezwa. Kwa usanidi upya unaobadilika mbinu zingine zinaweza kuhitajika. Kwa mfano, sehemu za mfumo zinaweza kuanzishwa upya kwa vigezo vipya vya usanidi kwa njia sawa na kuanzisha upya michakato tofauti ya mfumo unaosambazwa.
(Maoni yangu ya unyenyekevu ni kuzuia usanidi wa wakati wa kukimbia kwa sababu huongeza ugumu wa mfumo.
Inaweza kuwa moja kwa moja kutegemea tu usaidizi wa OS wa kuanzisha upya michakato. Ingawa, inaweza kuwa haiwezekani kila wakati.)

Kipengele kimoja muhimu cha kutumia usanidi tuli ambao wakati mwingine huwafanya watu kuzingatia usanidi unaobadilika (bila sababu zingine) ni kukatika kwa huduma wakati wa sasisho la usanidi. Hakika, ikiwa itabidi tufanye mabadiliko kwenye usanidi tuli, tunapaswa kuanzisha upya mfumo ili maadili mapya yawe na ufanisi. Mahitaji ya muda wa chini yanatofautiana kwa mifumo tofauti, kwa hivyo inaweza kuwa sio muhimu sana. Ikiwa ni muhimu, basi tunapaswa kupanga mapema kwa ajili ya kuanzisha upya mfumo wowote. Kwa mfano, tunaweza kutekeleza Utoaji wa muunganisho wa AWS ELB. Katika hali hii wakati wowote tunapohitaji kuanzisha upya mfumo, tunaanza mfano mpya wa mfumo sambamba, kisha kubadili ELB kwake, huku tukiruhusu mfumo wa zamani ukamilishe kuhudumia miunganisho iliyopo.

Vipi kuhusu kuweka usanidi ndani ya vizalia vya programu vilivyotolewa au nje? Kuweka usanidi ndani ya vizalia vya programu kunamaanisha kuwa katika hali nyingi usanidi huu umepitisha mchakato wa uhakikisho wa ubora kama vizalia vya programu vingine. Kwa hivyo mtu anaweza kuwa na uhakika kwamba usanidi ni wa ubora mzuri na wa kuaminika. Kinyume chake usanidi katika faili tofauti unamaanisha kuwa hakuna athari za nani na kwa nini alifanya mabadiliko kwenye faili hiyo. Je, hii ni muhimu? Tunaamini kuwa kwa mifumo mingi ya uzalishaji ni bora kuwa na usanidi thabiti na wa ubora wa juu.

Toleo la vizalia vya programu huruhusu kujua wakati iliundwa, ina thamani gani, ni vipengele vipi vilivyowezeshwa/kuzimwa, ni nani aliyehusika kufanya kila mabadiliko katika usanidi. Huenda ikahitaji jitihada fulani ili kuweka usanidi ndani ya vizalia vya programu na ni chaguo la kubuni kufanya.

Faida hasara

Hapa tungependa kuangazia baadhi ya faida na kujadili baadhi ya hasara za mbinu iliyopendekezwa.

faida

Vipengele vya usanidi unaoweza kuunganishwa wa mfumo kamili uliosambazwa:

  1. Cheki tuli cha usanidi. Hii inatoa kiwango cha juu cha kujiamini, kwamba usanidi ni sahihi kutokana na vikwazo vya aina.
  2. Lugha tajiri ya usanidi. Kwa kawaida mbinu zingine za usanidi huwa na kikomo kwa ubadilishaji unaobadilika zaidi.
    Kutumia Scala mtu anaweza kutumia anuwai ya huduma za lugha kufanya usanidi kuwa bora. Kwa mfano, tunaweza kutumia sifa kutoa maadili chaguo-msingi, vitu vya kuweka upeo tofauti, tunaweza kurejelea vals hufafanuliwa mara moja tu katika mawanda ya nje (KAUSHA). Inawezekana kutumia mlolongo halisi, au mifano ya madarasa fulani (Seq, Map, Nk).
  3. DSL. Scala ina msaada mzuri kwa waandishi wa DSL. Mtu anaweza kutumia vipengele hivi ili kuanzisha lugha ya usanidi ambayo ni rahisi zaidi na inayofaa mtumiaji wa mwisho, ili usanidi wa mwisho uweze kusomeka angalau na watumiaji wa kikoa.
  4. Uadilifu na mshikamano katika nodi zote. Moja ya faida za kuwa na usanidi wa mfumo mzima uliosambazwa katika sehemu moja ni kwamba maadili yote yanafafanuliwa madhubuti mara moja na kisha kutumika tena katika maeneo yote tunapohitaji. Pia chapa matamko ya bandari salama hakikisha kuwa katika usanidi wote sahihi unaowezekana, nodi za mfumo zitazungumza lugha moja. Kuna utegemezi wazi kati ya nodi ambayo inafanya kuwa ngumu kusahau kutoa huduma zingine.
  5. Ubora wa juu wa mabadiliko. Mbinu ya jumla ya kupitisha mabadiliko ya usanidi kupitia mchakato wa kawaida wa PR huweka viwango vya juu vya ubora pia katika usanidi.
  6. Mabadiliko ya usanidi wa wakati mmoja. Wakati wowote tunapofanya mabadiliko yoyote katika uwekaji kiotomatiki wa usanidi huhakikisha kuwa nodi zote zinasasishwa.
  7. Urahisishaji wa maombi. Programu haihitaji kuchanganua na kuthibitisha usanidi na kushughulikia thamani zisizo sahihi za usanidi. Hii hurahisisha programu kwa ujumla. (Ongezeko fulani la uchangamano liko kwenye usanidi wenyewe, lakini ni ubadilishanaji makini kuelekea usalama.) Ni rahisi sana kurudi kwenye usanidi wa kawaida - ongeza tu vipande vilivyokosekana. Ni rahisi kuanza na usanidi uliokusanywa na kuahirisha utekelezaji wa vipande vya ziada hadi nyakati za baadaye.
  8. Usanidi uliotolewa. Kwa sababu ya ukweli kwamba mabadiliko ya usanidi yanafuata mchakato sawa wa ukuzaji, kwa hivyo tunapata vizalia vya programu vilivyo na toleo la kipekee. Inaturuhusu kubadilisha usanidi nyuma ikiwa inahitajika. Tunaweza hata kupeleka usanidi ambao ulitumika mwaka mmoja uliopita na utafanya kazi kwa njia sawa. Usanidi thabiti huboresha utabiri na uaminifu wa mfumo uliosambazwa. Usanidi umewekwa kwa wakati wa kukusanya na hauwezi kuathiriwa kwa urahisi kwenye mfumo wa uzalishaji.
  9. Modularity. Mfumo unaopendekezwa ni wa moduli na moduli zinaweza kuunganishwa kwa njia mbalimbali
    saidia usanidi tofauti (usanidi / mpangilio). Hasa, inawezekana kuwa na mpangilio mdogo wa nodi moja na mpangilio mkubwa wa nodi nyingi. Ni busara kuwa na mipangilio mingi ya uzalishaji.
  10. Kupima. Kwa madhumuni ya majaribio mtu anaweza kutekeleza huduma ya kejeli na kuitumia kama utegemezi kwa njia salama. Miundo michache tofauti ya majaribio yenye sehemu mbalimbali zilizobadilishwa na kejeli inaweza kudumishwa kwa wakati mmoja.
  11. Mtihani wa ujumuishaji. Wakati mwingine katika mifumo iliyosambazwa ni vigumu kuendesha majaribio ya ujumuishaji. Kwa kutumia mbinu iliyoelezwa ya kuweka usanidi salama wa mfumo kamili uliosambazwa, tunaweza kuendesha sehemu zote zilizosambazwa kwenye seva moja kwa njia inayoweza kudhibitiwa. Ni rahisi kuiga hali hiyo
    wakati moja ya huduma haipatikani.

Hasara

Mbinu ya usanidi iliyokusanywa ni tofauti na usanidi wa "kawaida" na inaweza isikidhi mahitaji yote. Hapa kuna baadhi ya ubaya wa usanidi uliojumuishwa:

  1. Usanidi wa tuli. Huenda haifai kwa programu zote. Katika baadhi ya matukio kuna haja ya kurekebisha haraka usanidi katika uzalishaji kwa kupita hatua zote za usalama. Mbinu hii inafanya kuwa ngumu zaidi. Mkusanyiko na uwekaji upya unahitajika baada ya kufanya mabadiliko yoyote katika usanidi. Hii ni kipengele na mzigo.
  2. Kizazi cha usanidi. Wakati usanidi unatolewa na zana fulani ya otomatiki mbinu hii inahitaji mkusanyiko unaofuata (ambao unaweza kushindwa). Huenda ikahitaji jitihada za ziada ili kuunganisha hatua hii ya ziada kwenye mfumo wa ujenzi.
  3. Vyombo. Kuna zana nyingi zinazotumika leo ambazo zinategemea usanidi wa maandishi. Baadhi yao
    haitatumika wakati usanidi unakusanywa.
  4. Mabadiliko ya mawazo yanahitajika. Wasanidi programu na DevOps wanafahamu faili za usanidi wa maandishi. Wazo la kuandaa usanidi linaweza kuonekana kuwa la kushangaza kwao.
  5. Kabla ya kuanzisha usanidi unaoweza kuunganishwa mchakato wa uundaji wa programu ya ubora wa juu unahitajika.

Kuna vikwazo kadhaa vya mfano uliotekelezwa:

  1. Ikiwa tutatoa usanidi wa ziada ambao hauhitajiki na utekelezaji wa nodi, mkusanyaji hautatusaidia kugundua utekelezaji ambao haupo. Hii inaweza kushughulikiwa kwa kutumia HList au ADTs (kesi madarasa) kwa usanidi wa nodi badala ya sifa na Muundo wa Keki.
  2. Tunapaswa kutoa boilerplate katika faili ya usanidi: (package, import, object matamko;
    override def's kwa vigezo ambavyo vina maadili chaguo-msingi). Hili linaweza kushughulikiwa kwa kiasi kwa kutumia DSL.
  3. Katika chapisho hili hatuzingatii usanidi upya wa nguvu wa nguzo za nodi zinazofanana.

Hitimisho

Katika chapisho hili tumejadili wazo la kuwakilisha usanidi moja kwa moja kwenye msimbo wa chanzo kwa njia salama ya aina. Mbinu inaweza kutumika katika programu nyingi kama mbadala wa xml- na usanidi mwingine wa maandishi. Licha ya kwamba mfano wetu umetekelezwa katika Scala, inaweza pia kutafsiriwa kwa lugha zingine zinazoweza kuunganishwa (kama Kotlin, C #, Swift, nk). Mtu anaweza kujaribu mbinu hii katika mradi mpya na, ikiwa haifai vizuri, badilisha kwa njia ya zamani.

Bila shaka, usanidi unaoweza kuunganishwa unahitaji mchakato wa ukuzaji wa ubora wa juu. Kwa kurudi inaahidi kutoa usanidi wa hali ya juu sawa.

Njia hii inaweza kupanuliwa kwa njia mbalimbali:

  1. Mtu anaweza kutumia macros kutekeleza uthibitishaji wa usanidi na kushindwa kwa wakati wa kukusanya ikiwa kuna kushindwa kwa vikwazo vya mantiki ya biashara.
  2. DSL inaweza kutekelezwa ili kuwakilisha usanidi kwa njia ya kikoa inayoweza kufaa mtumiaji.
  3. Usimamizi wa rasilimali wenye nguvu na marekebisho ya usanidi otomatiki. Kwa mfano, tunaporekebisha idadi ya nodi za nguzo tunaweza kutaka (1) nodi kupata usanidi uliobadilishwa kidogo; (2) meneja wa nguzo ili kupokea maelezo mapya ya nodi.

Shukrani

Ningependa kusema asante kwa Andrey Saksonov, Pavel Popov, Anton Nehaev kwa kutoa maoni ya msukumo juu ya rasimu ya chapisho hili ambalo lilinisaidia kuifanya iwe wazi zaidi.

Chanzo: mapenzi.com