Pendekatan umum, seperti Ozz sudah sebutkan , adalah antrian pesan . Dari perspektif desain, antrian pesan pada dasarnya adalah antrian FIFO , yang merupakan tipe data yang agak mendasar:
Apa yang membuat antrian pesan istimewa adalah bahwa sementara aplikasi Anda bertanggung jawab untuk antrian, proses yang berbeda akan bertanggung jawab untuk antrian. Dalam istilah antrian, aplikasi Anda adalah pengirim pesan, dan proses penghapusan adalah penerima. Keuntungan yang jelas adalah bahwa seluruh proses tidak sinkron, penerima bekerja secara independen dari pengirim, selama ada pesan untuk diproses. Kerugian yang jelas adalah bahwa Anda memerlukan komponen tambahan, pengirim, agar semuanya berfungsi.
Karena arsitektur Anda sekarang bergantung pada dua komponen yang bertukar pesan, Anda dapat menggunakan istilah komunikasi antar-proses yang bagus untuknya.
Bagaimana memperkenalkan antrian mempengaruhi desain aplikasi Anda?
Tindakan tertentu dalam aplikasi Anda menghasilkan email. Memperkenalkan antrian pesan berarti bahwa tindakan tersebut sekarang harus mendorong pesan ke antrian (dan tidak lebih). Pesan-pesan itu harus membawa jumlah minimum informasi mutlak yang diperlukan untuk membangun email ketika penerima Anda memprosesnya.
Format dan isi pesan
Format dan isi pesan Anda sepenuhnya terserah Anda, tetapi Anda harus mengingat semakin kecil semakin baik. Antrian Anda harus secepat mungkin untuk menulis dan memprosesnya, melemparkan sejumlah besar data ke dalamnya mungkin akan membuat kemacetan.
Selain itu beberapa layanan antrian berbasis cloud memiliki batasan ukuran pesan dan dapat membagi pesan yang lebih besar. Anda tidak akan melihat, pesan perpecahan akan disajikan sebagai satu ketika Anda memintanya, tetapi Anda akan dikenakan biaya untuk beberapa pesan (dengan asumsi tentu saja Anda menggunakan layanan yang memerlukan biaya).
Desain penerima
Karena kita berbicara tentang aplikasi web, pendekatan umum untuk receiver Anda adalah skrip cron sederhana. Itu akan berjalan setiap x
menit (atau detik) dan itu akan:
- Pop
n
jumlah pesan dari antrian,
- Memproses pesan (yaitu mengirim email).
Perhatikan bahwa saya mengatakan pop daripada mengambil atau mengambil, itu karena penerima Anda tidak hanya mendapatkan item dari antrian, tetapi juga menghapusnya (yaitu menghapusnya dari antrian atau menandainya sebagai diproses). Bagaimana persisnya itu akan terjadi tergantung pada implementasi Anda pada antrian pesan dan kebutuhan spesifik aplikasi Anda.
Tentu saja apa yang saya jelaskan pada dasarnya adalah operasi batch , cara paling sederhana untuk memproses antrian. Bergantung pada kebutuhan Anda, Anda mungkin ingin memproses pesan dengan cara yang lebih rumit (yang juga membutuhkan antrian yang lebih rumit).
Lalu lintas
Penerima Anda dapat mempertimbangkan lalu lintas pertimbangan dan menyesuaikan jumlah pesan yang diproses berdasarkan lalu lintas pada saat berjalan. Pendekatan sederhana adalah untuk memprediksi jam lalu lintas tinggi Anda berdasarkan data lalu lintas masa lalu dan dengan asumsi Anda pergi dengan skrip cron yang berjalan setiap x
menit Anda bisa melakukan sesuatu seperti ini:
if(
now() > 2pm && now() < 7pm
) {
process(10);
} else {
process(100);
}
function process(count) {
for(i=0; i<=count; i++) {
message = dequeue();
mail(message)
}
}
Pendekatan yang sangat naif & kotor, tetapi berhasil. Jika tidak, baik, pendekatan lain adalah mencari tahu lalu lintas server Anda saat ini di setiap iterasi dan menyesuaikan jumlah item proses yang sesuai. Tolong jangan mengoptimalkan mikro jika itu tidak benar-benar diperlukan, Anda akan membuang-buang waktu.
Penyimpanan antrian
Jika aplikasi Anda sudah menggunakan database, maka satu tabel di atasnya akan menjadi solusi paling sederhana:
CREATE TABLE message_queue (
id int(11) NOT NULL AUTO_INCREMENT,
timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
processed enum('0','1') NOT NULL DEFAULT '0',
message varchar(255) NOT NULL,
PRIMARY KEY (id),
KEY timestamp (timestamp),
KEY processed (processed)
)
Sebenarnya tidak lebih rumit dari itu. Anda tentu saja dapat menjadikannya serumit yang Anda butuhkan, misalnya, Anda dapat menambahkan bidang prioritas (yang berarti bahwa ini bukan lagi antrian FIFO, tetapi jika Anda benar-benar membutuhkannya, siapa yang peduli?). Anda juga bisa membuatnya lebih sederhana, dengan melewatkan bidang yang telah diproses (tetapi kemudian Anda harus menghapus baris setelah Anda memprosesnya).
Tabel basis data akan ideal untuk 2000 pesan per hari, tetapi mungkin tidak akan baik untuk jutaan pesan per hari. Ada sejuta faktor untuk dipertimbangkan, segala sesuatu di infrastruktur Anda berperan dalam skalabilitas keseluruhan aplikasi Anda.
Bagaimanapun, dengan asumsi Anda telah mengidentifikasi antrian berbasis basis data sebagai hambatan, langkah selanjutnya adalah melihat layanan berbasis cloud. Amazon SQS adalah layanan yang saya gunakan, dan melakukan apa yang dijanjikan. Saya yakin ada beberapa layanan serupa di luar sana.
Antrian berdasarkan memori juga sesuatu yang perlu dipertimbangkan, terutama untuk antrian yang berumur pendek. memcached sangat baik sebagai penyimpanan antrian pesan.
Penyimpanan apa pun yang Anda putuskan untuk dijadikan antrian, cerdas dan abstraksi. Baik pengirim maupun penerima Anda tidak terikat pada penyimpanan tertentu, jika tidak beralih ke penyimpanan lain di lain waktu akan menjadi PITA lengkap.
Pendekatan kehidupan nyata
Saya membuat antrian pesan untuk email yang sangat mirip dengan apa yang Anda lakukan. Itu pada proyek PHP dan saya membangunnya di sekitar Zend Queue , komponen dari Zend Framework yang menawarkan beberapa adapter untuk penyimpanan yang berbeda. Penyimpanan saya di mana:
- Array PHP untuk pengujian unit,
- Amazon SQS pada produksi,
- MySQL pada dev dan lingkungan pengujian.
Pesan saya sesederhana mungkin, aplikasi saya membuat array kecil dengan informasi penting ( [user_id, reason]
). Toko pesan adalah versi serial array itu (pertama itu adalah format serialisasi internal PHP, kemudian JSON, saya tidak ingat mengapa saya beralih). Ini reason
adalah konstanta dan tentu saja saya punya meja besar di suatu tempat yang memetakan reason
penjelasan yang lebih lengkap (saya berhasil mengirim sekitar 500 email ke klien dengan cryptic reason
daripada pesan yang lebih lengkap satu kali).
Bacaan lebih lanjut
Standar:
Alat:
Berbunyi menarik: