Конфигуратсияи тартибдодашудаи системаи тақсимшуда

Дар ин мақола мо мехоҳем як роҳи ҷолиби мубориза бо конфигуратсияи системаи тақсимшударо мубодила кунем.
Конфигуратсия мустақиман бо забони Scala ба таври бехатар муаррифӣ карда мешавад. Намунаи амалӣ дар муфассал тавсиф карда шудааст. Ҷанбаҳои гуногуни пешниҳод, аз ҷумла таъсир ба раванди рушди умумӣ баррасӣ мешаванд.

Конфигуратсияи тартибдодашудаи системаи тақсимшуда

(бо забони русӣ)

Муқаддима

Сохтани системаҳои тақсимшудаи мустаҳкам истифодаи конфигуратсияи дуруст ва ҳамоҳангро дар ҳама гиреҳҳо талаб мекунад. Ҳалли маъмулӣ ин истифодаи тавсифи матнии ҷойгиркунӣ (терраформ, ansible ё чизи шабеҳ) ва файлҳои конфигуратсияи ба таври худкор тавлидшуда (аксар вақт - барои ҳар як гиреҳ/нақш бахшида шудааст) мебошад. Мо инчунин мехоҳем ҳамон протоколҳои версияҳои якхеларо дар ҳар як гиреҳи муошират истифода барем (дар акси ҳол мо бо мушкилоти номувофиқӣ дучор мешавем). Дар ҷаҳони JVM ин маънои онро дорад, ки ҳадди аққал китобхонаи паёмнависӣ бояд дар ҳама гиреҳҳои муошират як версия бошад.

Дар бораи санҷиши система чӣ гуфтан мумкин аст? Албатта, мо бояд пеш аз ворид шудан ба санҷишҳои ҳамгироӣ барои ҳама ҷузъҳо санҷишҳои воҳид гузаронем. Барои он ки натиҷаҳои санҷишро дар вақти корӣ экстраполятсия карда тавонем, мо бояд боварӣ ҳосил кунем, ки версияҳои ҳамаи китобхонаҳо ҳам дар вақти корӣ ва ҳам дар муҳити озмоишӣ якхела нигоҳ дошта мешаванд.

Ҳангоми гузаронидани санҷишҳои ҳамгироӣ, дар ҳама гиреҳҳо доштани як роҳи синф одатан осонтар аст. Мо танҳо бояд боварӣ ҳосил кунем, ки ҳамон як роҳи синф ҳангоми ҷойгиркунӣ истифода мешавад. (Истифодаи роҳҳои синфҳои гуногун дар гиреҳҳои гуногун имконпазир аст, аммо муаррифии ин конфигуратсия ва дуруст ҷобаҷогузории он мушкилтар аст.) Ҳамин тавр, барои содда нигоҳ доштани чизҳо мо танҳо роҳҳои синфҳои якхеларо дар ҳама гиреҳҳо баррасӣ хоҳем кард.

Конфигуратсия тамоюли дар якҷоягӣ бо нармафзор инкишоф меёбад. Мо одатан версияҳоро барои муайян кардани гуногун истифода мебарем
марҳилаҳои эволютсияи нармафзор. Ба назар чунин менамояд, ки конфигуратсияро дар зери идоракунии версия фаро гирифтан ва конфигуратсияҳои гуногунро бо баъзе нишонаҳо муайян кардан лозим аст. Агар дар истеҳсол танҳо як конфигуратсия мавҷуд бошад, мо метавонем версияи ягонаро ҳамчун идентификатор истифода барем. Баъзан мо метавонем якчанд муҳити истеҳсолӣ дошта бошем. Ва барои ҳар як муҳити мо шояд як шохаи алоҳидаи конфигуратсия лозим шавад. Ҳамин тавр, конфигуратсияҳо метавонанд бо шоха ва версия қайд карда шаванд, то конфигуратсияҳои гуногунро ба таври беназир муайян кунанд. Ҳар як тамғаи шоха ва версия ба маҷмӯи ягонаи гиреҳҳои тақсимшуда, портҳо, захираҳои беруна, версияҳои китобхонаи синфҳои дар ҳар як гиреҳ мувофиқат мекунанд. Дар ин ҷо мо танҳо як шохаи ягонаро фаро мегирем ва конфигуратсияҳоро аз рӯи версияи се компоненти даҳӣ (1.2.3), ба мисли дигар артефактҳо муайян мекунем.

Дар муҳитҳои муосир файлҳои конфигуратсия дигар ба таври дастӣ тағир дода намешаванд. Одатан мо тавлид мекунем
файлҳои конфигуратсия дар вақти ҷойгиркунӣ ва ҳеҷ гоҳ ба онҳо даст нарасонед баъд. Пас метавон пурсид, ки чаро мо то ҳол формати матниро барои файлҳои конфигуратсия истифода мебарем? Варианти қобили қабул ин ҷойгир кардани конфигуратсия дар дохили як воҳиди компилятсионӣ ва фоида аз тасдиқи конфигуратсияи вақти компиляция мебошад.

