Veavakirina Pergala Belavkirî ya Berhevkirî

Ez dixwazim ji we re mekanîzmayek balkêş ji bo xebata bi veavakirina pergalek belavkirî re bibêjim. Veavakirin rasterast bi zimanek berhevkirî (Scala) bi karanîna celebên ewledar têne destnîşan kirin. Ev post mînakek mîhengek wusa peyda dike û li ser cûrbecûr aliyên pêkanîna veavakirinek berhevkirî di pêvajoya pêşkeftina giştî de nîqaş dike.

Veavakirina Pergala Belavkirî ya Berhevkirî

(Îngilîzî)

Pîrozbahiyê

Avakirina pergalek belavkirî ya pêbawer tê vê wateyê ku hemî girêk veavakirina rast, bi girêkên din re hevdemkirî bikar tînin. Teknolojiyên DevOps (terraform, ansible an tiştek wusa) bi gelemperî têne bikar anîn da ku bixweber pelên vesazkirinê (bi gelemperî ji bo her girêk taybetî) çêbikin. Di heman demê de em dixwazin pê bawer bin ku hemî girêkên ragihandinê protokolên wekhev bikar tînin (di nav de heman versiyonê). Wekî din, lihevnekirin dê di pergala meya belavkirî de were çêkirin. Di cîhana JVM de, yek encamên vê hewcedariyê ev e ku heman guhertoya pirtûkxaneyê ku peyamên protokolê vedihewîne divê li her deverê were bikar anîn.

Di derbarê ceribandina pergalek belavkirî de çi ye? Bê guman, em texmîn dikin ku berî ku em derbasî ceribandina entegrasyonê bibin hemî pêkhate ceribandinên yekîneyê hene. (Ji bo ku em encamên testê li dema xebitandinê derxînin, divê em di qonaxa ceribandinê û dema xebitandinê de jî komek pirtûkxaneyek wekhev peyda bikin.)

Dema ku bi ceribandinên entegrasyonê re dixebitin, pir caran hêsantir e ku meriv heman sinifê li her derê li ser hemî girêkan bikar bîne. Tiştê ku divê em bikin ev e ku pê ewle bin ku heman sinifê di dema xebitandinê de tê bikar anîn. (Her çend ku bi tevahî gengaz e ku meriv girêkên cihêreng bi rêgezên pola cihêreng bixebite, ev yek tevliheviyê li ser veavakirina giştî û dijwariyên ceribandinên danîn û entegrasyonê zêde dike.) Ji bo mebestên vê postê, em texmîn dikin ku hemî girêk dê heman polê bikar bînin.

Veavakirin bi serîlêdanê re pêşve diçe. Em guhertoyan bikar tînin da ku qonaxên cûda yên pêşveçûna bernameyê nas bikin. Wusa dixuye ku mentiqî ye ku meriv guhertoyên cihêreng ên mîhengan jî nas bike. Û veavakirinê bixwe di pergala kontrolkirina guhertoyê de cîh bikin. Ger di hilberînê de tenê yek veavakirin hebe, wê hingê em dikarin bi tenê jimareya guhertoyê bikar bînin. Ger em gelek mînakên hilberînê bikar bînin, wê hingê em ê hewceyê çendan bikin
şaxên veavakirinê û etîketek din ji bilî guhertoyê (mînak, navê şaxê). Bi vî awayî em dikarin bi zelalî veavakirina rastîn nas bikin. Her nasnavê veavakirinê bi rengek yekta bi tevliheviyek taybetî ya girêkên belavkirî, port, çavkaniyên derveyî, û guhertoyên pirtûkxaneyê re têkildar e. Ji bo mebestên vê postê em ê texmîn bikin ku tenê şaxek heye û em dikarin bi sê hejmarên ku bi xalek (1.2.3) veqetandî ne, veavakirinê bi awayê asayî nas bikin.

Di hawîrdorên nûjen de, pelên vesazkirinê kêm kêm bi destan têne afirandin. Pir caran ew di dema bicîhkirinê de têne çêkirin û êdî nayên destgirtin (da ku tiştekî neşkênin). Pirsek xwezayî derdikeve: çima em hîn jî formata nivîsê bikar tînin da ku veavakirinê hilînin? Alternatîfek maqûl xuya dike ku ew şiyana karanîna koda birêkûpêk ji bo veavakirinê û sûdwergirtina ji kontrolên dema berhevkirinê ye.

Di vê postê de em ê fikra temsîlkirina mîhengek di hundurê hunerek berhevkirî de vekolînin.

Veavakirina berhevkirî

Ev beş mînakek mîhengek berhevkirî ya statîk peyda dike. Du karûbarên hêsan têne bicîh kirin - karûbarê echo û muwekîlê karûbarê echo. Li ser bingeha van her du karûbaran, du vebijarkên pergalê têne berhev kirin. Di vebijarkekê de, her du karûbar li ser heman nodê, di vebijarkek din de - li ser girêkên cihêreng têne bicîh kirin.

Bi gelemperî pergalek belavkirî çend girêk dihewîne. Hûn dikarin girêkan bi karanîna nirxên hin celeb nas bikin NodeId:

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

an

case class NodeId(hostName: String)

an jî jî

object Singleton
type NodeId = Singleton.type

Nod rolên cihêreng pêk tînin, ew karûbaran dimeşînin û girêdanên TCP/HTTP di navbera wan de têne saz kirin.

Ji bo danasîna pêwendiyek TCP-ê em bi kêmanî jimareyek portê hewce ne. Di heman demê de em dixwazin protokola ku li ser wê portê tê piştgirî kirin nîşan bidin da ku pê ewle bibin ku hem xerîdar û hem jî server heman protokolê bikar tînin. Em ê pêwendiyê bi karanîna çîna jêrîn diyar bikin:

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

ko Port - tenê jimareyek Int Rêjeya nirxên pejirandî destnîşan dike:

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

Cûreyên paqijkirî

Pirtûkxaneyê bibînin nirxandin и min nûçe. Bi kurtasî, pirtûkxane dihêle hûn li celebên ku di dema berhevkirinê de têne kontrol kirin astengan zêde bikin. Di vê rewşê de, nirxên jimareya portê ya derbasdar hejmarên 16-bit in. Ji bo veavakirinek berhevkirî, karanîna pirtûkxaneya safîkirî ne mecbûrî ye, lê ew şiyana berhevkar a kontrolkirina veavakirinê baştir dike.

Ji bo protokolên HTTP (REST), ji bilî jimareya portê, dibe ku em riya karûbarê jî hewce bikin:

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

Cureyên Phantom

Ji bo naskirina protokolê di dema berhevkirinê de, em pîvanek celebek ku di nav polê de nayê bikar anîn bikar tînin. Ev biryar ji ber vê yekê ye ku em di dema xebitandinê de mînakek protokolê bikar neynin, lê em dixwazin ku berhevkar lihevhatina protokolan kontrol bike. Bi danasîna protokolê, em ê nikaribin karûbarek neguncaw wekî girêdayîbûnê derbas bikin.

Yek ji protokolên hevpar REST API-ya bi serialîzasyona Json e:

sealed trait JsonHttpRestProtocol[RequestMessage, ResponseMessage]

ko RequestMessage - cureyê daxwazê, ResponseMessage - cureyê bersivê.
Bê guman, em dikarin danasînên din ên protokolê yên ku rastbûna danasîna ku em hewce dikin bikar bînin.

Ji bo mebestên vê postê, em ê guhertoyek hêsan a protokolê bikar bînin:

sealed trait SimpleHttpGetRest[RequestMessage, ResponseMessage]

Li vir daxwaz rêzek e ku bi url-ê ve hatî pêvekirî ye û bersiv di laşê bersiva HTTP de rêzika vegerî ye.

Veavakirina karûbarê bi navê karûbar, port û pêwendiyan ve tête diyar kirin. Ev hêman dikarin di Scala de bi çend awayan bêne temsîl kirin (mînak, HList-s, cureyên daneya cebrî). Ji bo mebestên vê postê, em ê Nimûneya Cake bikar bînin û modulên ku bikar tînin temsîl dikin trait's. (Nimûneya kekê ne hêmanek pêdivî ya vê nêzîkbûnê ye. Ew bi tenê yek pêkanînek gengaz e.)

Girêdanên di navbera karûbaran de dikarin wekî rêbazên ku ports vedigerin werin temsîl kirin EndPoint'yên girêkên din:

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

Ji bo afirandina karûbarek echo, ya ku hûn hewce ne jimareyek portê û nîşanek e ku port protokola echo piştgirî dike. Dibe ku em portek taybetî diyar nekin, ji ber ku ... taybetmendî dihêle hûn bêyî pêkanîna rêbazan (rêbazên razber) eşkere bikin. Di vê rewşê de, dema ku vesazkirinek konkret diafirîne, berhevkar dê ji me hewce bike ku em pêkanîna rêbazek razber peyda bikin û jimareyek portê peyda bikin. Ji ber ku me rêbaz bicîh kiriye, dema ku mîhengek taybetî diafirîne, dibe ku em portek cûda diyar nekin. Nirxa xwerû dê were bikar anîn.

