සම්පාදනය කරන ලද බෙදා හරින ලද පද්ධති වින්‍යාසය

බෙදා හරින ලද පද්ධතියක වින්යාසය සමඟ වැඩ කිරීම සඳහා එක් රසවත් යාන්ත්රණයක් ඔබට කියන්නට කැමැත්තෙමි. වින්‍යාසය ආරක්ෂිත වර්ග භාවිතා කරමින් සම්පාදනය කරන ලද භාෂාවකින් (Scala) සෘජුවම නිරූපණය කෙරේ. මෙම සටහන එවැනි වින්‍යාසයකට උදාහරණයක් සපයන අතර සම්පාදනය කරන ලද වින්‍යාසයක් සමස්ත සංවර්ධන ක්‍රියාවලියට ක්‍රියාත්මක කිරීමේ විවිධ පැති සාකච්ඡා කරයි.

සම්පාදනය කරන ලද බෙදා හරින ලද පද්ධති වින්‍යාසය

(ඉංග්රීසි)

හැඳින්වීම

විශ්වාසදායක බෙදාහැරීමේ පද්ධතියක් ගොඩනැගීම යනු සියලුම නෝඩ් වෙනත් නෝඩ් සමඟ සමමුහුර්ත කර ඇති නිවැරදි වින්‍යාසය භාවිතා කිරීමයි. DevOps තාක්ෂණයන් (terraform, ansible හෝ එවැනි දෙයක්) සාමාන්‍යයෙන් ස්වයංක්‍රීයව වින්‍යාස ගොනු උත්පාදනය කිරීමට භාවිතා කරයි (බොහෝ විට එක් එක් නෝඩය සඳහා විශේෂිත). සියලුම සන්නිවේදන නෝඩ් එක සමාන ප්‍රොටෝකෝල (එකම අනුවාදය ඇතුළුව) භාවිතා කරන බවට සහතික වීමටද අපි කැමැත්තෙමු. එසේ නොවුවහොත්, නොගැලපීම අපගේ බෙදාහැරීමේ පද්ධතියට ගොඩනගනු ඇත. JVM ලෝකයේ, මෙම අවශ්‍යතාවයේ එක් ප්‍රතිවිපාකයක් වන්නේ ප්‍රොටෝකෝල පණිවිඩ අඩංගු පුස්තකාලයේ එකම අනුවාදය සෑම තැනකම භාවිතා කළ යුතු බවයි.

බෙදා හරින ලද පද්ධතියක් පරීක්ෂා කිරීම ගැන කුමක් කිව හැකිද? ඇත්ත වශයෙන්ම, අපි ඒකාබද්ධතා පරීක්ෂණයට යාමට පෙර සියලුම සංරචක ඒකක පරීක්ෂණ ඇති බව උපකල්පනය කරමු. (පරීක්‍ෂණ ප්‍රතිඵල ධාවන කාලයට විකාශනය කිරීම සඳහා, අපි පරීක්‍ෂණ අදියරේදී සහ ධාවන වේලාවේදී සමාන පුස්තකාල කට්ටලයක් ද සැපයිය යුතුය.)

ඒකාබද්ධතා පරීක්ෂණ සමඟ වැඩ කරන විට, සියලුම නෝඩ් වල සෑම තැනකම එකම පන්ති මාර්ගය භාවිතා කිරීම බොහෝ විට පහසු වේ. අපි කරන්න ඕනේ එකම classpath එක runtime එකේදී භාවිතා කරන බව සහතික කරගන්න එක. (විවිධ පන්ති මාර්ග සමඟ විවිධ නෝඩ් ධාවනය කිරීමට සම්පුර්ණයෙන්ම හැකි වුවද, මෙය සමස්ත වින්‍යාසය සඳහා සංකීර්ණතාවයක් සහ යෙදවීම සහ ඒකාබද්ධ කිරීමේ පරීක්ෂණ සමඟ ඇති දුෂ්කරතා එක් කරයි.) මෙම පෝස්ටුවෙහි අරමුණු සඳහා, අපි උපකල්පනය කරන්නේ සියලුම නෝඩ් එකම පන්ති මාර්ගය භාවිතා කරනු ඇති බවයි.

වින්‍යාසය යෙදුම සමඟ පරිණාමය වේ. වැඩසටහන් පරිණාමයේ විවිධ අවධීන් හඳුනා ගැනීමට අපි අනුවාද භාවිතා කරමු. වින්‍යාසයන්හි විවිධ අනුවාද හඳුනා ගැනීම ද තාර්කික බව පෙනේ. තවද වින්‍යාසය අනුවාද පාලන පද්ධතියේ තබන්න. නිෂ්පාදනයේ එක් වින්‍යාසයක් පමණක් තිබේ නම්, අපට අනුවාද අංකය භාවිතා කළ හැකිය. අපි බොහෝ නිෂ්පාදන අවස්ථා භාවිතා කරන්නේ නම්, අපට කිහිපයක් අවශ්ය වනු ඇත
වින්යාස ශාඛා සහ අනුවාදයට අමතරව අතිරේක ලේබලයක් (උදාහරණයක් ලෙස, ශාඛාවේ නම). මේ ආකාරයෙන් අපට නිශ්චිත වින්‍යාසය පැහැදිලිව හඳුනාගත හැකිය. සෑම වින්‍යාස හඳුනාගැනීමක්ම බෙදා හරින ලද නෝඩ්, වරාය, බාහිර සම්පත් සහ පුස්තකාල අනුවාදවල නිශ්චිත සංයෝජනයකට අනන්‍යව අනුරූප වේ. මෙම සටහනේ අරමුණු සඳහා අපි උපකල්පනය කරන්නේ එක් ශාඛාවක් පමණක් බවත්, තිතකින් (1.2.3) වෙන් කරන ලද සංඛ්‍යා තුනක් භාවිතා කර සාමාන්‍ය ආකාරයෙන් වින්‍යාසය හඳුනා ගත හැකිය.

