Outbox Pattern untuk Microservice
Saat kita publish event ke message queue, kemudian queuenya gagal setelah setelah beberapa kali, di beberapa message queue akan menggap gagal dan tidak akan ada lagi retry setelah nya.
Apa yang akan terjadi? Data yang harusnya dikirim ke service tujuan tidak akan dikirim lagi dan akan terjadi inkonsistensi data. Ini baru case pertama.
Case selanjutnya, apabila ada data yang harus dikirim dalam waktu berbeda, namun pemrosesannya terjadi pada saat yang hampir bersamaan? Bagaimana cara menanggulangi case ini.
Kali ini kita akan bahas Outbox Pattern yang diterapkan waktu saya mendevelop fitur Reprocess Leads di Mitsubishi Salesforce ID.
The Outbox Pattern
Outbox Pattern adalah konsep yang dimana kita mengumpulkan data yang akan dikirim ke event bus / message broker ke dalam database. Kemudian setelahnya kita melakukan pengiriman secara queue berdasarkan data yang ada didalam database.
![Outbox Pattern Implementation](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2FOutboxPattern1.1f761584.webp&w=1920&q=75)
Pada gambar diatas ketika data berubah maka akan ditulis ke table outbox sebagai data yang akan dikirim, kemudian data akan dibaca oleh message queue dan dipublish ke event bus.
Kenapa kita butuh Outbox Pattern ?
Outbox Pattern dibutukan untuk ensure semua data dikirim dengan tepat tanpa adanya kegagalan. Data yang dikirim bisa jadi gagal karena jaringan, atau message broker down, atau bahkan server down. Sehingga tidak ada yang bisa menjamin data tadi dapat di retry dikesempatan berikutnya. Sehingga dengan menyimpan data ke Outbox sebelum dikirim ke message broker / event bus, kita dapat memastikan data tersebut sudah pernah dikirim sebelumnya atau belum, dan dapat melakukan retry apabila pengiriman data / event tidak berhasil.
Lalu contoh berikutnya
![Outbox Pattern Implementation](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fwithout-outbox-pattern.5327afb3.png&w=3840&q=75)
Pada gambar diatas ketika ordering service melakukan publish event, dapat terjadi putus koneksi, sehingga data yang dikirim akan hilang. Pada gambar dibawah ini ordering service akan menyimpan data pada datastore. Kemudian di saat yang telah ditentukan background worker akan “menarik” data kemudian melakukan publish event ke message bus. Apabila message bus tidak meresponse, maka “status” data pada datastore tidak akan diupdate oleh background worker.
Sebaliknya, apabila message bus sukses mendapatkan data, maka background worker akan melakukan update ke data bahwa data sudah “Processed” sehingga data itu tidak akan diproses kedua kalinya.
![Outbox Pattern Implementation](/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Foutbox-pattern-implementation.0dd968cb.png&w=3840&q=75)
Pada case study yang ada di PT Berlian Sistem Informasi, data lead yang masuk berdasarkan ketertarikan yang terjadi pada customer survey akan dikumpulkan pada table customer survey. Namun alih alih mendistribusikan customer yang tertarik langsung ke Salesman dan mengirim notifikasi ke salesman bahwa ada customer yang teratrik. Tim SFID akan menarik data yang masuk pada hari H+1 di table customer survey (pooling table). Data ditarik dengan menggunakan Hangfire dan distribusi leads ke salesman yang qualify pada dini hari untuk menghindari high load pada database.
Kemudian nomor WA salesman yang qualify mendapatkan lead, akan disimpan kembali ke table Outbox Message, table outbox kedua ini berguna untuk menyimpan data notifikasi,data notifikasi akan dikirimkan pada salesman pada jam kerja (sekitar jam 8). Sehingga distribusi leads tidak akan mengganggu load database pada saat salesman bekerja, dan whatsapp notifikasi dapat terdeliver pada waktu yang tepat.
Solved? Yes, sementara iya, customer tertarik, salesman senang dapat lead baru. Tapi tidak mengganggu load transaksi. Oh iya, untuk distribusi customer ke salesman pada fitur ini menggunakan algoritma Round Robin, mungkin kita bahas di pertemuan selanjutnya. See ya.