Таньд энэ нийтлэлийг уншиж буй энэ өдрийн мэндийг хүргэе . Хамгийн түрүүнд Үзэгдлээр хөтлүүлсэн архитектур ( Event-Driven Architecture ) гэж юу вэ талаар ярих хэрэгтэй бизээ .

Үзэгдлээр хөтлүүлсэн архитектур гэж юу вэ ?

Үзэгдлээр хөтлүүлсэн архитектур нь програм хангамжийн зохион байгуулалтын арга бөгөөд системийн бүрэлдэхүүн хэсгүүд нь хэрэглэгчийн үйлдэл эсвэл системийн төлөв өөрчлөлт зэрэг үзэгдлүүдийг үүсгэж, тэдгээрт хариу үйлдэл үзүүлэх замаар харилцдаг билээ . Бүрэлдэхүүн хэсгүүд нь бие биенээсээ хамаарал бага тул бие даан ажиллах боломжтой ба үзэгдлүүдэд бодит цаг хугацаанд хариу өгч чадна. Энэ архитектур нь scale хийх чадвар, уян хатан байдал, хариу үйлдлийн хурдыг сайжруулдаг.

Үйлчилгээ хоорондын харилцаа

Үйлчилгээ хоорондын харилцаа гэдэг нь системийн бүрэлдэхүүн хэсгүүд хэрхэн харилцан ажиллаж, мэдээлэл солилцдогийг заадаг ойлголт юм. Энэ харилцаа нь хоёр үндсэн төрөлд хуваагддаг: Синхрон (Synchronous) ба Асинхрон (Asynchronous). Синхрон харилцаанд үйлчилгээ нэг бүр нь бусад үйлчилгээний хариуг хүлээж байж үргэлжлүүлэн ажилладаг бөгөөд энэ нь тодорхой дараалал, шууд хариу шаардах процесс дээр тохиромжтой. Харин асинхрон харилцаанд үйлчилгээ бие даан ажиллаж, үзэгдэл эсвэл мессежээр бусад үйлчилгээнд мэдэгдэл өгч, хариуг нь дараа нь авч болохоор зохицуулдаг. Үзэгдлээр хөтлүүлсэн архитектур нь ихэвчлэн асинхрон харилцааг ашигладаг бөгөөд ингэснээр системийн бүрэлдэхүүн хэсгүүд нь нэг нэгнээсээ хараат бус ажиллах боломжтой болж, хурдан хариу үйлдэл, уян хатан scale хийх чадварыг хангадаг. Ийм архитектурыг хэрэгжүүлэхдээ ихэвчлэн RabbitMQ эсвэл Kafka зэрэг мессеж брокеруудыг ашиглан үйлчилгээнүүд хоорондын мессеж дамжуулалтыг зохицуулдаг.

RabbitMQ

Decoding RabbitMQ

RabbitMQ нь мессеж дамжуулагч систем буюу message broker бөгөөд системийн бүрэлдэхүүн хэсгүүд хооронд мэдээлэл илгээх, хүлээн авах үүрэг гүйцэтгэдэг. Энэ нь асинхрон харилцааг хэрэгжүүлэхэд голлон ашиглагддаг. RabbitMQ нь мессежүүдийг дараалалд оруулж хадгалдаг тул үйлчилгээ шууд боловсруулахаас үл хамааран дараа нь авч боловсруулж чадна. Publisher-Subscriber загвараар ажиллаж, нэг үйлчилгээ мессеж илгээж, олон үйлчилгээ түүнийг хүлээн авч боловсруулж болно. Мөн RabbitMQ нь мессежийг алга болохоос сэргийлэх, хадгалах боломжийг олгодог ба мессежийг тодорхой нөхцөл, routing key ашиглан зохицсон үйлчилгээ рүү чиглүүлэх боломжтой. Жишээ нь үйлчилгээ A хэрэглэгчээс захиалга авсан тохиолдолд үйлчилгээ B захиалгыг боловсруулна. Үйлчилгээ A RabbitMQ руу мессеж илгээж, үйлчилгээ B дараа нь мессежийг хүлээн авч боловсруулдаг.

Жишээ Код :

Producer.js

const amqp = require('amqplib');

async function send() {
  const conn = await amqp.connect('amqp://localhost:5672');
  const channel = await conn.createChannel();
  const queue = 'test_queue';

  await channel.assertQueue(queue, { durable: true });

  for(let i=0; i<100 ; i++) {
    const message = 'Hello RabbitMQ' + i.toString();
    channel.sendToQueue(queue, Buffer.from(message));

  }
//   console.log("Sent:", message);
  setTimeout(() => {
    channel.close();
    conn.close();
  }, 500);
}

send();

Consumer1.js

const amqp = require('amqplib');