නවීන පරිසරයන් තුළ, වින්‍යාස ගොනු අතින් සාදනු ලබන්නේ කලාතුරකිනි. බොහෝ විට ඒවා යෙදවීමේදී ජනනය වන අතර තවදුරටත් ස්පර්ශ නොවේ (එසේ නම් කිසිවක් කඩන්න එපා) ස්වාභාවික ප්‍රශ්නයක් පැන නගී: වින්‍යාසය ගබඩා කිරීමට අපි තවමත් පෙළ ආකෘතිය භාවිතා කරන්නේ ඇයි? ශක්‍ය විකල්පයක් ලෙස පෙනෙන්නේ වින්‍යාස කිරීම සඳහා නිත්‍ය කේතය භාවිතා කිරීමේ හැකියාව සහ සම්පාදන-කාල චෙක්පත් වලින් ප්‍රයෝජන ගැනීමයි.

මෙම ලිපියෙන් අපි සම්පාදනය කරන ලද පුරාවස්තුවක් තුළ වින්‍යාසයක් නියෝජනය කිරීමේ අදහස ගවේෂණය කරන්නෙමු.

සම්පාදනය කරන ලද වින්‍යාසය

මෙම කොටස ස්ථිතික සම්පාදනය කරන ලද වින්‍යාසයකට උදාහරණයක් සපයයි. සරල සේවා දෙකක් ක්රියාත්මක වේ - echo සේවාව සහ echo සේවා සේවාදායකයා. මෙම සේවා දෙක මත පදනම්ව, පද්ධති විකල්ප දෙකක් එකලස් කර ඇත. එක් විකල්පයක, සේවා දෙකම එකම නෝඩයක පිහිටා ඇත, තවත් විකල්පයක් - විවිධ නෝඩ් මත.

සාමාන්‍යයෙන් බෙදා හරින ලද පද්ධතියක නෝඩ් කිහිපයක් අඩංගු වේ. ඔබට යම් ආකාරයක අගයන් භාවිතයෙන් නෝඩ් හඳුනා ගත හැකිය NodeId:

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

පිරිපහදු කළ වර්ග

පුස්තකාලය බලන්න පිරිපහදු කළ හැක и මගේ වාර්තාව. කෙටියෙන් කිවහොත්, සම්පාදනය කරන අවස්ථාවේ දී පරීක්ෂා කරන ලද වර්ගවලට බාධා කිරීම් එකතු කිරීමට පුස්තකාලය ඔබට ඉඩ සලසයි. මෙම අවස්ථාවෙහිදී, වලංගු තොට අංක අගයන් 16-bit පූර්ණ සංඛ්‍යා වේ. සම්පාදනය කරන ලද වින්‍යාසයක් සඳහා, පිරිපහදු කළ පුස්තකාලය භාවිතා කිරීම අනිවාර්ය නොවේ, නමුත් එය වින්‍යාසය පරීක්ෂා කිරීමට සම්පාදකයාගේ හැකියාව වැඩි දියුණු කරයි.

HTTP (REST) ​​ප්‍රොටෝකෝල සඳහා, වරාය අංකයට අමතරව, අපට සේවාව සඳහා මාර්ගයද අවශ්‍ය විය හැකිය:

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

ෆැන්ටම් වර්ග

සම්පාදනය කරන අවස්ථාවේදී ප්‍රොටෝකෝලය හඳුනා ගැනීම සඳහා, අපි පන්තිය තුළ භාවිතා නොකරන ආකාරයේ පරාමිතියක් භාවිතා කරමු. මෙම තීරණයට හේතු වී ඇත්තේ අපි ධාවන වේලාවේදී ප්‍රොටෝකෝල අවස්ථාවක් භාවිතා නොකිරීමයි, නමුත් අපි සම්පාදකයා ප්‍රොටෝකෝල අනුකූලතාව පරීක්ෂා කිරීමට කැමතියි. ප්‍රොටෝකෝලය සඳහන් කිරීමෙන්, අපට නුසුදුසු සේවාවක් යැපීමක් ලෙස සම්මත කිරීමට නොහැකි වනු ඇත.

පොදු ප්‍රොටෝකෝල වලින් එකක් වන්නේ Json අනුක්‍රමිකකරණය සහිත REST API ය:

sealed trait JsonHttpRestProtocol[RequestMessage, ResponseMessage]

එහිදී RequestMessage - ඉල්ලීම් වර්ගය, ResponseMessage - ප්රතිචාර වර්ගය.
ඇත්ත වශයෙන්ම, අපට අවශ්‍ය විස්තරයේ නිරවද්‍යතාවය සපයන වෙනත් ප්‍රොටෝකෝල විස්තර භාවිතා කළ හැකිය.

මෙම ලිපියේ අරමුණු සඳහා, අපි ප්‍රොටෝකෝලයේ සරල කළ අනුවාදයක් භාවිතා කරන්නෙමු:

sealed trait SimpleHttpGetRest[RequestMessage, ResponseMessage]

මෙහිදී ඉල්ලීම url වෙත අමුණා ඇති තන්තුවක් වන අතර ප්‍රතිචාරය වන්නේ HTTP ප්‍රතිචාරයේ අන්තර්ගත තන්තුවයි.

සේවා වින්‍යාසය සේවා නාමය, වරායන් සහ පරායත්තතා මගින් විස්තර කෙරේ. මෙම මූලද්‍රව්‍ය Scala හි ආකාර කිහිපයකින් නිරූපණය කළ හැක (උදාහරණයක් ලෙස, HList-s, වීජීය දත්ත වර්ග). මෙම ලිපියේ අරමුණු සඳහා, අපි කේක් රටාව භාවිතා කර මොඩියුල භාවිතා කරමු trait'ov. (කේක් රටාව මෙම ප්‍රවේශයේ අවශ්‍ය අංගයක් නොවේ. එය ක්‍රියාත්මක කළ හැකි එකකි.)

සේවා අතර යැපීම් වරාය ආපසු ලබා දෙන ක්‍රම ලෙස නිරූපණය කළ හැක EndPointවෙනත් නෝඩ් වල:

  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 ප්‍රොටෝකෝලය සඳහා සහය දක්වන බවට ඇඟවීමක් පමණි. අපි නිශ්චිත වරායක් සඳහන් නොකළ හැකිය, මන්ද... ක්‍රියාත්මක කිරීමකින් තොරව ක්‍රම ප්‍රකාශ කිරීමට ලක්ෂණ ඔබට ඉඩ සලසයි (වියුක්ත ක්‍රම). මෙම අවස්ථාවෙහිදී, කොන්ක්‍රීට් වින්‍යාසයක් නිර්මාණය කිරීමේදී, සම්පාදකයා විසින් වියුක්ත ක්‍රමය ක්‍රියාත්මක කිරීම සහ වරාය අංකයක් ලබා දීම අවශ්‍ය වේ. අපි ක්‍රමය ක්‍රියාත්මක කර ඇති බැවින්, නිශ්චිත වින්‍යාසයක් නිර්මාණය කිරීමේදී, අපි වෙනත් වරායක් සඳහන් නොකරමු. පෙරනිමි අගය භාවිතා කරනු ඇත.

