مرتب ٿيل ورهايل سسٽم جي ترتيب

مان توهان کي ٻڌائڻ چاهيان ٿو ته ورهايل سسٽم جي ترتيب سان ڪم ڪرڻ لاء هڪ دلچسپ ميکانيزم. ٺاھ جوڙ سڌي طرح ھڪڙي مرتب ٿيل ٻولي (اسڪالا) ۾ محفوظ قسم استعمال ڪندي نمائندگي ڪئي وئي آھي. هي پوسٽ اهڙي ترتيب جو هڪ مثال مهيا ڪري ٿو ۽ مجموعي ترقي جي عمل ۾ مرتب ڪيل ترتيب کي لاڳو ڪرڻ جي مختلف پهلوئن تي بحث ڪري ٿو.

مرتب ٿيل ورهايل سسٽم جي ترتيب

(انگريزي)

تعارف

هڪ قابل اعتماد ورهايل سسٽم جي تعمير جو مطلب اهو آهي ته سڀئي نوڊس صحيح ترتيب استعمال ڪن ٿا، ٻين نوڊس سان هم وقت سازي. DevOps ٽيڪنالاجيون (terraform، جوابي يا اهڙي شيءِ) عام طور تي استعمال ٿينديون آهن خودڪار طريقي سان ٺاھڻ واريون فائلون (اڪثر هر نوڊ لاءِ مخصوص). اسان اهو پڻ پڪ ڪرڻ چاهيون ٿا ته سڀئي مواصلاتي نوڊس هڪجهڙا پروٽوڪول استعمال ڪري رهيا آهن (ساڳئي ورزن سميت). ٻي صورت ۾، اسان جي ورهايل نظام ۾ مطابقت پيدا ڪئي ويندي. JVM دنيا ۾، هن گهرج جو هڪ نتيجو اهو آهي ته لائبريري جو ساڳيو نسخو پروٽوڪول پيغامن تي مشتمل آهي هر جڳهه استعمال ڪيو وڃي.

ورهايل سسٽم جي جانچ بابت ڇا؟ يقينن، اسان فرض ڪريون ٿا ته سڀني حصن ۾ يونٽ ٽيسٽ آهن ان کان اڳ اسان انٽيگريشن ٽيسٽ ڏانهن وڃو. (اسان لاءِ ٽيسٽ جي نتيجن کي رن ٽائم تائين وڌائڻ لاءِ، اسان کي لازمي طور تي ٽيسٽنگ اسٽيج تي ۽ رن ٽائم تي لائبريرين جو هڪجهڙو سيٽ مهيا ڪرڻ گهرجي.)

جڏهن انٽيگريشن ٽيسٽ سان ڪم ڪري رهيو آهي، اهو اڪثر آسان هوندو آهي ساڳيو ڪلاس پاٿ هر هنڌ سڀني نوڊس تي استعمال ڪرڻ. اسان کي اهو ڪرڻو آهي ته رن ٽائم تي ساڳيو ڪلاس پاٿ استعمال ٿئي. (جڏهن ته اهو مڪمل طور تي ممڪن آهي ته مختلف نوڊس کي مختلف ڪلاس پاٿن سان هلائڻ، ان سان مجموعي ترتيب ۾ پيچيدگي شامل ٿئي ٿي ۽ ڊيپلائيمينٽ ۽ انٽيگريشن ٽيسٽن ۾ مشڪلاتون پيدا ٿين ٿيون.) هن پوسٽ جي مقصدن لاءِ، اسان فرض ڪري رهيا آهيون ته سڀئي نوڊس ساڳيا ڪلاس پاٿ استعمال ڪندا.

تشڪيل ايپليڪيشن سان ترقي ڪري ٿي. پروگرام جي ارتقا جي مختلف مرحلن کي سڃاڻڻ لاءِ اسان ورجن استعمال ڪندا آهيون. اهو منطقي لڳي ٿو ته ترتيب جي مختلف نسخن جي سڃاڻپ پڻ. ۽ ٺاھ جوڙ پاڻ کي ورجن ڪنٽرول سسٽم ۾ رکي. جيڪڏهن پيداوار ۾ صرف هڪ ترتيب آهي، ته پوء اسان صرف نسخي نمبر استعمال ڪري سگهون ٿا. جيڪڏهن اسان ڪيترن ئي پيداوار جا مثال استعمال ڪندا آهيون، پوء اسان کي ڪيترن ئي جي ضرورت پوندي
configuration شاخون ۽ هڪ اضافي ليبل نسخي کان علاوه (مثال طور، شاخ جو نالو). هن طريقي سان اسان واضح طور تي صحيح تشڪيل جي سڃاڻپ ڪري سگهون ٿا. هر ترتيب جي سڃاڻپ ڪندڙ منفرد طور تي ورهايل نوڊس، بندرگاهن، خارجي وسيلن، ۽ لائبريري ورزن جي مخصوص ميلاپ سان ملندڙ جلندڙ آهي. هن پوسٽ جي مقصدن لاءِ اسان اهو فرض ڪنداسين ته هتي صرف هڪ شاخ آهي ۽ اسان ڊٽ (1.2.3) سان الڳ ٿيل ٽن نمبرن کي استعمال ڪندي معمولي طريقي سان ترتيب جي سڃاڻپ ڪري سگهون ٿا.

