معرفی MQTT
MQTT یک پروتکل بسیار سبک و باینری است و به دلیل حداقل سربار بسته آن، هنگام انتقال داده ها از طریق سیم در مقایسه با پروتکلهایی مانند HTTP برتری دارد. اجرای پروتکل در سمت کلاینت نیز بسیار آسان است. سهولت استفاده یکی از نگرانیهای کلیدی در توسعه MQTT بود و آن را برای دستگاههای کوچک با منابع محدود امروزی مناسب میکند.
درس تاریخ
پروتکل MQTT در سال 1999 توسط اندی استنفورد کلارک (IBM) و آرلن نیپر (Arcom، اکنون Cirrus Link) اختراع شد. آنها به پروتکلی برای حداقل تلفات باتری و حداقل پهنای باند برای اتصال خطوط لوله نفت از طریق ماهواره نیاز داشتند. این دو مخترع چندین الزام را برای پروتکل آینده مشخص کردند:
• پیاده سازی ساده
• کیفیت خدمات ارائه دادهها
• سبک وزن و پهنای باند کارآمد
• مستقل از داده
• آگاهی از جلسات مستمر
این اهداف هنوز هم در هسته MQTT هستند. با این حال، تمرکز اصلی پروتکل از سیستمهای تعبیهشده اختصاصی به موارد استفاده باز اینترنت اشیا (IoT) تغییر کردهاست. این تغییر در تمرکز، سردرگمی زیادی در مورد آنچه مخفف MQTT مخفف است ایجاد کرده است. پاسخ کوتاه این است که MQTT دیگر مخفف در نظر گرفته نمیشود. MQTT به سادگی نام پروتکل است.
پاسخ طولانی تر این است که مخفف قبلی مخفف MQ Telemetry Transport بود:
“MQ” به سری MQ اشاره دارد، محصولی که IBM برای پشتیبانی از حمل و نقل تلهمتری MQ توسعه دادهاست. زمانی که اندی استنفورد کلارک و آرلن نیپر پروتکل خود را در سال 1999 ایجاد کردند، نام آن را به نام محصول IBM نامیدند. بسیاری از منابع MQTT را به اشتباه به عنوان پروتکل صف پیام برچسب گذاری میکنند که درست نیست.
MQTT یک راهحل سنتی برای صفبندی پیام نیست (اگرچه در موارد خاصی میتوان پیامها را در صف قرار داد). در طول ده سال آینده، IBM از پروتکل داخلی استفاده کرد تا اینکه MQTT 3.1 را به عنوان یک نسخه بدون حق امتیاز در سال 2010 منتشر کرد. از آن زمان، همه از اجرا و استفاده از پروتکل استقبال میرکنند.
همراه با انتشار مشخصات پروتکل، IBM به پیاده سازی کلاینت MQTT در پروژه تازه تاسیس Paho بنیاد Eclipse کمک کرد.
این رویدادها قطعاً چیز بزرگی برای پروتکل بود زیرا شانس کمی برای پذیرش گسترده بدون اکوسیستم حمایتی وجود داشت.
استاندارد OASIS و نسخه فعلی
تقریباً 3 سال پس از انتشار اولیه، اعلام شد که MQTT زیر بالهای OASIS، یک سازمان باز با هدف پیشرفت استانداردها، استاندارد میشود. AMQP، SAML و DocBook تنها تعدادی از استانداردهای OASIS هستند که قبلاً منتشر شده بودند. فرآیند استانداردسازی حدود 1 سال طول کشید. در 29 اکتبر 2014، MQTT به استاندارد OASIS تایید شده رسمی تبدیل شد.
در مارس 2019، OASIS مشخصات جدید MQTT 5 را تصویب کرد. این نسخه جدید MQTT ویژگیهای جدیدی را به MQTT معرفی کرد که برای برنامههای IoT مستقر در پلتفرمهای ابری مورد نیاز است، و مواردی که برای اجرای پیامهای حیاتی به قابلیت اطمینان و مدیریت خطا نیاز دارند.
الگوی انتشار اشتراک (Publish Subscribe)
الگوی انتشار/اشتراک (همچنین به عنوان pub/sub شناخته میشود) جایگزینی برای معماری سنتی کلاینت-سرور فراهم میکند. در مدل کلاینت-سرور، کلاینت مستقیماً با یک نقطه پایانی ارتباط برقرار می کند. مدل pub/sub کلاینت ارسال کننده پیام (ناشر – publisher) را از کلاینت یا کلاینتهایی که پیام ها را دریافت می کنند (مشترکین – subscribers) جدا میکند. ناشران و مشترکین هرگز مستقیماً با یکدیگر تماس نمیگیرند. در واقع، آنها حتی از وجود دیگری آگاه نیستند. ارتباط بین آنها توسط یک جزء سوم (کارگزار-broker) انجام میشود. وظیفه کارگزار فیلتر کردن تمام پیام های دریافتی و توزیع صحیح آنها برای مشترکین است.
معماری Publish / Subscribe چیست؟
مدل pub/sub ارتباط مستقیم بین ناشر پیام و گیرنده/مشترک را حذف می کند. فعالیت فیلترینگ کارگزار این امکان را فراهم میکند که کنترل شود کدام کلاینت/مشترک چه پیامی را دریافت می کند. جداسازی دارای سه بعد است: مکان، زمان و همگام سازی:
• جداسازی فضا: ناشر و مشترک نیازی به شناخت یکدیگر ندارند (مثلاً عدم تبادل آدرس IP و پورت).
• جداسازی زمان: ناشر و مشترک نیازی به اجرای همزمان ندارند.
• جداسازی همگام سازی: عملیات هر دو مؤلفه نیازی به قطع شدن در حین انتشار یا دریافت ندارد.

مقیاس پذیری
مقیاس Pub/Sub بهتر از رویکرد سنتی کلاینت-سرور است. به این دلیل که عملیات روی کارگزار را میتوان به شدت موازی کرد و پیامها را میتوان به روش رویداد محور پردازش کرد. حافظه پنهان پیام و مسیریابی هوشمند پیامها اغلب عوامل تعیین کنندهای برای بهبود مقیاس پذیری هستند. با این وجود، افزایش مقیاس تا میلیونها اتصال یک چالش است. چنین سطح بالایی از اتصالات را می توان با گرههای کارگزار خوشهای به دست آورد تا بار را بر روی سرورهای منفرد بیشتری با استفاده از متعادل کننده های بار توزیع کند.
فیلتر کردن پیام
کارگزار نقشی محوری در فرآیند pub/sub ایفا میکند. کارگزار چندین گزینه فیلتر دارد که تمام پیامها را فیلتر میکند تا هر مشترک فقط پیامهای مورد علاقه خود را دریافت کند:
گزینه 1: فیلترینگ مبتنی بر موضوع
این فیلتر بر اساس موضوع(topic) یا موضوعی است که بخشی از هر پیام است. کلاینت دریافت کننده برای موضوعات مورد علاقه در کارگزار مشترک میشود. از آن نقطه به بعد، کارگزار تضمین میکند که کلاینت دریافت کننده تمام پیامهای منتشر شده در موضوعات مشترک شده را دریافت میکند. در کل، موضوعات رشتههایی با ساختار سلسله مراتبی هستند که امکان فیلتر کردن بر اساس تعداد محدودی از عبارات را فراهم میکنند.
گزینه 2: فیلتر مبتنی بر محتوا
در فیلترینگ مبتنی بر محتوا، کارگزار پیام را بر اساس یک زبان فیلتر محتوای خاص فیلتر میکند. کلاینتها دریافت کننده برای فیلتر کردن پیامهایی که به آنها علاقهمند هستند مشترک میشوند. یک نقطه ضعف قابل توجه در این روش این است که محتوای پیام باید از قبل شناخته شده باشد و نمیتوان آن را رمزگذاری کرد یا به راحتی تغییر داد.
گزینه 3: فیلتر مبتنی بر نوع
زمانی که از زبان های شی گرا استفاده میشود، فیلتر کردن بر اساس نوع/کلاس یک پیام (رویداد) یک روش معمول است. به عنوان مثال، یک مشترک میتواند به تمام پیامهایی که از نوع استثنا یا هر نوع فرعی هستند گوش دهد.
قبل از استفاده از مدل انتشار/اشتراک، چند نکته وجود دارد که باید در نظر بگیرید. جداسازی ناشر و مشترک، چند چالش خاص خود را به همراه دارد. از نحوه ساختار داده های منتشر شده از قبل آگاه باشید: برای فیلتر مبتنی بر موضوع، هم ناشر و هم مشترک باید بدانند از چه موضوعاتی استفاده کنند. همچنین تحویل پیام را در نظر داشته باشید. ناشر نمیتواند تصور کند که کسی به پیامهای ارسال شده گوش میدهد. در برخی موارد، این امکان وجود دارد که هیچ مشترکی پیام خاصی را نخواند.
MQTT
بسته به آنچه میخواهید به دست آورید، MQTT تمام جنبههای pub/sub را که ذکر کردیم را در بر میگیرد:
• MQTT ناشر و مشترک را به صورت مکانی جدا می کند. برای انتشار یا دریافت پیام، ناشران و مشترکین فقط باید hostname/IP و پورت کارگزار را بدانند.
• MQTT با زمان جدا می شود. اگرچه اکثر موارد استفاده از MQTT پیامها را در زمان واقعی ارسال میکنند، در صورت تمایل، کارگزار میتواند پیامها را برای کلاینتهایی که آنلاین نیستند ذخیره کند. (دو شرط برای ذخیره پیام ها باید رعایت شود: کلاینت با یک جلسه دائمی(persistent session) ارتباط برقرار کرده و در موضوعی با کیفیت خدمات بیشتر از 0 مشترک شده است).
• MQTT به صورت ناهمزمان کار میکند. از آنجایی که اکثر کتابخانههای سرویس گیرنده بهصورت ناهمزمان کار میکنند و بر اساس تماسهای برگشتی یا مدلی مشابه هستند، وظایف در زمان انتظار برای پیام یا انتشار پیام مسدود نمیشوند. در موارد استفاده خاص، همگام سازی مطلوب و امکان پذیر است. برای منتظر ماندن برای یک پیام خاص، برخی از کتابخانه ها دارای APIهای همزمان هستند. اما جریان معمولاً ناهمزمان است.
• استفاده از MQTT به خصوص در سمت کلاینت آسان است. اکثر سیستمهای pub/sub منطق را در سمت کارگزار دارند، اما MQTT واقعاً مطابق با ماهیت pub/sub است بخصوص هنگام استفاده از یک کتابخانه کلاینت و این باعث میشود که پروتکلی سبک برای دستگاههای کوچک و محدود باشد.
MQTT از فیلتر موضوعی پیام ها استفاده می کند. هر پیام حاوی یک موضوع (موضوع) است که کارگزار میتواند از آن برای تعیین اینکه آیا مشتری مشترک پیام را دریافت میکند یا خیر استفاده کند.
برای رسیدگی به چالش های یک سیستم pub/sub، پروتکل MQTT دارای سطوح کیفیت خدمات (QoS) است. شما به راحتی می توانید تعیین کنید که یک پیام با موفقیت از کلاینت به کارگزار یا از کارگزار به کلاینت تحویل داده شود. اما این احتمال وجود دارد که هیچ کس در یک موضوع خاص مشترک نشود. اگر این مورد برای سیستم مهم است، نحوه رسیدگی به چنین مواردی به کارگزار بستگی دارد.
به عنوان مثال، یک کارگزار MQTT ممکن است یک سیستم پلاگین داشته باشد که می تواند چنین مواردی را شناسایی کند. میتوانید از کارگزار بخواهید که اقدامی انجام دهد یا به سادگی هر پیامی را برای تجزیه و تحلیل تاریخی در پایگاه داده وارد کنید. برای منعطف نگه داشتن سلسله مراتبی درخت موضوع، مهم است که درخت موضوع را با دقت طراحی کنید و فضایی برای موارد استفاده در آینده ایجاد کنید. اگر از این استراتژیها پیروی کنید، MQTT برای محصولات نهایی عالی است.
تمایز: MQTT و صف های پیام
در مورد نام MQTT و اینکه آیا پروتکل به عنوان صف پیام پیاده سازی میشود یا خیر، سردرگمی زیادی وجود دارد. MQTT به محصول سری MQ از IBM اشاره دارد و ربطی به “صف پیام” ندارد. صرف نظر از اینکه نام از کجا آمده است، درک تفاوت بین MQTT و صف پیام سنتی مفید است:
• در صف پیام، هر پیام دریافتی در صف ذخیره میشود تا زمانی که کلاینت (که اغلب مصرف کننده نامیده می شود) دریافت کند. اگر هیچ کلاینتی پیام را دریافت نکند، پیام در صف باقی میماند
و منتظر میماند تا مصرف شود. در صف پیام، امکان ندارد پیامی توسط هیچ کلاینتی پردازش نشود.
• در یک صف پیام سنتی، یک پیام فقط توسط یک مصرف کننده قابل پردازش است. بار بین تمام مصرف کنندگان برای یک صف توزیع می شود. در MQTT رفتار کاملاً برعکس است: هر مشترکی که در موضوع مشترک میشود پیام را دریافت میکند.
• صفها نامگذاری شدهاند و باید به صراحت ایجاد شوند. کار با یک صف بسیار سختتر از یک موضوع است. قبل از اینکه بتوان از یک صف استفاده کرد، صف باید به طور صریح با یک دستور جداگانه ایجاد شود. تنها پس از نامگذاری و ایجاد صف امکان انتشار یا مصرف پیامها وجود دارد. در مقابل، موضوعات MQTT بسیار منعطف هستند و میتوانند در لحظه ایجاد شوند.
منبع : کتاب MQTT Essentials E-Book – HIVEMQ