සේවාදායක වින්‍යාසය තුළ අපි echo සේවාව මත යැපීමක් ප්‍රකාශ කරමු:

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

යැපීම අපනයනය කරන ලද සේවාවට සමාන වර්ගයකි echoService. විශේෂයෙන්ම, echo client හි අපට අවශ්‍ය වන්නේ එකම ප්‍රොටෝකෝලයයි. එබැවින්, සේවා දෙකක් සම්බන්ධ කරන විට, සෑම දෙයක්ම නිවැරදිව ක්රියා කරන බවට අපට සහතික විය හැකිය.

සේවා ක්රියාත්මක කිරීම

සේවාව ආරම්භ කිරීමට සහ නැවැත්වීමට ශ්‍රිතයක් අවශ්‍ය වේ. (සේවාව නැවැත්වීමේ හැකියාව පරීක්ෂා කිරීම සඳහා ඉතා වැදගත් වේ.) නැවතත්, එවැනි විශේෂාංගයක් ක්‍රියාත්මක කිරීම සඳහා විකල්ප කිහිපයක් තිබේ (උදාහරණයක් ලෙස, අපට වින්‍යාස වර්ගය මත පදනම්ව වර්ග පන්ති භාවිතා කළ හැකිය). මෙම ලිපියේ අරමුණු සඳහා අපි කේක් රටාව භාවිතා කරමු. අපි පන්තියක් භාවිතයෙන් සේවාව නියෝජනය කරන්නෙමු 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 — ඔබට තනි බලපෑම් (මොනාඩ් පාහේ) ඒකාබද්ධ කිරීමට ඉඩ සලසන ආචරණ වර්ගයේ පන්තියකි. වඩාත් සංකීර්ණ යෙදුම් වලදී එය භාවිතා කිරීම වඩා හොඳ බව පෙනේ Monad/ConcurrentEffect.

මෙම කාර්යය අත්සන භාවිතා කිරීමෙන් අපට සේවාවන් කිහිපයක් ක්‍රියාත්මක කළ හැකිය. උදාහරණයක් ලෙස, කිසිවක් නොකරන සේවාවක්:

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

(සෙමී. මූලාශ්රය, වෙනත් සේවාවන් ක්රියාත්මක වන - echo සේවාව, echo සේවාදායකයා
и ජීවිත කාලය පාලකයන්.)

නෝඩයක් යනු සේවා කිහිපයක් දියත් කළ හැකි වස්තුවකි (සම්පත් දාමයක් දියත් කිරීම කේක් රටාව මගින් සහතික කෙරේ):

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

මෙම නෝඩය සඳහා අවශ්‍ය නිශ්චිත වින්‍යාස වර්ගය අපි සඳහන් කරන බව කරුණාවෙන් සලකන්න. යම් සේවාවක් සඳහා අවශ්‍ය වින්‍යාස වර්ග වලින් එකක් සඳහන් කිරීමට අපට අමතක වුවහොත්, සම්පාදන දෝෂයක් ඇති වේ. එසේම, අපි අවශ්‍ය සියලු දත්ත සමඟ සුදුසු ආකාරයේ යම් වස්තුවක් සපයන්නේ නම් මිස අපට නෝඩයක් ආරම්භ කිරීමට නොහැකි වනු ඇත.

සත්කාරක නාම විභේදනය

දුරස්ථ ධාරකයකට සම්බන්ධ වීමට, අපට සැබෑ IP ලිපිනයක් අවශ්‍ය වේ. අනෙක් වින්‍යාසයට වඩා ලිපිනය පසුව දැන ගැනීමට ඉඩ ඇත. එබැවින් අපට node ID ලිපිනයකට සිතියම්ගත කරන ශ්‍රිතයක් අවශ්‍ය වේ:

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

මෙම කාර්යය ක්රියාත්මක කිරීමට ක්රම කිහිපයක් තිබේ:

  1. යෙදවීමට පෙර ලිපින අප දැනගතහොත්, අපට Scala කේතය ජනනය කළ හැක
    ලිපිනයන් සහ පසුව ගොඩනැගීම ක්රියාත්මක කරන්න. මෙය සම්පාදනය කර පරීක්ෂණ ධාවනය කරනු ඇත.
    මෙම අවස්ථාවේදී, ශ්‍රිතය ස්ථිතිකව දැනගත හැකි අතර එය සිතියම්ගත කිරීමක් ලෙස කේතයෙන් නිරූපණය කළ හැක Map[NodeId, NodeAddress].
  2. සමහර අවස්ථාවලදී, සැබෑ ලිපිනය දන්නේ නෝඩය ආරම්භ වූ පසුව පමණි.
    මෙම අවස්ථාවේදී, අපට වෙනත් නෝඩ් වලට පෙර ධාවනය වන "සොයාගැනීමේ සේවාවක්" ක්‍රියාත්මක කළ හැකි අතර සියලුම නෝඩ් මෙම සේවාව සමඟ ලියාපදිංචි වී අනෙකුත් නෝඩ් වල ලිපිනයන් ඉල්ලා සිටී.
  3. අපට වෙනස් කළ හැකි නම් /etc/hosts, එවිට ඔබට පූර්ව නිශ්චිත ධාරක නාම භාවිතා කළ හැක (වැනි my-project-main-node и echo-backend) සහ මෙම නම් සරලව සම්බන්ධ කරන්න
    යෙදවීමේදී IP ලිපින සමඟ.

මෙම ලිපියෙන් අපි මෙම අවස්ථා වඩාත් විස්තරාත්මකව සලකා බලන්නේ නැත. අපේ සඳහා
සෙල්ලම් බඩු උදාහරණයක, සියලුම නෝඩ් වලට එකම IP ලිපිනයක් ඇත - 127.0.0.1.

ඊළඟට, බෙදා හරින ලද පද්ධතියක් සඳහා විකල්ප දෙකක් අපි සලකා බලමු:

  1. සියලුම සේවාවන් එක් නෝඩයක් මත තැබීම.
  2. සහ විවිධ නෝඩ් වල echo සේවාව සහ echo client සත්කාරකත්වය.

සඳහා වින්යාස කිරීම එක් නෝඩයක්:

තනි නෝඩ් වින්‍යාසය

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 වැඩසටහන අවසන් කරන්න. (Ctrl-C ද සියලු සම්පත් නිවැරදිව ක්‍රියා කර නිදහස් කරයි.)

සමන්විත පද්ධතියක් නිර්මාණය කිරීම සඳහා එකම වින්‍යාස කිරීමේ සහ ක්‍රියාත්මක කිරීමේ ලක්ෂණ සමූහයක් භාවිතා කළ හැකිය වෙනම නෝඩ් දෙකක්:

නෝඩ් දෙකක වින්‍යාසය

  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'ඕම්, සහ සේවාදායක නෝඩය ටික වේලාවකට පසු අවසන් වේ. සෙමී. දියත් කිරීමේ යෙදුම.

සාමාන්ය සංවර්ධන ක්රියාවලිය

මෙම වින්‍යාස ප්‍රවේශය සමස්ත සංවර්ධන ක්‍රියාවලියට බලපාන්නේ කෙසේදැයි බලමු.

වින්‍යාසය ඉතිරි කේතය සමඟ සම්පාදනය කෙරෙන අතර කෞතුක වස්තුවක් (.jar) ජනනය වනු ඇත. වින්‍යාසය වෙනම කෞතුක වස්තුවක තැබීම අර්ථවත් බව පෙනේ. මෙයට හේතුව එකම කේතය මත පදනම්ව අපට බහුවිධ වින්‍යාසයන් තිබිය හැකි බැවිනි. නැවතත්, විවිධ වින්‍යාස ශාඛා වලට අනුරූප කෞතුක වස්තු ජනනය කළ හැකිය. පුස්තකාලවල නිශ්චිත අනුවාද මත යැපීම් වින්‍යාසය සමඟ සුරකින අතර, වින්‍යාසයේ එම අනුවාදය යෙදවීමට අප තීරණය කරන සෑම විටම මෙම අනුවාද සදහටම සුරැකේ.

ඕනෑම වින්‍යාස වෙනසක් කේත වෙනසක් බවට හැරේ. එබැවින්, එක් එක්
සාමාන්‍ය තත්ත්ව සහතික කිරීමේ ක්‍රියාවලිය මගින් වෙනස ආවරණය කෙරේ:

දෝෂ ලුහුබැඳීමේ ප්‍රවේශ පත්‍රය -> PR -> සමාලෝචනය -> අදාළ ශාඛා සමඟ ඒකාබද්ධ කරන්න ->
ඒකාබද්ධ කිරීම -> යෙදවීම

සම්පාදනය කරන ලද වින්‍යාසයක් ක්‍රියාත්මක කිරීමේ ප්‍රධාන ප්‍රතිවිපාක වනුයේ:

  1. වින්‍යාසය බෙදා හරින ලද පද්ධතියේ සියලුම නෝඩ් හරහා අනුකූල වේ. සියලුම නෝඩ් එකම ප්‍රභවයකින් එකම වින්‍යාසය ලබා ගැනීම හේතුවෙන්.

  2. නෝඩ් එකක පමණක් වින්‍යාසය වෙනස් කිරීම ගැටළු සහගතය. එබැවින්, "වින්යාස ප්ලාවිතය" විය නොහැක.

  3. වින්යාසය සඳහා කුඩා වෙනස්කම් සිදු කිරීම වඩාත් අපහසු වේ.

  4. බොහෝ වින්‍යාස වෙනස්කම් සමස්ත සංවර්ධන ක්‍රියාවලියේ කොටසක් ලෙස සිදුවනු ඇති අතර සමාලෝචනයට යටත් වේ.

නිෂ්පාදන වින්‍යාසය ගබඩා කිරීමට මට වෙනම ගබඩාවක් අවශ්‍යද? මෙම වින්‍යාසය තුළ මුරපද සහ අපි ප්‍රවේශය සීමා කිරීමට කැමති අනෙකුත් සංවේදී තොරතුරු අඩංගු විය හැක. මේ මත පදනම්ව, අවසාන වින්‍යාසය වෙනම ගබඩාවක ගබඩා කිරීම අර්ථවත් බව පෙනේ. ඔබට වින්‍යාසය කොටස් දෙකකට බෙදිය හැක-එකක් පොදු ප්‍රවේශ විය හැකි වින්‍යාස සැකසීම් සහ එකක් සීමා කළ සැකසුම් අඩංගු වේ. මෙය බොහෝ සංවර්ධකයින්ට පොදු සැකසුම් වෙත ප්‍රවේශ වීමට ඉඩ සලසයි. පෙරනිමි අගයන් අඩංගු අතරමැදි ලක්ෂණ භාවිතයෙන් මෙම වෙන්වීම සාක්ෂාත් කර ගැනීම පහසුය.

විය හැකි වෙනස්කම්

සම්පාදනය කරන ලද වින්‍යාසය පොදු විකල්ප කිහිපයක් සමඟ සංසන්දනය කිරීමට උත්සාහ කරමු:

  1. ඉලක්ක යන්ත්‍රයේ පෙළ ගොනුව.
  2. මධ්යගත යතුරු අගය ගබඩාව (etcd/zookeeper).
  3. ක්‍රියාවලිය නැවත ආරම්භ නොකර නැවත වින්‍යාසගත කළ හැකි/නැවත ආරම්භ කළ හැකි ක්‍රියාවලි සංරචක.
  4. කෞතුක භාණ්ඩ සහ අනුවාද පාලනයෙන් පිටත වින්‍යාසය ගබඩා කිරීම.

