azizdevfull / laravel-micro-rabbitmq
High-performance Microservice Event Bus (Pub/Sub) for Laravel using RabbitMQ.
Package info
github.com/azizdevfull/laravel-micro-rabbitmq
pkg:composer/azizdevfull/laravel-micro-rabbitmq
Requires
- php: ^8.2
- illuminate/console: ^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
- php-amqplib/php-amqplib: ^3.6
Requires (Dev)
- laravel/pint: ^1.29
- orchestra/testbench: ^8.0|^9.0|^10.0|^11.0
- phpunit/phpunit: ^10.0|^11.0|^12.0
This package is auto-updated.
Last update: 2026-05-21 09:14:26 UTC
README
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. Circuit Breaker - Domino Qulashini To'xtatish
- ๐ก 7. Transactional Outbox Pattern
- ๐งฑ 8. Chidamlilik va Himoya (Fault Tolerance)
- ๐งช 9. Test Yozish (Faking)
- ๐ป 10. 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: Yoqilgan bo'lsa, kelgantrace_id(yoki yangi UUID)ContextvaLog::withContext()orqali barcha log yozuvlariga avtomatik qo'shiladi. Handler ichida alohida hech narsa qilmasdan ELK/Loki da so'rovni oxirigacha kuzatish mumkin bo'ladi.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.circuit_breaker.enabled/MICRO_RABBITMQ_CIRCUIT_BREAKER: RPC uchun Circuit Breaker'ni yoqadi/o'chiradi (Default:true).circuit_breaker.threshold/MICRO_RABBITMQ_CB_THRESHOLD: Nechta ketma-ket xatoda circuit ochiladi (Default:5).circuit_breaker.timeout_seconds/MICRO_RABBITMQ_CB_TIMEOUT: Circuit ochiq turgan vaqt (soniyada). Bu vaqtdan keyin bitta "probe" request o'tkaziladi (Default:30).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
Realistic Benchmark Natijalari
Muhim: Qisqa "burst" testlarda sun'iy yuqori raqamlar chiqadi. Quyidagi natijalar 5000โ25000 xabarlik sustained load bilan o'lchangan (1 consumer, SQLite, prefetch_count=1):
| Workload | 5 000 xabar | 10 000 | 15 000 | 20 000 | 25 000 |
|---|---|---|---|---|---|
light (CPU only) |
238 eps | 211 | 219 | 211 | 215 |
db (INSERT) |
214 eps | 214 | 212 | 214 | 212 |
db_read (INSERT + SELECT) |
244 eps | 229 | 229 | 229 | 216 |
Asosiy xulosalar:
-
Haqiqiy bottleneck โ
prefetch_count=1, handler emas.lightvadbworkload orasida farq atigi ~3 eps. Sababi:prefetch=1bilan consumer har bir xabarni ACK qilmasdan keyingisini ololmaydi โ bu RabbitMQ round-trip latency ceiling ni belgilaydi (~215 eps). Handler ichida DB query bo'lsa ham bo'lmasa ham natija bir xil. -
Kichik testlardagi yuqori raqamlarga ishonmang. Burst rejimida (100โ400 xabar) consumer tayyor xabarlarni oldindan o'qib, 900โ1200 eps ko'rsatishi mumkin. Bu real sustained throughput emas.
-
Throughputni oshirish:
prefetch_countva consumer worker sonini oshiring:
MICRO_RABBITMQ_PREFETCH=20
# 4 ta parallel consumer php artisan micro:consume & php artisan micro:consume & php artisan micro:consume & php artisan micro:consume &
prefetch=20 + 4 consumer bilan taxminiy throughput: 215 ร 4 ร ~3 = ~2500 eps. Aniq raqam uchun o'z muhitingizda o'lchang.
๐ง 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. Circuit Breaker - Domino Qulashini To'xtatish
Muammo: user-service o'chib qoldi. Unga har bir RPC so'rov 5 soniya timeout bilan kutadi. Agar 100 ta concurrent so'rov bo'lsa โ 100 ร 5 soniya = server thread pool to'ladi va boshqa barcha xizmatlar ham ishlashdan to'xtaydi. Bu Cascading Failure (Domino qulashi).
MicroRabbit Yechimi: Circuit Breaker. Belgilangan miqdorda xato yig'ilsa, tizim o'sha routing key uchun RPC so'rovlarni RabbitMQ ga umuman yubormasdan, darhol xato qaytaradi. Thread pool saqlanadi.
[CLOSED] โ 5 xato โ [OPEN] โ 30 soniya โ [HALF-OPEN] โ muvaffaqiyat โ [CLOSED]
โ
Normal โ Blokli ๐ Sinov โ
Normal
use Azizdev\MicroRabbit\Facades\MicroRabbit; try { $balance = MicroRabbit::request('get.user.balance', ['user_id' => 7], 5); } catch (\RuntimeException $e) { // Circuit ochiq bo'lsa ham, timeout bo'lsa ham โ bu catch ga tushadi // $e->getMessage() da "Circuit Breaker" yoki "RPC Timeout" yozuvi bo'ladi return response()->json(['error' => 'Balans xizmati vaqtincha mavjud emas'], 503); }
Circuit Breaker avtomatik ishlaydi โ dasturchi hech narsa qo'shimcha qilmaydi. .env orqali sozlanadi:
MICRO_RABBITMQ_CIRCUIT_BREAKER=true MICRO_RABBITMQ_CB_THRESHOLD=5 # 5 ta xatoda circuit ochiladi MICRO_RABBITMQ_CB_TIMEOUT=30 # 30 soniyadan keyin recovery probe o'tadi
Eslatma: Circuit Breaker faqat
request()(RPC) uchun ishlaydi. Oddiypublish()asinxron bo'lgani uchun unga circuit breaker kerak emas.
๐ก 7. 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).
๐งฑ 8. 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. - Circuit Breaker: RPC orqali murojaat qilingan xizmat o'chib qolsa, belgilangan xato chegarasidan keyin so'rovlar darhol rad etiladi. Thread pool to'lib qolmaydi, bitta xizmatning o'lishi qolganlarni olib ketmaydi (qarang: 6-bo'lim).
- Distributed Tracing (Auto):
MICRO_RABBITMQ_TRACING=truebo'lsa, kelgan xabardagitrace_idavtomatik ravishdaLog::withContext()orqali joriy handlerning barcha log yozuvlariga qo'shiladi. ELK/Loki da bitta so'rovni servisdan-servisga kuzatish uchun handler ichida hech narsa yozish shart emas.
Dasturchi xatoni to'g'rilagach, qabristondagi xatlarni bitta komanda bilan yana hayotga qaytarishi mumkin:
php artisan micro:retry {navbat_nomi}
๐งช 9. 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'); });
๐ป 10. 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.