Дар ин мақола мо идеяи нигоҳ доштани конфигуратсияро дар артефакти тартибдодашуда баррасӣ хоҳем кард.

Конфигуратсияи компилятсионӣ

Дар ин бахш мо мисоли конфигуратсияи статикиро баррасӣ хоҳем кард. Ду хидмати оддӣ - хидмати эхо ва муштарии хидмати echo танзим ва татбиқ карда мешаванд. Сипас ду системаи тақсимоти гуногун бо ҳарду хидматҳо ба вуҷуд меоянд. Яке барои конфигуратсияи як гиреҳ ва дигаре барои конфигуратсияи ду гиреҳ аст.

Системаи маъмулии тақсимшуда аз якчанд гиреҳ иборат аст. Гиреҳҳоро метавон бо истифода аз як навъ муайян кард:

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

ё танҳо

case class NodeId(hostName: String)

ё ҳатто

object Singleton
type NodeId = Singleton.type

Ин гиреҳҳо нақшҳои гуногунро иҷро мекунанд, баъзе хидматҳоро иҷро мекунанд ва бояд бо дигар гиреҳҳо тавассути пайвастҳои TCP/HTTP муошират кунанд.

Барои пайвасти TCP ҳадди аққал рақами порт лозим аст. Мо инчунин мехоҳем боварӣ ҳосил кунем, ки муштарӣ ва сервер як протоколро гуфтугӯ мекунанд. Барои моделсозии пайвастшавӣ байни гиреҳҳо, биёед синфи зеринро эълон кунем:

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

ки дар Port танҳо як Int дар доираи иҷозатдодашуда:

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

Намудҳои тозашуда

дидан тозашуда китобхона. Хулоса, он имкон медиҳад, ки ба намудҳои дигар маҳдудиятҳои вақти тартибдиҳӣ илова карда шаванд. Дар ин маврид Int танҳо иҷозат дода мешавад, ки арзишҳои 16-бит дошта бошанд, ки рақами портро нишон дода метавонанд. Барои истифодаи ин китобхона барои ин равиши конфигуратсия талаб карда намешавад. Чунин ба назар мерасад, ки он хеле хуб мувофиқат мекунад.

Барои HTTP (REST) ​​ба мо инчунин метавонад роҳи хидмат лозим бошад:

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

Навъи фантом

Барои муайян кардани протокол ҳангоми тартибдиҳӣ мо хусусияти Scala-и эъломияи аргументи навъиро истифода мебарем. Protocol ки дар синф истифода намешавад. Ин ба ном аст намуди фантом. Дар вақти кор ба мо хеле кам ба намунаи идентификатори протокол ниёз дорем, аз ин рӯ мо онро нигоҳ намедорем. Ҳангоми тартиб додани ин навъи фантом бехатарии иловагии навъиро медиҳад. Мо наметавонем портро бо протоколи нодуруст гузаронем.

Яке аз протоколҳои васеъ истифодашаванда REST API бо силсилаи Json мебошад:

sealed trait JsonHttpRestProtocol[RequestMessage, ResponseMessage]

ки дар RequestMessage навъи асосии паёмҳоест, ки муштарӣ метавонад ба сервер ирсол кунад ва ResponseMessage паёми ҷавобӣ аз сервер аст. Албатта, мо метавонем тавсифҳои дигари протоколро эҷод кунем, ки протоколи иртиботро бо дақиқии дилхоҳ муайян мекунанд.

Барои мақсадҳои ин мақола мо версияи соддатари протоколро истифода мебарем:

sealed trait SimpleHttpGetRest[RequestMessage, ResponseMessage]

Дар ин протокол паёми дархост ба url замима карда мешавад ва паёми посух ҳамчун сатри оддӣ бармегардад.

Конфигуратсияи хадамотро метавон бо номи хадамот, маҷмӯи портҳо ва баъзе вобастагӣ тавсиф кард. Якчанд роҳҳои имконпазири муаррифии ҳамаи ин унсурҳо дар Scala вуҷуд доранд (масалан, HList, намудҳои додаҳои алгебравӣ). Барои мақсадҳои ин мақола мо намунаи тортро истифода мебарем ва қисмҳои якҷояшавандаро (модулҳоро) ҳамчун хислатҳо муаррифӣ мекунем. (Шакли торт талабот барои ин равиши конфигуратсияи тартибдодашаванда нест. Ин танҳо як амали имконпазири идея аст.)

Вобастагиҳоро метавон бо истифода аз намунаи торт ҳамчун нуқтаи ниҳоии гиреҳҳои дигар муаррифӣ кард:

  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 танҳо ба порти танзимшуда ниёз дорад. Ва мо изҳор медорем, ки ин порт протоколи echo -ро дастгирӣ мекунад. Дар хотир доред, ки дар айни замон ба мо лозим нест, ки бандари мушаххасро муайян кунем, зеро хислатҳо ба эъломияи усулҳои абстрактӣ иҷозат медиҳанд. Агар мо усулҳои абстрактиро истифода барем, компилятор татбиқро дар мисоли конфигуратсия талаб мекунад. Дар ин ҷо мо татбиқро таъмин кардем (8081) ва он ҳамчун арзиши пешфарз истифода мешавад, агар мо онро дар конфигуратсияи мушаххас гузаред.