පෙළ ගොනු කුඩා වෙනස්කම් අනුව සැලකිය යුතු නම්යශීලී බවක් ලබා දෙයි. පද්ධති පරිපාලකයාට දුරස්ථ නෝඩයට ඇතුල් විය හැක, සුදුසු ගොනු වලට වෙනස්කම් සිදු කර සේවාව නැවත ආරම්භ කරන්න. කෙසේ වෙතත්, විශාල පද්ධති සඳහා, එවැනි නම්යශීලීභාවයක් අවශ්ය නොවේ. සිදු කරන ලද වෙනස්කම් වෙනත් පද්ධතිවල කිසිදු හෝඩුවාවක් ඉතිරි නොකරයි. කිසිවෙක් වෙනස්කම් සමාලෝචනය නොකරයි. හරියටම වෙනස්කම් කළේ කවුරුන්ද සහ කුමන හේතුවක් නිසාද යන්න තීරණය කිරීම අපහසුය. වෙනස්කම් පරීක්ෂා නොකෙරේ. පද්ධතිය බෙදා හරිනු ලැබුවහොත්, පරිපාලකයා වෙනත් නෝඩ් වල අනුරූප වෙනස් කිරීම අමතක කළ හැකිය.

(එසේම සම්පාදනය කරන ලද වින්‍යාසයක් භාවිතා කිරීමෙන් අනාගතයේදී පෙළ ගොනු භාවිතා කිරීමේ හැකියාව වසා නොගන්නා බව ද සටහන් කළ යුතුය. ප්‍රතිදානයට සමාන වර්ගයක් නිපදවන විග්‍රහකය සහ වලංගුකාරකයක් එක් කිරීම ප්‍රමාණවත් වේ. Config, සහ ඔබට පෙළ ගොනු භාවිතා කළ හැක. සම්පාදනය කරන ලද වින්‍යාසයක් සහිත පද්ධතියක සංකීර්ණත්වය පෙළ ගොනු භාවිතා කරන පද්ධතියක සංකීර්ණතාවයට වඩා තරමක් අඩු බව එය වහාම අනුගමනය කරයි, මන්ද පෙළ ගොනු සඳහා අමතර කේතයක් අවශ්‍ය වේ.)

මධ්‍යගත යතුරු අගය ගබඩාවක් යනු බෙදා හරින ලද යෙදුමක මෙටා පරාමිතීන් බෙදා හැරීම සඳහා හොඳ යාන්ත්‍රණයකි. වින්‍යාස පරාමිති මොනවාද සහ දත්ත පමණක් මොනවාද යන්න අප තීරණය කළ යුතුය. අපි කාර්යයක් කරමු C => A => B, සහ පරාමිතීන් C කලාතුරකින් වෙනස් වන අතර දත්ත A - බොහෝ විට. මේ අවස්ථාවේ දී අපට එය පැවසිය හැකිය C - වින්යාස පරාමිතීන්, සහ A - දත්ත. වින්‍යාස පරාමිති දත්ත වලට වඩා වෙනස් වන බව පෙනේ, ඒවා සාමාන්‍යයෙන් දත්ත වලට වඩා අඩුවෙන් වෙනස් වේ. එසේම, දත්ත සාමාන්‍යයෙන් එක් මූලාශ්‍රයකින් (පරිශීලකයාගෙන්), සහ වින්‍යාස පරාමිති තවත් ප්‍රභවයකින් (පද්ධති පරිපාලකගෙන්) පැමිණේ.

වැඩසටහන නැවත ආරම්භ නොකර කලාතුරකින් වෙනස් වන පරාමිති යාවත්කාලීන කිරීමට අවශ්‍ය නම්, මෙය බොහෝ විට වැඩසටහනේ සංකූලතාවයට හේතු විය හැක, මන්ද අපට කෙසේ හෝ පරාමිති ලබා දීමට, ගබඩා කිරීමට, විග්‍රහ කිරීමට සහ පරීක්ෂා කිරීමට සහ වැරදි අගයන් සැකසීමට අවශ්‍ය වනු ඇත. එබැවින්, වැඩසටහනේ සංකීර්ණත්වය අඩු කිරීමේ දෘෂ්ටි කෝණයෙන්, වැඩසටහන් ක්රියාත්මක කිරීමේදී වෙනස් කළ හැකි පරාමිතීන් ගණන අඩු කිරීම අර්ථවත් කරයි (නැතහොත් එවැනි පරාමිතීන් සඳහා කිසිසේත්ම සහාය නොදක්වයි).

මෙම තනතුරේ අරමුණු සඳහා, අපි ස්ථිතික සහ ගතික පරාමිතීන් අතර වෙනස හඳුනා ගනිමු. සේවාවේ තර්කනය වැඩසටහනේ ක්‍රියාකාරිත්වය අතරතුර පරාමිතීන් වෙනස් කිරීමට අවශ්‍ය නම්, අපි එවැනි පරාමිතීන් ගතික ලෙස හඳුන්වමු. එසේ නොමැතිනම් විකල්ප ස්ථිතික වන අතර සම්පාදනය කරන ලද වින්‍යාසය භාවිතයෙන් වින්‍යාසගත කළ හැක. ගතික ප්‍රතිසංවිධානය සඳහා, මෙහෙයුම් පද්ධති ක්‍රියාවලි නැවත ආරම්භ කරන ආකාරය හා සමානව, නව පරාමිති සමඟ වැඩසටහනේ කොටස් නැවත ආරම්භ කිරීමට අපට යාන්ත්‍රණයක් අවශ්‍ය විය හැකිය. (අපගේ මතය අනුව, තත්‍ය කාලීන නැවත වින්‍යාස කිරීම වළක්වා ගැනීම සුදුසුය, මෙය පද්ධතියේ සංකීර්ණත්වය වැඩි කරන බැවින්, හැකි නම්, ක්‍රියාවලි නැවත ආරම්භ කිරීම සඳහා සම්මත OS හැකියාවන් භාවිතා කිරීම වඩා හොඳය.)