Di veavakirina xerîdar de em pêwendiyek bi karûbarê echo re eşkere dikin:

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

Girêdayîn ji heman celebê karûbarê îxrackirî ye echoService. Bi taybetî, di muwekîlê echo de em heman protokolê hewce dikin. Ji ber vê yekê, dema ku du karûbaran ve girêdidin, em dikarin pê ewle bin ku her tişt dê rast bixebite.

Pêkanîna xizmetên

Ji bo destpêkirin û rawestandina karûbarê fonksiyonek pêdivî ye. (Qanûna rawestandina karûbarê ji bo ceribandinê krîtîk e.) Dîsa, ji bo pêkanîna taybetmendiyek wusa çend vebijark hene (mînak, em dikarin li gorî celebê veavakirinê çînên tîpan bikar bînin). Ji bo mebestên vê postê, em ê Patterna Cake bikar bînin. Em ê xizmetê bi karanîna polê temsîl bikin cats.Resource, ji ber Vê polê jixwe rê dide ku di bûyera pirsgirêkan de bi ewlehî serbestberdana çavkaniyan garantî bike. Ji bo bidestxistina çavkaniyek, pêdivî ye ku em veavakirin û çarçoveyek dema xebitandinê ya amade peyda bikin. Fonksiyona destpêkirina karûbarê dikare bi vî rengî xuya bike:

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

ko

  • Config - cureyê veavakirinê ji bo vê karûbarê
  • AddressResolver - Tiştek dema xebitandinê ya ku dihêle hûn navnîşanên girêkên din fêr bibin (li jêr binêre)

û cureyên din ji pirtûkxaneyê cats:

  • F[_] - celebê bandorê (di rewşa herî hêsan de F[A] dikare tenê fonksiyonek be () => A. Di vê postê de em ê bikar bînin cats.IO.)
  • Reader[A,B] - kêm-zêde bi fonksiyonê re hevwate ye A => B
  • cats.Resource - çavkaniyek ku dikare were bidestxistin û berdan
  • Timer - timer (dihêle hûn ji bo demekî xew bikin û navberên demê bipîvin)
  • ContextShift - analog ExecutionContext
  • Applicative - çînek celebek bandorek ku dihêle hûn bandorên kesane (hema hema monad) bi hev re bikin. Di sepanên tevlihevtir de ew çêtir xuya dike ku were bikar anîn Monad/ConcurrentEffect.

Bi karanîna vê nîşana fonksiyonê em dikarin gelek karûbaran bicîh bikin. Mînakî, karûbarek ku tiştek nake:

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

(Cm. kanî, ku tê de karûbarên din têne bicîh kirin - xizmeta echo, muwekîlê echo
и kontrolkerên jiyana.)

Nod tiştek e ku dikare gelek karûbaran bide destpêkirin (destpêkirina zincîreka çavkaniyan ji hêla Modela Cake ve tê misoger kirin):

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

Ji kerema xwe bala xwe bidin ku em celebek rast a veavakirinê ya ku ji bo vê girêk hewce dike diyar dikin. Ger em ji bîr bikin ku yek ji celebên vesazkirinê yên ku ji hêla karûbarek taybetî ve hewce ne diyar bikin, dê xeletiyek berhevkirinê hebe. Di heman demê de, em ê nikaribin girêkek dest pê bikin heya ku em hin tiştan ji celebê guncan digel hemî daneyên pêwîst peyda nekin.

Çareserkirina Navê Host

Ji bo girêdana bi mêvandarek dûr ve, em hewceyê navnîşek IP-ya rastîn in. Mimkun e ku navnîş ji yên mayî derengtir were zanîn. Ji ber vê yekê em pêdivî bi fonksiyonek heye ku ID-ya nodê li navnîşanek nexşe dike:

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

