NodeJs Üzerinde RabbitMQ Kullanarak MongoDB’de Audit Log Tutma

Selamlar,

https://youtu.be/JkhLPpJkO64

Bu makalede NodeJs üzerinde yapılan tüm Audit işlemleri, MongoDB’de RabbitMQ kullanarak loglayacağız. Örneğin, bir data güncellendiğinde bunu anlık olarak değil de, performansı arttırmak amacı ile bir RabbitMQ’ya atacağız. Daha sonra Microservices olarak çalışan başka bir NodeJs uygulaması, RabbitMQ’nun ilgili kanalını dinleyip, MongoDB’ye kaydedecek. Bu makale Angular ve NodeJs Üzerinde SocketIO Kullanılarak Real Time Data Bildirilmesi makalesinin devamıdır.

Gelin ilk önce bir kayıt güncellendiğinde, bu işlemi RabbitMQ’ya, daha sonradan işlenmek üzere atalım. RabbitMQ hakkında daha detaylı bilgiye, bu makaleden erişebilirsiniz.

Öncelikle NodeJS projesine, RabbitMQ ile işlem yapılabilmesi için “AMQP” kütüphanesi, aşağıdaki komut ile yüklenir.

İlk önce RabbitMQ, Mac tarafında “rabbitmq-server” komutu ile ayağa kaldırılır.

Eğer herşey yolunda ise, “http://localhost:15672/” url satırından aşağıdaki gibi bir ekran ile karşılaşılması lazımdır.

Şimdi sıra geldi NodeJs üzerindeki service.js sayfasından, “/updatePeople” methodunun güncellenmesine. Amaç, güncellenen kaydın logunun MongoDB’de tutulmasıdır.

service.js: Öncelikle NodeJs üzerindeki service.js sayfasına, aşağıdaki gibi RabbitMQ’ya bağlanılıp, istenen bir paketin belirlenen bir queue’ya atabilecek function yazılır.

  • “var amqp = require(‘amqplib/callback_api’)”: RabbitMq’ya ilgili paketin atılabilmesi için gerekli “amqplib” projeye eklenir.
  • “const rabbitUrl = ‘amqp://localhost'” : RabbitMQ locale çalıştığı için, ilgili URL atanır.
  • “function sendRabbitMQ(queueName, data) {” : RabbitMQ’ta atma işleminin yapıldığı functiondır. “queueName” : Atılacak channel, “data” : String olarak atılcak datayı belirler.
    • “amqp.connect(‘amqp://localhost’, function (error0, connection) {: RabbitMQ’ya bağlanılır.
    • “if (error0) { throw error0; }” : Hata var ise, fırlatılır.
    • “connection.createChannel(function (error1, channel) {“: Kanal yaratılır.
      • “if (error1) { throw error1; }” : Kanal yaratma işleminde, hata var ise dönülür.
      • “var queue = queueName” : Datanın atılacağı queue, burada gelen string parametre ile atanır.
      • “channel.assertQueue(queue, { durable: false })” : RabbitMQ’daki datanın hızdan kazanılması adına, disk’e yazılması engellenir. “durable: true” ==> yapılır ise, sunucu kapanıp açılsa dahi kuyruktaki paketler kaybolmaz.
      • channel.sendToQueue(queue, Buffer.from(data))” : Belirtilen channel’a güncellenen person data, json string olarak gönderilir.
      • “setTimeout(function ()”: Yarım saniye sonra connection kapanır.

service/updatePeople():

“sendRabbitMQ(“logChannel”, JSON.stringify(updatePerson))” : Tek eklenen satır burasıdır. Var olan bir person kaydı güncellendiği zaman, güncellene datanın RabitMQ’nın “logChannel”‘ına json olarak atıldığı kısım burasıdır. İstenir ise loglama işlem direk burada da yapılabilirdi. Ama amaç, sonucun client’a en hızlı şekilde dönülmesi durumlarında, ya da her kayıt işleminde data üzerinde bir takım vakit alacak işler yaplacak ise var olan sistemden bağımsız bu işleri yürütmek çok daha sağlıklıdır.

“Microservicesler, bir çeşit asenkron çalışan mekanizmalardır.”

RabbitMQ’ya atıldıktan sonra, “http://localhost:15672/#/queues” url satırına gidilince aşağıdaki gibi bir ekran ile karşılaşılır. Görüldüğü gibi “logChannel” Queue’lere eklenmiştir. Ve işlenmeyi bekleyen 1 paket bulunmaktadır. (Ready 1)

service/insertPeople():

“sendRabbitMQ(“logChannelInsert”, JSON.stringify(person))” : Ekelenen tek satır budur. RabbitMQ’nun “logChannel” kanalına yeni kaydedilen kayıt, atılır. Ve microservisler tarafından işlenmek amacı ile, sıraya konur.

Şimdi sıra geldi, NodeJS ile yeni bir RabbitMQ Consumer Microservice yazmaya.

consumer.js:

  • Yeni bir consumer.js dosyası oluşturulur ve aşağıda görüldüğü gibi “amqplib” kütüphanesi RabbitMQ işlemleri için eklenir.

  • Express kütüphanesi aşağıdaki gibi eklenir.

  • RabbitMQ ile listeden çekilen data, MongoDB’ye yazılması için eklenmesi gereken mongoose kütüphanesi aşağıdaki gibi projeye eklenir.

  • “amqp.connect(‘amqp://localhost’, function (error0, connection) {” : Local’de çalışan RabbitMQ’ya bağlanılır.
  • “connection.createChannel(function (error1, channel) {” : Channel yaratılır.
  • “var queue = ‘logChannel'”: Dinlenecek kuyruk, burada tanımlanır.
  • “channel.assertQueue(queue, { durable: false })” : Queue alınan datanın, harddisk’e yazılması engellenir.
  • “channel.consume(queue, function (data) {” : İlgili kanal dinlenir ve person data’sı, parametre olarak beklenir.
  • “person = JSON.parse(data.content.toString())” : Çekilen Json string data, person Objesine cast edilir.
  • “noAck: true” : Çekilen datanın RabbitMQ kuyruğundan, kaldırılması sağlanır.

Şimdi sıra geldi, çekilen datanın mongoDB’ye yazılmasına.

consumer.js: Öncelikle localdeki, mongoDB’ye bağlanılır.

Kaydedilecek “userslog” Scheması, aşağıdaki gibi oluşturulur. mongoDB’deki döküman karşılığı, “Userlog” değişkenine aktarılır.

Kuyruktan gelen person kayıt, mongoDB’de “usersLog” dökümanına kaydedilir.

consumer.js: Kodun son hali aşağıdaki gibidir.

Bu makalede, NodeJs’üzerinde microservicesler ile işlem yapılan tüm data bir kuyruğa kondu. Amaç, üzerinde işlem yapılan herbir satırın yedeğinin alınması idi. Bunu da var olan sistemin üzerine yük bindirmeden, hatta gerektiğinde, araya girip data’nın üzerinde işlem yapılmasına olanak veren bir yöntem ile yapıldı. Bu makale serisinde, NodeJs üzerinde aynı bir puzzle’ın parçaları gibi birçok bileşeni çevresinde yapılandırıldı. Böylece test, debug ve refactoring işleri kolaylaştırıldı. Ayrıca dağıtık mimari ile, ekipte birden fazla kişinin farklı teknolojilerle çalışmasına imkan sağlandı.

Geldik bir makalenin daha sonuna. Yeni bir makalede görüşmek üzere hepinize hoşçakalın.

Source :

Herkes Görsün:

Bunlar da hoşunuza gidebilir...

3 Cevaplar

  1. Özkan dedi ki:

    eline sağlık

  2. Ali Kadir Bagcioglu dedi ki:

    mongodb de neden schema kullanmadan gelen datayi collection’a yazmadiniz, schema kullanmanin ve schema ya cast etmenin bu case de bir avantaji var mi?

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.