ස්ථිතික වින්‍යාසය භාවිතා කිරීමේ එක් වැදගත් අංගයක් වන්නේ මිනිසුන් ගතික ප්‍රතිසංවිධානය සලකා බැලීමට සලස්වන අතර වින්‍යාස යාවත්කාලීන කිරීමෙන් පසු පද්ධතිය නැවත පණගැන්වීමට ගතවන කාලය (අක්‍රීය කාලය). ඇත්ත වශයෙන්ම, අපට ස්ථිතික වින්‍යාසය සඳහා වෙනස්කම් කිරීමට අවශ්‍ය නම්, නව අගයන් ක්‍රියාත්මක වීමට අපට පද්ධතිය නැවත ආරම්භ කිරීමට සිදුවේ. අක්‍රීය වීමේ ගැටලුව විවිධ පද්ධති සඳහා බරපතලකම අනුව වෙනස් වේ. සමහර අවස්ථාවලදී, බර අවම වන අවස්ථාවකදී ඔබට නැවත පණගැන්වීමක් උපලේඛනගත කළ හැකිය. ඔබට අඛණ්ඩ සේවාවක් සැපයීමට අවශ්ය නම්, ඔබට ක්රියාත්මක කළ හැකිය AWS ELB සම්බන්ධතාවය කාන්දු වීම. ඒ සමගම, අපට පද්ධතිය නැවත ආරම්භ කිරීමට අවශ්ය වූ විට, අපි මෙම පද්ධතියේ සමාන්තර අවස්ථාවක් දියත් කරමු, සමතුලිතකය එයට මාරු කර පැරණි සම්බන්ධතා සම්පූර්ණ වන තෙක් බලා සිටින්න. සියලුම පැරණි සම්බන්ධතා අවසන් වූ පසු, අපි පද්ධතියේ පැරණි අවස්ථාව වසා දමමු.

කෞතුක වස්තුවේ ඇතුළත හෝ පිටත වින්‍යාසය ගබඩා කිරීමේ ගැටලුව අපි දැන් සලකා බලමු. අපි කෞතුක වස්තුවක් තුළ වින්‍යාසය ගබඩා කරන්නේ නම්, අවම වශයෙන් කෞතුක වස්තුව එකලස් කිරීමේදී වින්‍යාසයේ නිවැරදි බව තහවුරු කිරීමට අපට අවස්ථාව තිබුණි. වින්‍යාසය පාලිත කෞතුක වස්තුවෙන් පිටත නම්, මෙම ගොනුවට වෙනස්කම් කළේ කවුරුන්ද සහ ඇයි දැයි සොයා බැලීම අපහසුය. එය කොතරම් වැදගත්ද? අපගේ මතය අනුව, බොහෝ නිෂ්පාදන පද්ධති සඳහා ස්ථාවර සහ උසස් තත්ත්වයේ වින්යාසයක් තිබීම වැදගත් වේ.

කෞතුක වස්තුවක අනුවාදය ඔබට එය නිර්මාණය කළේ කවදාද, එහි අඩංගු අගයන් මොනවාද, සක්‍රීය / අක්‍රීය කර ඇති කාර්යයන් සහ වින්‍යාසයේ කිසියම් වෙනසක් සඳහා වගකිව යුත්තේ කවුරුන්ද යන්න තීරණය කිරීමට ඔබට ඉඩ සලසයි. ඇත්ත වශයෙන්ම, කෞතුක වස්තුවක් තුළ වින්‍යාසය ගබඩා කිරීම සඳහා යම් උත්සාහයක් අවශ්‍ය වේ, එබැවින් ඔබ දැනුවත් තීරණයක් ගත යුතුය.

වාසි සහ අවාසි

යෝජිත තාක්ෂණයේ වාසි සහ අවාසි පිළිබඳව මම වාසය කිරීමට කැමැත්තෙමි.

වාසි

සම්පාදනය කරන ලද බෙදා හරින ලද පද්ධති වින්‍යාසයක ප්‍රධාන ලක්ෂණ ලැයිස්තුවක් පහත දැක්වේ:

  1. ස්ථිතික වින්‍යාස පරීක්ෂාව. එය ඔබට සහතික වීමට ඉඩ සලසයි
    වින්‍යාසය නිවැරදියි.
  2. පොහොසත් වින්යාස භාෂාව. සාමාන්‍යයෙන්, අනෙකුත් වින්‍යාස ක්‍රම උපරිම වශයෙන් තන්තු විචල්‍ය ආදේශනයට සීමා වේ. Scala භාවිතා කරන විට, ඔබේ වින්‍යාසය වැඩිදියුණු කිරීමට පුළුල් පරාසයක භාෂා විශේෂාංග තිබේ. උදාහරණයක් ලෙස අපට භාවිතා කළ හැකිය
    පෙරනිමි අගයන් සඳහා ලක්ෂණ, කණ්ඩායම් පරාමිතීන් වෙත වස්තු භාවිතා කරමින්, අපට සංවෘත විෂය පථයේ එක් වරක් පමණක් ප්‍රකාශ කරන ලද vals වෙත යොමු කළ හැකිය (DRY). වින්‍යාසය තුළ ඔබට ඕනෑම පන්තියක් ක්ෂණිකව ක්‍රියාත්මක කළ හැකිය (Seq, Map, අභිරුචි පන්ති).
  3. DSL. Scala හි DSL නිර්මාණය කිරීම පහසු කරන භාෂා විශේෂාංග ගණනාවක් ඇත. මෙම විශේෂාංග වලින් ප්‍රයෝජන ගැනීමට සහ ඉලක්කගත පරිශීලක කණ්ඩායමට වඩාත් පහසු වින්‍යාස භාෂාවක් ක්‍රියාත්මක කිරීමට හැකි වන අතර එමඟින් වින්‍යාසය අවම වශයෙන් වසම් විශේෂඥයින්ට කියවිය හැකිය. විශේෂඥයින්ට, උදාහරණයක් ලෙස, වින්යාස සමාලෝචන ක්රියාවලියට සහභාගී විය හැක.
  4. නෝඩ් අතර අඛණ්ඩතාව සහ සමමුහුර්තභාවය. සම්පූර්ණ බෙදා හරින ලද පද්ධතියක වින්‍යාසය තනි ලක්ෂ්‍යයක ගබඩා කර තිබීමේ එක් වාසියක් නම්, සියලුම අගයන් හරියටම එක් වරක් ප්‍රකාශ කර ඒවා අවශ්‍ය ඕනෑම තැනක නැවත භාවිතා කිරීමයි. තොට ප්‍රකාශ කිරීමට ෆැන්ටම් වර්ග භාවිතා කිරීමෙන් නෝඩ් සියලුම නිවැරදි පද්ධති වින්‍යාසයන්හි අනුකූල ප්‍රොටෝකෝල භාවිතා කරන බව සහතික කරයි. නෝඩ් අතර පැහැදිලි අනිවාර්ය පරායත්තතා තිබීම සියලුම සේවාවන් සම්බන්ධ කර ඇති බව සහතික කරයි.
  5. උසස් තත්ත්වයේ වෙනස්කම්. පොදු සංවර්ධන ක්‍රියාවලියක් භාවිතා කරමින් වින්‍යාසයේ වෙනස්කම් සිදු කිරීම මඟින් වින්‍යාසය සඳහාද උසස් තත්ත්වයේ ප්‍රමිතීන් ලබා ගැනීමට හැකි වේ.
  6. සමගාමී වින්‍යාස යාවත්කාලීන කිරීම. වින්‍යාස වෙනස් කිරීමෙන් පසු ස්වයංක්‍රීය පද්ධති යෙදවීම සියලුම නෝඩ් යාවත්කාලීන වන බව සහතික කරයි.
  7. යෙදුම සරල කිරීම. යෙදුමට විග්‍රහ කිරීම, වින්‍යාස පරීක්ෂා කිරීම හෝ වැරදි අගයන් හැසිරවීම අවශ්‍ය නොවේ. මෙය යෙදුමේ සංකීර්ණත්වය අඩු කරයි. (අපගේ උදාහරණයේ නිරීක්ෂණය කරන ලද සමහර වින්‍යාස සංකීර්ණතා සම්පාදනය කරන ලද වින්‍යාසයේ ගුණාංගයක් නොවේ, නමුත් වැඩි ආකාරයේ ආරක්ෂාවක් සැපයීමේ ආශාව මගින් මෙහෙයවනු ලබන දැනුවත් තීරණයක් පමණි.) සුපුරුදු වින්‍යාසය වෙත ආපසු යාම තරමක් පහසුය - නැතිවූ දේ ක්‍රියාත්මක කරන්න. කොටස්. එමනිසා, ඔබට, උදාහරණයක් ලෙස, සම්පාදනය කරන ලද වින්‍යාසයකින් ආරම්භ කළ හැකිය, අනවශ්‍ය කොටස් ක්‍රියාත්මක කිරීම සැබවින්ම අවශ්‍ය වන තෙක් කල් දැමීම.
  8. අනුවර්තනය කරන ලද වින්‍යාසය. වින්‍යාස වෙනස්කම් වෙනත් ඕනෑම වෙනස්කමක සාමාන්‍ය ඉරණම අනුගමනය කරන බැවින්, අපට ලැබෙන ප්‍රතිදානය අද්විතීය අනුවාදයක් සහිත කෞතුක වස්තුවකි. උදාහරණයක් ලෙස, අවශ්‍ය නම්, වින්‍යාසයේ පෙර අනුවාදය වෙත ආපසු යාමට මෙය අපට ඉඩ සලසයි. අපට වසරකට පෙර සිට වින්‍යාසය භාවිතා කළ හැකි අතර පද්ධතිය හරියටම ක්‍රියා කරයි. ස්ථායී වින්‍යාසයක් බෙදා හරින ලද පද්ධතියක පුරෝකථනය කිරීමේ හැකියාව සහ විශ්වසනීයත්වය වැඩි දියුණු කරයි. වින්‍යාසය සම්පාදනය කිරීමේ අදියරේදී සවි කර ඇති බැවින්, නිෂ්පාදනයේදී එය ව්‍යාජ ලෙස සකස් කිරීම තරමක් අපහසුය.
  9. මොඩියුලරිටි. යෝජිත රාමුව මොඩියුලර් වන අතර විවිධ පද්ධති නිර්මාණය කිරීම සඳහා මොඩියුල විවිධ ආකාරවලින් ඒකාබද්ධ කළ හැකිය. විශේෂයෙන්, ඔබට පද්ධතිය එක් ප්‍රතිමූර්තියක තනි නෝඩයක් මත ක්‍රියාත්මක වන පරිදි සහ තවත් නෝඩ් කිහිපයක් මත ක්‍රියාත්මක වන ලෙස වින්‍යාසගත කළ හැක. පද්ධතියේ නිෂ්පාදන අවස්ථා සඳහා ඔබට වින්‍යාස කිහිපයක් සෑදිය හැක.
  10. පරීක්ෂා කිරීම. තනි සේවාවන් ව්‍යාජ වස්තූන් සමඟ ප්‍රතිස්ථාපනය කිරීමෙන්, ඔබට පරීක්ෂා කිරීමට පහසු පද්ධතියේ අනුවාද කිහිපයක් ලබා ගත හැකිය.
  11. ඒකාබද්ධතා පරීක්ෂණය. සමස්ත බෙදාහැරීමේ පද්ධතිය සඳහා තනි වින්‍යාසයක් තිබීම ඒකාබද්ධතා පරීක්ෂාවේ කොටසක් ලෙස පාලිත පරිසරයක සියලුම සංරචක ක්‍රියාත්මක කිරීමට හැකි වේ. නිදසුනක් ලෙස, සමහර නෝඩ් වලට ප්රවේශ විය හැකි තත්වයක් අනුකරණය කිරීම පහසුය.

අවාසි සහ සීමාවන්

