در هنرجوآموز، بهعنوان معمار راهکار روی یک پلتفرم رسانهای آموزشی کار کردم که در سطح کل پلتفرم به بیش از ۵۰۰۰ کاربر همزمان خدمت میداد. مسئولیت من طراحی معماری ترکیبی رسانه و سیگنالینگ بر پایهٔ LiveKit، WebRTC، NATS JetStream و Go بود؛ HLS نیز فقط برای بازپخشی به کار میرفت که چند ساعت پس از پایان نشست زنده در دسترس قرار میگرفت.
این مطالعهٔ موردی مرزهای تأییدشدهٔ معماری و منطق پشت آنها را شرح میدهد. عمداً جزئیات اختصاصی استقرار را افشا نمیکند و هیچ اندازهگیریای را که نتوانم بهصورت عمومی مستند کنم، ادعا نمیکند.
عدد ۵۰۰۰ کاربر به چه معناست
عدد تأییدشده، همزمانی در سطح پلتفرم است: بیش از ۵۰۰۰ کاربر میتوانستند همزمان در سرویس آموزشی حضور داشته باشند. این عدد به معنای ۵۰۰۰ ناشر همزمان، ۵۰۰۰ کاربر در یک اتاق، یا ۵۰۰۰ اتصال ورودی WebRTC به یک SFU نیست. اینها الگوهای بار متفاوتی هستند و هرگز نباید معادل یکدیگر در نظر گرفته شوند.
این تمایز جهت طراحی را تعیین کرد. مدرسها و دانشآموزان فعال به رسانهٔ فوری و دوسویه نیاز داشتند. بازپخش HLS عمداً با چند ساعت تأخیر ارائه میشد و نمیتوانست جای کلاس زنده را بگیرد.
تصمیم محوری معماری
من معماری زندهٔ WebRTC را همراه با مسیری جداگانه برای بازپخش با تأخیر طراحی کردم:
- LiveKit و WebRTC برای مدرسها، مدیران جلسه و شرکتکنندگانی که به تعامل بلادرنگ نیاز داشتند
- بازپخش HLS برای محتوایی که چند ساعت پس از نشست در دسترس قرار میگرفت
HLS مسیر جایگزین بینندگان نشست جاری نبود و جای مسیر زنده را نمیگرفت. مرز اصلی، زمانی بود: WebRTC در جایی حفظ شود که رسانهٔ فوری و دوسویه اهمیت دارد؛ HLS فقط در جایی ارائه شود که بازپخش با تأخیر نیاز محصول را برآورده میکند.
این جداسازی مهمترین درس پروژه است. مقیاسدادن یک پلتفرم رسانهای فقط مسئلهٔ ظرفیت SFU نیست؛ مسئلهٔ دستهبندی نیز هست: باید مشخص شود چه کسی باید در نشست بلادرنگ مشارکت کند و چه کسی فقط نیازمند مصرف محتواست.
سیگنالینگ بهعنوان سیستمی جداگانه
مسیریابی رسانه و سیگنالینگ برنامه دو مسئلهٔ متفاوت را حل میکنند. LiveKit نشستهای رسانهای WebRTC را مدیریت میکرد. NATS JetStream ستون فقرات سیگنالینگ برای سرویسهای پیرامونی برنامه بود و Go بخشی از لایهٔ سرویسی هماهنگکنندهٔ این گردشکارها را تشکیل میداد.
شفاف نگهداشتن این مسئولیتها، استدلال دربارهٔ طراحی را آسانتر کرد:
- وضعیت رسانه متعلق به لایهٔ رسانهٔ بلادرنگ بود
- رویدادهای برنامه متعلق به لایهٔ سیگنالینگ و سرویس بودند
- بازپخش با تأخیر متعلق به مسیر HLS بود
- تغییر میان نقشهای مخاطبان باید آگاهانه انجام میشد
این تفکیک مانع از آن میشود که گذرگاه پیام نقش مسیریاب رسانه را بازی کند یا SFU وضعیت برنامهای را حمل کند که مالک آن نیست.
الگویی بازاستفادهپذیر برای مرز ارتقای نقش
شواهد عمومی این پروژه نشان نمیدهند که جابهجایی زنده میان مسیر بینندهٔ غیرفعال و یک نقش تعاملی WebRTC در محیط عملیاتی پیادهسازی شده باشد. آنچه در ادامه میآید یک الگوی طراحی بازاستفادهپذیر است، نه ادعایی دربارهٔ پیادهسازی عملیاتی هنرجوآموز.
اگر یک بینندهٔ غیرفعال لازم باشد تعاملی شود، این تغییر فقط یک کلید رابط کاربری نیست. سیستم باید نشست بلادرنگ را برقرار کند، آمادهبودن شرکتکننده را تأیید کند و تنها پس از آن کاربر را فعال بداند. تغییر معکوس نیز باید منابع بلادرنگ را آزاد کند تا شرکتکنندهٔ غیرفعال برای همیشه متصل نماند.
یک الگوی بازاستفادهپذیر، ماشین حالت کوچکی است:
- بیننده یک نقش تعاملی درخواست میکند
- سیاست برنامه این تغییر را مجاز میکند
- سیگنالینگ ایجاد نشست را هماهنگ میکند
- کلاینت به اتاق LiveKit میپیوندد
- وضعیت برنامه فقط پس از آمادهشدن رسانه تغییر میکند
- تنزل نقش منابع بلادرنگ را آزاد میکند؛ بازپخش با تأخیر، هرگاه در دسترس باشد، تجربهای جداگانه پس از نشست باقی میماند
سیاست و توپولوژی دقیق به محصول وابستهاند، اما ترتیب این مراحل چنین نیست. سیستمهای توزیعشده زمانی شکننده میشوند که وضعیت کسبوکار موفقیت یک تغییر را پیش از وجود وضعیت رسانهای وابسته اعلام کند.
حالتهای خطایی که در طراحی در نظر گرفته شدند
معماری باید خطاها را از هم تفکیک میکرد، نه اینکه همه را به یک خطای عمومی اتصال فروبکاهد:
- بازپخش HLS ممکن است چند ساعت بعد در دسترس باشد، اما جای نشست زندهٔ WebRTC را نمیگیرد
- ممکن است سیگنالینگ در دسترس باشد، در حالی که نشست رسانه هنوز آماده نیست
- ممکن است کلاینت دوباره متصل شود، بدون آنکه اجازهٔ تکرار یک نقش فعال را داشته باشد
- ممکن است تغییر نقش پس از تأیید سیاست و پیش از آمادهشدن رسانه مهلت زمانیاش تمام شود
- بینندگان غیرفعال پس از تنزل نقش نباید ظرفیت تعاملی مصرف کنند
اینها خطاهای مرزیاند. مالکیت روشن و تغییرات بیاثر در اجرای مجدد، از افزودن یک حلقهٔ تلاش مجدد دیگر مهمترند.
چه چیزهایی را میتوانم و نمیتوانم بهصورت عمومی ادعا کنم
میتوانم عدد همزمانی در سطح پلتفرم، نقش خود بهعنوان معمار راهکار، معماری زندهٔ WebRTC و بازپخش HLS با تأخیر پس از نشست، و استفاده از LiveKit، NATS JetStream و Go برای هماهنگی را مستند کنم.
تعداد اختصاصی نودها، توپولوژی منطقهای، تأخیر دقیق، آپتایم، هزینهٔ زیرساخت یا روش آزمون بار را بهعنوان واقعیت عمومی ارائه نمیکنم. همچنین ادعا نمیکنم که همهٔ کاربران همزمان، شرکتکنندهٔ فعال WebRTC یا ناشر بودهاند، در یک اتاق حضور داشتهاند، یا اتصالشان به یک SFU ختم شده است. ادعا نمیکنم جابهجایی زنده میان WebRTC و HLS پیادهسازی شده بود. این محدودیت مهم است، زیرا یک مطالعهٔ موردی مهندسی مفید باید مرز شواهد خود را آشکار کند.
چکلیست بازاستفاده
برای یک پلتفرم آموزشی یا رویدادی دیگر، کار را با این پرسشها آغاز میکنم:
- کدام نقشها واقعاً به رسانهٔ بلادرنگ و دوسویه نیاز دارند؟
- آیا بازپخش HLS با تأخیر برای دسترسی پس از نشست مناسب است، بدون آنکه بهعنوان مسیر جایگزین زنده معرفی شود؟
- مالک سیاست اتاق، وضعیت رسانه و وضعیت برنامه چه کسی است؟
- آیا ارتقا به نقش تعاملی، تغییری صریح و قابل مشاهده در وضعیت است؟
- آیا تلاش مجدد میتواند شرکتکنندهٔ تکراری یا مجوز منقضی ایجاد کند؟
- آیا اعداد ظرفیت برای ناشران، مشترکان، اتاقها و همزمانی کل پلتفرم از یکدیگر جدا شدهاند؟
- آیا هر ادعای عملکرد منتشرشده، الگوی باری را که اندازهگیری کرده مشخص میکند؟
نتیجه یک توپولوژی جهانشمول نیست؛ روشی امنتر برای تصمیمگیری است که نشان میدهد زیرساخت بلادرنگ کجا ارزش ایجاد میکند و مسیر پخش کجا انتخاب قابلاتکاتری است.
جمعبندی
پروژهٔ هنرجوآموز اصلی را تقویت کرد که در طراحی سیستمهای توزیعشده به کار میبرم: پیش از آنکه همهٔ اجزا را بهطور یکنواخت مقیاس دهید، بارهای کاری با نیازهای متفاوت از نظر سازگاری، تأخیر و تعامل را از هم جدا کنید.
برای این پلتفرم، این اصل به معنای حفظ WebRTC برای تعامل زنده، استفاده از HLS فقط برای بازپخش با تأخیر، و صریح نگهداشتن سیگنالینگ برنامه با NATS JetStream و Go بود. نتیجهٔ بیش از ۵۰۰۰ کاربر همزمان در سطح پلتفرم اهمیت دارد، اما درس مهندسی بازاستفادهپذیرتر همان مرزی است که مدیریت این الگوی همزمانی را ممکن کرد.