Мо метавонем вобастагӣ дар конфигуратсияи муштарии хидмати echo эълон кунем:

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

Вобастагӣ бо ҳамон намуд дорад echoService. Аз чумла, хамин протоколро талаб мекунад. Аз ин рӯ, мо итминон дошта метавонем, ки агар мо ин ду вобастагиро пайваст кунем, онҳо дуруст кор мекунанд.

Татбиқи хидматҳо

Барои оғоз кардан ва ба таври зебо хомӯш кардани хидмат хидмат ба функсия ниёз дорад. (Қобилияти қатъ кардани хидмат барои санҷиш муҳим аст.) Боз чанд варианти муайян кардани чунин функсия барои конфигуратсияи додашуда вуҷуд дорад (масалан, мо метавонем синфҳои навъиро истифода барем). Барои ин мақола мо бори дигар намунаи тортро истифода мебарем. Мо метавонем хидматеро бо истифода аз он муаррифӣ кунем cats.Resource ки аллакай қавс ва озод кардани захираҳоро таъмин мекунад. Барои ба даст овардани манбаъ мо бояд конфигуратсия ва контексти вақти корӣ пешниҳод кунем. Ҳамин тавр, функсияи оғози хидмат метавонад чунин бошад:

  type ResourceReader[F[_], Config, A] = Reader[Config, Resource[F, A]]

  trait ServiceImpl[F[_]] {
    type Config
    def resource(
      implicit
      resolver: AddressResolver[F],
      timer: Timer[F],
      contextShift: ContextShift[F],
      ec: ExecutionContext,
      applicative: Applicative[F]
    ): ResourceReader[F, Config, Unit]
  }

ки дар

  • Config — намуди конфигуратсияе, ки аз ҷониби ин оғозкунандаи хидмат талаб карда мешавад
  • AddressResolver — объекти вақти корӣ, ки қобилияти гирифтани суроғаҳои воқеии гиреҳҳои дигарро дорад (барои тафсилот хонданро давом диҳед).

навъхои дигар аз cats:

  • F[_] — намуди таъсир (Дар соддатарин ҳолат F[A] одил шуда метавонист () => A. Дар ин мақола мо истифода хоҳем кард cats.IO.)
  • Reader[A,B] — каму беш синоними функсия аст A => B
  • cats.Resource — роххои ба даст овардан ва озод кардан дорад
  • Timer — барои хобидан/вакт чен кардан имкон медихад
  • ContextShift - аналоги ExecutionContext
  • Applicative - бастаи функсияҳои амалкунанда (қариб як монад) (дар ниҳоят мо метавонем онро бо чизи дигар иваз кунем)

Бо истифода аз ин интерфейс мо метавонем якчанд хидматҳоро амалӣ кунем. Масалан, хидмате, ки ҳеҷ кор намекунад:

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

(Нигаред Рамзи манбаъ барои татбиқи дигар хидматҳо - хидмати эхо,
муштарии эхо ва контроллерҳои умр.)

Гиреҳ як объекти ягонаест, ки якчанд хидматҳоро иҷро мекунад (оғоз кардани занҷири захираҳо аз ҷониби Cake Pattern фаъол карда мешавад):

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

Дар хотир доред, ки дар гиреҳ мо навъи дақиқи конфигуратсияро, ки ба ин гиреҳ лозим аст, муайян мекунем. Компилятор ба мо иҷозат намедиҳад, ки объектро (Торт) бо навъи нокифоя созем, зеро ҳар як хусусияти хидматрасонӣ маҳдудиятро дар он эълон мекунад. Config навъи. Инчунин мо наметавонем гиреҳро бидуни таъмини конфигуратсияи пурра оғоз кунем.

Ҳалли суроғаи гиреҳ

Барои барқарор кардани пайвастшавӣ ба мо суроғаи воқеии мизбон барои ҳар як гиреҳ лозим аст. Он метавонад дертар аз қисмҳои дигари конфигуратсия маълум шавад. Аз ин рӯ, ба мо роҳе лозим аст, ки харитасозӣ байни ID гиреҳ ва суроғаи воқеии он пешниҳод кунем. Ин харитасозӣ як функсия аст:

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