Gelek awayên pêkanîna vê fonksiyonê hene:

  1. Ger navnîşan berî bicîhkirinê ji me re têne zanîn, wê hingê em dikarin koda Scala bi hilberînin
    navnîşanan û paşê avakirinê bimeşînin. Ev ê testan berhev bike û bimeşîne.
    Di vê rewşê de, fonksiyon dê bi statîkî were zanîn û dikare di kodê de wekî nexşeyek were destnîşan kirin Map[NodeId, NodeAddress].
  2. Di hin rewşan de, navnîşana rastîn tenê piştî ku node dest pê kir tê zanîn.
    Di vê rewşê de, em dikarin "karûbarek vedîtinê" ku berî girêkên din dimeşe û hemî girêk dê bi vê karûbarê re qeyd bikin û navnîşanên girêkên din bixwazin.
  3. Ger em dikarin biguherînin /etc/hosts, wê hingê hûn dikarin navên mêvandar ên pêşwextkirî bikar bînin (wek my-project-main-node и echo-backend) û bi tenê van navan girêdin
    bi navnîşanên IP-ê di dema sazkirinê de.

Di vê postê de em ê van rewşan bi berfirehî nenirxînin. Ji bo me
di mînakek pêlîstokê de, hemî girêkan dê xwediyê heman navnîşana IP-yê bin - 127.0.0.1.

Piştre, em du vebijarkan ji bo pergalek belavkirî dihesibînin:

  1. Hemî karûbaran li ser yek nodê danîn.
  2. Û mêvandariya karûbarê echo û muwekîlê echo li ser girêkên cihêreng.

Veavakirina ji bo yek girêk:

Veavakirina yekane

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

Objekt veavakirina hem xerîdar û hem jî serverê pêk tîne. Veavakirinek dem-jiyînê jî tê bikar anîn da ku piştî navberê lifetime bernameyê biqedîne. (Ctrl-C di heman demê de hemî çavkaniyan rast dixebite û azad dike.)

Ji bo afirandina pergalek ku jê pêk tê, dikare heman koma veavakirin û taybetmendiyên pêkanînê were bikar anîn du girêkên cuda:

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

Giring! Bala xwe bidin ka karûbar çawa bi hev ve girêdayî ne. Em karûbarek ku ji hêla girêkek ve hatî bicîh kirin wekî pêkanîna rêbazek girêdayîbûna girêkek din destnîşan dikin. Cûreya girêdayîbûnê ji hêla berhevkar ve tê kontrol kirin, ji ber ku cureyê protokolê dihewîne. Dema ku were xebitandin, girêdayî dê ID-ya girêka hedefa rast hebe. Bi saya vê nexşeyê, em jimareya portê tam carekê diyar dikin û her gav garantî ne ku em li porta rast binihêrin.

Pêkanîna du girêkên pergalê

Ji bo vê veavakirinê, em heman pêkanînên karûbarê bêyî guhertin bikar tînin. Cûdahiya tenê ev e ku me naha du tişt hene ku karûbarên cihêreng bicîh dikin:

  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
  }

Nodeya yekem serverê pêk tîne û tenê pêdivî bi veavakirina serverê heye. Nodeya duyemîn xerîdar bicîh tîne û beşek cûda ya veavakirinê bikar tîne. Her weha her du girêk jî hewceyê rêveberiya jiyanê ne. Hêza serverê heta ku neyê rawestandin bêdawî dimeşîne SIGTERM'om, û girêka xerîdar piştî demekê bi dawî dibe. Cm. sepana destpêkirinê.

Pêvajoya pêşveçûna gelemperî

Ka em bibînin ka ev nêzîkatiya veavakirinê çawa bandorê li pêvajoya pêşkeftina giştî dike.

Veavakirin dê bi koda mayî re were berhev kirin û hunerek (.jar) dê were çêkirin. Wusa dixuye ku têgihîştinek e ku meriv veavakirinê di hunerek cûda de bihêle. Ev ji ber ku em dikarin li ser bingeha heman kodê gelek veavakirin hene. Dîsa, mimkun e ku hunerên ku bi şaxên mîhengên cihêreng re têkildar in biafirînin. Girêdanên li ser guhertoyên taybetî yên pirtûkxaneyan digel veavakirinê têne hilanîn, û her gava ku em biryar didin ku wê guhertoya veavakirinê bi cih bikin ev guhertoyên herheyî têne hilanîn.

Her guhertinek vesazkirinê vediguhere guherînek kodê. Û ji ber vê yekê, her yek
guhertin dê ji hêla pêvajoya ewlehiya kalîteya normal ve were vegirtin:

Bilêt di şopandina xeletiyê de -> PR -> vekolîn -> bi şaxên têkildar re bibin yek ->
entegrasyon -> bicihkirin

Encamên sereke yên pêkanîna mîhengek berhevkirî ev in:

  1. Veavakirin dê li seranserê hemî girêkên pergala belavkirî hevgirtî be. Ji ber ku hemî girêk ji çavkaniyek yekane heman veavakirinê distînin.

  2. Guhertina veavakirinê tenê di yek ji girêkan de pirsgirêk e. Ji ber vê yekê, "hilweşîna mîhengê" ne mimkûn e.

  3. Çêkirina guhertinên piçûk di veavakirinê de dijwartir dibe.

  4. Pir guheztinên vesazkirinê dê wekî beşek ji pêvajoya pêşkeftinê ya giştî pêk were û dê were lêkolîn kirin.

Ma ez pêdivî ye ku depoyek cihêreng da ku veavakirina hilberînê hilîne? Dibe ku ev veavakirin şîfre û agahiyên hesas ên din ên ku em dixwazin gihîştina wan sînordar bikin hebin. Li ser vê yekê, wusa dixuye ku meriv konfigurasyona paşîn li depoyek cihêreng hilîne. Hûn dikarin veavakirinê li du beşan dabeş bikin -yek ku mîhengên vesazkirinê yên gihîştî yên gelemperî vedihewîne û yek jî mîhengên sînorkirî vedihewîne. Ev ê dihêle ku piraniya pêşdebiran bigihîjin mîhengên hevpar. Vê veqetandinê bi karanîna taybetmendiyên navîn ên ku nirxên xwerû vedihewînin hêsan e.

Guhertoyên gengaz

Ka em hewl bidin ku veavakirina berhevkirî bi hin alternatîfên hevpar re bidin ber hev:

  1. Pelê nivîsê li ser makîneya armancê.
  2. Dikana nirx-kilît a navendî (etcd/zookeeper).
  3. Parçeyên pêvajoyê yên ku bêyî destpêkirina pêvajoyê ji nû ve têne mîheng kirin / dest pê kirin.
  4. Veavakirina li derveyî huner û guhertoya kontrolê hilîne.

Pelên nivîsê di warê guhertinên piçûk de nermbûnek girîng peyda dikin. Rêvebirê pergalê dikare têkeve girêka dûr, di pelên guncan de guheztinan bike û karûbarê ji nû ve bide destpêkirin. Ji bo pergalên mezin, lêbelê, nermbûnek wusa dibe ku ne xwestek be. Guhertinên hatine kirin di pergalên din de tu şopê nahêlin. Kes guhertinan nanirxîne. Zehmet e ku meriv diyar bike ka kê tam guhertin û ji ber çi sedemê çêkiriye. Guhertin nayên ceribandin. Ger pergal were belavkirin, wê hingê dibe ku rêveber ji bîr bike ku li ser girêkên din guhertina têkildar bike.

(Herwiha divê were zanîn ku bi karanîna veavakirinek berhevkirî îhtîmala karanîna pelên nivîsê di pêşerojê de nagire. Ew ê bes be ku parser û erêkerek ku heman celebê hilberê çêbike lê zêde bike. Config, û hûn dikarin pelên nivîsê bikar bînin. Ew tavilê dişopîne ku tevliheviya pergalek bi veavakirinek berhevkirî ji tevliheviya pergalê ku pelên nivîsê bikar tîne hinekî kêmtir e, ji ber ku pelên nivîsê kodek zêde hewce dike.)

Firoşgehek nirx-kilît a navendî mekanîzmayek baş e ji bo belavkirina pîvanên meta yên serîlêdanek belavkirî. Pêdivî ye ku em biryar bidin ka pîvanên mîhengê çi ne û tenê dane çi ne. Bila fonksiyonek me hebe C => A => B, û parametre C kêm caran diguhere, û daneyên A - gelek caran. Di vê rewşê de em dikarin bibêjin C - Parametreyên veavakirinê, û A - dane. Wusa dixuye ku pîvanên vesazkirinê ji daneyan cûda dibe ku ew bi gelemperî ji daneyan kêmtir caran diguhezin. Di heman demê de, dane bi gelemperî ji çavkaniyek (ji bikarhêner), û pîvanên vesazkirinê ji yeka din (ji rêvebirê pergalê) tê.

Ger kêm kêm parametreyên guheztinê hewce ne ku bêyî destpêkirina bernameyê ji nû ve werin nûve kirin, wê hingê ev pir caran dibe sedema tevliheviya bernameyê, ji ber ku em ê hewce bikin ku bi rengekî parametreyan radest bikin, hilînin, parkirin û kontrol bikin, û nirxên nerast pêvajoyê bikin. Ji ber vê yekê, ji nihêrîna kêmkirina tevliheviya bernameyê, maqûl e ku meriv hejmara parametreyên ku dikarin di dema xebata bernameyê de biguhezin kêm bikin (an jî hîç pîvanên weha piştgirî nakin).

