Mail Gönderme İşleminin Queue'lanması
-
Başlık tam olarak konuyu açıklayamıyor ancak mevzu şu. Bir servis içinde farklı 3-4 tane farklı servislerden farklı methodlar çağrılıyor ve bu methodlar kendi içlerinde işlem yaptıkran sonra mail atabiliyor. 1. servis methodu çalışıp mail attıktan sonra 2. servis servisin methodunda exception olduğu zaman DB kayıtları rollback ediliyor. Ancak 1. servisin çağırdığı mail gitmiş oluyor ama o kayıt rollback olduğu için kullanıcıya geçersiz mail gitmiş oluyor. Bu tür durumlardan kaçınmak için nasıl bir yöntem izliyorsunuz, yada bu durumlar için kullandığınız bir pattern vs. varmı?
Not: PHP Laravel ile geliştirme yapıyorum ancak başka bir framework yada dil deki yöntemi kendim implemente edebilirim, dil sorun değil yani.
TeRRoR tarafından 17/Ara/19 22:49 tarihinde düzenlenmiştir -
ben olsam bunları bir queue da biriktirip bunlar için ayrı bir mail gonderme jobu yazardım, o job 10 dk da bir çalışır eğer 3 task te tamamlanmışsa maili gonderir yoksa queue dan silerdi falan.
-
yolbulucu bunu yazdı
ben olsam bunları bir queue da biriktirip bunlar için ayrı bir mail gonderme jobu yazardım, o job 10 dk da bir çalışır eğer 3 task te tamamlanmışsa maili gonderir yoksa queue dan silerdi falan.
Hocam benimde aklıma geldi o yöntem ama orada işlem ağacındaki her işlemin aynı job-id ile tutulması, onların takip edilmesi, servisin sonunda onun bittiğini filan tanımlamak gibi bir sürü hammamlık ve çok manuel ve hataya açık bir yapı olarak görünüyor.
-
Hocam her türlü angarya iş, kullanıcıya yanlış eposta göndermekten iyidir.
Ben olsam job için bir id ve status tutardım. (STAGE1, ... STAGEN, DONE) gibi. Ortaya da bir Kafka ya da RabbitMQ koyup, job her aşamayı geçince status update ederdim. DONE statusune geçerse tüm mailleri o zaman attırırdım. Mailin 5 dakika geç gitmesi, yanlış gitmesinden daha sağlıklı bence.
Message Broker kullandıktan sonra 3-4 servis değil onlarca servisin bile olsa her birinin birbiri ile haberleşmesine gerek olmayacağı için zannedildiği kadar karmaşık olmayan bir yapı çıkar ortaya.
-
TeRRoR bunu yazdıyolbulucu bunu yazdı
ben olsam bunları bir queue da biriktirip bunlar için ayrı bir mail gonderme jobu yazardım, o job 10 dk da bir çalışır eğer 3 task te tamamlanmışsa maili gonderir yoksa queue dan silerdi falan.
Hocam benimde aklıma geldi o yöntem ama orada işlem ağacındaki her işlemin aynı job-id ile tutulması, onların takip edilmesi, servisin sonunda onun bittiğini filan tanımlamak gibi bir sürü hammamlık ve çok manuel ve hataya açık bir yapı olarak görünüyor.
hocam o kadar da karmaşık olmayacak ki,
bir tane queue var diyelim , sen mail gondermek yerine her üç parçadan biri bittiğinde bu queue ya atıyosun mail işini, sonra yazdığın diğer worker da bu queue ya gelenleri takip edip gelen işlerin üç parçası da tamamlanmışsa mailleri atıyor. zaten bu üç mailinde ortak noktası olan bir id vardır elinde illa
-
Microservis mimarisinde kullanılan orchestrated saga gibi bir pattern işini görür gibi. Saga'nı iyi tasarlarsan tüm adımların sağlıklı olduktan sonra eposta gider
-
Herkese cevapları için teşekkürler. Henüz implemente etmedim ancak aklıma şöyle bir fikir geldi. Bu mail gönderme işlemleri bir request içerisinde gerçekleşiyor. Request içinde bir array (queue) oluşturup, yönetilen hatalarda el ile, yönetilmeyen hatalarda da middleware'da yakalayıp bu mail array'ini boşaltmayı. Eğer request hatasız respons'a dönersede otomatik olarak bu queue daki mailleri göndermeyi en basit çözüm olarak düşündüm ama hayırlısı bakalım.
-
şöyle gidebilirsim hocam;
bir mail gönderme servisi yap, diğer tüm servisler mail göndermek için bu servisi kullansın. bu mail servisinin de transactioni kurugusu olsun. tüm servislerini kullanırken bir transaction kimliğiyle çağır, onlar da mail serivisine aynı kimlikle mail actionları göndersin. transaction tamamlandığında mail servisine bu kimlikle tamamlandı gönderip mailleri göndertirsin. rollback durumunda da aynı kimlikle mail servisine rollback gönderirsin.
-
Merhaba Hocam,
Eğer mikroservis kullanıyorsan bir ekosistemin var ise mail gönderme için bir servis yapar broker a bağlarsın birde logstash koyarsın mailler log stashe gider burada 3 mail geldikten sonra mail gönderme servisine yönlendirirsin yoksa bir timeout koyarsın veriyi uçurursun özellikle kafka geçmiş verileri kanalda tutabildiği için çok daha rahat işini çözebilirsin diğerlerinde bu veriyi senin tutman gerekebilir.
Böyle bir ekosistemin yok ise;Bir mail gönderme servisin olur(veya tabloya uyarlayabilrisin mimarine kalmış) her mail gönderecek servis belirli bir task id ile maili gönderir bu task id 3 servis içinde aynı olmalı fakat bu mail servise bu task id için commit mesajı gelmediği sürece mailleri göndermeyecek, rollback gelirse silecek.
1. senaryo servislerin sıralı çalışıyor ise işini bitiren bu servise mail gönderir ama sadece en son commit yapar arada rollback olduğunda burada rollback ilgili task id ile rollback komutu verilir
2. senaryo servislerin sıralı değil veya değişken adımların var ise her bir task id si ile birlikte kaç mail olması gerektiğini mail servisinin enpointine gönderirsin eğer mail servisinin elinde ilgili id ile belirtilen sayıda mail var ise otomatik commit yapar gönderir yoksa beklemeye devam eder yine rollback geldiğinde siler.
bunlara benzer senaryoları artırabilrisiniz
Not olarak : ihtiyacınızın sebebini detayını bilmemek ile birlikte mevcut belirttiğiniz tasarım hatalı gibi görünüyor ya işlemlerin birbirinden bağımsız tasarlanması gerekir ve her birinin maili bir diğerini etkilemez veya FaaS sistemlerinde olduğu gibi her bir methodu çağırıp yöneten ve hepsi için bir transaction yönetebilecek main function olur main function bu işlemleri halleder.
Kolay gelsin.