laravel-micro-rabbitmq maintained by azizdevfull
🐉 Laravel MicroRabbit
MicroRabbit — bu Laravel mikroxizmatlari (Microservices) uchun yaratilgan, "Enterprise" darajasidagi o'zini-o'zi tiklovchi (Self-Healing) RabbitMQ event-bus kutubxonasi.
U shunchaki xabarlarni jo'natib qabul qilmaydi. U tarmoq uzilishlari, server qulashlari, dublikat xabarlar, zaharli ma'lumotlar (poison payloads) va qotib qolgan jarayonlar ta'sirini keskin kamaytirish uchun mo'ljallangan qudratli yadroga ega.
📑 Mundarija
- 🐉 Laravel MicroRabbit
- 📑 Mundarija
- 📦 1. O'rnatish
- ⚙️ 2. Konfiguratsiya (
config/micro-rabbitmq.php) - 🎧 3. Xabarlarni Qabul Qilish (Consumer)
- 📨 4. Xabar Jo'natish (Publish)
- ⏱ 5. RPC - Sinxron Javob Kutish
- 🛡 6. Transactional Outbox Pattern
- 🧱 7. Chidamlilik va Himoya (Fault Tolerance)
- 🧪 8. Test Yozish (Faking)
- 💻 9. Konsol Komandalari
📦 1. O'rnatish
Kutubxonani Composer orqali loyihangizga qo'shing:
composer require azizdevfull/laravel-micro-rabbitmq
So'ngra kutubxona sozlamalari (config) va Outbox tizimi uchun migratsiyalarni loyihangizga ko'chirib oling:
php artisan vendor:publish --tag="micro-rabbitmq-config"
php artisan vendor:publish --tag="micro-rabbit-migrations"
Baza jadvallarini yarating:
php artisan migrate
.env faylingizga RabbitMQ ulanish ma'lumotlarini kiriting:
MICRO_RABBITMQ_HOST=127.0.0.1
MICRO_RABBITMQ_PORT=5672
MICRO_RABBITMQ_USER=guest
MICRO_RABBITMQ_PASSWORD=guest
# Majburiy emas, qo'shimcha xavfsizlik sozlamalari:
MICRO_RABBITMQ_HEARTBEAT=30
MICRO_RABBITMQ_OUTBOX=false
MICRO_RABBITMQ_MONITORING=true
MICRO_RABBITMQ_PUBLISH_TIMEOUT=5
MICRO_RABBITMQ_OUTBOX_BATCH_SIZE=20
idempotency va distributed lock funksiyalari uchun production'da CACHE_DRIVER=redis tavsiya qilinadi.
⚙️ 2. Konfiguratsiya (config/micro-rabbitmq.php)
Kutubxonani publish qilganingizdan so'ng, loyihangizda config/micro-rabbitmq.php fayli paydo bo'ladi. Uning ichidagi asosiy sozlamalar nima vazifa bajarishini bilish juda muhim:
connection.heartbeat: (Default: 30). Tarmoq xavfsizlik devorlari (Firewall) jim turgan ulanishni uzib yubormasligi uchun Worker har 30 soniyada RabbitMQ ga "Men tirikman" deb belgi (ping) berib turadi. Bu o'lik ulanishlarning oldini oladi.features.idempotency: Dublikatlardan himoya. Yoqilgan bo'lsa, tizimmessage_idlarni keshda saqlaydi va bitta xatni 2 marta o'qimaydi.features.idempotency_ttl_seconds: Idempotency kaliti cache'da qancha vaqt yashashi (Default:86400soniya).features.idempotency_processing_ttl_seconds: Worker ishlayotgan paytdagi lock qancha yashashi (Default:300soniya).features.publish_timeout_seconds: Oddiypublish()broker tasdig'ini maksimal necha soniya kutishi (Default:5).consumer.prefetch_count/MICRO_RABBITMQ_PREFETCH: Har bir consumer bir vaqtda nechta unacked xabar ushlashini belgilaydi. Throughputni oshiradi, lekin juda katta qiymat fairness va xotira sarfiga salbiy ta'sir qilishi mumkin.features.publish_confirm_batch_size/MICRO_RABBITMQ_PUBLISH_CONFIRM_BATCH: Publisher broker confirm'ni har nechta xabardan keyin kutishini belgilaydi. Katta batch odatda publish tezligini oshiradi.features.publish_confirm_max_wait_ms/MICRO_RABBITMQ_PUBLISH_CONFIRM_MAX_WAIT_MS: Batch to'lmagan bo'lsa ham necha ms dan keyin confirm flush bo'lishi. Kichik qiymat latency'ni tushiradi, katta qiymat throughput'ni oshirishi mumkin.features.tracing: Barcha xatlarga Log zanjiri uchun yagonatrace_idyopishtiriladi.features.outbox.enabled: Transactional Outbox pattern'ni yoqadi. Xatlar to'g'ridan-to'g'ri havo orqali emas, Baza orqali kafolatli jo'natiladi.features.outbox.max_attempts: RabbitMQ o'chib qolsa, Outbox worker xatni jo'natishga necha marta urinishini belgilaydi (Default: 3).features.outbox.publish_timeout_seconds: Outbox relay broker tasdig'ini maksimal necha soniya kutishi (Default:5).features.outbox.batch_size: Outbox worker bir aylanishda nechta xabar olishga urinishini belgilaydi (Default:20).paths:micro:cacheqaysi papkalarni skan qilishini belgilaydi. Default:[base_path('app')].retry.backoff_multiplier,retry.max_delay_ms,retry.jitter_ms: Retry kechikishining exponential backoff+jitter strategiyasi.retry.non_retryable_exceptions: Qayta urinilmaydigan exception klasslari ro'yxati.monitoring.*: Metrika cache'i va alert thresholdlari (outbox backlog,blocked,DLQ size,publish timeout) uchun sozlamalar.
Production benchmarklar uchun amaliy boshlang'ich tuning:
MICRO_RABBITMQ_PREFETCH=20
MICRO_RABBITMQ_PUBLISH_CONFIRM_BATCH=50
MICRO_RABBITMQ_PUBLISH_CONFIRM_MAX_WAIT_MS=10
🎧 3. Xabarlarni Qabul Qilish (Consumer)
MicroRabbit'da xabarlarni qabul qilish uchun config fayllarda marshrutlarni ro'yxatdan o'tkazish shart emas. Tizim PHP 8 Attributes orqali Auto-Discovery (o'zini-o'zi topish) xususiyatiga ega.
Default holatda micro:cache faqat base_path('app') ichini skan qiladi. Agar handlerlar boshqa joyda bo'lsa, config/micro-rabbitmq.php dagi paths array'iga qo'shib qo'ying.
Shunchaki istalgan papkada bitta Action klass yarating va unga atributlarni qo'shing:
namespace App\Actions;
use Azizdev\MicroRabbit\Attributes\ConsumeEvent;
use Azizdev\MicroRabbit\Attributes\MicroConfig;
#[ConsumeEvent(routingKey: 'order.created', queue: 'order_processing_queue', exchange: 'micro_events')]
#[MicroConfig(tries: 5, delayMs: 15000, retry: true)]
class OrderCreatedAction
{
public function handle(array $payload)
{
// 1. Kelgan datani o'qiymiz
$orderId = $payload['id'];
// 2. Biznes logikani bajaramiz
// ...
// 3. Agar RPC qilingan bo'lsa, Return yozish kifoya, MicroRabbit uni javob qilib qaytaradi!
return ['status' => 'success', 'processed_at' => now()];
}
}
Atributlar nima qiladi?
#[ConsumeEvent](Majburiy):routingKey: Qaysi nomdagi xatni eshitishi kerakligi (masalan:user.registered).queue: RabbitMQ da qaysi navbat yaratilishi kerakligi.exchange: Qaysi pochtadan kutayotgani (Default:micro_events).
#[MicroConfig](Ixtiyoriy): Worker charchab qolmasligi uchun xatoliklar qoidasi.tries: Agar kod xatolik (Exception) bersa, necha marta qayta urinish kerak? (Default: 3).delayMs: Qayta urinishlar orasida necha millisoniya kutish (uxlash) kerak? (Default: 10000 = 10 sek).retry: Qayta urinish tizimini umuman o'chirib qo'yish (falsebo'lsa, 1-xatodayoq qabristonga ketadi).
DIQQAT: Klassni yozib bo'lgach, tizim uni tanib olishi uchun doim keshni yangilang:
php artisan micro:cache
📨 4. Xabar Jo'natish (Publish)
Xabar jo'natish juda oddiy. Fasaddan foydalanamiz:
use Azizdev\MicroRabbit\Facades\MicroRabbit;
// Eng sodda usul:
MicroRabbit::publish('user.registered', [
'id' => 1,
'name' => 'Azizbek'
]);
Tizim bu xatga avtomatik ravishda trace_id, message_id va hozirgi timestamp ni qo'shib, xavfsiz tarzda o'rab jo'natadi.
⏱ 5. RPC - Sinxron Javob Kutish
Mikroxizmatlar orasida kimdandir tezkor ma'lumot olish kerak bo'lganda (Sinxron), biz request dan foydalanamiz.
Muammo: Agar narigi xizmat o'chib yotgan bo'lsa, oddiy tizimlar cheksiz kutib, serverni qotirib qo'yadi. MicroRabbit Yechimi: Qat'iy Taymer (Strict Timeout).
use Azizdev\MicroRabbit\Facades\MicroRabbit;
try {
// 3-parametr: 5 soniya kutish taymeri
$response = MicroRabbit::request('get.user.balance', ['user_id' => 7], 5);
echo "Foydalanuvchi balansi: " . $response['balance'];
} catch (\Exception $e) {
// Agar 5 soniyada javob kelmasa yoki narigi servis o'chgan bo'lsa
// Tizim qulab tushmaydi, balki chiroyli xatolik otadi!
return response()->json(['error' => 'To\'lov tizimi vaqtinchalik ishlamayapti'], 504);
}
🛡 6. Transactional Outbox Pattern
Dahshatli ssenariy: Mijozdan pulni yechdingiz, bazaga yozdingiz. Endi RabbitMQ ga xat otayotganingizda server interneti uzildi. Mijozning puli ketdi, lekin xizmat ko'rsatilmadi!
Buning yagona yechimi — Outbox Pattern. .env da MICRO_RABBITMQ_OUTBOX=true qiling. Endi MicroRabbit::publish() havo orqali xat otmaydi, balki uni o'sha vaqtdagi Tranzaksiya bilan birga Bazaga yozib qo'yadi.
use Illuminate\Support\Facades\DB;
use Azizdev\MicroRabbit\Facades\MicroRabbit;
DB::transaction(function () use ($user) {
// 1. Pul yechiladi
$user->decrement('balance', 50000);
// 2. Xat bazadagi "micro_outbox" jadvaliga tushadi (Tarmoq uzilsa ham 0% xavf)
MicroRabbit::publish('payment.success', ['user_id' => $user->id]);
});
Bazada yig'ilgan xatlarni tinimsiz ravishda RabbitMQ ga otib turuvchi pochta xizmatini serveringizda (Supervisor orqali) yoqib qo'ying:
php artisan micro:outbox:work
Bu Worker RabbitMQ o'chib qolsa ham qulab tushmaydi. U ulanish tiklanishini kutadi va o'zini-o'zi tiklaydi (Auto-Recovery).
🧱 7. Chidamlilik va Himoya (Fault Tolerance)
Kutubxona "Arvoh" xatolardan quyidagicha himoyalangan:
- Idempotency: RabbitMQ adashib bitta xatni 2 marta jo'natib yuborsa ham, Worker qorovuli xatning ID sini eslab qoladi va 2-martasida uni ignor qiladi.
- Kutish Zali (Delayed Retry): Kodingiz API ga ulana olmay qulasa, worker xatni asrash uchun uni maxsus
_delayednavbatiga otadi. Xat u yerda masalan 10 soniya uxlaydi va yana asosiy navbatga qaytadi. - Qabriston (DLX - Dead Letter Exchange): Agar xat 3 marta urinib ham xatolik beraversa, boshqa sog'lom xatlarga xalaqit bermasligi uchun u
_failednavbatiga (Qabristonga) otib yuboriladi.
Dasturchi xatoni to'g'rilagach, qabristondagi xatlarni bitta komanda bilan yana hayotga qaytarishi mumkin:
php artisan micro:retry {navbat_nomi}
🧪 8. Test Yozish (Faking)
MicroRabbit bilan Pest yoki PHPUnit orqali test yozish "Oltin Standart" darajasida. Test paytida haqiqiy RabbitMQ ga ulanib vaqt o'tkazmaysiz.
use Azizdev\MicroRabbit\Facades\MicroRabbit;
test('buyurtma tasdiqlanganda xat otilishi kerak', function () {
// 1. Qopqonni yoqamiz (Xatlar RabbitMQ o'rniga xotiraga tushadi)
MicroRabbit::fake();
// 2. Asosiy loyihaning mantiqiy qismi ishlaydi
$this->postJson('/api/orders/confirm', ['id' => 123]);
// 3. Xat aniq otilganiga ishonch hosil qilamiz
MicroRabbit::assertPublished('order.confirmed');
// 4. (Ixtiyoriy) Payload ichidagi datalarni chuqur tekshiramiz
MicroRabbit::assertPublished('order.confirmed', function ($payload) {
return $payload['id'] === 123;
});
// 5. Ortiqcha boshqa xat ketib qolmaganini tekshiramiz
MicroRabbit::assertNotPublished('order.failed');
});
💻 9. Konsol Komandalari
php artisan micro:cache—pathsbo'yicha attributlarni topib, yashin tezligida ishlashi uchun keshga yozadi. Doim kod o'zgarganda urilishi shart.php artisan micro:consume --queue={queue}— Event worker'ni ishga tushiradi.--queueberilmasa barcha topilgan navbatlarni tinglaydi.php artisan micro:outbox:work— Outbox pattern yoqilgan bo'lsa, bazadan xatlarni olib uzluksiz RabbitMQ ga otib turuvchi asosiy dvigatel.php artisan micro:retry {queue}—_failed(Qabriston) ga tushib qolgan xatlarni qaytadan ishlash uchun asosiy navbatga qaytaradi.php artisan micro:health— Outbox backlog, DLQ hajmi va publish timeout metrikalarini tekshiradi.