Якчанд роҳҳои имконпазири татбиқи чунин функсия вуҷуд доранд.

  1. Агар мо суроғаҳои воқеиро пеш аз ҷойгиркунӣ донем, дар вақти эҷоди ҳостҳои гиреҳ, мо метавонем рамзи Scala-ро бо суроғаҳои воқеӣ тавлид кунем ва баъд аз он сохтмонро иҷро кунем (ки тафтиши вақтро тартиб медиҳад ва сипас маҷмӯи санҷиши интегратсияро иҷро мекунад). Дар ин ҳолат, функсияи харитасозии мо ба таври статикӣ маълум аст ва метавонад ба чизе ба монанди a содда карда шавад Map[NodeId, NodeAddress].
  2. Баъзан мо суроғаҳои воқеиро танҳо дар лаҳзаи дертар, вақте ки гиреҳ воқеан оғоз мешавад, ба даст меорем ё мо суроғаҳои гиреҳҳоеро, ки ҳанӯз оғоз нашудаанд, надорем. Дар ин ҳолат, мо метавонем хидмати кашфе дошта бошем, ки пеш аз ҳама гиреҳҳои дигар оғоз мешавад ва ҳар як гиреҳ метавонад суроғаи худро дар ин хидмат таблиғ кунад ва ба вобастагӣ обуна шавад.
  3. Агар мо метавонем тағир диҳем /etc/hosts, мо метавонем номҳои мизбони пешакӣ муайяншударо истифода барем (масалан my-project-main-node ва echo-backend) ва танҳо ин номро бо суроғаи IP дар вақти ҷойгиркунӣ алоқаманд кунед.

Дар ин мақола мо ин парвандаҳоро ба таври муфассал шарҳ намедиҳем. Дар асл дар мисоли бозичаҳои мо ҳама гиреҳҳо суроғаи IP-и якхела доранд - 127.0.0.1.

Дар ин мақола мо ду тарҳбандии системаҳои тақсимшударо баррасӣ хоҳем кард:

  1. Тарҳбандии гиреҳи ягона, ки дар он ҳама хидматҳо дар гиреҳи ягона ҷойгир шудаанд.
  2. Ду тарҳбандии гиреҳ, ки дар он хидмат ва муштарӣ дар гиреҳҳои гуногун ҷойгиранд.

Конфигуратсия барои а гиреҳи ягона тарҳ чунин аст:

Конфигуратсияи гиреҳи ягона

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

Дар ин ҷо мо конфигуратсияи ягонаеро эҷод мекунем, ки ҳам конфигуратсияи сервер ва ҳам муштариро васеъ мекунад. Мо инчунин як контролери давраи ҳаётро танзим мекунем, ки одатан пас аз он мизоҷ ва серверро қатъ мекунад lifetime фосила мегузарад.

Барои сохтани тарҳбандии система бо ду гиреҳи ҷудогона як маҷмӯи татбиқ ва конфигуратсияҳои хидматрасониро метавон истифода бурд. Мо танҳо бояд эҷод кунем ду конфигуратсияи гиреҳи алоҳида бо хидматҳои мувофиқ:

Конфигуратсияи ду гиреҳ

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

Бубинед, ки мо вобастагиро чӣ гуна муайян мекунем. Мо хидмати дигари гиреҳро ҳамчун вобастагии гиреҳи ҷорӣ зикр мекунем. Навъи вобастагӣ санҷида мешавад, зеро он дорои навъи фантомест, ки протоколро тавсиф мекунад. Ва дар вақти корӣ мо ID гиреҳи дурустро хоҳем дошт. Ин яке аз ҷанбаҳои муҳими равиши конфигуратсияи пешниҳодшуда мебошад. Он ба мо имкон медиҳад, ки портро танҳо як маротиба насб кунем ва боварӣ ҳосил кунем, ки мо ба порти дуруст ишора мекунем.

Амалисозии ду гиреҳ

Барои ин конфигуратсия мо маҳз ҳамон амалҳои хидматҳоро истифода мебарем. Умуман тағирот нест. Аммо, мо ду амалисозии гиреҳҳои гуногунро эҷод мекунем, ки маҷмӯи хидматҳои гуногунро дар бар мегиранд:

  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
  }

Гиреҳи аввал серверро амалӣ мекунад ва ба он танҳо конфигуратсияи тарафи сервер ниёз дорад. Гиреҳи дуюм муштариро амалӣ мекунад ва ба қисми дигари конфигуратсия ниёз дорад. Ҳарду гиреҳ баъзе мушаххасоти умрро талаб мекунанд. Барои мақсадҳои ин гиреҳи хидматрасонии почта мӯҳлати беохир дорад, ки метавонад бо истифода аз он қатъ карда шавад SIGTERM, дар ҳоле ки муштарии echo пас аз давомнокии ниҳоии танзимшуда қатъ мешавад. нигаред барномаи оғоз Барои маълумоти.

Раванди рушди умумӣ

Биёед бубинем, ки ин равиш тарзи корамонро бо конфигуратсия чӣ гуна тағир медиҳад.

Конфигуратсия ҳамчун код тартиб дода мешавад ва артефактро тавлид мекунад. Ба назар чунин менамояд, ки артефакти конфигуратсияро аз дигар артефактҳои код ҷудо кунед. Аксар вақт мо метавонем конфигуратсияҳои сершуморро дар як пойгоҳи код дошта бошем. Ва албатта, мо метавонем версияҳои сершумори шохаҳои гуногуни конфигуратсия дошта бошем. Дар конфигуратсия мо метавонем версияҳои мушаххаси китобхонаҳоро интихоб кунем ва ин ҳар вақте ки мо ин конфигуратсияро ҷойгир мекунем, доимӣ мемонад.

Тағироти конфигуратсия ба тағири код табдил меёбад. Пас, он бояд бо ҳамон раванди кафолати сифат фаро гирифта шавад:

Чипта -> PR -> барраси -> якҷоякунӣ -> ҳамгироии муттасил -> густариши пайваста

Оқибатҳои зерини муносибат вуҷуд доранд:

  1. Конфигуратсия барои мисоли система мувофиқ аст. Чунин ба назар мерасад, ки ҳеҷ гуна робитаи нодурусти байни гиреҳҳо вуҷуд надорад.
  2. Тағир додани конфигуратсия танҳо дар як гиреҳ осон нест. Ворид шудан ва тағир додани баъзе файлҳои матнӣ беасос ба назар мерасад. Ҳамин тавр, тағирёбии конфигуратсия камтар имконпазир мегардад.
  3. Тағироти конфигуратсияи хурд осон нест.
  4. Аксарияти тағироти конфигуратсия ҳамон як раванди таҳияро пайгирӣ мекунанд ва аз баррасии он мегузарад.

Оё барои конфигуратсияи истеҳсолот ба мо анбори алоҳида лозим аст? Конфигуратсияи истеҳсолӣ метавонад дорои маълумоти ҳассос бошад, ки мо мехоҳем онҳоро аз дастрасии бисёр одамон дур нигоҳ дорем. Ҳамин тавр, нигоҳ доштани як анбори алоҳида бо дастрасии маҳдуд, ки конфигуратсияи истеҳсолиро дар бар мегирад, бамаврид аст. Мо метавонем конфигуратсияро ба ду қисм тақсим кунем - яке, ки параметрҳои кушодатарини истеҳсолот ва қисми махфии конфигуратсияро дар бар мегирад. Ин имкон медиҳад, ки дастрасӣ ба аксари таҳиягарон ба аксари параметрҳо ҳангоми маҳдуд кардани дастрасӣ ба чизҳои воқеан ҳассос. Бо истифода аз хислатҳои мобайнӣ бо арзишҳои пешфарз ин корро анҷом додан осон аст.

Вариантҳо

Биёед тарафҳои мусбат ва манфии равиши пешниҳодшударо дар муқоиса бо дигар усулҳои идоракунии конфигуратсия бубинем.

Пеш аз ҳама, мо якчанд алтернативаҳоро ба ҷанбаҳои гуногуни роҳи пешниҳодшудаи муносибат бо конфигуратсия номбар мекунем:

  1. Файли матнӣ дар мошини мавриди ҳадаф.
  2. Нигоҳдории мутамаркази арзиши калид (масалан etcd/zookeeper).
  3. Ҷузъҳои зерпросес, ки метавонанд бе раванди аз нав оғоз карда шаванд, аз нав танзим кардан/аз нав оғоз кардан мумкин аст.
  4. Конфигуратсия берун аз артефакт ва версияи назорати.

Файли матнӣ дар робита ба ислоҳи муваққатӣ чандирӣ медиҳад. Администратори система метавонад ба гиреҳи ҳадаф ворид шуда, тағирот ворид кунад ва хидматро бозоғоз кунад. Ин метавонад барои системаҳои калонтар он қадар хуб набошад. Дар паси тағирот ҳеҷ осоре боқӣ намондааст. Тағйирот аз ҷониби як ҷуфти дигар дида намешавад. Мумкин аст фаҳмидани он ки сабаби тағирот чист, душвор бошад. Он санҷида нашудааст. Аз нуқтаи назари системаи тақсимшуда, маъмур метавонад навсозии конфигуратсияро дар яке аз гиреҳҳои дигар фаромӯш кунад.

(Btw, агар дар ниҳоят барои оғоз кардани истифодаи файлҳои конфигуратсияи матнӣ лозим шавад, мо бояд танҳо таҳлилгар + валидаторро илова кунем, ки метавонад якхеларо тавлид кунад. Config нависед ва ин барои оғози истифодаи конфигуратсияҳои матн кофӣ хоҳад буд. Ин инчунин нишон медиҳад, ки мураккабии конфигуратсияи вақти компиляция нисбат ба мураккабии конфигуратсияҳои матнӣ каме хурдтар аст, зеро дар версияи матнӣ ба мо коди иловагӣ лозим аст.)

Нигоҳдории мутамаркази арзишҳои калидӣ як механизми хуб барои паҳн кардани параметрҳои мета барнома мебошад. Дар ин ҷо мо бояд дар бораи он фикр кунем, ки мо арзишҳои конфигуратсияро меҳисобем ва он чӣ танҳо маълумот аст. Функсия дода мешавад C => A => B мо одатан арзишҳои кам тағйирёбанда меномем C "конфигуратсия", дар ҳоле ки маълумот зуд-зуд иваз карда мешавад A - танҳо маълумотро ворид кунед. Конфигуратсия бояд ба функсия пеш аз маълумот дода шавад A. Бо дарназардошти ин идея мо метавонем бигӯем, ки он басомади тағирот дар назар аст, ки он метавонад барои фарқ кардани маълумоти конфигуратсия аз додаҳо истифода шавад. Инчунин маълумот одатан аз як манбаъ (корбар) ва конфигуратсия аз манбаи дигар (администратор) меояд. Мубориза бо параметрҳое, ки пас аз раванди оғозсозӣ тағир дода мешаванд, боиси афзоиши мураккабии барнома мегардад. Барои чунин параметрҳо мо бояд механизми интиқоли онҳо, таҳлил ва санҷиш, коркарди арзишҳои нодурустро идора кунем. Аз ин рӯ, барои кам кардани мураккабии барнома, мо беҳтар мебуд, ки шумораи параметрҳоеро, ки метавонанд дар вақти иҷро тағйир ёбанд (ё ҳатто онҳоро тамоман нест кунем) кам кунем.

Аз нуқтаи назари ин пост мо бояд байни параметрҳои статикӣ ва динамикӣ фарқ кунем. Агар мантиқи хидматрасонӣ тағироти ками баъзе параметрҳоро дар вақти кор талаб кунад, мо метавонем онҳоро параметрҳои динамикӣ номида тавонем. Дар акси ҳол, онҳо статикӣ мебошанд ва метавонанд бо истифода аз равиши пешниҳодшуда танзим карда шаванд. Барои аз нав конфигуратсияи динамикӣ метавонад равишҳои дигар лозим шавад. Масалан, қисмҳои системаро бо параметрҳои конфигуратсияи нав ба монанди аз нав оғоз кардани равандҳои алоҳидаи системаи тақсимшуда аз нав оғоз кардан мумкин аст.
(Фикри хоксоронаи ман ин аст, ки аз навсозии вақти корӣ канорагирӣ кунед, зеро он мураккабии системаро зиёд мекунад.
Такя ба дастгирии OS барои равандҳои бозоғозӣ метавонад осонтар бошад. Бо вуҷуди ин, ин на ҳамеша имконпазир аст.)

Яке аз ҷанбаҳои муҳими истифодаи конфигуратсияи статикӣ, ки баъзан одамонро водор месозад, ки конфигуратсияи динамикӣ (бе сабабҳои дигар) ба назар гиранд, вақти қатъи хидмат ҳангоми навсозии конфигуратсия мебошад. Дар ҳақиқат, агар мо бояд ба конфигуратсияи статикӣ тағирот ворид кунем, мо бояд системаро бозоғоз кунем, то арзишҳои нав самаранок шаванд. Талабот ба вақти бекорӣ барои системаҳои гуногун фарқ мекунад, аз ин рӯ шояд он қадар муҳим набошад. Агар ин муҳим бошад, пас мо бояд ҳама гуна бозоғозии системаро пешакӣ ба нақша гирем. Масалан, мо метавонем амалӣ кунем Дренажии пайвасти AWS ELB. Дар ин сенария, вақте ки ба мо лозим аст, ки системаро бозоғоз кунем, мо як мисоли нави системаро дар баробари оғоз мекунем ва сипас ELB-ро ба он мегузарем ва ба системаи кӯҳна имкон медиҳем, ки хидматрасонии пайвастҳои мавҷударо анҷом диҳад.

Дар бораи нигоҳ доштани конфигуратсия дар дохили артефакт ё берун аз он чӣ гуфтан мумкин аст? Нигоҳ доштани конфигуратсия дар дохили артефакт маънои онро дорад, ки дар аксари ҳолатҳо ин конфигуратсия ҳамон раванди кафолати сифатро мисли дигар артефактҳо гузаштааст. Пас, касе метавонад боварӣ дошта бошад, ки конфигуратсия сифати хуб ва боэътимод аст. Баръакс, конфигуратсия дар файли алоҳида маънои онро дорад, ки ҳеҷ гуна осори кӣ ва чаро ба ин файл тағирот ворид карда нашудааст. Оё ин муҳим аст? Мо боварӣ дорем, ки барои аксари системаҳои истеҳсолӣ беҳтар аст, ки конфигуратсияи устувор ва баландсифат дошта бошад.

Версияи артефакт имкон медиҳад, ки муайян карда шавад, ки он кай офарида шудааст, кадом арзишҳо дар он доранд, кадом хусусиятҳо фаъол / ғайрифаъол шудаанд ва барои ворид кардани ҳар як тағирот дар конфигуратсия кӣ масъул аст. Он метавонад барои нигоҳ доштани конфигуратсия дар дохили артефакт каме кӯшиш талаб кунад ва ин интихоби тарроҳӣ аст.

Тарафҳо ва муқобилҳо

Дар ин ҷо мо мехостем баъзе бартариҳоро қайд кунем ва баъзе камбудиҳои усули пешниҳодшударо баррасӣ кунем.

афзалиятҳо

Хусусиятҳои конфигуратсияи мукаммали системаи паҳншуда:

  1. Санҷиши статикии конфигуратсия. Ин сатҳи баланди эътимодро медиҳад, ки конфигуратсия бо маҳдудиятҳои навъи мувофиқ дуруст аст.
  2. Забони бойи конфигуратсия. Одатан равишҳои дигари конфигуратсия бо ивазкунии аксари тағйирёбанда маҳдуданд.
    Бо истифода аз Scala метавон як доираи васеи хусусиятҳои забонро барои беҳтар кардани конфигуратсия истифода бурд. Масалан, мо метавонем хислатҳоро барои таъмин кардани арзишҳои пешфарз истифода барем, объектҳоро барои таъини доираи гуногун истифода барем. vals танҳо як маротиба дар доираи беруна муайян карда мешавад (DRY). Истифодаи пайдарпайии аслӣ ё мисолҳои синфҳои муайян имконпазир аст (Seq, Mapва ғайра).
  3. DSL. Scala барои нависандагони DSL дастгирии сазовор дорад. Яке метавонад аз ин хусусиятҳо истифода барад, то забони конфигуратсияеро таъсис диҳад, ки қулайтар ва барои истифодабарандаи ниҳоӣ мувофиқ бошад, то конфигуратсияи ниҳоӣ ҳадди аққал аз ҷониби корбарони домен хонда шавад.
  4. Беайбӣ ва ҳамоҳангӣ дар саросари гиреҳҳо. Яке аз бартариҳои доштани конфигуратсия барои тамоми системаи тақсимшуда дар як ҷо дар он аст, ки ҳама арзишҳо ба таври қатъӣ як маротиба муайян карда мешаванд ва сипас дар ҳама ҷойҳое, ки ба мо лозим аст, дубора истифода мешаванд. Ҳамчунин эъломияҳои порти бехатарро нависед, ки дар ҳама конфигуратсияҳои дурусти имконпазир гиреҳҳои система бо як забон ҳарф мезананд. Дар байни гиреҳҳо вобастагии возеҳ вуҷуд дорад, ки фаромӯш кардани пешниҳоди баъзе хидматҳоро душвор мекунад.
  5. Сифати баланди тағирот. Равиши умумии интиқоли тағироти конфигуратсия тавассути раванди муқаррарии PR стандартҳои баланди сифатро низ дар конфигуратсия муқаррар мекунад.
  6. Тағироти конфигуратсияи ҳамзамон. Ҳар вақте ки мо дар конфигуратсия ягон тағирот ворид мекунем, ҷойгиркунии худкор кафолат медиҳад, ки ҳама гиреҳҳо нав карда мешаванд.
  7. Соддасозии барнома. Ба барнома лозим нест, ки конфигуратсияро таҳлил ва тасдиқ кунад ва арзишҳои конфигуратсияи нодурустро идора кунад. Ин барномаи умумиро содда мекунад. (Баъзе афзоиши мураккабӣ дар худи конфигуратсия аст, аммо ин як ивази бошуурона ба бехатарӣ аст.) Бозгашт ба конфигуратсияи муқаррарӣ хеле осон аст - танҳо қисмҳои гумшударо илова кунед. Оғози конфигуратсияи тартибдодашуда осонтар аст ва татбиқи қисмҳои иловагиро ба баъзе вақтҳои дертар ба таъхир гузоред.
  8. Конфигуратсияи версиявӣ. Аз сабаби он, ки тағиротҳои конфигуратсия бо ҳамон як раванди рушд пайравӣ мекунанд, дар натиҷа мо артефактро бо версияи беназир мегирем. Он ба мо имкон медиҳад, ки агар лозим бошад, конфигуратсияро баргардонем. Мо ҳатто метавонем конфигуратсияеро, ки як сол пеш истифода шуда буд, ҷойгир кунем ва он маҳз ҳамин тавр кор хоҳад кард. Конфигуратсияи устувор пешгӯӣ ва эътимоднокии системаи тақсимшударо беҳтар мекунад. Конфигуратсия дар вақти тартибдиҳӣ муқаррар карда мешавад ва онро дар системаи истеҳсолӣ ба осонӣ тағир додан мумкин нест.
  9. Модулият. Чаҳорчӯбаи пешниҳодшуда модулист ва модулҳоро метавон бо роҳҳои гуногун муттаҳид кард
    конфигуратсияҳои гуногунро дастгирӣ мекунад (конфигуратсияҳо / тарҳҳо). Аз ҷумла, мумкин аст, ки тарҳбандии миқёси хурди як гиреҳ ва танзими миқёси калони бисёр гиреҳ дошта бошад. Якчанд тарҳҳои истеҳсолӣ оқилона аст.
  10. Санҷиш. Бо мақсади санҷиш метавон хидмати тақаллубиро татбиқ карда, онро ҳамчун вобастагӣ ба таври бехатар истифода барад. Якчанд тарҳҳои гуногуни санҷиширо бо қисмҳои гуногун бо масхара иваз кардан мумкин аст, ҳамзамон нигоҳ дошта шаванд.
  11. Санҷиши ҳамгироӣ. Баъзан дар системаҳои тақсимшуда гузаронидани санҷишҳои ҳамгироӣ душвор аст. Бо истифода аз равиши тавсифшуда барои чоп кардани конфигуратсияи бехатари системаи пурраи тақсимшуда, мо метавонем ҳамаи қисмҳои тақсимшударо дар як сервер ба таври идорашаванда иҷро кунем. Ба вазъият тақлид кардан осон аст
    вақте ки яке аз хидматҳо дастнорас мешавад.