جديد ماحول ۾، ترتيب ڏيڻ واريون فائلون گهٽ ۾ گهٽ دستي طور تي ٺاهيا ويا آهن. گهڻو ڪري اهي ترتيب ڏيڻ دوران ٺاهيا ويندا آهن ۽ هاڻي نه ڇڪيا ويندا آهن (ته جيئن ڪجھ به نه ٽوڙيو). هڪ قدرتي سوال پيدا ٿئي ٿو: اسان اڃا تائين ترتيب ڏيڻ لاء ٽيڪسٽ فارميٽ ڇو استعمال ڪندا آهيون؟ هڪ قابل عمل متبادل لڳي ٿو ترتيب ڏيڻ لاءِ باقاعده ڪوڊ استعمال ڪرڻ جي صلاحيت ۽ مرتب وقت جي چڪاس مان فائدو.

هن پوسٽ ۾ اسان هڪ مرتب ڪيل آرٽيڪل جي اندر ترتيب جي نمائندگي ڪرڻ جي خيال کي ڳوليندا سين.

ترتيب ڏنل ترتيب

هي سيڪشن جامد مرتب ڪيل ترتيب جو هڪ مثال مهيا ڪري ٿو. ٻه سادي خدمتون لاڳو ڪيون ويون آهن - گونج سروس ۽ گونج سروس ڪلائنٽ. انهن ٻن خدمتن جي بنياد تي، ٻه سسٽم جا اختيار گڏ ڪيا ويا آهن. ھڪڙي اختيار ۾، ٻئي خدمتون ھڪڙي نوڊ تي واقع آھن، ٻئي اختيار ۾ - مختلف نوڊس تي.

عام طور تي هڪ ورهايل نظام ڪيترن ئي نوڊس تي مشتمل آهي. توھان ڪجھ قسم جا قدر استعمال ڪندي نوڊس جي سڃاڻپ ڪري سگھو ٿا 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-بٽ انٽيگرز آهن. مرتب ڪيل ٺاھ جوڙ لاءِ، سڌريل لئبرري استعمال ڪرڻ لازمي نه آھي، پر اھو ٺاھيندڙ جي صلاحيت کي بھتر ڪري ٿو ته جيئن ٺاھ جوڙ کي چيڪ ڪري سگھي.

HTTP (REST) ​​پروٽوڪول لاءِ، پورٽ نمبر کان علاوه، اسان کي شايد خدمت جي رستي جي ضرورت پوندي:

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

پريت جا قسم

مرتب وقت تي پروٽوڪول کي سڃاڻڻ لاءِ، اسان استعمال ڪريون ٿا هڪ قسم جو پيٽرول جيڪو ڪلاس ۾ استعمال نه ڪيو ويو آهي. اهو فيصلو هن حقيقت جي ڪري آهي ته اسان رن ٽائم تي هڪ پروٽوڪول مثال استعمال نه ڪندا آهيون، پر اسان چاهيون ٿا ته مرتب ڪندڙ کي پروٽوڪول مطابقت جي جانچ ڪرڻ لاء. پروٽوڪول جي وضاحت ڪندي، اسان انحصار جي طور تي هڪ نامناسب خدمت پاس ڪرڻ جي قابل نه هوندا.

عام پروٽوڪول مان هڪ آهي REST API Json serialization سان:

sealed trait JsonHttpRestProtocol[RequestMessage, ResponseMessage]

جتي RequestMessage - درخواست جو قسم، ResponseMessage - جواب جو قسم.
يقينن، اسان ٻين پروٽوڪول وضاحتن کي استعمال ڪري سگھون ٿا جيڪي وضاحت جي درستگي مهيا ڪن ٿيون جيڪي اسان کي گھربل آھن.

هن پوسٽ جي مقصدن لاء، اسان پروٽوڪول جو هڪ آسان نسخو استعمال ڪنداسين:

sealed trait SimpleHttpGetRest[RequestMessage, ResponseMessage]

هتي درخواست url ۾ شامل ڪيل اسٽرنگ آهي ۽ جواب HTTP جواب جي جسم ۾ واپسي اسٽرنگ آهي.

خدمت جي تشڪيل بيان ڪيل آهي خدمت جو نالو، بندرگاهن، ۽ انحصار. اهي عناصر اسڪالا ۾ ڪيترن ئي طريقن سان نمائندگي ڪري سگھجن ٿيون (مثال طور، HList-s، الجبرائي ڊيٽا جا قسم). هن پوسٽ جي مقصدن لاء، اسان ڪيڪ جو نمونو استعمال ڪنداسين ۽ ماڊل استعمال ڪندي نمائندگي ڪنداسين trait'او. (ڪيڪ جو نمونو هن طريقي جو گهربل عنصر نه آهي. اهو صرف هڪ ممڪن عمل آهي.)

خدمتن جي وچ ۾ انحصار کي طريقن جي طور تي نمائندگي ڪري سگهجي ٿو جيڪي بندرگاهن کي واپس ڪن ٿا 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)
  }