Ji bo mebestên vê postê, em ê di navbera pîvanên statîk û dînamîkî de cûda bikin. Ger mantiqa karûbar di dema xebata bernameyê de pîvanan biguhezîne, wê hingê em ê van pîvanan wekî dînamîk bi nav bikin. Wekî din vebijark statîk in û dikarin bi karanîna veavakirina berhevkirî werin mîheng kirin. Ji bo veavakirina dînamîk, dibe ku me hewce bike mekanîzmayek ku beşên bernameyê bi pîvanên nû ji nû ve bidin destpêkirin, mîna ku pêvajoyên pergala xebitandinê ji nû ve têne destpêkirin. (Li gorî me, tê pêşniyar kirin ku ji nûveavakirina rast-demê dûr bikevin, ji ber ku ev tevliheviya pergalê zêde dike. Heke gengaz be, çêtir e ku meriv kapasîteyên OS-ya standard ji bo destpêkirina pêvajoyên nû bikar bîne.)

Yek aliyek girîng a karanîna veavakirina statîk ku mirovan dihêle ku veavakirina dînamîkî bihesibîne dema ku pêdivî ye ku pergalê piştî nûvekirinek veavakirinê (dema dakêşanê) ji nû ve dest pê bike. Di rastiyê de, ger hewce bike ku em di veavakirina statîk de guheztinan bikin, ji bo ku nirxên nû bandor bibin divê em pergalê ji nû ve bidin destpêkirin. Pirsgirêka daketinê ji bo pergalên cihêreng giraniya xwe diguhere. Di hin rewşan de, hûn dikarin di demekê de ku bar kêmtirîn e, ji nû ve dest pê bikin. Heke hûn hewce ne ku karûbarê domdar peyda bikin, hûn dikarin bicîh bikin Têkiliya AWS ELB diherike. Di heman demê de, gava ku em hewce ne ku pergalê ji nû ve bidin destpêkirin, em mînakek paralel a vê pergalê dest pê dikin, balanserê wê vediguhezînin, û li benda qedandina girêdanên kevn in. Piştî ku hemî girêdanên kevn qediyan, me mînaka kevn a pergalê qut kir.

Ka em naha mijara hilanîna mîhengê li hundur an derveyî hunerê bifikirin. Ger em veavakirinê di hundurê hunerê de hilînin, wê hingê bi kêmanî me fersendek hebû ku di dema komkirina hunerê de rastbûna veavakirinê verast bikin. Ger veavakirin li derveyî hunera kontrolkirî be, dijwar e ku meriv bişopîne ka kê guheztinên vê pelê çêkiriye û çima. Çiqas girîng e? Bi dîtina me, ji bo gelek pergalên hilberînê girîng e ku vesazkirinek bi îstîqrar û kalîteyê hebe.

Guhertoya artifactê dihêle hûn diyar bikin ka ew kengê hatî afirandin, kîjan nirxan dihewîne, kîjan fonksiyonên çalak / neçalak in, û kî berpirsiyar e ji her guhartina veavakirinê. Bê guman, hilanîna veavakirinê di hundurê hunerê de hin hewil hewce dike, ji ber vê yekê hûn hewce ne ku biryarek agahdar bidin.

The pro û aliyan

Ez dixwazim li ser erênî û neyînîyên teknolojiya pêşniyarkirî bisekinim.

avantajên

