
ستون حاوية على خادم واحد
صندوق معادن عارية واحد يشغل عشرات إلى مئات حاويات Hoody. يجعل KSM و BTRFS dedup التكلفة الإضافية قريبة من الصفر.
Stripe يُرسل جسم الحدث بـ POST إلى مسار أنبوب مع ?n=12. اثنا عشر مشتركاً يطلبون نفس المسار بـ GET مع ?n=12. الأنبوب يحتفظ بالرسالة حتى يتّصل الجميع، ثم يبثّ إلى الاثني عشر دفعةً واحدة. لا وسيط، لا مجموعة مستهلِكين، لا DLQ.
Hoody Pipe بثّ HTTP بوضع متعدّد المستقبِلين. أضف ?n=N على روابط المرسِل والمستقبِل والأنبوب ينتظر حتى يلتصق N قارئاً، ثم يعكس الجسم لكلّهم في الوقت ذاته. البطيئون يخنقون اتّصالهم — السريعون يستمرّون في التدفّق.
نقطة نهاية Stripe لديك تُمرِّر جسم الحدث مباشرةً إلى /api/v1/pipe/billing?n=12. الاتّصال محصور ريثما ينتظر الأنبوب اجتماع الاثني عشر مستقبِلاً.
كل مشترك حلقة curl في حاوية، تطلب نفس المسار بـ GET مع ?n=12. الأنبوب يحتفظ بالجسم في الذاكرة حتى يتّصل القارئ الثاني عشر — لا طابور على القرص، لا شيء يجب تفريغه.
حالما يتّصل الجميع، يبثّ الجسم إلى الاثني عشر دفعةً واحدة. القارئ البطيء يُطبّق ضغطاً عكسياً على مقبسه؛ الباقون يستمرّون. حين يفصل آخر قارئ، ينسى الأنبوب الرسالة.
# جانب المرسل — معالج webhook الخاص بك بـ Stripe.
# الأنبوب يحمل الجسم حتى 12 قارئ متصلين.
curl -X POST "https://api.hoody.com/api/v1/pipe/billing?n=12" \
-H "Authorization: Bearer $HOODY_TOKEN" \
-H "Content-Type: application/json" \
--data-binary "@stripe-event.json"
# جانب المتلقي — واحد من اثني عشر حاوية مشترك.
# نفس المسار، نفس n. بث جسم الحدث حين التوزيع جاهز.
curl -N "https://api.hoody.com/api/v1/pipe/billing?n=12" \
-H "Authorization: Bearer $HOODY_TOKEN" | ./billing-handler.sh
# n يجب أن تطابق على كلا الجانبين — عدم التطابق يرجع 400.
# الافتراضي n=1 من نقطة إلى نقطة. n=12 للتوزيع إلى اثني عشر.نفس الرابط، نفس سلسلة الاستعلام، على الطرفَين. اتّصال المرسِل هو الوسيط؛ اتّصالات القرّاء هي مجموعة المستهلِكين. الضغط العكسي لكل مقبس، لا لكل موضوع، لأنّه لا يوجد موضوع — هناك جسم واحد في الطيران واثنا عشر مقبساً يسحبان منه.
إضافة مشترك هي curl إضافي في حاوية إضافيّة. إزالته هي قتل curl. لا إعداد وسيط، لا إعادة توازن مجموعة مستهلِكين، لا DLQ يجب تفريغه — طوبولوجيا العنقود هي ببساطة العمليّات التي تصادف أنّها تعمل الآن.
الأنبوب لا يتتبّع من المشترك. ينتظر فقط n اتّصالات لكل حدث. ارفع n على الطرفَين والحدث التالي ينتظر العدد الجديد. لا حالة عضويّة يمكن أن تتلف لأنّه لا توجد عضويّة.
كل سطر أدناه فئة عمل تختفي حين يكون الوسيط هو البروتوكول. لا بنية تحتيّة لتوفيرها، لا تجريدات لتعلّمها — فقط curl و?n.
لا SQS، لا عنقود Kafka، لا exchange في RabbitMQ. الأنبوب هو الطابور، ويحيا لرسالة واحدة في كل مرّة.
لا offsets، لا commits، لا rebalances. الأنبوب يحتفظ بالجسم حتى تلتصق n مقابس — هذا هو نموذج التنسيق بأكمله.
إن انفصل المرسِل دون استعداد n قرّاء، الأنبوب ينتهي وقته (TTL 5 دقائق) وStripe يُعيد المحاولة. لا دلو رسائل سامّة لتتفقّده.
المشتركون حلقات curl. المرسِلون curl. البروتوكول HTTP. أيّ شيء يستطيع ضرب رابط يستطيع الانضمام إلى العنقود.
قارئ بطيء يخنق اتّصاله. الأحد عشر الآخرون يستمرّون بكامل السرعة. لا حظر رأس-الطابور عبر الأسطول.
الجسم يختفي لحظة فصل آخر قارئ. لا سياسة احتفاظ يجب ضبطها، لا ضغط سجلّ يجب جدولته، لا مهمّة GDPR delete-on-request يجب كتابتها.
اثنا عشر مشتركاً، رابط واحد، لا وسيط.
الوسطاء أدناه هم الأشياء التي اعتدت تثبيتها قبل أن يصبح تفرّع HTTP مُعامل استعلام. الجانب الأيمن هو ما يستبدلها — مسار واحد، n واحد، واثنتا عشرة عمليّة curl لا تعرف أنّها عنقود.
اثنا عشر مستقبِلاً يطلبون نفس المسار بـ GET مع نفس n. الأنبوب هو الوسيط — وينسى الرسالة لحظة فصل آخر قارئ.
إن مدّيتَ يدك إلى أيّ من هذه لبثّ webhook إلى N مستهلِكاً، نموذج الأنبوب يقوم بالمهمّة نفسها في استدعاءَي curl — مرسِل على جانب، مستقبِلون على الآخر.
التفرّع الذي اعتدت كتابة سبرنت لأجله صار مُعامل استعلام. أضف ?n=12 وأطلق.