هڪ گونج سروس ٺاهڻ لاء، توهان سڀني کي ضرورت آهي هڪ پورٽ نمبر ۽ هڪ اشارو آهي ته پورٽ گونج پروٽوڪول کي سپورٽ ڪري ٿو. اسان شايد هڪ مخصوص بندرگاهن جي وضاحت نه ڪري سگهون، ڇاڪاڻ ته ... خاصيتون توهان کي بغير عمل جي طريقن جو اعلان ڪرڻ جي اجازت ڏين ٿا (خلاصي طريقا). انهي صورت ۾، جڏهن هڪ ڪنڪريٽ ترتيب ٺاهيندي، گڏ ڪرڻ وارو اسان کي لازمي طريقي سان عمل درآمد ڪرڻ ۽ پورٽ نمبر مهيا ڪرڻ جي ضرورت پوندي. جيئن ته اسان طريقو لاڳو ڪيو آهي، جڏهن هڪ مخصوص تشڪيل ٺاهيندي، اسان شايد مختلف بندرگاهن جي وضاحت نه ڪري سگهون. ڊفالٽ قدر استعمال ڪيو ويندو.

ڪلائنٽ جي ترتيب ۾ اسان گونج سروس تي انحصار جو اعلان ڪريون ٿا:

  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 - هڪ اثر قسم جو ڪلاس جيڪو توهان کي انفرادي اثرات کي گڏ ڪرڻ جي اجازت ڏئي ٿو (تقريبا هڪ موناد). وڌيڪ پيچيده ايپليڪيشنن ۾ اهو استعمال ڪرڻ بهتر لڳي ٿو Monad/ConcurrentEffect.

هن فنڪشن جي دستخط کي استعمال ڪندي اسان ڪيترن ئي خدمتن کي لاڳو ڪري سگهون ٿا. مثال طور، هڪ خدمت جيڪا ڪجھ به نه ڪندي:

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

(سي ايم. ذريعو، جنهن ۾ ٻيون خدمتون لاڳو ڪيون وينديون آهن - گونج سروس, گونج ڪلائنٽ
и حياتياتي سنڀاليندڙ.)

هڪ نوڊ هڪ اعتراض آهي جيڪو ڪيترن ئي خدمتن کي شروع ڪري سگهي ٿو (وسيلن جي زنجير جي شروعات ڪيڪ پيٽرن طرفان يقيني بڻائي ٿي):

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

مهرباني ڪري نوٽ ڪريو ته اسان وضاحت ڪري رهيا آهيون صحيح قسم جي تشڪيل جيڪا هن نوڊ لاءِ گهربل آهي. جيڪڏهن اسان هڪ خاص خدمت جي گهربل ترتيبن جي قسمن مان هڪ بيان ڪرڻ وساريندا آهيون، اتي هڪ تاليف جي غلطي هوندي. انهي سان گڏ، اسان هڪ نوڊ شروع ڪرڻ جي قابل نه هوندا جيستائين اسان سڀني ضروري ڊيٽا سان مناسب قسم جو ڪجهه اعتراض مهيا نه ڪندا آهيون.

ميزبان جو نالو قرارداد

ريموٽ ميزبان سان ڳنڍڻ لاء، اسان کي حقيقي IP پتي جي ضرورت آهي. اهو ممڪن آهي ته ايڊريس باقي ترتيب جي ڀيٽ ۾ بعد ۾ معلوم ٿي ويندي. تنهنڪري اسان کي هڪ فنڪشن جي ضرورت آهي جيڪا نقشي جي نوڊ ID کي ايڊريس تي:

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