Li jêr navnîşek taybetmendiyên sereke yên veavakirina pergala belavkirî ya berhevkirî heye:

  1. Kontrola veavakirina statîk. Destûrê dide we ku hûn pê ewle bin
    veavakirina rast e.
  2. Zimanê veavakirina dewlemend. Bi gelemperî, rêbazên din ên vesazkirinê herî zêde bi veguheztina guhêrbar a rêzê ve têne sînorkirin. Dema ku Scala bikar tînin, cûrbecûr taybetmendiyên zimanî hene ku mîhengê we çêtir bikin. Mînak em dikarin bikar bînin
    taybetmendiyên ji bo nirxên xwerû, bi karanîna tiştan ji bo parametreyên komê, em dikarin valên ku tenê carekê hatine ragihandin (DRY) di çarçoveyek dorpêçkirî de binav bikin. Hûn dikarin her dersan rasterast di hundurê veavakirinê de destnîşan bikin (Seq, Map, dersên xwerû).
  3. DSL. Scala gelek taybetmendiyên zimanî hene ku çêkirina DSL-ê hêsantir dike. Mimkun e ku meriv ji van taybetmendiyan sûd werbigire û zimanek veavakirinê ku ji bo koma hedefa bikarhêneran rehettir e bicîh bîne, da ku veavakirin bi kêmî ve ji hêla pisporên domainê ve were xwendin. Pispor dikarin, wek nimûne, beşdarî pêvajoya vekolîna veavakirinê bibin.
  4. Yekbûn û hevdemî di navbera girêkan de. Yek ji avantajên ku veavakirina tevahî pergala belavbûyî li yek xalek hatî hilanîn ev e ku hemî nirx tam carekê têne ragihandin û dûv re li ku derê hewce ne ji nû ve têne bikar anîn. Bikaranîna celebên fantom ji bo ragihandina benderan piştrast dike ku nod di hemî mîhengên pergalê yên rast de protokolên lihevhatî bikar tînin. Di navbera nokan de girêdanên mecbûrî yên eşkere piştrast dike ku hemî karûbar bi hev ve girêdayî ne.
  5. Guhertinên kalîteya bilind. Guhertinên veavakirinê bi karanîna pêvajoyek pêşkeftina hevpar dihêle ku meriv ji bo veavakirinê jî standardên kalîteya bilind bi dest bixe.
  6. Nûvekirina veavakirina hevdemî. Sazkirina pergalê ya otomatîk piştî guheztinên mîhengê piştrast dike ku hemî nod têne nûve kirin.
  7. Hêsankirina serîlêdanê. Serlêdan hewcedariya parsek, kontrolkirina veavakirinê, an bi karanîna nirxên xelet nake. Ev tevliheviya serîlêdanê kêm dike. (Hin ji tevliheviya veavakirinê ku di mînaka me de têne dîtin ne taybetmendiyek veavakirina berhevkirî ye, lê tenê biryarek hişmend e ku ji ber xwestek ji bo peydakirina ewlehiya celebek mezintir tê rêve kirin.) Vegera li veavakirina asayî pir hêsan e - tenê ya winda bicîh bikin parçeyên. Ji ber vê yekê, hûn dikarin, mînakî, bi mîhengek berhevkirî dest pê bikin, pêkanîna beşên nehewce taloq bikin heya dema ku ew bi rastî hewce be.
  8. Veavakirina verastkirî. Ji ber ku guhertinên mîhengê çarenûsa asayî ya her guhertinên din dişopînin, encamek ku em distînin hunerek bi guhertoyek bêhempa ye. Ev rê dide me, bo nimûne, ku ger hewce be vegere guhertoyek berê ya veavakirinê. Tewra em dikarin veavakirina salek berê bikar bînin û pergal dê bi heman rengî bixebite. Veavakirinek stabîl pêşbînbûn û pêbaweriya pergalek belavbûyî çêtir dike. Ji ber ku veavakirin di qonaxa berhevkirinê de rast e, di hilberînê de sextekirina wê pir dijwar e.
  9. Modularity. Çarçoveya pêşniyarkirî modular e û modul dikarin bi awayên cûda bêne hev kirin ku pergalên cûda çêbikin. Bi taybetî, hûn dikarin pergalê mîheng bikin da ku di yek pêkvekirinê de li ser girêkek yekane, û di yekî din de li ser gelek girêkan bixebite. Hûn dikarin ji bo nimûneyên hilberîna pergalê gelek veavakirinan biafirînin.
  10. Testing. Bi guheztina karûbarên kesane bi tiştên xapînok, hûn dikarin çend guhertoyên pergalê yên ku ji bo ceribandinê rehet in bistînin.
  11. testkirina entegrasyonê. Ji bo tevahiya pergala belavkirî vesazkirinek yekane dihêle ku meriv hemî pêkhateyan di hawîrdorek kontrolkirî de wekî beşek ceribandina entegrasyonê bimeşîne. Mînakî, rewşek ku hin girêk bigihîjin hev, hêsan e.

Dezawantaj û sînor