සම්පාදනය කරන ලද වින්‍යාසය වෙනත් වින්‍යාස ප්‍රවේශයන්ගෙන් වෙනස් වන අතර සමහර යෙදුම් සඳහා සුදුසු නොවිය හැක. පහත දැක්වෙන අවාසි කිහිපයක්:

  1. ස්ථිතික වින්යාසය. සමහර විට ඔබ සියලු ආරක්ෂිත යාන්ත්‍රණයන් මඟහරිමින් නිෂ්පාදනයේ වින්‍යාසය ඉක්මනින් නිවැරදි කළ යුතුය. මෙම ප්රවේශය සමඟ එය වඩාත් අපහසු විය හැකිය. අවම වශයෙන්, සම්පාදනය කිරීම සහ ස්වයංක්‍රීයව යෙදවීම තවමත් අවශ්‍ය වනු ඇත. මෙය ප්රවේශයේ ප්රයෝජනවත් ලක්ෂණයක් වන අතර සමහර අවස්ථාවලදී අවාසියකි.
  2. වින්යාස උත්පාදනය. වින්‍යාස ගොනුව ස්වයංක්‍රීය මෙවලමක් මඟින් ජනනය කරන්නේ නම්, ගොඩනැගීමේ ස්ක්‍රිප්ට් එක ඒකාබද්ධ කිරීමට අමතර උත්සාහයන් අවශ්‍ය විය හැක.
  3. මෙවලම්. දැනට, වින්‍යාසය සමඟ වැඩ කිරීමට නිර්මාණය කර ඇති උපයෝගිතා සහ ශිල්පීය ක්‍රම පදනම් වී ඇත්තේ පෙළ ගොනු මත ය. සම්පාදනය කරන ලද වින්‍යාසය තුළ එවැනි සියලු උපයෝගිතා/තාක්‍ෂණ ලබා ගත නොහැක.
  4. ආකල්පවල වෙනසක් අවශ්‍යයි. සංවර්ධකයින් සහ DevOps පෙළ ගොනු වලට හුරුවී ඇත. වින්‍යාසයක් සම්පාදනය කිරීමේ අදහස තරමක් අනපේක්ෂිත හා අසාමාන්‍ය විය හැකි අතර ප්‍රතික්ෂේප වීමට හේතු විය හැක.
  5. උසස් තත්ත්වයේ සංවර්ධන ක්රියාවලියක් අවශ්ය වේ. සම්පාදනය කරන ලද වින්‍යාසය සුවපහසු ලෙස භාවිතා කිරීම සඳහා, යෙදුම ගොඩනැගීමේ සහ යෙදවීමේ ක්‍රියාවලියේ සම්පූර්ණ ස්වයංක්‍රීයකරණය (CI/CD) අවශ්‍ය වේ. එසේ නොමැතිනම් එය තරමක් අපහසු වනු ඇත.

සම්පාදනය කරන ලද වින්‍යාසය පිළිබඳ අදහසට සම්බන්ධ නොවන සලකා බැලූ උදාහරණයේ සීමාවන් ගණනාවක් ගැන ද අපි වාසය කරමු:

  1. අපි නෝඩය විසින් භාවිතා නොකරන අනවශ්‍ය වින්‍යාස තොරතුරු සපයන්නේ නම්, නැතිවූ ක්‍රියාත්මක කිරීම හඳුනා ගැනීමට සම්පාදකය අපට උදව් නොකරනු ඇත. මෙම ගැටළුව විසඳා ගත හැක්කේ කේක් රටාව අතහැර වඩාත් දෘඩ වර්ග භාවිතා කිරීමෙනි, උදාහරණයක් ලෙස, HList හෝ වීජීය දත්ත වර්ග (අවස්ථා පන්ති) වින්‍යාසය නියෝජනය කිරීමට.
  2. වින්‍යාස ගොනුවේ වින්‍යාසයටම සම්බන්ධ නොවන රේඛා ඇත: (package, import,වස්තු ප්රකාශන; override defපෙරනිමි අගයන් ඇති පරාමිති සඳහා වේ). ඔබ ඔබේම DSL ක්‍රියාත්මක කරන්නේ නම් මෙය අර්ධ වශයෙන් වළක්වා ගත හැක. මීට අමතරව, වෙනත් ආකාරයේ වින්‍යාස කිරීම් (උදාහරණයක් ලෙස, XML) ගොනු ව්‍යුහය මත යම් සීමාවන් ද පනවා ඇත.
  3. මෙම පළකිරීමේ අරමුණු සඳහා, අපි සමාන නෝඩ් පොකුරක ගතික ප්‍රතිසංවිධානය සලකා බලන්නේ නැත.

නිගමනය

මෙම ලිපියෙන් අපි Scala වර්ගයේ පද්ධතියේ උසස් හැකියාවන් භාවිතා කරමින් ප්‍රභව කේතයේ වින්‍යාසය නියෝජනය කිරීමේ අදහස ගවේෂණය කළෙමු. මෙම ප්‍රවේශය xml හෝ පෙළ ගොනු මත පදනම් වූ සාම්ප්‍රදායික වින්‍යාස ක්‍රම සඳහා ප්‍රතිස්ථාපනයක් ලෙස විවිධ යෙදුම්වල භාවිතා කළ හැක. අපගේ උදාහරණය Scala හි ක්‍රියාත්මක වුවද, එම අදහස් වෙනත් සම්පාදනය කරන ලද භාෂාවලට (කොට්ලින්, C#, Swift, ... වැනි) මාරු කළ හැකිය. ඔබට පහත ව්‍යාපෘති වලින් එකකින් මෙම ප්‍රවේශය උත්සාහ කළ හැකි අතර, එය ක්‍රියා නොකරන්නේ නම්, නැතිවූ කොටස් එකතු කරමින් පෙළ ගොනුව වෙත යන්න.

ස්වාභාවිකවම, සම්පාදනය කරන ලද වින්‍යාසයකට උසස් තත්ත්වයේ සංවර්ධන ක්‍රියාවලියක් අවශ්‍ය වේ. ඊට ප්‍රතිචාර වශයෙන්, වින්‍යාසවල උසස් තත්ත්වය සහ විශ්වසනීයත්වය සහතික කෙරේ.

සලකා බැලූ ප්රවේශය පුළුල් කළ හැකිය:

  1. compile-time checks කිරීමට ඔබට macros භාවිතා කළ හැක.
  2. අවසාන පරිශීලකයින්ට ප්‍රවේශ විය හැකි ආකාරයෙන් වින්‍යාසය ඉදිරිපත් කිරීමට ඔබට DSL ක්‍රියාත්මක කළ හැක.
  3. ඔබට ස්වයංක්‍රීය වින්‍යාස ගැලපීම සමඟ ගතික සම්පත් කළමනාකරණය ක්‍රියාත්මක කළ හැකිය. උදාහරණයක් ලෙස, පොකුරේ ඇති නෝඩ් ගණන වෙනස් කිරීම සඳහා (1) සෑම නෝඩයකටම තරමක් වෙනස් වින්‍යාසයක් ලැබීම අවශ්‍ය වේ; (2) පොකුරු කළමනාකරුට නව නෝඩ් පිළිබඳ තොරතුරු ලැබුණි.

පිළිගැනීම්

කෙටුම්පත් ලිපිය පිළිබඳ ඔවුන්ගේ නිර්මාණාත්මක විවේචන සඳහා Andrei Saksonov, Pavel Popov සහ Anton Nekhaev ට ස්තුති කිරීමට මම කැමතියි.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න