async function receive() {
  const conn = await amqp.connect('amqp://localhost:5672');
  const channel = await conn.createChannel();
  const queue = 'test_queue';

  await channel.assertQueue(queue, { durable: true });

  console.log("Waiting for messages...");
  channel.consume(queue, (msg) => {
    if (msg !== null) {
      console.log("Received:", msg.content.toString());
      channel.ack(msg);
    }
  });
}

receive();

Consumer2.js

const amqp = require('amqplib');

async function receive() {
  const conn = await amqp.connect('amqp://localhost:5672');
  const channel = await conn.createChannel();
  const queue = 'test_queue';

  await channel.assertQueue(queue, { durable: true });

  console.log("Waiting for messages...");
  channel.consume(queue, (msg) => {
    if (msg !== null) {
      console.log("Received:", msg.content.toString());
      channel.ack(msg);
    }
  });
}

receive();

Apache Kafka

Meet Apache Kafka - Software Engineering Daily

Apache Kafka нь өндөр хүчин чадалтай, тархсан (distributed) мессеж брокер систем бөгөөд их хэмжээний өгөгдлийг бодит цаг хугацаанд дамжуулах, хадгалах, боловсроход зориулагдсан. Kafka нь ихэвчлэн асинхрон харилцаанд ашиглагддаг бөгөөд системийн бүрэлдэхүүн хэсгүүд хооронд үзэгдэл (event) буюу мессежийг үр дүнтэй тараах боломжийг олгодог.

Kafka-д topics гэж нэрлэгдсэн логик урсгалууд бий бөгөөд producer үйлчилгээ мессежийг topic-д илгээдэг, consumer үйлчилгээ дараа нь тухайн topic-аас мессежүүдийг хүлээн авч боловсруулна. Мессежүүд дараалалд хадгалагдаж, олон consumer нэгэн зэрэг уншиж болдог. Kafka нь өндөр ачаалал, найдвартай ажиллагаа, өгөгдлийг удаан хугацаанд хадгалах боломжтой тул real-time analytics, лог цуглуулах, event-driven системд тохиромжтой.

Жишээ нь, хэрэглэгч вэбсайт дээр бүтээгдэхүүн захиалсан бол producer үйлчилгээ захиалгын мэдээллийг Kafka-д илгээж, consumer үйлчилгээ захиалгыг боловсруулж, илгээх процессыг асинхроноор хянаж хэрэгжүүлдэг.

Producer.js

const { Kafka } = require('kafkajs');

const kafka = new Kafka({
  clientId: 'my-app',
  brokers: ['localhost:9092']
});

const producer = kafka.producer();

async function send() {
  await producer.connect();
  const message = { value: 'Hello Kafka' };

  await producer.send({
    topic: 'test_topic',
    messages: [message]
  });

  console.log("Sent:", message.value);
  await producer.disconnect();
}

send();

Consumer1.js

const { Kafka } = require('kafkajs');

const kafka = new Kafka({
  clientId: 'my-app1',
  brokers: ['localhost:9092']
});

const consumer = kafka.consumer({ groupId: 'test-group1' });

async function receive() {
  await consumer.connect();
  await consumer.subscribe({ topic: 'test_topic', fromBeginning: true });

  await consumer.run({
    eachMessage: async ({ message }) => {
      console.log("Received:", message.value.toString());
    }
  });
}

receive();

Consumer2.js

const { Kafka } = require('kafkajs');

const kafka = new Kafka({
  clientId: 'my-app2',
  brokers: ['localhost:9092']
});

const consumer = kafka.consumer({ groupId: 'test-group2' });

async function receive() {
  await consumer.connect();
  await consumer.subscribe({ topic: 'test_topic', fromBeginning: true });

  await consumer.run({
    eachMessage: async ({ message }) => {
      console.log("Received:", message.value.toString());
    }
  });
}

receive();

Дүгнэлт

RabbitMQ нь мессежүүдийг дараалалд оруулж хадгалдаг бөгөөд Publisher-Subscriber загварын дагуу ажилладаг. Энэ нь мессежийг тодорхой нэг queue-д илгээж, consumer түүнийг дараа нь авч боловсруулдаг. Үйлчилгээ хоорондын харилцаа ил тод, хялбар зохицуулалт шаарддаг жижиг болон дунд ачаалалтай системд тохиромжтой.

Apache Kafka нь их хэмжээний өгөгдөл, өндөр ачааллыг дэмждэг тархсан систем бөгөөд producer-service нь topic-д мессеж илгээж, олон consumer зэрэг хүлээн авч боловсруулдаг. Мессежүүд дараалалд хадгалагддаг бөгөөд асинхрон харилцаа, real-time аналитик, лог цуглуулах, event-driven архитектурт илүү тохиромжтой. Kafka нь өндөр ачаалал, найдвартай хадгалах чадвартай тул масштаблах боломж илүү байдаг.

The Essential Engineering Education

Боловсролыг Инженерчлэв.

Leave a Reply