Veavakirina berhevkirî ji nêzîkatiyên din ên veavakirinê cûda dibe û dibe ku ji bo hin serlêdanan negunca be. Li jêr hinek kêmasiyan hene:

  1. Veavakirina statîk. Carinan hûn hewce ne ku zû veavakirinê di hilberînê de rast bikin, hemî mekanîzmayên parastinê derbas bikin. Bi vê nêzîkatiyê dikare dijwartir bibe. Bi kêmanî, berhevkirin û bicîhkirina otomatîkî dê hîn jî hewce bike. Ev hem taybetmendiyek kêrhatî ya nêzîkbûnê ye û hem jî di hin rewşan de dezavantajek e.
  2. nifşê veavakirinê. Ger pelê veavakirinê ji hêla amûrek otomatîk ve were çêkirin, dibe ku ji bo yekkirina skrîpta çêkirinê hewildanên zêde hewce bike.
  3. Amûrên. Heya nuha, karûbar û teknîkên ku ji bo xebitandina mîhengê hatine çêkirin li ser pelên nivîsê ne. Hemî karûbar/teknîkên weha dê di veavakirinek berhevkirî de peyda nebin.
  4. Guhertina helwestan pêwîst e. Pêşdebir û DevOps bi pelên nivîsê re fêr bûne. Hema ramana berhevkirina vesazkirinê dibe ku hinekî nediyar û ne asayî be û bibe sedema redkirinê.
  5. Pêvajoyek pêşveçûna kalîteya bilind hewce ye. Ji bo ku hûn bi rehetî veavakirina berhevkirî bikar bînin, otomatîkkirina tevahî ya pêvajoya çêkirin û bicîhkirina serîlêdanê (CI/CD) hewce ye. Wekî din ew ê pir nerehet be.

Werin em her weha li ser çend sînorkirinên mînaka berçav a ku bi ramana veavakirinek berhevkirî re ne têkildar rawestin:

  1. Ger em agahdariya mîhengê ya nepêwist ku ji hêla girêkê ve nayê bikar anîn peyda bikin, wê hingê berhevkar dê alîkariya me neke ku pêkanîna wenda nas bike. Ev pirsgirêk bi terikandina Nimûneya Cake û karanîna celebên hişktir dikare were çareser kirin, mînakî, HList an celebên daneya cebrî (dersên dozê) ji bo temsîlkirina veavakirinê.
  2. Di pelê veavakirinê de rêz hene ku bi xwe veavakirinê re ne têkildar in: (package, import,daxuyaniyên tiştan; override def's ji bo parametreyên ku nirxên xwerû hene). Ger hûn DSL-ya xwe bicîh bînin ev dikare bi qismî were dûr kirin. Wekî din, cûreyên din ên veavakirinê (mînak, XML) jî li ser avahiya pelê hin sînoran ferz dikin.
  3. Ji bo mebestên vê postê, em ji nû veavakirina dînamîkî ya komek girêkên mîna hev nahesibînin.

encamê

Di vê postê de, me ramana temsîlkirina veavakirinê di koda çavkaniyê de bi karanîna kapasîteyên pêşkeftî yên pergala celebê Scala vekoland. Ev nêzîkatî dikare di sepanên cihêreng de wekî şûna rêbazên veavakirina kevneşopî yên ku li ser bingeha pelên xml an nivîsê têne bikar anîn. Her çend mînaka me di Scala de hatî bicîh kirin jî, heman raman dikarin li zimanên din ên berhevkirî (wek Kotlin, C#, Swift, ...) werin veguheztin. Hûn dikarin vê nêzîkatiyê di yek ji projeyên jêrîn de biceribînin, û heke ew nexebite, biçin pelê nivîsê, parçeyên winda zêde bikin.

Bi xwezayî, veavakirinek berhevkirî pêvajoyek pêşkeftina kalîteya bilind hewce dike. Di vegerê de, kalîteya bilind û pêbaweriya mîhengan tê peyda kirin.

Nêzîkatiya fikirîn dikare were berfireh kirin:

  1. Hûn dikarin makroyan bikar bînin da ku kontrolên dema berhevkirinê bikin.
  2. Hûn dikarin DSL-ê bicîh bikin da ku veavakirinê bi rengek ku ji bikarhênerên dawîn re bigihîjin pêşkêş bikin.
  3. Hûn dikarin rêveberiya çavkaniya dînamîkî bi verastkirina veavakirina otomatîkî bicîh bînin. Mînakî, guhertina hejmara girêkên di komê de hewce dike ku (1) her girêk vesazkirinek hinekî cûda werbigire; (2) rêveberê komê di derheqê girêkên nû de agahdarî wergirt.

Spasdarî

Ez dixwazim spasiya Andrey Saksonov, Pavel Popov û Anton Nekhaev bikim ji bo rexneyên wan ên çêker ên li ser pêşnûmeya gotarê.

Source: www.habr.com

Add a comment