нуқсонҳои

Равиши конфигуратсияи тартибдодашуда аз конфигуратсияи "муқаррарӣ" фарқ мекунад ва он метавонад ба ҳама ниёзҳо мувофиқат накунад. Инҳоянд баъзе камбудиҳои конфигуратсияи тартибдодашуда:

  1. Конфигуратсияи статикӣ. Он метавонад барои ҳама барномаҳо мувофиқ набошад. Дар баъзе мавридҳо зарурати зуд ислоҳ кардани конфигуратсия дар истеҳсолот бо гузашти тамоми чораҳои бехатарӣ ба миён меояд. Ин усул корро душвортар мегардонад. Ҷамъоварӣ ва дубора ҷойгиркунӣ пас аз ворид кардани ҳама гуна тағирот дар конфигуратсия талаб карда мешавад. Ин ҳам хусусият ва ҳам бори гарон аст.
  2. Насли конфигуратсия. Вақте ки конфигуратсия аз ҷониби баъзе асбоби автоматизатсия тавлид мешавад, ин равиш тартиб додани минбаъдаро талаб мекунад (ки метавонад дар навбати худ ноком шавад). Он метавонад кӯшиши иловагиро талаб кунад, ки ин қадами иловагӣ ба системаи сохтмон ворид карда шавад.
  3. Асбобҳо. Имрӯз абзорҳои зиёде мавҷуданд, ки ба конфигуратсияҳои матнӣ такя мекунанд. Баъзеи онхо
    вақте ки конфигуратсия тартиб дода мешавад, татбиқ намегардад.
  4. Тағйир додани тафаккур лозим аст. Таҳиягарон ва DevOps бо файлҳои конфигуратсияи матнӣ шиносанд. Идеяи тартиб додани конфигуратсия метавонад барои онҳо аҷиб бошад.
  5. Пеш аз ворид кардани конфигуратсияи компилятсионӣ раванди таҳияи нармафзори баландсифат лозим аст.

Баъзе маҳдудиятҳои намунаи амалӣ мавҷуданд:

  1. Агар мо конфигуратсияи иловагиеро пешниҳод кунем, ки онро татбиқи гиреҳ талаб намекунад, компилятор ба мо барои муайян кардани татбиқи ғоибона кӯмак намекунад. Инро метавон бо истифода аз он ҳал кард HList ё ADTs (синфҳои парванда) барои конфигуратсияи гиреҳ ба ҷои хислатҳо ва намунаи торт.
  2. Мо бояд дар файли конфигуратсия якчанд таблиғ пешниҳод кунем: (package, import, object эъломияҳо;
    override def's барои параметрҳое, ки арзишҳои пешфарз доранд). Ин метавонад қисман бо истифода аз DSL ҳал карда шавад.
  3. Дар ин мақола мо конфигуратсияи динамикии кластерҳои гиреҳҳои шабеҳро фаро намегирем.

хулоса

Дар ин мақола мо идеяи муаррифии конфигуратсияро мустақиман дар коди сарчашма бо роҳи бехатар баррасӣ кардем. Ин равишро метавон дар бисёр барномаҳо ҳамчун иваз ба xml ва дигар конфигуратсияҳои матнӣ истифода бурд. Сарфи назар аз он, ки намунаи мо дар Scala амалӣ шудааст, онро метавон ба дигар забонҳои компилятсионӣ низ тарҷума кард (ба монанди Kotlin, C#, Swift ва ғайра). Ин усулро метавон дар як лоиҳаи нав санҷида, дар сурати мувофиқат накунад, ба усули кӯҳна гузаштан мумкин аст.

Албатта, конфигуратсияи компилятсионӣ раванди таҳияи сифати баландро талаб мекунад. Дар ивази он ваъда медиҳад, ки конфигуратсияи боэътимоди баландсифатро таъмин мекунад.

Ин равишро метавон бо роҳҳои гуногун васеъ кард:

  1. Яке метавонад макросҳоро барои иҷрои тасдиқи конфигуратсия истифода барад ва дар вақти компиляция дар сурати нокомии маҳдудиятҳои мантиқии тиҷоратӣ ноком шавад.
  2. DSL-ро метавон амалӣ кард, то конфигуратсияро ба тариқи барои истифодабаранда дӯстона муаррифӣ кунад.
  3. Идоракунии захираҳои динамикӣ бо танзимоти автоматии конфигуратсия. Масалан, вақте ки мо шумораи гиреҳҳои кластерро танзим мекунем, мо метавонем бихоҳем (1) гиреҳҳо конфигуратсияи каме тағирёфтаро ба даст оранд; (2) мудири кластер барои гирифтани маълумоти гиреҳҳои нав.

ташаккур

Ман мехоҳам ба Андрей Саксонов, Павел Попов, Антон Нехаев ташаккур мегӯям, ки дар бораи лоиҳаи ин мақола фикру мулоҳизаҳои илҳомбахше доданд, ки ба ман возеҳтар шудани он кӯмак карданд.

Манбаъ: will.com