ھن فنڪشن کي لاڳو ڪرڻ جا ڪيترائي طريقا آھن:

  1. جيڪڏهن ايڊريس اسان کي ڊيپلائيمينٽ کان اڳ معلوم ٿي وڃن ته پوءِ اسان ان سان اسڪالا ڪوڊ ٺاهي سگهون ٿا
    ايڊريس ۽ پوء تعمير کي هلائڻ. هي ٽيسٽ گڏ ڪندو ۽ هلائيندو.
    انهي صورت ۾، فنڪشن کي مستحڪم طور سڃاتو ويندو ۽ نقشي جي طور تي ڪوڊ ۾ نمائندگي ڪري سگهجي ٿو 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 پروگرام کي ختم ڪريو. (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'om، ۽ ڪلائنٽ نوڊ ڪجهه وقت کان پوء ختم ٿي ويندو آهي. سي ايم. لانچر ايپ.

عام ترقي جي عمل

اچو ته ڏسو ته هي ترتيب ڏيڻ وارو طريقو مجموعي ترقي جي عمل کي ڪيئن متاثر ڪري ٿو.

ترتيب ترتيب ڏني ويندي باقي ڪوڊ سان گڏ ۽ هڪ آرٽيڪل (. jar) ٺاهي ويندي. اهو سمجهڻ لڳي ٿو ته ترتيب کي الڳ نموني ۾ رکڻ لاء. اهو ئي سبب آهي ته اسان وٽ هڪ ئي ڪوڊ جي بنياد تي ڪيترائي ترتيب ڏئي سگهون ٿا. ٻيهر، اهو ممڪن آهي ته مختلف ترتيبن جي شاخن سان لاڳاپيل نمونا پيدا ڪرڻ. لائبريرين جي مخصوص ورزن تي انحصار کي ترتيب سان محفوظ ڪيو ويندو آهي، ۽ اهي نسخا هميشه لاءِ محفوظ ٿي ويندا آهن جڏهن به اسان ان ترتيب جي نسخي کي ترتيب ڏيڻ جو فيصلو ڪريون ٿا.

ڪا به ترتيب واري تبديلي ڪوڊ جي تبديلي ۾ بدلجي ٿي. ۽ تنهن ڪري، هر هڪ
تبديلي کي ڍڪيو ويندو عام معيار جي يقين جي عمل سان:

بگ ٽريڪر ۾ ٽڪيٽ -> پي آر -> جائزو -> لاڳاپيل شاخن سان ضم ڪريو ->
انضمام -> لڳائڻ

مرتب ڪيل تشڪيل کي لاڳو ڪرڻ جا بنيادي نتيجا آهن:

  1. تشڪيل ورهايل سسٽم جي سڀني نوڊس جي برابر هوندي. انهي حقيقت جي ڪري ته سڀئي نوڊس هڪ ئي ذريعن کان ساڳي ترتيب حاصل ڪن ٿا.

  2. اهو صرف هڪ نوڊس ۾ تشڪيل کي تبديل ڪرڻ ڏکيو آهي. تنهن ڪري، "ترتيباتي drift" ممڪن ناهي.

  3. ٺاھ جوڙ ۾ ننڍيون تبديليون ڪرڻ وڌيڪ ڏکيو ٿي پوي ٿو.

  4. اڪثر جوڙجڪ تبديليون مجموعي ترقي جي عمل جي حصي جي طور تي ٿينديون آهن ۽ نظرثاني جي تابع هونديون.

ڇا مون کي پيداوار جي ترتيب کي ذخيرو ڪرڻ لاءِ الڳ مخزن جي ضرورت آهي؟ ھن تشڪيل ۾ پاسورڊ ۽ ٻي حساس معلومات شامل ٿي سگھي ٿي جن تائين اسان رسائي کي محدود ڪرڻ چاھيون ٿا. انهي جي بنياد تي، اهو سمجهڻ لڳي ٿو ته حتمي ترتيب کي الڳ الڳ مخزن ۾ ذخيرو ڪرڻ لاء. توھان ڪنفيگريشن کي ٻن حصن ۾ ورهائي سگھو ٿا- ھڪڙو عوامي طور تي رسائي جي ترتيب واري سيٽنگن تي مشتمل آھي ۽ ھڪڙو محدود سيٽنگن تي مشتمل آھي. هي اڪثر ڊولپرز کي عام سيٽنگن تائين رسائي جي اجازت ڏيندو. ھي علحدگيءَ آسان آھي حاصل ڪرڻ لاءِ وچولي خصوصيتن کي استعمال ڪندي جن ۾ ڊفالٽ ويلز شامل آھن.

ممڪن تبديليون

اچو ته مرتب ڪيل ترتيب کي ڪجھ عام متبادلن سان ڀيٽڻ جي ڪوشش ڪريون:

  1. ٽارگيٽ مشين تي متن فائل.
  2. مرڪزي اهم-قيمتي اسٽور (etcd/zookeeper).
  3. پروسيس جا حصا جيڪي ٻيهر ترتيب ڏئي سگھجن ٿا / ٻيهر شروع ڪرڻ کان سواءِ پروسيس کي ٻيهر شروع ڪرڻ.
  4. آرٽيڪل ۽ ورزن ڪنٽرول کان ٻاهر اسٽوريج جي ترتيب.

ٽيڪسٽ فائلون ننڍيون تبديلين جي لحاظ کان اهم لچڪدار مهيا ڪن ٿيون. سسٽم ايڊمنسٽريٽر ريموٽ نوڊ ۾ لاگ ان ڪري سگھي ٿو، مناسب فائلن ۾ تبديليون ڪري ۽ سروس کي ٻيهر شروع ڪري سگھي ٿو. جڏهن ته، وڏي سسٽم لاءِ، اهڙي لچڪ شايد گهربل نه هجي. تبديليون ٻين سسٽم ۾ ڪوبه نشان نه ڇڏيندا آهن. تبديلين جو ڪو به جائزو نٿو وٺي. اهو طئي ڪرڻ ڏکيو آهي ته ڪير تبديليون ڪيون ۽ ڪهڙي سبب لاء. تبديليون آزمائشي نه آهن. جيڪڏهن سسٽم ورهايو ويو آهي، پوء منتظم شايد ٻين نوڊس تي لاڳاپيل تبديلي ڪرڻ وساري سگهي ٿو.

(اهو پڻ ياد رکڻ گهرجي ته مرتب ڪيل ترتيب کي استعمال ڪرڻ سان مستقبل ۾ ٽيڪسٽ فائلن جي استعمال جي امڪان کي بند نٿو ڪري. اهو هڪ پارسر ۽ تصديق ڪندڙ شامل ڪرڻ لاء ڪافي هوندو جيڪو ساڳئي قسم جي پيداوار پيدا ڪري ٿو. Config، ۽ توهان ٽيڪسٽ فائلون استعمال ڪري سگهو ٿا. اهو فوري طور تي هيٺ ڏنل آهي ته هڪ مرتب ڪيل ترتيب سان سسٽم جي پيچيدگي ٽيڪسٽ فائلن کي استعمال ڪندي سسٽم جي پيچيدگي کان ڪجهه گهٽ آهي، ڇاڪاڻ ته ٽيڪسٽ فائلن کي اضافي ڪوڊ جي ضرورت آهي.)

هڪ مرڪزي اهم-قيمتي اسٽور هڪ ورهايل ايپليڪيشن جي ميٽا پيٽرولن کي ورهائڻ لاءِ سٺو ميکانيزم آهي. اسان کي فيصلو ڪرڻ جي ضرورت آهي ته ڇا ترتيب جي ماپ آهن ۽ ڇا صرف ڊيٽا آهن. اچو ته هڪ فنڪشن ڪريون C => A => B، ۽ پيرا ميٽرز C نادر تبديليون، ۽ ڊيٽا A - اڪثر. ان صورت ۾ اسان اهو چئي سگهون ٿا C - ٺاھ جوڙ جي ماپ، ۽ A - ڊيٽا. اهو ظاهر ٿئي ٿو ته ترتيب جي پيٽرولر ڊيٽا کان مختلف آهن انهي ۾ اهي عام طور تي ڊيٽا جي ڀيٽ ۾ گهٽ بار بار تبديل ڪندا آهن. انهي سان گڏ، ڊيٽا عام طور تي هڪ ذريعو (استعمال ڪندڙ کان)، ۽ ترتيب جي پيٽرولر ٻئي کان (سسٽم ايڊمنسٽريٽر کان) اچي ٿو.

جيڪڏهن پروگرام کي ٻيهر شروع ڪرڻ کان سواءِ گهٽ ۾ گهٽ تبديل ٿيندڙ پيٽرولرن کي اپڊيٽ ڪرڻ جي ضرورت آهي، ته پوءِ اهو اڪثر ڪري پروگرام جي پيچيدگيءَ جو سبب بڻجي سگهي ٿو، ڇاڪاڻ ته اسان کي ڪنهن به طرح پيرا ميٽرز پهچائڻ، اسٽور ڪرڻ، پارس ڪرڻ ۽ چيڪ ڪرڻ، ۽ غلط قدرن تي عمل ڪرڻ جي ضرورت پوندي. تنهن ڪري، پروگرام جي پيچيدگي کي گهٽائڻ جي نقطي نظر کان، اهو سمجھندو آهي ته پيٽرولر جي تعداد کي گهٽائڻ لاء جيڪي پروگرام جي آپريشن دوران تبديل ٿي سگهن ٿيون (يا اهڙن پيرا ميٽرن کي سپورٽ نه ڪندا).

هن پوسٽ جي مقصدن لاء، اسان جامد ۽ متحرڪ پيٽرولر جي وچ ۾ فرق ڪنداسين. جيڪڏهن خدمت جي منطق کي پروگرام جي آپريشن دوران پيٽرولر کي تبديل ڪرڻ جي ضرورت آهي، ته پوء اسان اهڙن پيٽرولن کي متحرڪ سڏينداسين. ٻي صورت ۾ اختيار جامد آهن ۽ ترتيب ڏنل ترتيب جي استعمال سان ترتيب ڏئي سگھجن ٿيون. متحرڪ ٻيهر ترتيب ڏيڻ لاءِ، اسان کي پروگرام جي حصن کي نئين پيٽرولن سان ٻيهر شروع ڪرڻ لاءِ ميڪانيزم جي ضرورت پئجي سگھي ٿي، جيئن ته آپريٽنگ سسٽم جا عمل ٻيهر شروع ٿين ٿا. (اسان جي راء ۾، اهو مشورو ڏنو ويو آهي ته حقيقي وقت جي بحالي کان بچڻ لاء، ڇو ته اهو سسٽم جي پيچيدگي کي وڌائي ٿو. جيڪڏهن ممڪن هجي، اهو بهتر آهي ته معياري OS صلاحيتن کي ٻيهر شروع ڪرڻ لاء استعمال ڪيو وڃي.)

جامد ترتيبن کي استعمال ڪرڻ جو هڪ اهم پاسو جيڪو ماڻهن کي متحرڪ ٻيهر ترتيب ڏيڻ تي غور ڪري ٿو اهو وقت آهي جيڪو سسٽم کي ترتيب ڏيڻ جي تازه ڪاري (ڊائون ٽائم) کان پوءِ ريبوٽ ڪرڻ ۾ وٺندو آهي. حقيقت ۾، جيڪڏهن اسان کي جامد ترتيبن ۾ تبديليون ڪرڻ جي ضرورت آهي، اسان کي نئين قدرن کي اثر انداز ڪرڻ لاء سسٽم کي ٻيهر شروع ڪرڻو پوندو. بند وقت جو مسئلو مختلف سسٽمن جي شدت ۾ مختلف آهي. ڪجهه حالتن ۾، توهان هڪ وقت تي ريبوٽ شيڊول ڪري سگهو ٿا جڏهن لوڊ گهٽ ۾ گهٽ آهي. جيڪڏهن توهان کي مسلسل خدمت مهيا ڪرڻ جي ضرورت آهي، توهان لاڳو ڪري سگهو ٿا AWS ELB ڪنيڪشن ڊريننگ. ساڳئي وقت، جڏهن اسان کي سسٽم کي ريبوٽ ڪرڻ جي ضرورت آهي، اسان هن سسٽم جو هڪ متوازي مثال شروع ڪيو، ان کي بيلنس کي تبديل ڪريو، ۽ پراڻي ڪنيڪشن کي مڪمل ڪرڻ لاء انتظار ڪريو. سڀني پراڻي ڪنيڪشن ختم ٿيڻ کان پوء، اسان سسٽم جي پراڻي مثال کي بند ڪيو.

اچو ته ھاڻي ان مسئلي تي غور ڪريون جنھن جي ترتيب کي آرٽيڪل جي اندر يا ٻاھر رکڻ جي. جيڪڏهن اسان هڪ آرٽيڪل جي اندر ترتيب کي ذخيرو ڪريون ٿا، ته پوء گهٽ ۾ گهٽ اسان وٽ اهو موقعو هوندو هو ته آرٽيڪل جي اسيمبليء دوران ترتيب جي صحيحيت جي تصديق ڪرڻ. جيڪڏهن ڪنفيگريشن ڪنٽرول ٿيل آرٽيڪل کان ٻاهر آهي، اهو ٽريڪ ڪرڻ ڏکيو آهي ته هن فائل ۾ ڪنهن تبديليون ڪيون ۽ ڇو. اهو ڪيترو اهم آهي؟ اسان جي راء ۾، ڪيترن ئي پيداوار سسٽم لاء اهو ضروري آهي ته هڪ مستحڪم ۽ اعلي معيار جي جوڙجڪ هجڻ ضروري آهي.

هڪ آرٽيڪل جو نسخو توهان کي اهو طئي ڪرڻ جي اجازت ڏئي ٿو ته اهو ڪڏهن ٺاهيو ويو، ان ۾ ڪهڙا قدر شامل آهن، ڪهڙا افعال فعال/معذور آهن، ۽ ترتيب ۾ ڪنهن به تبديلي جو ذميوار ڪير آهي. يقينا، هڪ آرٽيڪل جي اندر ترتيب کي محفوظ ڪرڻ لاء ڪجهه ڪوشش جي ضرورت آهي، تنهنڪري توهان کي هڪ باخبر فيصلو ڪرڻ جي ضرورت آهي.

عروض ۽ اتفاق

مان تجويز ڪيل ٽيڪنالاجي جي فائدن ۽ نقصانن تي رهڻ چاهيان ٿو.

فائدن

هيٺ ڏنل هڪ مرتب ڪيل ورهايل سسٽم جي جوڙجڪ جي مکيه خاصيتن جي هڪ فهرست آهي:

  1. جامد ترتيب جي چڪاس. توهان کي پڪ ڪرڻ جي اجازت ڏئي ٿي
    تشڪيل صحيح آهي.
  2. وڏي ترتيب واري ٻولي. عام طور تي، ٻيون ٺاھ جوڙ جا طريقا محدود آھن string variable متبادل تائين. جڏهن اسڪالا استعمال ڪري رهيا آهيو، توهان جي ترتيب کي بهتر ڪرڻ لاءِ ٻولي جون خاصيتون موجود آهن. مثال طور اسان استعمال ڪري سگهون ٿا
    ڊفالٽ ويلز لاءِ خاصيتون، شيون استعمال ڪندي گروپ پيراميٽرز ۾، اسان حوالو ڪري سگھون ٿا والز جو اعلان ڪيل صرف هڪ ڀيرو (DRY) بند ٿيل دائري ۾. توهان ڪنهن به ڪلاس کي ترتيب ڏئي سگهو ٿا سڌو سنئون ترتيب جي اندر (Seq, Map، ڪسٽم ڪلاس).
  3. ڊي ايس ايل. اسڪالا ۾ ڪيتريون ئي ٻوليون خاصيتون آھن جيڪي ڊي ايس ايل ٺاھڻ کي آسان بڻائين ٿيون. اهو ممڪن آهي ته انهن خاصيتن مان فائدو وٺن ۽ هڪ ترتيب واري ٻولي کي لاڳو ڪرڻ لاء استعمال ڪندڙن جي ٽارگيٽ گروپ لاء وڌيڪ آسان آهي، انهي جي ترتيب کي گهٽ ۾ گهٽ ڊومين ماهرن طرفان پڙهي سگهجي ٿو. ماهر، مثال طور، ٺاھ جوڙ جي نظرثاني جي عمل ۾ حصو وٺي سگھن ٿا.
  4. نوڊس جي وچ ۾ سالميت ۽ هم وقت سازي. هڪ ئي نقطي تي ذخيرو ٿيل پوري ورهايل سسٽم جي ترتيب ڏيڻ جو هڪ فائدو اهو آهي ته سڀني قدرن کي هڪ ڀيرو بيان ڪيو ويندو آهي ۽ پوءِ ٻيهر استعمال ڪيو ويندو آهي جتي انهن جي ضرورت هجي. بندرگاهن جو اعلان ڪرڻ لاءِ پريتم قسم جو استعمال يقيني بڻائي ٿو ته نوڊس سڀني صحيح سسٽم جي ترتيبن ۾ مطابقت رکندڙ پروٽوڪول استعمال ڪري رهيا آهن. نوڊس جي وچ ۾ واضح لازمي انحصار کي يقيني بڻائي ٿو ته سڀئي خدمتون ڳنڍيل آهن.
  5. اعلي معيار جي تبديليون. ھڪڙي عام ترقي واري عمل کي استعمال ڪندي ترتيبن ۾ تبديليون ڪرڻ ممڪن بڻائي ٿي ترتيب ڏيڻ لاءِ اعليٰ معيار جا معيار پڻ حاصل ڪرڻ.
  6. ساڳئي وقت ترتيب جي تازه ڪاري. ترتيب جي تبديلين کان پوء خودڪار سسٽم جي ترتيب يقيني بڻائي ٿي ته سڀئي نوڊس اپڊيٽ ٿيل آهن.
  7. ايپليڪيشن کي آسان ڪرڻ. ائپليڪيشن کي پارس ڪرڻ، ترتيب ڏيڻ جي چڪاس، يا غلط قدرن کي سنڀالڻ جي ضرورت ناهي. هي ايپليڪيشن جي پيچيدگي کي گھٽائي ٿو. (ڪجهه تشڪيل جي پيچيدگي جو اسان جي مثال ۾ مشاهدو ڪيو ويو آهي مرتب ڪيل ترتيب جي هڪ خاصيت نه آهي، پر صرف هڪ شعوري فيصلو جيڪو وڏي قسم جي حفاظت فراهم ڪرڻ جي خواهش سان هلائي ٿو.) اهو عام ترتيب ڏانهن موٽڻ بلڪل آسان آهي - صرف غائب کي لاڳو ڪريو. حصا تنهن ڪري، توهان، مثال طور، هڪ مرتب ڪيل ترتيب سان شروع ڪري سگهو ٿا، غير ضروري حصن جي عمل کي ان وقت تائين ملتوي ڪري جيستائين اهو واقعي گهربل هجي.
  8. تصديق ٿيل ٺاھ جوڙ. جيئن ته ٺاھ جوڙ تبديليون ڪنهن ٻئي تبديلين جي معمولي قسمت جي پيروي ڪندا آهن، اسان کي حاصل ڪيل پيداوار هڪ منفرد ورزن سان هڪ نموني آهي. اهو اسان کي اجازت ڏئي ٿو، مثال طور، جيڪڏهن ضروري هجي ته ترتيب جي پوئين ورزن ڏانهن واپس وڃو. اسان هڪ سال اڳ جي ترتيب پڻ استعمال ڪري سگهون ٿا ۽ سسٽم بلڪل ساڳيو ڪم ڪندو. هڪ مستحڪم ترتيب ورهايل نظام جي اڳڪٿي ۽ اعتبار کي بهتر بڻائي ٿي. جيئن ته ٺاھ جوڙ جي ٺاھ جوڙ جي مرحلي تي مقرر ڪيو ويو آهي، ان کي پيداوار ۾ جعلي ڪرڻ ڪافي ڏکيو آهي.
  9. ماڊلرٽي. تجويز ڪيل فريم ورڪ ماڊلر آهي ۽ ماڊلز کي مختلف طريقن سان گڏ ڪري سگهجي ٿو مختلف سسٽم ٺاهڻ لاء. خاص طور تي، توھان سسٽم کي ترتيب ڏئي سگھوٿا ھڪڙي ھڪڙي نوڊ تي ھڪڙي ھڪڙي نوڊ تي، ۽ ٻئي ۾ گھڻن نوڊس تي. توهان سسٽم جي پيداوار جي مثالن لاء ڪيترائي ترتيب ٺاهي سگهو ٿا.
  10. جاچڻ. ٺٺولي شين سان انفرادي خدمتن کي تبديل ڪندي، توهان سسٽم جا ڪيترائي نسخا حاصل ڪري سگهو ٿا جيڪي جانچ لاءِ آسان آهن.
  11. انضمام جي جاچ. پوري ورهايل سسٽم لاءِ هڪ واحد تشڪيل حاصل ڪرڻ اهو ممڪن بڻائي ٿو ته ڪنٽرول ٿيل ماحول ۾ سڀني اجزاء کي انضمام جي جاچ جي حصي طور هلائڻ. اهو نقل ڪرڻ آسان آهي، مثال طور، هڪ صورتحال جتي ڪجهه نوڊس پهچن ٿا.

نقصان ۽ حدون

مرتب ڪيل ٺاھ جوڙ ٻين ٺاھ جوڙ جي طريقن کان مختلف آھي ۽ ڪجھ ايپليڪيشنن لاء مناسب نه ٿي سگھي. هيٺيان ڪجهه نقصان آهن:

  1. جامد ترتيب. ڪڏهن ڪڏهن توهان کي جلدي پيداوار ۾ ترتيبن کي درست ڪرڻ جي ضرورت آهي، سڀني حفاظتي ميکانيزم کي ختم ڪندي. هن طريقي سان اهو وڌيڪ ڏکيو ٿي سگهي ٿو. گهٽ ۾ گهٽ، تاليف ۽ خودڪار لڳائڻ جي اڃا به ضرورت پوندي. هي ٻئي طريقي جي هڪ مفيد خصوصيت آهي ۽ ڪجهه ڪيسن ۾ هڪ نقصان.
  2. ٺاھ جوڙ جي نسل. صورت ۾ ٺاھ جوڙ فائيل هڪ خودڪار اوزار جي ٺاهيل آهي، اضافي ڪوششون گهربل اسڪرپٽ کي ضم ڪرڻ لاء.
  3. اوزار. في الحال، ترتيب سان ڪم ڪرڻ لاء ٺهيل افاديت ۽ ٽيڪنالاجيون ٽيڪسٽ فائلن تي ٻڌل آهن. اهڙيون سڀئي افاديتون / ٽيڪنڪون موجود نه هونديون هڪ مرتب ڪيل ترتيب ۾.
  4. روين ۾ تبديلي جي ضرورت آهي. ڊولپرز ۽ DevOps ٽيڪسٽ فائلن جا عادي آهن. هڪ ترتيب ترتيب ڏيڻ جو تمام گهڻو خيال ٿي سگهي ٿو ڪجهه غير متوقع ۽ غير معمولي ۽ رد ڪرڻ جو سبب.
  5. هڪ اعلي معيار جي ترقي جي عمل جي ضرورت آهي. ترتيب ڏنل ترتيب کي آرام سان استعمال ڪرڻ لاء، ايپليڪيشن جي تعمير ۽ ترتيب ڏيڻ جي عمل جي مڪمل آٽوميشن (CI/CD) ضروري آهي. ٻي صورت ۾ ان کي ڪافي تڪليف ٿيندي.

اچو ته اسان غور ڪيل مثال جي ڪيترن ئي حدن تي پڻ غور ڪريون جيڪي مرتب ڪيل ترتيب جي خيال سان لاڳاپيل نه آهن:

  1. جيڪڏهن اسان غير ضروري تشڪيل جي معلومات مهيا ڪندا آهيون جيڪا نوڊ طرفان استعمال نه ڪئي وئي آهي، پوء گڏ ڪرڻ وارو اسان کي غائب عمل کي ڳولڻ ۾ مدد نه ڪندو. اهو مسئلو حل ڪري سگهجي ٿو ڪيڪ جي نموني کي ڇڏي ڏيڻ ۽ وڌيڪ سخت قسم جي استعمال سان، مثال طور، HList يا الجبرائي ڊيٽا جا قسم (ڪيس ڪلاس) ترتيب ڏيڻ جي نمائندگي ڪرڻ لاءِ.
  2. ڪنفيگريشن فائل ۾ سٽون آھن جيڪي پاڻ ٺاھڻ سان لاڳاپيل نه آھن: (package, importاعتراض جو اعلان؛ override defجي پيرا ميٽرن لاءِ جيڪي ڊفالٽ قدر آھن). اهو جزوي طور بچي سگهجي ٿو جيڪڏهن توهان پنهنجي ڊي ايس ايل کي لاڳو ڪريو. ان کان سواء، ترتيب جي ٻين قسمن (مثال طور، XML) پڻ فائل جي جوڙجڪ تي ڪجهه پابنديون لاڳو ڪن ٿيون.
  3. هن پوسٽ جي مقصدن لاء، اسان ساڳئي نوڊس جي ڪلستر جي متحرڪ ٻيهر ترتيب ڏيڻ تي غور نه ڪري رهيا آهيون.

ٿڪل

هن پوسٽ ۾، اسان اسڪالا قسم جي سسٽم جي جديد صلاحيتن کي استعمال ڪندي ماخذ ڪوڊ ۾ تشڪيل جي نمائندگي ڪرڻ جو خيال ڳوليو. اهو طريقو مختلف ايپليڪيشنن ۾ استعمال ڪري سگهجي ٿو روايتي ترتيب جي طريقن جي متبادل طور تي xml يا ٽيڪسٽ فائلن جي بنياد تي. جيتوڻيڪ اسان جو مثال اسڪالا ۾ لاڳو ڪيو ويو آهي، ساڳيا خيال ٻين مرتب ڪيل ٻولين (جهڙوڪ Kotlin، C#، Swift، ...) ڏانهن منتقل ٿي سگهن ٿا. توھان ھيٺ ڏنل منصوبن مان ھڪڙي ۾ ھن طريقي جي ڪوشش ڪري سگھو ٿا، ۽، جيڪڏھن اھو ڪم نٿو ڪري، ٽيڪسٽ فائل ڏانھن وڃو، غائب حصن کي شامل ڪندي.

قدرتي طور تي، هڪ مرتب ڪيل ترتيب کي اعلي معيار جي ترقي جي عمل جي ضرورت آهي. واپسي ۾، ترتيب جي اعلي معيار ۽ اعتبار کي يقيني بڻايو وڃي ٿو.

غور ڪيل طريقي کي وڌايو وڃي ٿو:

  1. توهان ميڪرو استعمال ڪري سگهو ٿا ڪمپائل ٽائيم چيڪ ڪرڻ لاءِ.
  2. توهان هڪ DSL لاڳو ڪري سگهو ٿا ترتيب پيش ڪرڻ لاءِ انهي طريقي سان جيڪا آخري استعمال ڪندڙن تائين پهچندي.
  3. توھان لاڳو ڪري سگھوٿا متحرڪ وسيلن جي انتظام کي خودڪار ترتيب جي ترتيب سان. مثال طور، ڪلستر ۾ نوڊس جي تعداد کي تبديل ڪرڻ جي ضرورت آھي (1) ھر نوڊ کي ٿورڙي مختلف ترتيب ملي ٿي. (2) ڪلستر مينيجر کي نئين نوڊس بابت ڄاڻ ملي ٿي.

مڃيل نشانيون

مان آندري ساڪسونوف، پاول پوپوف ۽ انتون نيخائيف جو شڪريو ادا ڪرڻ چاهيان ٿو انهن جي ڊرافٽ آرٽيڪل جي تعميري تنقيد لاءِ.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو