آموزش‌های کلادفلر به‌زودی در این بخش قرار داده می‌شود.

برچسب: برنامه‌نویسی

  • مرورگر بی‌سر یا Headless Browser؛ ابزاری برای اتوماسیون و هوش مصنوعی

    اول از همه بیایید ببینیم وقتی میگیم «مرورگر» دقیقا منظورمون چیه. شما وقتی می‌خواید یه سایتی مثل گوگل یا اینستاگرام رو باز کنید، برنامه کروم، فایرفاکس یا هر مرورگر دیگه‌ای رو باز می‌کنید. یه پنجره خوشگل جلوتون باز میشه که یه نوار آدرس داره، دکمه‌های «عقب» و «جلو» داره، می‌تونید توش اسکرول کنید، روی لینک‌ها کلیک کنید و خلاصه کلی کار گرافیکی انجام بدید. به کل این ظاهر و پوسته‌ای که شما می‌بینید و باهاش کار می‌کنید، میگن رابط کاربری گرافیکی یا به اختصار GUI. این رابط کاربری مثل صورت و بدن یه آدمه که باعث میشه بتونیم باهاش ارتباط برقرار کنیم.

    حالا تصور کنید ما بیایم و کل این ظاهر گرافیکی رو از مرورگر حذف کنیم. یعنی دیگه هیچ پنجره‌ای نباشه، هیچ دکمه‌ای، هیچ نوار آدرسی که دیده بشه. انگار که جسم مرورگر رو گرفتیم و فقط روحش باقی مونده. چیزی که به دست میاد دقیقا یک مرورگر بی‌سر یا Headless Browser هست. این مرورگر دیگه ظاهر نداره، اما مغزش هنوز سر جاشه. یعنی چی؟ یعنی هنوزم می‌تونه یه صفحه وب رو به طور کامل بارگذاری کنه، کدهای HTML رو بخونه و بفهمه، استایل‌ها و رنگ‌بندی صفحه (همون کدهای CSS) رو درک کنه و حتی کدهای پیچیده جاوا اسکریپت و Ajax رو اجرا کنه. در واقع، همه کارهایی که یه مرورگر معمولی انجام میده رو انجام میده، فقط ما نتیجه رو به صورت گرافیکی نمی‌بینیم.

    پس چجوری کنترلش می‌کنیم؟ به جای کلیک کردن و تایپ کردن توی یه پنجره، ما از طریق خط فرمان (Command-Line) یا از طریق ارتباط شبکه‌ای بهش دستور میدیم. انگار داریم پشت تلفن باهاش حرف می‌زنیم و بهش میگیم: «برو به سایت فلان، روی اون دکمه کلیک کن، توی اون کادر فلان چیز رو بنویس و بعد یه عکس از صفحه بگیر و برای من بفرست». همه این کارها رو در پشت صحنه انجام میده، بدون اینکه حتی یک پیکسل روی مانیتور شما نمایش داده بشه. این ویژگی باعث میشه مرورگرهای بی‌سر فوق‌العاده سریع و سبک باشن، چون دیگه لازم نیست انرژی و منابع سیستم رو صرف کشیدن و نقاشی کردن ظاهر صفحه کنن.

    این قابلیت که مرورگرهای بی‌سر می‌تونن HTML رو دقیقا مثل یه مرورگر معمولی درک کنن، خیلی مهمه. یعنی می‌تونن بفهمن چیدمان صفحه چجوریه، رنگ‌ها چی هستن، فونت‌ها چطور انتخاب شدن و از همه مهم‌تر، جاوا اسکریپت و Ajax رو اجرا کنن. خیلی از روش‌های تست دیگه، این قابلیت اجرای جاوا اسکریپت رو ندارن و اینجاست که مرورگرهای بی‌سر یه مزیت بزرگ پیدا می‌کنن.

    جالبه بدونید که این ایده اونقدر مهم و کاربردی شد که مرورگرهای بزرگ هم به فکر افتادن. گوگل کروم از نسخه ۵۹ به بعد و موزیلا فایرفاکس از نسخه ۵۶ به بعد، این قابلیت رو به صورت داخلی و بومی توی خودشون قرار دادن. این یعنی دیگه لازم نیست برای داشتن یه مرورگر بی‌سر، حتما یه نرم‌افزار جدا نصب کنیم. می‌تونیم به خود کروم یا فایرفاکس دستور بدیم که در حالت بی‌سر اجرا بشن. این حرکت باعث شد که خیلی از ابزارهای قدیمی‌تر که برای همین کار ساخته شده بودن، مثل PhantomJS، تقریبا بازنشسته بشن و کنار برن، چون دیگه خود غول‌های بزرگ این کار رو راحت کرده بودن.

    خب، این مرورگر نامرئی به چه دردی می‌خوره؟

    شاید الان با خودتون بگید خیلی خب، فهمیدیم چیه، ولی چرا باید کسی بخواد از یه مرورگر بدون صفحه نمایش استفاده کنه؟ کاربردش چیه؟ اتفاقا کاربردهای خیلی مهم و زیادی داره که در ادامه با هم چندتا از اصلی‌ترین‌هاشون رو بررسی می‌کنیم.

    ۱. اتوماسیون تست در اپلیکیشن‌های وب (Web Testing)

    این یکی از بزرگ‌ترین و مهم‌ترین کاربردهای مرورگرهای بی‌سر هست. تصور کنید شما یه تیم برنامه‌نویسی هستید که یه سایت فروشگاهی بزرگ طراحی کردید. توی این سایت هزاران دکمه، فرم ثبت‌نام، فرم ورود، مراحل خرید و کلی چیز دیگه وجود داره. حالا شما می‌خواید مطمئن بشید که همه این‌ها درست کار می‌کنن. مثلا اگه کاربر روی دکمه «افزودن به سبد خرید» کلیک کرد، واقعا محصول به سبد خرید اضافه میشه؟ اگه فرم ثبت‌نام رو پر کرد، اطلاعاتش درست توی سیستم ثبت میشه؟

    یه راهش اینه که یه نفر آدم بشینه و دونه دونه این کارها رو دستی انجام بده. روی همه دکمه‌ها کلیک کنه، همه فرم‌ها رو پر کنه و ببینه چی میشه. این کار فوق‌العاده وقت‌گیر، خسته‌کننده و پر از خطای انسانیه. حالا فرض کنید شما هر روز یه تغییر کوچیک توی سایت میدید. باید هر روز دوباره کل این مراحل رو تست کنید؟ معلومه که نه!

    اینجاست که مرورگرهای بی‌سر وارد میشن. توسعه‌دهنده‌ها اسکریپت‌ها یا برنامه‌های کوچیکی می‌نویسن که به مرورگر بی‌سر دستور میده به صورت خودکار این کارها رو انجام بده. مثلا یه اسکریپت می‌نویسن که:

    • صفحه ثبت‌نام رو باز کن.
    • توی کادر نام کاربری، بنویس «تست».
    • توی کادر رمز عبور، بنویس «۱۲۳۴۵۶».
    • روی دکمه ثبت‌نام کلیک کن.
    • ببین آیا پیام «ثبت‌نام با موفقیت انجام شد» نمایش داده میشه یا نه.

    این تست‌ها می‌تونن در عرض چند ثانیه هزاران بار اجرا بشن. اینجوری تیم توسعه مطمئن میشه که حتی با کوچیک‌ترین تغییرات، عملکرد اصلی سایت خراب نشده. چون مرورگر بی‌سر هیچ رابط گرافیکی نداره، این تست‌ها خیلی سریع‌تر و با مصرف منابع کمتری انجام میشن. این موضوع به خصوص در محیط‌های CI/CD (یکپارچه‌سازی و تحویل مداوم) که سرعت اجرای تست‌ها خیلی مهمه، یه مزیت بزرگ به حساب میاد.

    توی این زمینه ابزارهای مختلفی وجود دارن که از مرورگرهای بی‌سر برای تست استفاده می‌کنن:

    • Capybara: این ابزار از مرورگر بی‌سر (چه WebKit چه کروم بی‌سر) استفاده می‌کنه تا رفتار کاربر رو توی پروتکل‌های تست خودش شبیه‌سازی کنه.
    • Jasmine: این فریمورک به طور پیش‌فرض از ابزاری به نام Selenium استفاده می‌کنه، اما می‌تونه از WebKit یا کروم بی‌سر هم برای اجرای تست‌های مرورگر کمک بگیره.
    • Cypress: یک فریمورک خیلی محبوب برای تست کردن بخش فرانت‌اند یا همون ظاهر سایت‌ها.
    • QF-Test: ابزاری برای تست خودکار برنامه‌ها از طریق رابط کاربری گرافیکی که می‌تونه از مرورگر بی‌سر هم برای تست کردن استفاده کنه.
    • Testsigma: یک پلتفرم اتوماسیون تست مبتنی بر هوش مصنوعی و ابری که از تست با مرورگر بی‌سر پشتیبانی می‌کنه.

    ۲. گرفتن اسکرین‌شات از صفحات وب

    یکی دیگه از کاربردهای خیلی ساده و مفید مرورگرهای بی‌سر، گرفتن عکس از صفحات وبه. فرض کنید شما می‌خواید ببینید ظاهر سایتتون روی دستگاه‌های مختلف با اندازه‌های صفحه نمایش متفاوت چجوری دیده میشه. یا مثلا می‌خواید یه سرویسی درست کنید که هر روز از صفحه اول سایت‌های خبری عکس بگیره و آرشیو کنه.

    با یه دستور ساده به مرورگر بی‌سر، می‌تونید بهش بگید که یه سایت خاص رو باز کنه و از کل صفحه یا یه قسمت مشخص از اون، یه عکس با کیفیت بگیره و ذخیره کنه. این کار برای تست چیدمان (Layout) صفحه خیلی کاربردیه. توسعه‌دهنده‌ها می‌تونن به صورت خودکار از صفحات مختلف اسکرین‌شات بگیرن و اون‌ها رو با هم مقایسه کنن تا مطمئن بشن که تغییرات جدید، ظاهر سایت رو به هم نریخته. این کار کمک می‌کنه تا اجرای تست در محیط‌های مختلف آسون‌تر بشه و مقایسه بین حالت‌های مختلف رابط کاربری راحت‌تر انجام بگیره.

    ۳. اجرای تست‌های خودکار برای کتابخانه‌های جاوا اسکریپت

    دنیای وب مدرن پر از کتابخانه‌های جاوا اسکریپته. این کتابخانه‌ها کدهای از پیش نوشته شده‌ای هستن که به توسعه‌دهنده‌ها کمک می‌کنن کارهای پیچیده رو راحت‌تر انجام بدن. مثلا یه کتابخونه برای ساختن نمودارهای خوشگل، یا یه کتابخونه برای مدیریت انیمیشن‌ها.

    سازنده‌های این کتابخانه‌ها باید مطمئن بشن که کدشون توی مرورگرهای مختلف درست کار می‌کنه. اون‌ها هم از مرورگرهای بی‌سر استفاده می‌کنن تا تست‌های خودکار رو برای کتابخونه‌هاشون اجرا کنن. این تست‌ها توی محیط مرورگر بی‌سر خیلی سریع‌تر و بهینه‌تر اجرا میشن، چون دیگه اون سربار مربوط به رابط کاربری وجود نداره.

    ۴. اتوماسیون تعامل با صفحات وب

    این مورد یه کم شبیه به تست خودکاره، اما هدفش فقط تست کردن نیست. گاهی وقتا ما می‌خوایم یه سری کارهای تکراری رو توی یه سایت به صورت خودکار انجام بدیم. مثلا فرض کنید شما می‌خواید یه ربات برای اینستاگرام بنویسید که به صورت خودکار وارد اکانت شما بشه، چندتا عکس رو لایک کنه و یه کامنت بذاره.

    این کار دقیقا با مرورگر بی‌سر انجام میشه. شما یه اسکریپت می‌نویسید که به مرورگر دستور میده صفحه لاگین اینستاگرام رو باز کنه، نام کاربری و رمز عبور شما رو وارد کنه، دکمه ورود رو بزنه و بعدش کارهای دیگه‌ای که ازش خواستید رو انجام بده. در واقع هر کاری که یه آدم می‌تونه توی مرورگر انجام بده (کلیک کردن، تایپ کردن، اسکرول کردن و…)، یه مرورگر بی‌سر هم می‌تونه به صورت برنامه‌ریزی شده انجام بده. این کارها می‌تونه شامل پر کردن فرم‌ها، کلیک روی دکمه‌ها و لینک‌ها و شبیه‌سازی ورودی‌های کیبورد باشه. هر چیزی که بشه خودکارش کرد تا در زمان و تلاش صرفه‌جویی بشه، با مرورگر بی‌سر ممکنه.

    ۵. استخراج داده یا وب اسکرپینگ (Web Scraping)

    یکی دیگه از کاربردهای فوق‌العاده مهم مرورگرهای بی‌سر، جمع‌آوری اطلاعات از وب‌سایت‌هاست که بهش میگن وب اسکرپینگ. تصور کنید شما می‌خواید قیمت یه محصول خاص رو از ۱۰ تا سایت فروشگاهی مختلف جمع‌آوری کنید و با هم مقایسه کنید. به جای اینکه دستی به هر ۱۰ تا سایت سر بزنید، می‌تونید یه برنامه بنویسید که با استفاده از مرورگر بی‌سر، به صورت خودکار به این سایت‌ها بره، صفحه محصول رو باز کنه و قیمت رو از توی کد HTML صفحه استخراج کنه.

    این کار برای جمع‌آوری داده‌های عمومی از اینترنت خیلی مفیده. مثلا جمع‌آوری اطلاعات آب و هوا، نتایج ورزشی، قیمت سهام یا هر اطلاعات دیگه‌ای که به صورت عمومی روی وب‌سایت‌ها موجوده. خوبی استفاده از مرورگر بی‌سر برای این کار اینه که می‌تونه با سایت‌های مدرن که از جاوا اسکریپت برای نمایش محتوا استفاده می‌کنن هم کار کنه. خیلی از سایت‌ها وقتی شما بازشون می‌کنید، اول یه صفحه خالی نشون میدن و بعد با جاوا اسکریپت اطلاعات رو از سرور می‌گیرن و توی صفحه قرار میدن. ابزارهای اسکرپینگ ساده نمی‌تونن این اطلاعات رو ببینن، اما چون مرورگر بی‌سر جاوا اسکریپت رو اجرا می‌کنه، صبر می‌کنه تا صفحه کامل لود بشه و بعد اطلاعات رو استخراج می‌کنه.

    جالبه بدونید که حتی گوگل هم به این موضوع توجه داشته. در سال ۲۰۰۹، گوگل اعلام کرد که استفاده از یه مرورگر بی‌سر می‌تونه به موتور جستجوش کمک کنه تا محتوای سایت‌هایی که از Ajax استفاده می‌کنن رو بهتر ایندکس کنه. Ajax یه تکنولوژی بود که به صفحات وب اجازه میداد بدون رفرش شدن کامل، اطلاعات جدید رو بارگذاری کنن. این برای ربات‌های جستجوگر قدیمی یه چالش بود، اما مرورگرهای بی‌سر این مشکل رو حل کردن.

    بعضی سرویس‌ها مثل Web Scraper API و Web Unblocker از شرکت Oxylabs، یه قابلیتی به نام Headless Browser دارن که به کاربرها اجازه میده داده‌های عمومی رو از سایت‌های پیچیده جمع‌آوری کنن. با این قابلیت میشه:

    • دستورالعمل‌های مرورگر رو برای خودکارسازی تعاملات کاربر تنظیم کرد.
    • رفتار مرورگر رو برای شبیه‌سازی یه کاربر واقعی، شخصی‌سازی کرد.
    • جاوا اسکریپت رو اجرا کرد و داده‌های بیشتری رو توی صفحه بارگذاری کرد.

    اینجوری عملیات اسکرپینگ شما برای مدیریت تعاملات مختلف صفحه و چالش‌ها، مجهزتر میشه و دیگه نیازی به ابزارهای خارجی نیست.

    آیا از مرورگرهای بی‌سر استفاده نادرست هم میشه؟

    مثل هر تکنولوژی دیگه‌ای، از مرورگرهای بی‌سر هم میشه برای کارهای نادرست و مخرب استفاده کرد. بیایید چند نمونه از این سوءاستفاده‌ها رو ببینیم، اما حواستون باشه که در نهایت به یه نتیجه‌گیری جالب می‌رسیم.

    • انجام حملات DDoS: حمله DDoS یا «محروم‌سازی از سرویس توزیع‌شده» یعنی اینکه تعداد خیلی خیلی زیادی درخواست به سمت یه سرور سایت فرستاده بشه تا سرور نتونه جواب بده و از دسترس خارج بشه. هکرها می‌تونن از ارتشی از مرورگرهای بی‌سر استفاده کنن تا این درخواست‌ها رو به صورت خودکار به سمت سایت هدف بفرستن. یه گزارش در سال ۲۰۱۳ به یه بات‌نت (شبکه‌ای از کامپیوترهای آلوده) اشاره کرد که از مرورگر بی‌سر برای یه حمله DDoS به مدت ۱۵۰ ساعت استفاده کرده بود.
    • افزایش غیرواقعی بازدید تبلیغات (Ad Fraud): بعضی از تبلیغات آنلاین بر اساس تعداد بازدید پول پرداخت می‌کنن. افراد سودجو می‌تونن با استفاده از مرورگرهای بی‌سر، به صورت خودکار و در مقیاس بزرگ، صفحاتی که تبلیغشون توش هست رو باز کنن تا اینجوری آمار بازدید رو به صورت تقلبی بالا ببرن و پول بیشتری به جیب بزنن. در سال ۲۰۱۴، مقاله‌ای به این موضوع اشاره کرد که ترافیک وب بی‌سر، اقتصاد اینترنت رو تهدید می‌کنه.
    • خودکارسازی سایت‌ها به روش‌های ناخواسته: گاهی وقتا از این ابزارها برای دور زدن قوانین یه سایت استفاده میشه. مثلا برای Credential Stuffing. این یعنی هکرها یه لیست بزرگ از نام‌های کاربری و رمزهای عبوری که از جاهای دیگه لو رفته رو برمی‌دارن و با مرورگر بی‌سر سعی می‌کنن به صورت خودکار با اون‌ها وارد اکانت‌های کاربری یه سایت دیگه بشن. چون خیلی از آدما از یه رمز عبور برای چندتا سایت استفاده می‌کنن، این روش متاسفانه گاهی وقتا جواب میده.

    اما یه نکته خیلی مهم! با وجود همه این نگرانی‌ها، یه تحقیق جالبی در سال ۲۰۱۸ انجام شد. این تحقیق ترافیک مرورگرها رو بررسی کرد و به این نتیجه رسید که هیچ ترجیحی از طرف افراد خرابکار برای استفاده از مرورگرهای بی‌سر وجود نداره. یعنی هیچ نشانه‌ای وجود نداره که بگیم مرورگرهای بی‌سر بیشتر از مرورگرهای معمولی برای کارهای مخرب مثل حملات DDoS، تزریق SQL یا حملات Cross-site scripting استفاده میشن. پس با اینکه پتانسیل سوءاستفاده وجود داره، در عمل به نظر نمیرسه که این ابزارها انتخاب اول هکرها باشن.

    ابزارهای کنترل این ارواح نامرئی: چطور با مرورگر بی‌سر کار کنیم؟

    همونطور که گفتیم، مرورگرهای بزرگی مثل کروم و فایرفاکس الان حالت بی‌سر داخلی دارن. این کار از طریق API ها یا رابط‌های برنامه‌نویسی انجام میشه که به توسعه‌دهنده‌ها اجازه میده از طریق کد، مرورگر رو کنترل کنن. برای اینکه این کار راحت‌تر بشه، یه سری نرم‌افزارها و کتابخانه‌ها به وجود اومدن که یه رابط یکپارچه برای اتوماسیون مرورگرها فراهم می‌کنن. بیایید با چندتا از معروف‌ترین‌هاشون آشنا بشیم.

    ۱. Selenium WebDriver

    سلنیوم شاید قدیمی‌ترین و معروف‌ترین ابزار تو این حوزه باشه. این یه پروژه خیلی بزرگه که به شما اجازه میده مرورگرهای مختلف (نه فقط کروم و فایرفاکس) رو به صورت خودکار کنترل کنید. نکته مهم در مورد سلنیوم اینه که یه پیاده‌سازی سازگار با استاندارد W3C از WebDriver هست. W3C کنسرسیوم وب جهانیه که استانداردهای وب رو تعیین می‌کنه. اینکه سلنیوم با این استانداردها سازگاره یعنی یه ابزار قابل اعتماد و استاندارده.

    ۲. Playwright

    پلی‌رایت یه کتابخونه نسبتا جدیده که توسط مایکروسافت توسعه داده شده. این یه کتابخونه برای Node.js هست (Node.js به شما اجازه میده جاوا اسکریپت رو خارج از مرورگر و روی سرور اجرا کنید). با پلی‌رایت می‌تونید سه تا از مهم‌ترین موتورهای مرورگر دنیا رو کنترل کنید: Chromium (موتور کروم و اج)، Firefox و WebKit (موتور سافاری). این یعنی با یه ابزار می‌تونید سایتتون رو روی سه تا مرورگر اصلی تست کنید.

    ۳. Puppeteer

    پاپی‌تیر هم یه کتابخونه Node.js دیگه است که این یکی توسط تیم گوگل کروم توسعه داده شده. همونطور که از اسم سازنده‌اش مشخصه، پاپی‌تیر به طور تخصصی برای کنترل مرورگر کروم (یا کرومیوم) طراحی شده. این ابزار خیلی قدرتمنده و به شما کنترل سطح بالایی روی مرورگر میده. خیلی از مثال‌هایی که در مورد اتوماسیون می‌زنیم، مثل همون ربات اینستاگرام، به راحتی با پاپی‌تیر قابل پیاده‌سازیه.

    بیایید یه نگاه عمیق‌تر به یه مثال واقعی با پاپی‌تیر بندازیم. یه توسعه‌دهنده می‌خواست یه ربات اینستاگرام بسازه که با Azure Functions (یه سرویس بدون سرور از مایکروسافت) کار کنه. اون از Browserless استفاده کرده بود که در واقع پاپی‌تیر در حال اجرا توی یه کانتینر داکره. کدش برای لاگین کردن به اینستاگرام یه چیزی شبیه این بود:

    const browser = await puppeteer.connect({
        browserWSEndpoint: process.env.WS_ENDPOINT
    });

    تو این تیکه کد، به جای اینکه یه مرورگر جدید باز کنه، داره به یه مرورگری که از قبل در حال اجراست (همون Browserless) وصل میشه. آدرس اون مرورگر توی یه متغیر محیطی به اسم WS_ENDPOINT ذخیره شده. این کار کمک می‌کنه تا منابع بهینه‌تر مصرف بشن. بعدش با دستوراتی مثل page.type() و page.click()، فرم لاگین رو پر می‌کنه و وارد سایت میشه. این یه نمونه عالی از قدرت پاپی‌تیر برای اتوماسیون کارهای واقعیه.

    رویکردهای جایگزین: شبیه‌سازی مرورگر بدون مرورگر واقعی

    یه راه دیگه هم برای تست و اتوماسیون وجود داره که یه کم متفاوته. به جای استفاده از یه مرورگر کامل (حتی به صورت بی‌سر)، از نرم‌افزارهایی استفاده می‌کنیم که فقط API های مرورگر رو شبیه‌سازی می‌کنن. این ابزارها معمولا کدهای HTML رو تجزیه می‌کنن (HTML parsing)، کوکی‌ها رو مدیریت می‌کنن، درخواست‌های XHR (که برای Ajax استفاده میشه) رو انجام میدن و تا حدی جاوا اسکریپت رو هم پشتیبانی می‌کنن.

    اما تفاوت بزرگشون اینه که اون‌ها DOM رو رندر نمی‌کنن. DOM یا Document Object Model یه مدل درختی از تمام عناصر یه صفحه وبه. مرورگرهای واقعی این مدل رو می‌سازن و بعد بر اساس اون صفحه رو نقاشی می‌کنن. این ابزارهای شبیه‌ساز، مرحله نقاشی رو ندارن و پشتیبانیشون از رویدادهای DOM (مثل کلیک کردن، حرکت موس و …) هم محدوده.

    مزیت بزرگشون چیه؟ سرعت فوق‌العاده بالا. چون خیلی از کارهای سنگین یه مرورگر واقعی رو انجام نمیدن، معمولا خیلی سریع‌تر از مرورگرهای کامل عمل می‌کنن.
    عیبشون چیه؟ نمی‌تونن خیلی از سایت‌های محبوب و پیچیده امروزی رو به درستی تفسیر کنن. چون خیلی از سایت‌ها به شدت به جاوا اسکریپت و تعاملات پیچیده DOM وابسته‌ان.

    چندتا از این ابزارها عبارتند از:

    • jsdom: این معروف‌ترین و کامل‌ترین ابزار برای شبیه‌سازی مرورگر در محیط Node.js هست.
    • Deno: این یه محیط اجرایی جدیده برای جاوا اسکریپت (یه جورایی رقیب Node.js) که API های مرورگر رو به عنوان بخشی از طراحی اصلی خودش ارائه میده.
    • HtmlUnit: این یه مرورگر بی‌سر نوشته شده به زبان جاواست. HtmlUnit از موتور Rhino برای پشتیبانی از جاوا اسکریپت و Ajax استفاده می‌کنه و حتی تا حدی قابلیت رندر کردن هم داره. این ابزار به خصوص برای تست سایت‌های تجارت الکترونیک محبوبه، چون برای تست کردن فرم‌ها، ریدایرکت‌های سایت و احراز هویت HTTP خیلی خوب عمل می‌کنه.
    • envjs: این یه تلاش قدیمی‌تر بود که در سال ۲۰۰۸ توسط جان رسیگ (خالق jQuery) معرفی شد. envjs هم یه محیط شبیه‌سازی شده مرورگر بود که به زبان جاوا اسکریپت برای موتور Rhino نوشته شده بود.

    جعبه ابزار مرورگرهای بی‌سر: نگاهی به چند نرم‌افزار خاص

    علاوه بر ابزارهای کنترل مرورگر و شبیه‌سازها، یه سری نرم‌افزارهای مستقل هم وجود دارن که API های مرورگر بی‌سر رو ارائه میدن. هر کدوم از این‌ها ویژگی‌های خاص خودشون رو دارن.

    • Splash: این یه مرورگر وب بی‌سر هست که به زبان پایتون و با استفاده از موتور چیدمان WebKit (از طریق Qt) نوشته شده. Splash یه API از نوع HTTP داره، از اسکریپت‌نویسی با زبان Lua پشتیبانی می‌کنه و حتی یه محیط توسعه داخلی مبتنی بر IPython (Jupyter) هم داره. توسعه این ابزار در سال ۲۰۱۳ در شرکت ScrapingHub شروع شد و جالبه بدونید که بخشی از بودجه‌اش توسط دارپا (DARPA)، آژانس پروژه‌های تحقیقاتی پیشرفته دفاعی آمریکا، تامین شده.
    • Zombie.js: همونطور که قبلا اشاره کردیم، این یه محیط مرورگر شبیه‌سازی شده برای Node.js هست که خیلی سبکه و برای تست‌های سریع استفاده میشه.
    • SimpleBrowser: این یه مرورگر وب بی‌سر هست که به زبان C# نوشته شده و از NET Standard 2.0. پشتیبانی می‌کنه. این ابزار برای توسعه‌دهنده‌هایی که در اکوسیستم دات‌نت کار می‌کنن مناسبه.
    • DotNetBrowser: این هم یه کتابخونه تجاری و غیر رایگان مبتنی بر کرومیوم برای دات‌نته. این کتابخونه یه حالت رندر خارج از صفحه (off-screen) ارائه میده و میشه بدون جاسازی یا نمایش هیچ پنجره‌ای ازش استفاده کرد.

    دوران جدید: وقتی هوش مصنوعی با مرورگر بی‌سر وب‌گردی می‌کنه!

    خب بچه‌ها، تا اینجا با مفهوم و کاربردهای کلاسیک مرورگر بی‌سر آشنا شدیم. اما داستان اینجا تموم نمیشه. اخیرا با ظهور هوش مصنوعی و به خصوص «عامل‌های هوشمند» (AI Agents)، مرورگرهای بی‌سر دوباره به شدت مورد توجه قرار گرفتن و یه نقش جدید و خیلی جالب پیدا کردن.

    قبلا مرورگرهای بی‌سر بیشتر ابزار دست توسعه‌دهنده‌ها برای تست و مهندس‌های سئو برای تحلیل سایت‌ها بودن. اما الان، مرورگرهای جدیدی که با هوش مصنوعی کار می‌کنن، مثل Comet از شرکت Perplexity و Dia از شرکت Browser Company of New York، دارن به این مفهوم یه معنی کاملا جدید میدن. این شرکت‌ها از مرورگرهای بی‌سر استفاده می‌کنن تا به عامل‌های هوشمندشون قدرت بدن که مثل یه انسان واقعی توی وب‌سایت‌ها بگردن، کلیک کنن، اسکرول کنن و با صفحات تعامل داشته باشن تا اطلاعات مورد نیازشون رو به دست بیارن.

    بیایید ببینیم این یعنی چی و چه فرقی با روش‌های قدیمی داره.

    روش قدیمی ربات‌های هوش مصنوعی

    تا همین چند وقت پیش، وقتی شما از یه هوش مصنوعی مثل ChatGPT یه سوال می‌پرسیدید، دو حالت داشت: یا از دانش از پیش آموزش دیده‌اش جواب میداد، یا برای گرفتن اطلاعات جدید، به وب‌سایت‌ها درخواست می‌فرستاد (به این روش میگن Retrieval-Augmented Generation یا RAG). وقتی این ربات‌ها به یه سایت سر می‌زدن، خودشون رو معرفی می‌کردن. یعنی توی درخواستشون یه چیزی به نام «رشته عامل کاربر» (User-Agent String) وجود داشت که مشخص می‌کرد این یه رباته. مثلا ChatGPT-User یا PerplexityBot. اینجوری مدیران سایت‌ها می‌فهمیدن که این بازدیدکننده یه رباته و می‌تونستن تصمیم بگیرن که بهش اجازه دسترسی بدن یا نه.

    روش جدید با مرورگر بی‌سر

    اما این موج جدید رابط‌های هوش مصنوعی، مثل عامل‌های خودکار و مرورگرهای هوش مصنوعی، یه جور دیگه کار می‌کنن. اون‌ها به جای اینکه یه درخواست ساده برای گرفتن اطلاعات بفرستن و بگن «من ربات هستم»، از یه مرورگر بی‌سر استفاده می‌کنن تا واقعا سایت رو مثل یه آدم باز کنن. اون‌ها کلیک می‌کنن، صفحات رو اسکرول می‌کنن و صبر می‌کنن تا همه چیز لود بشه.

    نکته مهم و حساس ماجرا اینجاست: این بازدیدها اغلب خودشون رو به عنوان یه بازدیدکننده استاندارد معرفی می‌کنن. مثلا از رشته عامل کاربر Chromium (موتور متن‌باز گوگل کروم) استفاده می‌کنن. نتیجه‌اش چیه؟ برای صاحب سایت خیلی خیلی سخت میشه که تشخیص بده این بازدیدکننده یه انسان واقعیه یا یه عامل هوش مصنوعی که داره وب‌گردی می‌کنه.

    این موضوع یه سری سوالات و نگرانی‌های جدی برای شرکت‌های رسانه‌ای و ناشران محتوا ایجاد کرده:

    • چقدر از ترافیک سایت ما واقعیه و چقدرش خودکاره؟
    • پلتفرم‌های تحلیل ترافیک چجوری باید این بازدیدهای عامل‌محور رو حساب کنن؟
    • برای تبلیغ‌دهنده‌ها، آیا این جلسات هوش مصنوعی آمار و ارقام رو خراب نمی‌کنه و راه جدیدی برای تقلب باز نمی‌کنه؟

    بر اساس یه گزارش جدید از شرکت Tollbit، مرورگرهای بی‌سر هوش مصنوعی می‌تونن روش‌های معمول مسدود کردن ربات‌ها رو دور بزنن. حتی بعضی از این سرویس‌ها مثل Browserless ادعا می‌کنن که می‌تونن ابزارهای تشخیص ربات رو فریب بدن و حتی کپچاها (CAPTCHA) رو هم حل کنن (همون سوال‌های تصویری که برای تشخیص انسان از ربات استفاده میشه).

    گزارش Tollbit یه نکته جالب دیگه رو هم فاش کرده: «در مورد Perplexity Comet، به نظر میرسه که این عامل از کامپیوتر دسکتاپ خود کاربر برای درخواست صفحات وب استفاده می‌کنه. این باعث میشه درخواست‌ها از یه آدرس IP خانگی (Residential IP) بیان که می‌تونه شرکت‌های ارائه دهنده خدمات تحویل محتوا (CDN) رو گیج کنه و اون‌ها فکر کنن این یه ترافیک قانونی و واقعیه».

    این مشکل چقدر جدیه؟

    هنوز اول راهیم، اما مدیران رسانه‌ها معتقدن که این مرورگرهای بی‌سر هوش مصنوعی یه تهدید برای کسب‌وکارشون محسوب میشن. استفاده از این مرورگرها روز به روز بیشتر میشه. مثلا همین چند وقت پیش، به میلیون‌ها کاربر PayPal و Venmo دسترسی رایگان به مرورگر Comet داده شد. تازه شایعه شده که OpenAI و گوگل هم دارن روی مرورگرهای هوش مصنوعی خودشون کار می‌کنن.

    این موضوع می‌تونه مرحله بعدی جنگ بین ناشران و ربات‌های هوش مصنوعی باشه. ناشران همین الان هم دارن تلاش می‌کنن تا جلوی ربات‌هایی که محتواشون رو بدون اجازه کپی می‌کنن (Scraping) بگیرن. مرورگرهای بی‌سر هوش مصنوعی می‌تونن تمام این تلاش‌ها رو دور بزنن.

    بر اساس داده‌های Tollbit، ترافیک انسانی به سمت سایت‌های ناشران داره کم میشه، در حالی که ترافیک ربات‌ها در حال افزایشه. این گزارش نشون میده که تعداد بازدیدکنندگان انسانی بین سه ماهه اول و دوم سال ۲۰۲۵، ۹.۴ درصد کاهش داشته. در همین حال، نسبت بازدید ربات‌های هوش مصنوعی به بازدیدکنندگان انسانی از ۱ به ۲۰۰ در سه ماهه اول، به ۱ به ۵۰ در سه ماهه دوم رسیده.

    یه نگرانی بزرگ دیگه اینه که تبلیغات سایت‌ها به جای انسان‌ها، به این عامل‌های هوش مصنوعی نمایش داده میشه. به گفته مدیرعامل Tollbit، این اتفاق در حالت عامل هوشمند ChatGPT هم میفته. این موضوع می‌تونه به یه تقلب تبلیغاتی در مقیاس غیرقابل باور تبدیل بشه و ارزش تبلیغات (CPM) رو به شدت پایین بیاره.

    جسی دوایر، مدیر ارتباطات در Perplexity، در جواب به این نگرانی‌ها گفته که هزینه‌ها برای خود Perplexity خیلی بیشتره: «وقتی یه کاربر، دستیار Comet خودش رو به یه سایت می‌فرسته، هزینه این کار برای Perplexity بین ۳۵۰ تا ۲۳۰۰ برابر بیشتر از هزینه ناشر برای نمایش یه صفحه به اون کاربره».

    چجوری میشه این ترافیک رو تشخیص داد؟

    تشخیص این نوع ترافیک خیلی سخته، اما غیرممکن نیست. چندتا سیگنال وجود داره که ناشران می‌تونن دنبالشون بگردن:

    • اگر درخواستی جاوا اسکریپت رو رندر نکنه، به احتمال زیاد از طرف انسان نیست، چون اکثر مرورگرهای امروزی جاوا اسکریپت رو فعال دارن.
    • اگر آدرس IP از یه مرکز داده (Data Center) بیاد، این هم می‌تونه یه نشونه باشه. مشکل اینجاست که خیلی از این درخواست‌ها، همونطور که گفتیم، از IP های خانگی میان.

    در حال حاضر، هیچ پرچم یا نشانه‌ای از طرف این مرورگرها به وب‌سایت فرستاده نمیشه که بگه «این مرورگر توسط هوش مصنوعی کنترل میشه» یا «این مرورگر توسط انسان کنترل میشه». این بزرگ‌ترین چالش فعلی برای ناشرانه.

    محدودیت‌ها و چالش‌های کار با مرورگرهای بی‌سر

    با همه خوبی‌ها و کاربردهای هیجان‌انگیزی که از مرورگرهای بی‌سر گفتیم، این تکنولوژی محدودیت‌های خودشم داره. مهمه که این محدودیت‌ها رو هم بشناسیم تا بدونیم کی و کجا نباید ازشون استفاده کنیم.

    ۱. تمرکز روی باگ‌های اشتباه

    یکی از مشکلات اینه که اجرای تست‌ها با مرورگرهای بی‌سر ممکنه باعث بشه توجه توسعه‌دهنده‌ها به سمت رفع باگ‌هایی بره که فقط در محیط بی‌سر اتفاق میفتن. اما باید یادمون باشه که کاربرهای نهایی هیچوقت با یه مرورگر بی‌سر به سایت ما سر نمی‌زنن. پس اولویت باید همیشه با رفع مشکلاتی باشه که توی یه مرورگر کامل و گرافیکی دیده میشن. این باگ‌های خاص محیط بی‌سر ممکنه به خاطر نحوه بارگذاری فایل‌ها یا مدیریت چیدمان صفحه در حالت بی‌سر باشه و باید در کنار اهداف کلی تست، ارزیابی بشن.

    ۲. چالش‌های دیباگ کردن (Debugging)

    گاهی وقتا توی تست‌های بی‌سر، بعضی صفحات خیلی سریع لود میشن. این سرعت بالا باعث میشه پیدا کردن و رفع کردن خطاهای ناپایدار (inconsistent failures) سخت بشه. مثلا ممکنه یه تست از هر ده بار اجرا، یک بار شکست بخوره چون نتونسته یه دکمه رو پیدا کنه، چون صفحه اونقدر سریع لود شده که اسکریپت تست ازش جا مونده. این نوع تست محدود ممکنه رفتارهای واقعی کاربر رو پنهان کنه و ما رو مجبور کنه که برای پیدا کردن مشکل، به تست‌های دستی یا مبتنی بر GUI برگردیم.

    یکی از راه‌حل‌های این مشکل، تست بین-مرورگری (Cross-browser testing) هست. یعنی اجرای تست‌ها روی نسخه‌های مختلف مرورگرها تا از پوشش قوی‌تر بعد از تغییرات بزرگ در کد، اطمینان حاصل بشه.

    ۳. چالش‌های فنی در عمل

    کار کردن با مرورگرهای بی‌سر همیشه هم راحت نیست. مثلا یه کاربری در ردیت گزارش داده بود که دستورات خط فرمان کروم بی‌سر روی ویندوز براش کار نمی‌کنه. دستوراتی مثل --headless --disable-gpu --dump-dom که باید کد HTML صفحه رو چاپ کنه، یا دستور --screenshot که باید یه عکس از صفحه بگیره، هیچ خروجی تولید نمی‌کردن. بعدا مشخص شد که در نسخه‌های اولیه، مثلا کروم ۵۹، حالت بی‌سر فقط روی مک و لینوکس در دسترس بوده و پشتیبانی از ویندوز در کروم ۶۰ اضافه شده. این نشون میده که همیشه باید به جزئیات فنی و سازگاری پلتفرم‌ها دقت کرد.

    یا مثلا یه توسعه‌دهنده اندروید در Stack Overflow می‌خواست از WebView (کامپوننتی برای نمایش صفحات وب در اپ‌های اندروید) به عنوان یه مرورگر بی‌سر برای اسکرپینگ یه سایت رستوران‌یاب استفاده کنه. اون می‌خواست به صورت خودکار فرم جستجو رو پر کنه و دکمه رو بزنه. کد جاوا اسکریپتی که برای این کار نوشته بود کار نمی‌کرد. این نشون میده که اتوماسیون در محیط‌های خاص مثل موبایل می‌تونه چالش‌های منحصر به فرد خودش رو داشته باشه.

    یکی از بزرگ‌ترین چالش‌ها در اتوماسیون، لاگین کردن و مدیریت کپچاهاست. یه کاربری در فروم Latenode مشکلش این بود که می‌خواست یه سری وظایف فیسبوک رو خودکار کنه. اون می‌تونست با SDK فیسبوک کاربر رو لاگین کنه و لینک‌ها رو جمع‌آوری کنه، اما وقتی می‌خواست این لینک‌ها رو با مرورگر بی‌سر باز کنه، مرورگر بی‌سر به عنوان اون کاربر لاگین نبود. این یه مشکل رایجه که چجوری جلسه (session) لاگین یه کاربر رو به یه مرورگر بی‌سر منتقل کنیم.

    مشکل کپچا هم خیلی جدیه. یه کاربر دیگه می‌گفت وقتی با مرورگر بی‌سر یه سایت رو اسکرپ می‌کنه، بعد از چند بار باز کردن صفحه، سایت شروع می‌کنه به نشون دادن کپچا. اون به این فکر افتاده بود که آیا میشه OCR (تشخیص نوری کاراکترها) رو با مرورگر بی‌سر ترکیب کرد تا کپچاها رو به صورت خودکار حل کنه. این‌ها همه نمونه‌هایی از مشکلات واقعی هستن که نشون میدن کار با این ابزارها همیشه هم یه مسیر صاف و ساده نیست.

    پرسش و پاسخ

    سوال: پس به طور خلاصه، مرورگر بی‌سر دقیقا چیه؟

    جواب: مرورگر بی‌سر یه مرورگر وب معمولیه، فقط بدون اون قسمت گرافیکی و پنجره‌ای که شما می‌بینید. اون در پشت صحنه اجرا میشه، صفحات وب رو مثل یه مرورگر استاندارد بارگذاری و درک می‌کنه، اما شما چیزی روی صفحه نمایش نمی‌بینید. این ویژگی اون رو برای کارهایی مثل تست خودکار، جمع‌آوری داده (اسکرپینگ) و نظارت بر سایت‌ها ایده‌آل می‌کنه. چون نیازی به رندر کردن تصاویر نداره، سرعتش خیلی بیشتره و منابع کمتری مصرف می‌کنه.

    سوال: چه فرقی بین یه مرورگر بی‌سر و یه مرورگر معمولی وجود داره؟

    جواب: هر دوتاشون می‌تونن HTML رو رندر کنن، CSS رو بارگذاری کنن و جاوا اسکریپت رو اجرا کنن. تفاوت اصلی اینه که مرورگر معمولی یه رابط کاربری گرافیکی داره که شما باهاش تعامل می‌کنید و برای وب‌گردی روزمره و تست‌های دستی مناسبه. اما مرورگر بی‌سر اون رابط گرافیکی رو حذف کرده و برای کارهای خودکار و اسکریپت‌نویسی بهینه شده. اون سریع‌تره و برای محیط‌هایی که منابع محدودی دارن (مثل سرورها) عالیه. البته برای تست‌های بصری و چک کردن ظاهر سایت، هنوز هم به مرورگر معمولی نیاز داریم.

    سوال: آیا کروم بی‌سر (Headless Chrome) می‌تونه جاوا اسکریپت رو اجرا کنه؟

    جواب: بله، قطعا! این یکی از بزرگ‌ترین نقاط قوتشه. کروم بی‌سر به طور کامل از اجرای جاوا اسکریپت پشتیبانی می‌کنه. این یعنی می‌تونه محتوای داینامیک و پویای وب‌سایت‌های مدرن رو رندر کنه. این قابلیت برای کارهایی مثل اسکرپ کردن سایت‌هایی که به شدت به جاوا اسکریپت وابسته‌ان یا شبیه‌سازی رفتار کاربر مثل کلیک کردن، تایپ کردن و جابجا شدن بین صفحات، حیاتی و ضروریه.

    سوال: تست بی‌سر (Headless Testing) یعنی چی؟

    جواب: تست بی‌سر یعنی انجام دادن تست‌های مرورگر بدون اینکه رابط کاربری یا GUI مرورگر باز بشه. این روش به تیم‌های توسعه اجازه میده حجم زیادی از تست‌ها رو با حداقل سربار و هزینه اجرا کنن. این کار فرایند تست رو سریع‌تر می‌کنه و به راحتی با چرخه‌های توسعه نرم‌افزار (مثل CI/CD) یکپارچه میشه. در مقابل، تست دستی کندتره، مستعد خطای انسانیه و مقیاس‌پذیر نیست. تست‌های بی‌سر می‌تونن خیلی سریع مشکلات رو بعد از تغییرات در کد یا روی نسخه‌های مختلف مرورگر پیدا کنن.

    سوال: آیا وب‌سایت‌ها می‌تونن تشخیص بدن که یه مرورگر بی‌سر داره بهشون سر می‌زنه؟

    جواب: بله، گاهی وقتا می‌تونن. بعضی سایت‌ها از اسکریپت‌هایی استفاده می‌کنن که نبود رابط کاربری، زمان‌بندی غیرعادی در تعاملات کاربر، یا تفاوت در رفتار جاوا اسکریپت رو چک می‌کنن. مثلا ممکنه رفتار حرکت موس رو شبیه‌سازی کنن یا ببینن آیا بعضی ویژگی‌های مرورگرهای استاندارد وجود داره یا نه. اما مرورگرهای بی‌سر مدرن مثل کروم و فایرفاکس خیلی پیچیده‌تر شدن و سعی می‌کنن رفتار یه کاربر واقعی رو تقلید کنن. توسعه‌دهنده‌ها هم می‌تونن تنظیمات رو طوری تغییر بدن که شبیه‌سازی بهتری انجام بشه و ریسک تشخیص کمتر بشه. با این حال، تشخیص دادن هنوزم یه بازی موش و گربه است.

    سوال: آیا مرورگرهای بی‌سر برای تست عملکرد (Performance Testing) خوبن؟

    جواب: بله، خیلی هم خوبن. اون‌ها می‌تونن جریان‌های کاری کاربر رو شبیه‌سازی کنن و زمان بارگذاری صفحه، رفتار رندر شدن و اجرای جاوا اسکریپت رو بدون اون سربار رابط کاربری، اندازه‌گیری کنن. این به توسعه‌دهنده‌ها کمک می‌کنه تا تاثیر تغییرات کد روی عملکرد سایت رو ارزیابی کنن، به خصوص وقتی می‌خوان تاخیرهای رندر شدن رو تحلیل کنن یا پاسخگویی رابط کاربری رو بهینه کنن. تست عملکرد بی‌سر، یه روش برای تست کردن عملکرد سایت در یه محیط سبک و سریع‌تره.

    منابع

    • [2] Automated Facebook login for server-side headless browsing – Other Questions / Headless Browser – Latenode Official Community
    • [4] 6 Popular Headless Browsers for Web Testing – KeyCDN
    • [6] Automated captcha solving for headless browsing – Other Questions / Headless Browser – Latenode Official Community
    • [8] Use Nightmare.js to Automate Headless Browsing | Linode Docs
    • [10] Headless Browsing with Puppeteer & Playwright on Pipedream
    • [12] Headless Browsers and How They Relate to Click Fraud | CHEQ
    • [14] It is possible to detect and block Chrome headless | Hacker News
    • [16] What are the remaining gaps in the elixir ecosystem? – Chat / Discussions – Elixir Programming Language Forum
    • [18] Headless Chrome Javascript API/headless_shell questions
    • [1] Headless browser – Wikipedia
    • [3] Any way to do headless browsing w/ RSelenium & Firefox? : r/RStudio
    • [5] What Is a Headless Browser and Where Is It Used?
    • [7] Headless Browsing Chrome CLI On Windows Not Working : r/chrome
    • [9] Is server‑side headless browsing supported within Retool workflows? – 💬 Workflows – Retool Forum
    • [11] Web Automation & Headless browsing using Puppeteer. | by Tohju Domo | Another DIY Javascript Experiment | Medium
    • [13] Has anyone found a way to record the UI with headless browsing? – Archive – The Club: Software Testing & Quality Engineering Community Forum | Ministry of Testing
    • [15] javascript – Android Headless Browsing through WebView? – Stack Overflow
    • [17] WTF is headless browsing, and how are AI agents fueling it? – Digiday
  • آموزش کار با uv؛ ابزار جدید مدیریت پکیج پایتون و جایگزین pip

    فکر کنین دارین روی یه پروژه پایتونی کار میکنین و مدام با نصب پکیج‌ها، مدیریت محیط‌های مجازی و چیزهایی شبیه این سر و کار دارین. uv اومده تا این کارها رو با یه روش متفاوت انجام بده. پس بیایین با هم ببینیم این uv اصلا چی هست و چه کارهایی انجام میده.

    uv دقیقا چیه؟ یه ابزار همه‌کاره؟

    خب، بذارین ساده بگم. uv یک ابزار مدیریت پکیج و پروژه برای پایتون هست که با زبان برنامه‌نویسی راست (Rust) نوشته شده. سازنده‌های این ابزار، یعنی شرکت Astral، همون‌هایی هستن که ابزار معروف Ruff رو ساختن که یک لینتر و فرمتر خیلی سریع برای پایتونه.

    هدف اصلی از ساخت uv این بوده که یک جایگزین سریع برای ابزارهای رایجی مثل pip و pip-tools باشه. یعنی شما میتونین بدون اینکه لازم باشه چیز جدیدی یاد بگیرین یا فرایندهای کاریتون رو تغییر بدین، از uv استفاده کنین.

    سازنده‌هاش میگن که uv بخشی از یک هدف بزرگتره به اسم «کارگو برای پایتون» (Cargo for Python). کارگو ابزار مدیریت پروژه و پکیج توی دنیای راست هست که خیلی سریع و قابل اعتماده. حالا تیم Astral میخواد یه همچین تجربه‌ای رو برای برنامه‌نویس‌های پایتون هم به وجود بیاره؛ یعنی یک ابزار واحد که هم سریع باشه، هم قابل اعتماد و هم استفاده ازش راحت باشه.

    جالبه بدونین که uv به صورت یک فایل اجرایی تنها (static binary) عرضه میشه. این یعنی برای نصب و استفاده ازش، خودتون نیازی به پایتون یا راست ندارین. این ویژگی کمک میکنه که دیگه درگیر مدیریت نصب pip روی نسخه‌های مختلف پایتون (مثلا pip در مقابل pip3 یا pip3.7) نباشین.

    سرعت، مهمترین ادعای uv

    یکی از اصلی‌ترین چیزهایی که سازنده‌های uv روش تاکید دارن، سرعته. اونها معیارهایی رو منتشر کردن که نشون میده uv چقدر میتونه سریع‌تر از ابزارهای دیگه باشه.

    • مقایسه با pip و pip-tools: طبق بنچمارک‌ها، uv موقعی که کش (cache) خالی باشه، حدود ۸ تا ۱۰ برابر سریع‌تر از pip و pip-tools عمل میکنه. حالا کش چیه؟ فکر کنین یه انباری دارین که پکیج‌هایی که قبلا دانلود کردین رو اونجا نگه میدارین. دفعه بعدی که به همون پکیج نیاز داشتین، به جای دانلود دوباره، از همون انباری برمیدارین. به این انباری میگن کش. وقتی این کش گرم باشه (یعنی قبلا پکیج‌ها دانلود شدن)، سرعت uv حتی بیشتر هم میشه و به ۸۰ تا ۱۱۵ برابر سریع‌تر از ابزارهای مشابه میرسه.
    • ساخت محیط مجازی (Virtual Environment): برای ساخت محیط‌های مجازی هم uv خیلی سریع‌تره. گفته شده که حدود ۸۰ برابر سریع‌تر از python -m venv و ۷ برابر سریع‌تر از virtualenv عمل میکنه، اونم در حالی که خودش هیچ وابستگی مستقیمی به پایتون نداره.

    برای بهینه کردن سرعت و مصرف حافظه، uv از یک کش سراسری برای ماژول‌ها استفاده میکنه تا از دانلود و ساخت مجدد وابستگی‌ها جلوگیری کنه. همچنین روی فایل‌سیستم‌هایی که پشتیبانی میکنن، از تکنیک‌هایی مثل Copy-on-Write و hardlink استفاده میکنه تا فضای کمتری روی دیسک اشغال بشه.

    ویژگی‌های کلیدی uv در یک نگاه

    اگه بخوایم ویژگی‌های اصلی uv رو لیست کنیم، به موارد زیر میرسیم:

    • جایگزین مستقیم: طراحی شده تا جایگزین ابزارهایی مثل pip, pip-tools, virtualenv و حتی ابزارهای دیگه‌ای مثل pipx, poetry, pyenv و twine بشه.
    • سرعت بالا: همونطور که گفتیم، ۱۰ تا ۱۰۰ برابر سریع‌تر از pip.
    • بهینه‌سازی فضای دیسک: با استفاده از کش سراسری، از نگهداری پکیج‌های تکراری جلوگیری میکنه.
    • نصب آسان: بدون نیاز به نصب راست یا پایتون، با دستوراتی مثل curl یا حتی خود pip نصب میشه.
    • پشتیبانی گسترده: روی سیستم‌عامل‌های مک، لینوکس و ویندوز کار میکنه.
    • مدیریت وابستگی پیشرفته: قابلیت‌هایی مثل بازنویسی نسخه‌های وابستگی (overrides)، استراتژی‌های مختلف برای حل وابستگی‌ها و رزولور (resolver) قدرتمند برای پیدا کردن تضادها داره.
    • پشتیبانی از قابلیت‌های مدرن: از نصب‌های قابل ویرایش (editable installs)، وابستگی‌های گیت (Git)، وابستگی‌های از طریق URL، وابستگی‌های محلی و فایل‌های محدودیت (constraint files) پشتیبانی میکنه.
    • مدیریت پروژه و اسکریپت: نه تنها پکیج‌ها، بلکه خود نسخه‌های پایتون رو هم مدیریت میکنه و میتونه اسکریپت‌هایی که وابستگی‌هاشون داخل خود فایل تعریف شده رو اجرا کنه.
    • فایل قفل سراسری (Universal Lockfile): مدیریت پروژه رو با فایل‌های قفل پایدار و قابل حمل ساده‌تر میکنه.
    • پشتیبانی از Workspace: برای پروژه‌های بزرگ و مقیاس‌پذیر، از فضاهای کاری به سبک کارگو پشتیبانی میکنه.

    چطوری uv رو نصب کنیم؟

    نصب uv خیلی ساده‌ست و چند تا راه مختلف داره.

    1. استفاده از نصب‌کننده‌های مستقل (Standalone Installers): این راحت‌ترین راهه و نیازی به ابزار دیگه‌ای نداره.
    • روی مک و لینوکس:
    curl -LsSf https://astral.sh/uv/install.sh | sh
    • روی ویندوز (با PowerShell):
    powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
    1. نصب از طریق PyPI: اگه پایتون و pip رو روی سیستمتون دارین، میتونین از این روش استفاده کنین.
    • با pip:
    pip install uv
    • یا با pipx:
    pipx install uv
    1. روش‌های دیگه:
    • با Homebrew (روی مک):
    brew install uv
    • با Pacman (روی توزیع‌های لینوکس مثل آرچ):
    pacman -S uv

    نکته مهم: بعد از نصب، ممکنه لازم باشه مسیر نصب uv رو به متغیر محیطی PATH سیستمتون اضافه کنین تا بتونین از هر جایی توی ترمینال بهش دسترسی داشته باشین.

    • برای لینوکس و مک:
    export PATH="$HOME/.local/bin:$PATH"
    • برای ویندوز: باید به صورت گرافیکی به بخش Environment Variables برین و مسیر %USERPROFILE%\.local\bin رو به متغیر Path اضافه کنین.

    بعد از اینکه نصب تموم شد، میتونین با زدن دستور uv توی ترمینال مطمئن بشین که درست نصب شده. اگه با نصب‌کننده مستقل نصب کردین، میتونین با دستور زیر خودش رو آپدیت کنین:

    uv self update

    استفاده از uv به سبک pip

    یکی از بهترین ویژگی‌های uv اینه که لازم نیست از همون اول همه چیز رو از نو یاد بگیرین. uv یک رابط کاربری به اسم uv pip داره که دقیقا مثل دستورات pip و pip-tools کار میکنه. اینطوری میتونین خیلی سریع و راحت به uv مهاجرت کنین.

    ساخت محیط مجازی

    برای ساخت یه محیط مجازی جدید، کافیه این دستور رو بزنین:

    uv venv

    این دستور یه پوشه به اسم .venv میسازه. بعدش باید فعالش کنین:

    • روی مک و لینوکس:
    source .venv/bin/activate
    • روی ویندوز:
    .venv\Scripts\activate

    نصب پکیج‌ها

    نصب پکیج‌ها هم دقیقا مثل pip هست، فقط اولش uv میاد:

    # نصب پکیج فلسک
    uv pip install flask
    
    # نصب از روی فایل requirements.txt
    uv pip install -r requirements.txt
    
    # نصب پروژه فعلی در حالت قابل ویرایش
    uv pip install -e .
    
    # نصب پروژه فعلی از روی دیسک
    uv pip install "package @ ."
    
    # نصب فلسک با قابلیت اضافی dotenv
    uv pip install "flask[dotenv]"

    کامپایل و همگام‌سازی وابستگی‌ها

    اگه با pip-tools کار کرده باشین، با دستورهای pip-compile و pip-sync آشنا هستین. uv هم معادل اینها رو داره:

    • uv pip compile: این دستور مثل pip-compile عمل میکنه. یعنی یک فایل ورودی مثل requirements.in رو میگیره و یک فایل requirements.txt قفل‌شده و دقیق ازش میسازه.
    uv pip compile docs/requirements.in --output-file docs/requirements.txt

    یه قابلیت جالب اینجا پرچم --universal هست. با این پرچم، uv یک فایل requirements.txt میسازه که مستقل از پلتفرمه.

    • uv pip sync: این دستور هم مثل pip-sync هست. یعنی محیط مجازی شما رو دقیقا با پکیج‌هایی که توی فایل requirements.txt لیست شدن، همگام میکنه. نه یکی کمتر، نه یکی بیشتر.
    uv pip sync docs/requirements.txt

    مدیریت کامل پروژه با uv

    علاوه بر جایگزینی pip، uv میتونه مثل ابزارهایی مثل Poetry یا Rye کل پروژه شما رو مدیریت کنه. بیایین یه مثال رو با هم ببینیم.

    1. شروع یک پروژه جدید:
      با دستور init یه پروژه جدید به اسم example میسازیم.
    $ uv init example
    Initialized project `example` at `/home/user/example`
    1. اضافه کردن وابستگی:
      وارد پوشه پروژه میشیم و پکیج ruff رو به عنوان وابستگی اضافه میکنیم.
    $ cd example
    $ uv add ruff
    Creating virtual environment at: .venv
    Resolved 2 packages in 170ms
    Built example @ file:///home/user/example
    Prepared 2 packages in 627ms
    Installed 2 packages in 1ms
    + example==0.1.0 (from file:///home/user/example)
    + ruff==0.5.0
    1. اجرای دستورات در محیط پروژه:
      با دستور run میتونیم دستورات رو داخل محیط مجازی پروژه‌مون اجرا کنیم.
    $ uv run ruff check
    All checks passed!
    1. قفل کردن وابستگی‌ها:
      با دستور lock میتونیم یه فایل قفل (lockfile) از وابستگی‌هامون بسازیم تا مطمئن بشیم همیشه همین نسخه‌ها نصب میشن.
    $ uv lock
    Resolved 2 packages in 0.33ms
    1. همگام‌سازی محیط:
      و در نهایت با دستور sync محیط مجازی رو با فایل قفل همگام میکنیم.
    $ uv sync
    Resolved 2 packages in 0.70ms
    Audited 1 package in 0.02ms

    مدیریت خود پایتون با uv

    یکی از قابلیت‌های خیلی جالب uv اینه که میتونه نسخه‌های مختلف پایتون رو براتون نصب و مدیریت کنه. این یعنی میتونه کار ابزاری مثل pyenv رو هم انجام بده. البته استفاده از این قابلیت اختیاریه و uv با پایتونی که از قبل روی سیستمتون نصب کردین هم به خوبی کار میکنه.

    • نصب چند نسخه پایتون:
    $ uv python install 3.10 3.11 3.12
    Searching for Python versions matching: Python 3.10
    Searching for Python versions matching: Python 3.11
    Searching for Python versions matching: Python 3.12
    Installed 3 versions in 3.42s
    + cpython-3.10.14-macos-aarch64-none
    + cpython-3.11.9-macos-aarch64-none
    + cpython-3.12.4-macos-aarch64-none
    • استفاده از یک نسخه خاص موقع نیاز:
      میتونین موقع ساخت محیط مجازی یا اجرای یک دستور، مشخص کنین که از کدوم نسخه پایتون استفاده بشه. uv اگه اون نسخه رو نداشته باشه، خودش دانلودش میکنه.
    # ساخت محیط مجازی با پایتون 3.12.0
    $ uv venv --python 3.12.0
    Using CPython 3.12.0
    Creating virtual environment at: .venv
    
    # اجرای یک دستور با نسخه 3.8 از PyPy
    $ uv run --python [email protected] -- python --version
    Python 3.8.16 ...
    • پین کردن نسخه پایتون برای یک پوشه:
      میتونین برای یک پوشه یا پروژه خاص، یک نسخه پایتون رو «پین» کنین. uv این کار رو با ساختن یک فایل به اسم .python-version انجام میده.
    $ uv python pin 3.11
    Pinned `.python-version` to `3.11`

    uv برای اسکریپت‌ها و ابزارهای خط فرمان

    uv میتونه کار ابزاری مثل pipx رو هم انجام بده، یعنی اجرای ابزارهای خط فرمانی که به صورت پکیج پایتون منتشر شدن.

    اجرای اسکریپت‌های تک‌فایلی

    فرض کنین یه اسکریپت پایتون دارین و میخوایین وابستگی‌هاش رو هم کنارش تعریف کنین.

    1. یه فایل پایتون به اسم example.py میسازیم:
    import requests; print(requests.get("https://astral.sh"))
    1. حالا با uv بهش میگیم که این اسکریپت به پکیج requests نیاز داره:
    $ uv add --script example.py requests
    Updated `example.py`

    این دستور اطلاعات وابستگی رو به صورت کامنت به خود فایل اضافه میکنه.

    1. در نهایت، با uv run اسکریپت رو اجرا میکنیم. uv خودش یه محیط ایزوله میسازه، وابستگی‌ها رو نصب میکنه و بعد اسکریپت رو اجرا میکنه.
    $ uv run example.py
    Reading inline script metadata from: example.py
    Installed 5 packages in 12ms
    

    نصب و اجرای ابزارهای خط فرمان

    • uvx برای اجرای موقت:
      uvx (که مخفف uv tool run هست) به شما اجازه میده یه ابزار رو بدون اینکه دائمی نصبش کنین، اجرا کنین. مثلا:
    $ uvx pycowsay 'hello world!'
    ...
    < hello world! >
    ------------
    \   ^__^
     \  (oo)\_______
        (__)\       )\/\
            ||----w |
            ||     ||
    • uv tool install برای نصب دائمی:
      اگه میخواین یه ابزار رو همیشه در دسترس داشته باشین، میتونین با این دستور نصبش کنین:
    $ uv tool install ruff
    Resolved 1 package in 6ms
    Installed 1 package in 2ms
    + ruff==0.5.0
    Installed 1 executable: ruff

    حالا میتونین از هر جایی دستور ruff رو اجرا کنین. برای دیدن لیست ابزارهای نصب‌شده هم از uv tool list استفاده میشه.

    قابلیت‌های پیشرفته و خاص uv

    uv چند تا قابلیت ویژه هم داره که اون رو از ابزارهای سنتی متمایز میکنه:

    • استراتژی‌های مختلف حل وابستگی: به صورت پیش‌فرض، uv همیشه سعی میکنه جدیدترین نسخه سازگار از هر پکیج رو نصب کنه. اما شما میتونین با فرستادن --resolution=lowest بهش بگین که پایین‌ترین نسخه سازگار رو نصب کنه. این قابلیت برای توسعه‌دهنده‌های کتابخانه‌ها خیلی مفیده تا مطمئن بشن کدشون با نسخه‌های قدیمی‌تر وابستگی‌ها هم کار میکنه.
    • حل وابستگی برای نسخه‌های مختلف پایتون: pip همیشه وابستگی‌ها رو بر اساس نسخه پایتونی که باهاش در حال اجراست، حل میکنه. اما uv پارامتری به اسم --python-version قبول میکنه. اینطوری شما میتونین حتی اگه روی سیستم‌تون پایتون ۳.۱۲ دارین، یک فایل نیازمندی‌های سازگار با پایتون ۳.۷ تولید کنین.
    • بازنویسی وابستگی‌ها (Overrides): uv مفهومی به اسم «override» داره که از «constraints» توی pip یک قدم فراتره. با استفاده از فایل‌های override (مثلا با -o overrides.txt)، شما میتونین به رزولور کمک کنین و وابستگی‌های تعریف‌شده توسط یک پکیج رو بازنویسی کنین. این قابلیت یه راه فرار برای مواقعی هست که یک پکیج محدودیت‌های اشتباهی (مثلا یک سقف نسخه نادرست) برای وابستگی‌هاش تعریف کرده.

    چشم‌انداز آینده: داستان Rye و «کارگو برای پایتون»

    همونطور که اول گفتیم، uv فقط یه ابزار ساده نیست، بلکه بخشی از یک چشم‌انداز بزرگتره. تیم Astral میخواد یک تجربه مثل «کارگو برای پایتون» بسازه؛ یعنی یک ابزار واحد که از راه‌اندازی اولیه پایتون گرفته تا مدیریت پروژه، پکیج، تست و انتشار، همه چیز رو پوشش بده.

    این چشم‌انداز خیلی شبیه به چیزیه که آرمین روناکر (Armin Ronacher)، خالق فلسک، با پروژه آزمایشی خودش به اسم Rye دنبال میکرد. تیم Astral و آرمین متوجه شدن که اهدافشون خیلی به هم نزدیکه و برای رسیدن به این هدف، نیاز به سرمایه‌گذاری زیادی روی ابزارهای پایه‌ای مثل یک رزولور و نصب‌کننده سریع و چندپلتفرمی هست. uv دقیقا همون ابزار پایه‌ای هست.

    در نتیجه، اونها تصمیم گرفتن با هم همکاری کنن و تیم Astral مسئولیت پروژه Rye رو به عهده گرفت. برنامه اینه که uv در نهایت به یک «کارگو برای پایتون» کامل و آماده برای استفاده تبدیل بشه و یک مسیر مهاجرت راحت از Rye به uv فراهم بشه. تا اون زمان، تیم Astral پروژه Rye رو نگهداری میکنه، اون رو به استفاده از uv در زیرساختش منتقل میکنه و ازش به عنوان یک بستر آزمایشی برای تجربه کاربری نهایی که در ذهن دارن، استفاده میکنه.

    محدودیت‌های فعلی uv

    با همه این خوبی‌ها، uv هنوز یه ابزار در حال توسعه‌ست و مثل هر ابزار دیگه‌ای، محدودیت‌هایی هم داره. مهمه که اینها رو هم بدونیم:

    • سازگاری ناقص با pip: هرچند uv بخش بزرگی از رابط کاربری pip رو پشتیبانی میکنه، اما هنوز همه قابلیت‌های اون رو پوشش نمیده. مثلا از فرمت‌های قدیمی مثل توزیع‌های .egg پشتیبانی نمیکنه. بعضی از این تفاوت‌ها عمدی هستن و بعضی‌ها به خاطر اینه که uv هنوز در مراحل اولیه توسعه قرار داره.
    • فایل requirements.txt وابسته به پلتفرم: uv، مثل pip-compile، فایل‌های requirements.txt تولید میکنه که مخصوص همون پلتفرم و نسخه پایتونی هستن که باهاش اجرا شدن. این برخلاف ابزارهایی مثل Poetry و PDM هست که فایل‌های قفل مستقل از پلتفرم (مثل poetry.lock و pdm.lock) میسازن. در نتیجه، ممکنه فایل requirements.txt ساخته‌شده با uv روی پلتفرم‌ها یا نسخه‌های پایتون مختلف به راحتی قابل استفاده نباشه، مگر اینکه از گزینه‌هایی مثل --universal استفاده بشه.

    ساخت و انتشار پروژه‌ها

    علاوه بر همه کارهایی که تا اینجا گفتیم، uv از ساخت (build) و انتشار (publish) پروژه‌ها هم پشتیبانی میکنه، حتی اگه اون پروژه‌ها با خود uv مدیریت نشن. این یعنی میتونه جایگزین ابزاری مثل twine هم باشه. برای جزئیات بیشتر در این مورد، باید به راهنمای انتشار در مستندات خود uv مراجعه کرد.


    پرسش و پاسخ‌

    سوال ۱: پس uv قراره جای همه ابزارهای پایتون رو بگیره؟
    جواب: هدف بلندمدتش همینه. سازنده‌هاش دوست دارن یه ابزار واحد بسازن که کار pip, virtualenv, pip-tools, pyenv, pipx, poetry و twine رو با هم انجام بده. اما در حال حاضر، تمرکزش روی جایگزینی pip, pip-tools و virtualenv هست.

    سوال ۲: آیا برای استفاده از uv باید زبان راست (Rust) بلد باشم؟
    جواب: اصلا و ابدا. uv با راست نوشته شده، ولی شما برای استفاده ازش نیازی به دونستن راست یا حتی نصب کردنش ندارین. همونطور که برای استفاده از گوگل کروم لازم نیست C++ بلد باشین.

    سوال ۳: اسم uv از کجا اومده و چطوری تلفظ میشه؟
    جواب: توی مستنداتش گفته شده که لطفا فقط بگین «uv». تلفظش هم «یو وی» هست (/juː viː/).

    سوال ۴: اگه من الان از Poetry یا PDM استفاده میکنم، باید سریع بیام سراغ uv؟
    جواب: نه لزوما. خود سازنده‌هاش هم گفتن که uv در حال حاضر برای پروژه‌هایی که حول محور pip و pip-tools ساخته شدن، مناسب‌تره. چون هنوز فایل قفل مستقل از پلتفرم مثل Poetry تولید نمیکنه. اما چشم‌انداز آینده‌ش اینه که به اون سمت هم حرکت کنه.

    سوال ۵: این ابزار توسط چه کسانی پشتیبانی میشه و آیا قابل اعتماده؟
    جواب: uv توسط شرکت Astral پشتیبانی میشه که تیم سازنده Ruff هم هست. Ruff الان یکی از محبوب‌ترین ابزارها توی اکوسیستم پایتونه. uv هم از کتابخونه‌های معتبری مثل PubGrub (که رزولور اصلیش هست) استفاده میکنه و از پروژه‌های موفقی مثل Cargo, pnpm و Bun الهام گرفته. پس میشه گفت پشتوانه قوی‌ای داره.

    منابع

    • [2] Introducing uv: Next-Gen Python Package Manager | by Vishnu Sivan | Medium
    • [4] GitHub – astral-sh/uv: An extremely fast Python package and project manager, written in Rust.
    • [1] uv
    • [3] uv: Python packaging in Rust
  • راهنمای کامل متا تگ‌ها برای سئو

    متا‌تگ‌ها روی چند تا چیز مهم تاثیر میذارن:

    • اینکه توی نتایج جستجوی گوگل چطور دیده بشید: عنوان و توضیحات شما، مثل یک بیلبورد تبلیغاتی دیجیتالی عمل میکنن و مستقیما روی نرخ کلیک (CTR) یا همون تعداد کلیکی که میگیرید، تاثیر دارن.
    • اینکه محتوای شما چطور توی شبکه‌های اجتماعی به اشتراک گذاشته میشه: تگ‌های درست باعث میشن وقتی لینک سایتتون توی فیسبوک، ایکس (توییتر سابق) و لینکدین شیر میشه، ظاهر حرفه‌ای و وسوسه‌کننده‌ای داشته باشه.
    • اینکه موتورهای جستجو چطور سایت شما رو میخزن (کراول میکنن) و ایندکس میکنن: تگ‌های فنی مثل یک نگهبان عمل میکنن و ربات‌های جستجو رو به سمت محتوای باارزش شما راهنمایی میکنن.

    این راهنما قرار نیست یک سری تئوری قدیمی و از مد افتاده رو لیست کنه؛ بلکه یک چارچوب استراتژیک و قطعیه که بر اساس ۲۵ سال تجربه و تست مداوم به دست اومده. ما تگ‌هایی که واقعا تاثیر دارن، اونایی که باید کامل نادیده بگیرید و اینکه چطور همه این‌ها رو توی یک استراتژی سئوی کامل برای رسیدن به نتیجه ترکیب کنید، پوشش میدیم.

    گوگل واقعا چطور صفحات رو رتبه‌بندی میکنه؟

    به لطف پرونده‌های حقوقی مهم و اطلاعاتی که لو رفته، ما الان یک نقشه راه مبتنی بر شواهد از معماری اصلی رتبه‌بندی گوگل داریم. این معماری روی دو تا سیگنال اصلی و سطح بالا ساخته شده:

    • سیگنال کیفیت (Q\*): این یک امتیاز داخلی و در سطح سایته که میزان اعتماد و اعتبار کلی یک دامنه رو میسنجه. این سیگنال، نسخه مدرن همون اصولی هست که پشت آپدیت تاریخی «پاندا» بود؛ آپدیتی که محتوای بی‌کیفیت رو هدف قرار میداد. داشتن یک امتیاز Q\* بالا، مثل یک مجوز ورود برای پتانسیل رتبه‌گیریه.
    • سیگنال محبوبیت (P\*): این سیگنال میسنجه که یک صفحه چقدر بازدیدکننده داره و چقدر باهاش تعامل برقرار میشه. این سیستم به شدت توسط سیستمی به اسم Navboost قدرت میگیره که اطلاعات کلیک agregated (تجمیع شده) کاربران از منابعی مثل کروم رو برای ۱۳ ماه تحلیل میکنه تا الگوهای رضایت کاربر رو شناسایی کنه.

    هر نکته و بهترین روشی که توی این راهنما گفته میشه، برای این طراحی شده که روی این دو تا سیگنال اصلی، تاثیر مثبت بذاره. ما فقط تگ‌ها رو بهینه نمیکنیم؛ ما داریم برای کیفیت و محبوبیت مهندسی میکنیم.

    راهنمای سریع تگ‌های ضروری

    برای اونایی که عجله دارن، این جدول مهم‌ترین متا تگ‌ها و هدف استراتژیکشون رو خلاصه میکنه.

    تگ / عنصرهدف اصلیتاثیر روی رتبه‌بندی
    تگ عنوان (Title Tag)مهم‌ترین عامل سئوی داخلی صفحه. به گوگل و کاربر میگه صفحه درباره چیه.مستقیم و بسیار بالا
    متا دیسکریپشن (Meta Description)مثل یک متن تبلیغاتی برای جذب کلیک در نتایج جستجو عمل میکنه.غیرمستقیم (روی نرخ کلیک و سیگنال محبوبیت تاثیر داره)
    متا روبوتس (Meta Robots)به ربات‌های جستجو دستور میده که با یک صفحه چکار کنن (ایندکس کنن یا نه، لینک‌ها رو دنبال کنن یا نه).مستقیم (میتونه یک صفحه رو از نتایج حذف کنه)
    تگ ویوپورت (Viewport Tag)برای طراحی واکنش‌گرا (ریسپانسیو) و تجربه کاربری خوب در موبایل ضروریه.غیرمستقیم (یک سیگنال مهم برای Mobile-First Indexing)
    تگ‌های اپن گراف (Open Graph)کنترل میکنه که لینک شما موقع اشتراک‌گذاری در فیسبوک، لینکدین و… چطور نمایش داده بشه.بدون تاثیر مستقیم روی گوگل (اما برای برندینگ و ترافیک اجتماعی مهمه)
    تگ‌های توییتر کاردز (Twitter Cards)کنترل میکنه که لینک شما موقع اشتراک‌گذاری در ایکس (توییتر) چطور نمایش داده بشه.بدون تاثیر مستقیم روی گوگل

    بخش اول: سه تفنگدار اصلی – استادی در نمایش نتایج جستجو

    با اینکه ده‌ها متا تگ مختلف وجود داره، فقط سه تاشون تاثیر مستقیم و قدرتمندی روی نحوه نمایش وب‌سایت شما در نتایج جستجوی گوگل دارن. استاد شدن توی این سه تا، غیرقابل مذاکره‌ است.

    ۱.۱ تگ عنوان (Title Tag) – قدرتمندترین ملک شما در صفحه نتایج

    تگ عنوان صفحه (که از نظر فنی یک متا تگ نیست، اما به خاطر اهمیتش همیشه با متا تگ‌ها درباره‌اش صحبت میشه)، بدون شک، مهم‌ترین عنصر تکی سئوی داخلی (On-page SEO) به حساب میاد. این همون لینک آبی رنگ توی نتایج جستجو، متنی که توی تب مرورگرتون میبینید و سیگنال اصلی برای کاربرها و موتورهای جستجو درباره موضوع یک صفحه‌ است.

    یک تگ عنوان عالی فقط ظرفی برای کلمات کلیدی نیست؛ بلکه یک قول دقیق و حساب‌شده‌ است که پلی بین جستجوی کاربر و محتوای شما میزنه.

    بهترین روش‌های استراتژیک:

    • مختصر و توصیفی باشید: سعی کنید یک عنوان کوتاه و مختصر بین ۵۰ تا ۶۰ کاراکتر بنویسید. هر چیزی طولانی‌تر از این احتمالا نصفه نمایش داده میشه.
    • روی قصد کاربر تمرکز کنید: به کلماتی فکر کنید که یک کاربر ممکنه جستجو کنه. آیا عنوان شما دقیقا چیزی که کاربر قراره پیدا کنه رو بازتاب میده؟ عنوانی مثل «راهنمای تنظیمات دوربین» خوبه، اما «راهنمای مبتدی برای تنظیمات دستی دوربین (ISO، دیافراگم، سرعت شاتر)» بهتره، چون با یک قصد جستجوی مشخص‌تر هماهنگه.
    • کلمات کلیدی رو هوشمندانه قرار بدید: اگه طبیعی به نظر میرسه، عبارت کلیدی اصلیتون رو نزدیک به ابتدای عنوان قرار بدید تا چشم کاربر رو بگیره.
    • مطمئن بشید که منحصر به فرد باشه: هر صفحه از سایت شما باید یک تگ عنوان منحصر به فرد داشته باشه. عنوان‌های تکراری موتورهای جستجو رو گیج میکنن و نشانه‌ای از محتوای بی‌کیفیت هستن.
    • از تکرار بیش از حد کلمات کلیدی (Keyword Stuffing) خودداری کنید: تکرار کلمات کلیدی برای کاربرها اسپم به نظر میرسه و برای موتورهای جستجو یک پرچم قرمز فوریه.

    برای اطلاعات عمیق‌تر درباره تگ‌های عنوان، میتونید به مقاله‌ام با عنوان «راهنمای قطعی بهترین روش‌های سئوی تگ عنوان بعد از افشاگری گوگل» مراجعه کنید.

    ۱.۲ متا دیسکریپشن – بیلبورد تبلیغاتی دیجیتال شما

    متا تگ دیسکریپشن خلاصه‌ای از محتوای یک صفحه‌ است. این تگ هیچ تاثیر مثبت مستقیمی روی رتبه‌بندی گوگل نداره، هرچند اسناد لو رفته نشون میدن که ویژگی‌های زیادی با متا دیسکریپشن صفحه در ارتباط هستن که پتانسیل این رو دارن که صفحات یا سایت‌ها رو جریمه (derank) کنن. گوگل در سال ۲۰۰۹ اعلام کرد که از متا دیسکریپشن توی الگوریتم‌های رتبه‌بندیش استفاده نمیکنه، اما متا دیسکریپشن‌های اسپم رو شناسایی میکنه و معمولا این کار رو برای جریمه کردن سایت‌ها انجام میده.

    عمل «پر کردن کلمات کلیدی» (Keyword stuffing) منسوخ شده و با هدف واقعی این تگ در تضاده.

    پس چرا اینقدر مهمه؟ چون با تاثیر گذاشتن روی رفتار کاربر، یک تاثیر غیرمستقیم عظیم داره. کارکرد امروزی متا دیسکریپشن اینه که به عنوان یک متن تبلیغاتی ارگانیک عمل کنه – یک خلاصه جذاب که طراحی شده تا کاربر رو قانع کنه روی نتیجه شما کلیک کنه، نه روی نتایج رقبا.

    خود گوگل میگه دیسکریپشن‌های باکیفیت «میتونن تا حد زیادی کیفیت و کمیت ترافیک جستجوی شما رو بهبود ببخشن».

    این موضوع مستقیما به سیستم‌های قدرتمند گوگل که رضایت کاربر رو میسنجن، خوراک میده. شواهد اخیر تایید میکنه که گوگل از سیستمی به اسم Navboost استفاده میکنه که اطلاعات کلیک تجمیع شده ۱۳ ماه گذشته کاربران رو تحلیل میکنه تا رتبه‌بندی‌ها رو اصلاح کنه.

    متا دیسکریپشن شما، ابزار اصلی شما برای بردن اون کلیکه و مستقیما از سیگنال اصلی «محبوبیت» (P\*) سایت شما پشتیبانی میکنه. یک نرخ کلیک (CTR) بالاتر با همون تعداد نمایش (impression)، میتونه ترافیک به مراتب بیشتری جذب کنه و این متا دیسکریپشن رو به یک اهرم قابل اندازه‌گیری برای رشد تبدیل کنه.

    بهترین روش‌های استراتژیک

    گوگل به متا دیسکریپشن شما نگاه میکنه تا نشانه‌هایی از کیفیت پایین در سراسر سایتتون پیدا کنه. شما یا این تگ رو خالی میذارید (و انتظار چیزی کمتر از حالت عادی رو دارید) یا دیسکریپشن‌های منحصر به فرد مینویسید (و از سیگنال‌های کیفیت منفی دوری میکنید). هیچ اهرم «تقویتی» مشخصی وجود نداره، اما اهرم‌های «تنبیهی» وجود دارن.

    یک استنتاج منطقی نشون میده که یا: ۱. اونها رو خالی بذارید (فرض میشه تلاشی نکردید، انتظار یک جریمه جزئی دارید – همونطور که مت کاتس توصیه کرده بود این یک گزینه است). ۲. اونها رو خراب کنید (فرض میشه تکراریه، تلاش کمی شده و غیره، جریمه بزرگتر). ۳. اونها رو منحصر به فرد بنویسید و با دستورالعمل‌های گوگل هماهنگ باشید (فرض میشه تلاش کردید، جریمه‌ای در کار نیست). هر چیزی که یک متای منحصر به فرد نباشه، جریمه خواهد شد، حتی اگه فقط ۰.۰۰۰۰۰۴ از امتیاز Q\* شما که ۰.۶۴۵۶۷ هست کم کنه. این باز هم یک تنزل رتبه است. شاید حتی حسش نکنید. همچنین ممکنه اولین دومینویی باشه که در زنجیره شکست شما سقوط میکنه.

    متن تبلیغاتی جذاب بنویسید

    دیسکریپشن شما باید مثل یک سخنرانی کوتاه باشه که کاربر رو قانع کنه این صفحه دقیقا همون چیزیه که دنبالشه. فقط کلمات کلیدی رو لیست نکنید؛ یک خلاصه توصیفی و درگیرکننده بنویسید. برای مثال، به جای لیستی از کلمات کلیدی مثل:

    <meta name="description" content="لوازم خیاطی، کاموا، مداد رنگی، چرخ خیاطی، نخ، ماسوره، سوزن">

    گوگل یک خلاصه مفید رو توصیه میکنه:

    <meta name="description" content="هر چیزی که برای دوختن لباس بعدیتون نیاز دارید رو تهیه کنید. دوشنبه تا جمعه از ۸ صبح تا ۵ بعد از ظهر باز هستیم، واقع در منطقه مد.">

    از صدای فعال استفاده کنید («کشف کنید چطور…») و یک فراخوان به اقدام (Call to Action) واضح داشته باشید («بیشتر یاد بگیرید»، «الان خرید کنید»، «پیش‌فاکتور رایگان خود را بگیرید»).

    به طول متن دقت کنید (پیکسل، نه کاراکتر)

    با اینکه از نظر فنی محدودیتی برای طول متا دیسکریپشن وجود نداره، گوگل اسنیپت‌ها (همون خلاصه‌ای که نشون میده) رو در صورت نیاز کوتاه میکنه تا توی عرض دستگاه جا بشن. یک استراتژی مبتنی بر موبایل (Mobile-first) ضروریه.

    • نتایج جستجوی موبایل: حدود ۱۲۰ کاراکتر (تقریبا ۶۸۰ پیکسل) رو هدف بگیرید تا مطمئن بشید پیام اصلیتون دیده میشه.
    • نتایج جستجوی دسکتاپ: فضای بیشتری دارید، تا حدود ۱۵۰-۱۶۰ کاراکتر (تقریبا ۹۲۰ پیکسل).

    اطلاعات مرتبط صفحه رو اضافه کنید

    متا دیسکریپشن جای خیلی خوبیه برای اضافه کردن اطلاعات مشخص و ساختاریافته‌ای که شاید در حالت عادی توی اسنیپت نمایش داده نشن. برای اخبار یا پست‌های وبلاگ، میتونید نویسنده و تاریخ انتشار رو لیست کنید. برای صفحات محصول، میتونید اطلاعات کلیدی مثل قیمت، سن و تولیدکننده رو کنار هم بیارید. گوگل مثال زیر رو برای یک صفحه کتاب ارائه میده:

    <meta name="description" content="نویسنده: الف. ن. نویسنده، تصویرگر: و. گوگ، قیمت: ۱۷.۹۹ دلار، تعداد صفحات: ۷۸۴">

    از کلمات کلیدی برای ارتباط استفاده کنید، نه برای رتبه‌بندی

    با اینکه کلمات کلیدی توی دیسکریپشن روی رتبه‌بندی تاثیر ندارن، اما روی درک کاربر تاثیر میذارن. وقتی عبارت جستجوی کاربر توی دیسکریپشن شما ظاهر بشه، گوگل اون رو bold میکنه که این کار، سیگنال مرتبط بودن رو میده و چشم کاربر رو به سمت خودش میکشه. یکی دو تا از کلمات کلیدی اصلیتون رو به طور طبیعی توی متنتون استفاده کنید.

    برای جلوگیری از پرچم‌های منفی، منحصر به فرد باشید

    دیسکریپشن‌های منحصر به فردی بسازید که هر صفحه خاص رو به دقت توصیف کنن. اطلاعات لو رفته از Content Warehouse گوگل تایید میکنه که گوگل چندین پرچم (flag) مشخص برای شناسایی دیسکریپشن‌های غیرمنحصر به فرد یا قالب‌بندی شده داره. دوری از اینها حیاتیه.

    • boilerplateMetadescription: این پرچم وقتی فعال میشه که یک دیسکریپشن در صفحات زیادی یکسان یا خیلی شبیه باشه.
    • partialBoilerplateMetadescription: گوگل حتی میتونه تشخیص بده که فقط بخشی از دیسکریپشن شما قالب‌بندی شده.
    • rootpageDuplicateMetadescription: وقتی گروهی از صفحات متا دیسکریپشن یکسانی دارن، گوگل میتونه صفحه اصلی یا «ریشه» اون گروه رو شناسایی کنه.

    ننوشتن دیسکریپشن‌های منحصر به فرد باعث میشه صفحات شما برای کاربرها کمتر مفید باشن و احتمال اینکه گوگل اسنیپت اونها رو بازنویسی کنه بیشتر بشه. اگه برای همه صفحات وقت ندارید، URLهای حیاتی مثل صفحه اصلی و صفحات محبوبتون رو در اولویت قرار بدید.

    کیفیت و اعتماد رو حفظ کنید (مخصوصا برای YMYL)

    گوگل فقط دنبال محتوای تکراری نیست؛ کیفیت رو هم ارزیابی میکنه. اطلاعات لو رفته چندین پرچم رو نشون میده که به دیسکریپشن‌های ضعیف اشاره دارن و باید به هر قیمتی ازشون دوری کرد:

    • lowQualityMetadescription (متا دیسکریپشن با کیفیت پایین)
    • fuzzyMetadescription (احتمالا به معنی یک دیسکریپشن مبهم یا نامشخص)
    • badMetadescription (یک پرچم کلی برای کیفیت پایین)

    برای صفحاتی که مربوط به موضوعات «پول شما یا زندگی شما» (YMYL) هستن – مثل سلامت، امور مالی یا ایمنی – استانداردهای اعتماد به شدت بالاست. متا دیسکریپشن باید کاملا دقیق و هماهنگ با نظر متخصصان باشه. هرگونه اغراق یا بیانیه گمراه‌کننده میتونه این پرچم‌های کیفیت رو فعال کنه، به اعتماد کاربر آسیب بزنه و تحت دستورالعمل‌های کیفیت گوگل به صورت منفی دیده بشه.

    زبان رو یکسان نگه دارید

    اطلاعات لو رفته نشون میده که گوگل زبان متا دیسکریپشن رو جدا از محتوای صفحه با متغیرهایی مثل metaDescriptionLanguages ردیابی میکنه و میتونه عدم تطابق رو با پرچم foreignMetadescription شناسایی کنه. مطمئن بشید که متا دیسکریپشن شما به همون زبان اصلی صفحه‌ای هست که توصیفش میکنه تا از گیج شدن و سیگنال‌های منفی احتمالی جلوگیری کنید.

    تولید برنامه‌نویسی شده رو در نظر بگیرید (برای سایت‌های بزرگ)

    برای سایت‌های بزرگ و مبتنی بر پایگاه داده (مثل سایت‌های جمع‌آوری محصول)، نوشتن دیسکریپشن‌های دستی میتونه غیرممکن باشه. در این موارد، تولید برنامه‌نویسی شده مناسبه و توسط گوگل هم تشویق میشه. دیسکریپشن‌های خوب تولید شده به این روش، برای انسان قابل خوندن، متنوع و از داده‌های مخصوص همون صفحه استفاده میکنن و به شما کمک میکنن تا از پرچم boilerplateMetadescription در مقیاس بزرگ دوری کنید.

    ویژگی‌های کلیدی از افشای داده‌های Content Warehouse در سال ۲۰۲۴

    افشای API کانتنت ورهوس گوگل در سال ۲۰۲۴ چندین ماژول و پرچم مرتبط با متا دیسکریپشن رو فاش کرد که روی رتبه‌بندی جستجو تاثیر میذارن. این ماژول‌ها بخشی از سیستم‌های داخلی گوگل مثل Trawler، Alexandria، Mustang و TeraGoogle هستن که محتوای وب رو پردازش و ارزیابی میکنن.

    گوگل سیگنال‌های مختلف متا دیسکریپشن رو ردیابی میکنه تا از کیفیت، منحصر به فرد بودن و مرتبط بودن محتوا مطمئن بشه. برخی از پرچم‌های کلیدی شناسایی شده در این افشاگری شامل موارد زیر هستن:

    پرچم / متغیرتوضیح / هدفماژول(های) مرتبط
    boilerplateMetadescriptionوقتی فعال میشه که یک دیسکریپشن در صفحات زیادی یکسان یا خیلی شبیه باشهMustang, Alexandria
    partialBoilerplateMetadescriptionوقتی تشخیص داده میشه که فقط بخشی از دیسکریپشن قالب‌بندی شدهMustang, Alexandria
    rootpageDuplicateMetadescriptionصفحه اصلی/ریشه رو وقتی چندین صفحه دیسکریپشن یکسان دارن، شناسایی میکنهMustang, TeraGoogle
    lowQualityMetadescriptionبه یک متا دیسکریپشن با کیفیت پایین اشاره دارهAlexandria, TeraGoogle
    fuzzyMetadescriptionمتا دیسکریپشن‌های مبهم یا نامشخص رو پرچم‌گذاری میکنهAlexandria, TeraGoogle
    badMetadescriptionپرچم کلی برای دیسکریپشن‌های با کیفیت پایینAlexandria, TeraGoogle
    foreignMetadescriptionوقتی متا دیسکریپشن به زبانی متفاوت از محتوای صفحه باشه، پرچم‌گذاری میکنهMustang
    metaDescriptionLanguagesزبان متا دیسکریپشن رو جدا از محتوای صفحه ردیابی میکنهMustang

    ماژول‌ها و سیستم‌های مرتبط

    • Trawler: مسئول خزیدن و کشف محتوای جدید در سراسر وب.
    • Alexandria: درک محتوا و تحلیل معنایی رو انجام میده، از جمله ارزیابی وضوح، ابهام و کیفیت متا دیسکریپشن‌ها.
    • Mustang: استخراج و طبقه‌بندی متادیتا رو مدیریت میکنه، از جمله تشخیص متا دیسکریپشن‌های تکراری و مبتنی بر زبان.
    • TeraGoogle: در امتیازدهی و رتبه‌بندی اسناد نقش داره و کیفیت و منحصر به فرد بودن متا دیسکریپشن‌ها رو در نظر میگیره.

    این سیستم‌ها به طور کلی صفحات وب رو بر اساس عوامل متعددی، از جمله کیفیت، منحصر به فرد بودن و مرتبط بودن متا دیسکریپشن‌ها، ارزیابی و رتبه‌بندی میکنن. اطمینان از اینکه هر صفحه یک متا دیسکریپشن منحصر به فرد، واضح و مرتبط به همان زبان محتوای صفحه داشته باشه، برای حفظ دید در نتایج جستجو و جلوگیری از جریمه‌های احتمالی بسیار مهمه.

    کنار اومدن با بازنویسی‌های مداوم گوگل

    یادتون باشه، هیچ تضمینی وجود نداره که گوگل از متا دیسکریپشن شما استفاده کنه. تولید اسنیپت‌ها توسط گوگل «کاملا خودکار» هست و طوری طراحی شده که «به بهترین شکل با جستجوی خاص کاربر مرتبط باشه». مطالعات نشون دادن که گوگل متا دیسکریپشن‌ها رو به طور مکرر بازنویسی میکنه—یک تحلیل در سال ۲۰۲۰ نرخ بازنویسی بیش از ۷۰ درصد رو در موبایل نشون داد.

    متغیرهای کانتنت ورهوس به ما دیدگاه روشنی میدن که چرا گوگل ممکنه یک اسنیپت رو بازنویسی کنه. متا دیسکریپشن شما به احتمال زیاد نادیده گرفته میشه اگه:

    • به عنوان lowQualityMetadescription، badMetadescription یا fuzzyMetadescription پرچم‌گذاری شده باشه.
    • به جای یک خلاصه مفید، لیستی از کلمات کلیدی باشه.
    • به عنوان boilerplateMetadescription پرچم‌گذاری شده باشه چون در صفحات زیاد دیگه‌ای هم استفاده شده.
    • با یک جستجوی خاص و معمولا طولانی (long-tail) کاربر همخوانی خوبی نداشته باشه و گوگل رو وادار کنه یک اسنیپت مرتبط‌تر از بدنه صفحه بیرون بکشه.

    یک استراتژی متعادل: بنویسیم یا ننویسیم؟

    با توجه به اینکه گوگل اغلب دیسکریپشن‌ها رو بازنویسی میکنه، یک استراتژی هوشمندانه و وابسته به نوع صفحه نیازه.

    • استراتژی راهنمایی (نوشتن دیسکریپشن): این بهترین راه برای صفحات اصلی کسب‌وکار، لندینگ پیج‌های کلیدی و دارایی‌های مهم برند شماست که کنترل پیام در اونها اولویت داره. با اینکه گوگل ممکنه باز هم اون رو بازنویسی کنه، دیسکریپشن شما بخشی از مواقع استفاده میشه و به عنوان یک گزینه پشتیبان حیاتی برای اشتراک‌گذاری در شبکه‌های اجتماعی عمل میکنه.
    • استراتژی دینامیک اجباری (حذف دیسکریپشن): این میتونه برای صفحاتی که برای هزاران عبارت جستجوی طولانی رتبه میگیرن، مثل راهنماهای عمیق یا محتوای تولید شده توسط کاربر، موثر باشه. در این موارد، اجازه دادن به گوگل برای اینکه به صورت دینامیک یک اسنیپت مرتبط رو بیرون بکشه، گاهی میتونه منجر به عملکرد بهتری بشه.

    موثرترین رویکرد اینه که تلاشتون رو بر اساس ارزش صفحه اولویت‌بندی کنید:

    • سطح ۱ (صفحات اصلی تجاری/تبدیل): همیشه یک دیسکریپشن دست‌نویس و بهینه‌سازی شده بنویسید.
    • سطح ۲ (صفحات اطلاعاتی با ترافیک بالا): اینها گزینه‌های قوی برای بهینه‌سازی و تست هستن.
    • سطح ۳ (صفحات طولانی/محتوای تولید شده توسط کاربر): حذف دیسکریپشن رو در نظر بگیرید تا از تولید دینامیک گوگل استفاده کنید.
    • سطح ۴ (فروشگاه‌های اینترنتی بزرگ): از قالب‌های برنامه‌نویسی شده استفاده کنید تا منحصر به فرد بودن و مرتبط بودن رو در مقیاس بزرگ تضمین کنید.

    کنترل پیشرفته اسنیپت

    برای وبمسترهایی که به دنبال کنترل دقیق‌تری هستن، گوگل ابزارهایی فراتر از متا دیسکریپشن فراهم کرده. شما میتونید از متا تگ nosnippet برای جلوگیری از نمایش هرگونه اسنیپت، تگ max-snippet:[number] برای پیشنهاد یک طول حداکثری و ویژگی HTML data-nosnippet برای جلوگیری از نمایش بخش خاصی از متن صفحه‌تون در اسنیپت استفاده کنید.

    اینها معمولا با متا تگ meta robots مدیریت میشن و یک لایه کنترل دیگه روی ظاهر صفحه‌تون در نتایج جستجو ارائه میدن.

    ۱.۳ متا تگ روبوتس: نگهبان قطعی

    متا تگ روبوتس قدرتمندترین متا تگ فنیه. این تگ دستورالعمل‌های مستقیمی به خزنده‌های موتور جستجو درباره نحوه برخورد با یک صفحه خاص میده. با اینکه فوق‌العاده مفیده، یک اشتباه اینجا میتونه کل صفحه‌تون – یا حتی کل سایتتون – رو از نتایج جستجو محو کنه.

    این تگ با دو ویژگی اصلی پیاده‌سازی میشه: name (که ربات رو مشخص میکنه، مثلا «googlebot») و content (که دستور رو ارائه میده). استفاده از «robots» برای name همه موتورهای جستجو رو هدف قرار میده.

    <meta name="robots" content="[directive1], [directive2]">

    شواهد از افشای کانتنت ورهوس گوگل

    داده‌های WWWDocInfo از افشای کانتنت ورهوس در سال ۲۰۲۴ دقیقا تایید میکنه که گوگل چطور این دستورالعمل‌ها رو ذخیره میکنه. وقتی گوگل‌بات یک صفحه رو میخزه، متا تگ روبوتس رو تجزیه میکنه و پرچم‌های بولین (boolean) خاصی رو برای اون URL تنظیم میکنه. این فقط یک دستورالعمل تئوری نیست؛ این یک ویژگی کدگذاری شده از اون سند در ایندکس گوگل هست.

    افشاگری نشون میده که متغیرهای زیر استفاده میشن:

    • seenNoindex: اگر noindex وجود داشته باشه، روی true تنظیم میشه.
    • seenNoarchive: اگر noarchive وجود داشته باشه، روی true تنظیم میشه.
    • seenNosnippet: اگر nosnippet وجود داشته باشه، روی true تنظیم میشه.
    • seenNotranslate: اگر notranslate وجود داشته باشه، روی true تنظیم میشه.
    • seenNopreview: اگر nopreview وجود داشته باشه، روی true تنظیم میشه.

    علاوه بر این، پرچم isRoboted نشون میده که آیا یک صفحه توسط فایل robots.txt هاست مسدود شده یا نه، که نشون میده گوگل هم دستورالعمل‌های سطح صفحه و هم سطح فایل رو ذخیره میکنه.

    دستورالعمل‌های ضروری و پرچم‌های متناظرشون

  • index / noindex
    • دستور: noindex به موتورهای جستجو میگه که این صفحه رو در نتایجشون قرار ندن. این برای محتوای ضعیف، نتایج جستجوی داخلی، صفحات تشکر و صفحات ورود ادمین ضروریه. index حالت پیش‌فرض هست و نیازی به مشخص کردنش نیست.
    • پرچم گوگل: وقتی گوگل این دستور رو میبینه، متغیر seenNoindex رو برای اون صفحه روی true تنظیم میکنه. این پرچم یک سیگنال مستقیم برای حذف سند از ایندکس جستجو است.
  • follow / nofollow
    • دستور: nofollow به موتورهای جستجو میگه که هیچ اعتبار رتبه‌بندی رو از طریق لینک‌های موجود در صفحه منتقل نکنن. follow حالت پیش‌فرض هست.
    • نکته: با اینکه یک متغیر خاص برای nofollow در این بخش خاص از افشاگری وجود نداره، تاثیر اون توسط سیستم‌های مدیریت لینک گوگل پردازش میشه و روی نحوه جریان پیدا کردن پیج‌رنک و سایر سیگنال‌های لینک از صفحه تاثیر میذاره.
  • noarchive
    • دستور: از نمایش لینک «Cached» (نسخه ذخیره شده) برای یک صفحه در نتایج جستجو توسط گوگل جلوگیری میکنه.
    • پرچم گوگل: این مستقیما با متغیر seenNoarchive مطابقت داره. اگه true باشه، گزینه مشاهده نسخه ذخیره شده حذف میشه.
  • nosnippet
    • دستور: از نمایش یک اسنیپت متنی یا پیش‌نمایش ویدیو در نتایج جستجو جلوگیری میکنه. این کار گوگل رو مجبور میکنه فقط عنوان و URL رو نشون بده.
    • پرچم گوگل: این به عنوان پرچم seenNosnippet ذخیره میشه. این به وبمسترها کنترل مستقیمی روی نحوه نمایش نتیجه‌شون میده.
  • none
    • دستور: یک میانبر معادل noindex, nofollow.
    • پرچم گوگل: این کار پرچم seenNoindex رو روی true تنظیم میکنه و به سیستم‌های پردازش لینک دستور میده که همه لینک‌های خروجی رو nofollow کنن.
  • یک ترکیب رایج noindex, follow هست. این به موتورهای جستجو میگه که صفحه رو نشون ندن اما هنوز لینک‌ها رو بخزن و اعتبار رو بهشون منتقل کنن. اما حواستون باشه، اگه یک صفحه برای مدت طولانی با پرچم seenNoindex باقی بمونه، گوگل در نهایت خزیدن مکرر اون رو متوقف میکنه و در نتیجه، در نهایت دنبال کردن لینک‌هاش رو هم متوقف خواهد کرد.


    بخش دوم: ساختارشکنی افسانه‌ها: تگ‌های قدیمی و فنی

    ۲.۱ متا تگ کلمات کلیدی (Keywords): یک کالبدشکافی قطعی

    بذارید کاملا واضح بگیم:

    متا تگ کلمات کلیدی توسط گوگل و بینگ برای اهداف رتبه‌بندی نادیده گرفته میشه.

    برای سال‌ها، از این تگ توسط اسپمرها سوءاستفاده میشد. موتورهای جستجوی بزرگ بیش از یک دهه پیش استفاده از اون رو به عنوان یک سیگنال رتبه‌بندی متوقف کردن. صرف هر زمانی روی اون، اتلاف وقت هست و با لو دادن استراتژی کلمات کلیدی شما به رقبا، میتونه بیشتر از اینکه فایده داشته باشه، ضرر بزنه.

    ۲.۲ تگ ویوپورت (Viewport): یک الزام غیرقابل مذاکره برای سئوی موبایل-محور

    در حالی که تگ کلمات کلیدی یک عتیقه است، متا تگ ویوپورت یک ضرورت مدرن محسوب میشه. این تگ برای طراحی واکنش‌گرا (responsive) حیاتیه و یک عنصر بنیادی برای موبایل-دوست بودن (mobile-friendliness) به حساب میاد.

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    این کد به مرورگر میگه که چطور ابعاد و مقیاس صفحه رو کنترل کنه تا با دستگاهی که استفاده میشه، هماهنگ بشه. در دنیای ایندکسینگ موبایل-محور گوگل، داشتن یک تگ ویوپورت مناسب، اختیاری نیست. نبود اون یک سیگنال منفی قویه که میتونه به شدت به دیده شدن شما آسیب بزنه.


    بخش سوم: گسترش جعبه‌ابزار – متا تگ‌ها برای یک وب اجتماعی و متصل

    ۳.۱ تگ‌های اپن گراف برای فیسبوک، لینکدین و بیشتر

    پروتکل اپن گراف (Open Graph) به هر صفحه وبی اجازه میده که وقتی در پلتفرم‌های اجتماعی به اشتراک گذاشته میشه، کارایی غنی داشته باشه. وقتی شما تگ‌های OG رو پیاده‌سازی میکنید، عنوان، توضیحات و تصویری که ظاهر میشه رو کنترل میکنید.

    چهار تگ ضروری OG:

    • og:title: عنوان محتوای شما.
    • og:url: آدرس URL کانونیکال (اصلی) صفحه‌تون.
    • og:image: آدرس URL تصویری که میخواید نماینده محتواتون باشه. از تصاویر باکیفیت با نسبت ابعاد ۱.۹۱:۱ (مثلا ۱۲۰۰ در ۶۳۰ پیکسل) استفاده کنید.
    • og:description: توضیحی از محتوا، شبیه به متا دیسکریپشن شما.

    ۳.۲ توییتر کاردز برای دید بهتر در X

    ایکس (توییتر سابق) از مجموعه متا تگ‌های خودش استفاده میکنه، هرچند اگه این تگ‌ها وجود نداشته باشن، از تگ‌های اپن گراف استفاده خواهد کرد. برای نمایش بهینه، بهتره که توییتر کاردز (Twitter Cards) رو پیاده‌سازی کنید.

    تگ‌های کلیدی توییتر کاردز:

    • twitter:card: نوع کارت. summary_large_image تقریبا همیشه بهترین انتخاب برای تعامل هست.
    • twitter:site: نام کاربری @ حساب ایکس ناشر.
    • twitter:title: عنوان محتوا.
    • twitter:description: توضیحات محتوا.
    • twitter:image: آدرس URL تصویر برای کارت.

    ۳.۳ هدف استراتژیک: ساختن یک «موجودیت متصل» برای اعتماد

    متا تگ‌های اجتماعی یک ابزار حیاتی برای سئوی موجودیت (Entity SEO) هستن. با لینک کردن صریح محتواتون به پروفایل‌های شبکه‌های اجتماعی برندتون، شما دارید سیگنال‌های واضح و قابل خوندن برای ماشین ارائه میدید که وب‌سایت شما رو به یک موجودیت شناخته شده و عمومی متصل میکنه.

    این کار به ساختن یک پروفایل از یک برند «متصل» و قابل اعتماد کمک میکنه، که یک جزء حیاتی از امتیاز کلی کیفیت (Q\*) سایت شماست.


    بخش چهارم: استراتژی پیشرفته – ادغام متا تگ‌ها در اکوسیستم سئوی شما

    ۴.۱ هم‌افزایی متا تگ‌ها و داده‌های ساختاریافته (Schema.org)

    متا تگ‌ها و داده‌های ساختاریافته با هم کار میکنن تا یک تصویر کامل از محتوای شما بسازن.

    • متا تگ‌ها یک خلاصه کلی برای صفحات نتایج جستجو و پلتفرم‌های اجتماعی فراهم میکنن.
    • داده‌های ساختاریافته جزئیات مشخص و دقیقی (مثل زمان پخت، کالری، امتیاز برای یک دستور پخت) رو در یک فرمت قابل خوندن برای ماشین ارائه میدن.

    وقتی گوگل این موجودیت‌های خاص رو از طریق اسکیما (schema) درک میکنه، میتونه به صفحه‌تون با یک ریچ اسنیپت (rich snippet) پاداش بده. این هم‌افزایی بین یک متا دیسکریپشن جذاب (که کاربر رو به کلیک ترغیب میکنه) و داده‌های ساختاریافته دقیق (که یک ریچ اسنیپت چشم‌نواز ایجاد میکنه) یک ترکیب قدرتمند برای به حداکثر رسوندن دیده شدن و نرخ کلیک (CTR) هست.

    ۴.۲ چارچوبی برای بازرسی و بهینه‌سازی متا تگ‌ها در مقیاس بزرگ

    • سایتتون رو بخزید (Crawl): از ابزاری مثل Screaming Frog SEO Spider استفاده کنید تا یک لیست کامل از همه URLها و تگ‌های عنوان و متا دیسکریپشن فعلیشون به دست بیارید.
    • مشکلات کلیدی رو شناسایی کنید: داده‌ها رو فیلتر کنید تا تگ‌های گمشده، تگ‌های تکراری و عنوان‌ها یا دیسکریپشن‌هایی که خیلی بلند یا خیلی کوتاه هستن رو پیدا کنید.
    • تلاشتون رو اولویت‌بندی کنید: با مهم‌ترین صفحاتتون شروع کنید: صفحه اصلی، صفحات دسته‌بندی اصلی و صفحاتی که در حال حاضر ترافیک ارگانیک قابل توجهی دریافت میکنن.
    • پیاده‌سازی و نظارت کنید: تغییراتتون رو اعمال کنید و از گوگل سرچ کنسول برای نظارت بر تاثیر اونها روی ایمپرشن‌ها و نرخ کلیک استفاده کنید.

    بخش پنجم: ضمیمه – سایر متا تگ‌های منسوخ شده و دیگر

    • متا تگ‌های جغرافیایی (Geo): گوگل از متا تگ‌های جغرافیایی برای رتبه‌بندی استفاده نمیکنه. برای هدف‌گیری جغرافیایی از hreflang استفاده کنید.
    • notranslate: استفاده از <meta name="google" content="notranslate"> به گوگل میگه که ترجمه خودکار صفحه‌تون رو ارائه نده.
    • revisit-after: این تگ توسط گوگل نادیده گرفته میشه. به جاش از یک نقشه سایت XML با تگ <lastmod> استفاده کنید.
    • NOODP: این تگ منسوخ شده چون پروژه دایرکتوری باز (DMOZ) در سال ۲۰۱۷ بسته شد.

    این مقاله گزیده‌ای از کتاب سئوی من – Strategic SEO 2025 – است.
    افشاگری: هوبو وب (Hobo Web) از هوش مصنوعی مولد زمانی که به طور خاص درباره تجربیات، ایده‌ها، داستان‌ها، مفاهیم، ابزارها، مستندات ابزار یا تحقیقات خودمان می‌نویسد، استفاده می‌کند. ابزار انتخابی ما برای این فرآیند Google Gemini Pro 2.5 Deep Research است. این کمک تضمین می‌کند که مشتریان ما در مورد هر چیزی که در آن دخیل هستیم و آنچه که ما از آن دفاع می‌کنیم، وضوح داشته باشند. همچنین تضمین می‌کند که وقتی مشتریان از جستجوی گوگل برای پرسیدن سوالی در مورد نرم‌افزار هوبو وب استفاده می‌کنند، پاسخ همیشه در دسترس آنها باشد و تا حد امکان دقیق و به‌روز باشد. تمام محتوا توسط شان اندرسون (Shaun Anderson) به عنوان صحیح تایید شده است. سیاست هوش مصنوعی ما را ببینید.


    پرسش و پاسخ کلاسی

    سوال ۱: اگه گوگل ۷۰ درصد مواقع متا دیسکریپشن رو بازنویسی میکنه، اصلا چرا باید براش وقت بذاریم؟
    جواب: سوال خیلی خوبیه. ببین، حتی اگه فقط ۳۰ درصد مواقع از دیسکریپشن شما استفاده کنه، باز هم ارزشش رو داره، مخصوصا برای صفحات مهم سایتتون مثل صفحه اصلی یا یک محصول پرفروش. شما روی اون ۳۰ درصد دارید کنترل پیام‌تون رو به دست میگیرید. علاوه بر این، وقتی لینک شما توی شبکه‌های اجتماعی مثل فیسبوک یا لینکدین به اشتراک گذاشته میشه، اونها تقریبا همیشه از متا دیسکریپشن شما استفاده میکنن. پس نوشتن اون باعث میشه همه جا حرفه‌ای به نظر برسید.

    سوال ۲: از بین همه این تگ‌ها، اگه قرار باشه فقط روی یکی خیلی تمرکز کنم، کدوم یکی باشه؟
    جواب: بدون شک تگ عنوان (Title Tag). این تگ هم روی رتبه‌بندی شما تاثیر مستقیم داره و هم اولین چیزیه که کاربر توی نتایج جستجو میبینه. یک عنوان خوب میتونه تفاوت بین کلیک گرفتن و نادیده گرفته شدن باشه. پس اگه وقتتون محدوده، اول از همه برید سراغ بهینه‌سازی عنوان‌هاتون.

    سوال ۳: این کارها خیلی فنی و سخت به نظر میرسن. من که برنامه‌نویس نیستم، میتونم انجامشون بدم؟
    جواب: اصلا نگران نباش. امروزه اکثر سیستم‌های مدیریت محتوا مثل وردپرس، ابزارها و افزونه‌هایی (مثل Yoast SEO یا Rank Math) دارن که این کارها رو خیلی ساده میکنن. شما فقط لازمه متن عنوان و دیسکریپشن رو توی فیلدهای مشخص شده وارد کنید. نیازی به کدنویسی مستقیم نیست. مهم اینه که «چی» بنویسید، نه لزوما «چطور» از نظر فنی واردش کنید.

    منابع

    • [1] The Definitive Guide to Meta Tag SEO Best Practices (Description, Robots, Keyword)
  • کامپایلر خودمیزبان یا Self Hosting، وقتی کامپایلر با زبان خودش نوشته می‌شود

    شاید تا حالا این جمله رو شنیده باشید: «کامپایلر زبان اکس با خود زبان اکس نوشته شده». اولین باری که من این رو شنیدم، با خودم گفتم این که غیر ممکنه. مثل این میمونه که بگی یه نفر قبل از اینکه به دنیا بیاد، خودش رو به دنیا آورده. یا مثل همون معمای معروف مرغ و تخم‌مرغه. چطور میشه یه ابزار، خودش رو بسازه؟ این سوالیه که امروز میخوایم با هم به جوابش برسیم. قراره وارد دنیای «خودمیزبانی» یا «سلف هاستینگ» بشیم و ببینیم این ایده چطور کار میکنه، چرا اینقدر مهمه و اصلا چه ارزشی داره.

    این موضوع فقط یه بحث تئوری نیست. درک کردنش به شما یه دید عمیق‌تر نسبت به نحوه ساخته شدن ابزارهایی که هر روز باهاشون کار می‌کنید میده؛ از سیستم‌عاملتون گرفته تا زبان‌های برنامه‌نویسی که دوست دارید.

    خودمیزبانی یعنی چی دقیقا؟

    وقتی میگیم یه برنامه خودمیزبانه، یعنی اون برنامه با استفاده از زبانی نوشته شده که خودش قراره پردازشش کنه. مثلا یه کامپایلر خودمیزبان، کامپایلریه که سورس کدش به همون زبانی نوشته شده که برای کامپایل کردنش طراحی شده.

    این ایده برای خیلی از زبان‌های برنامه‌نویسی مثل Go یا C# یه هدف مهمه. کامپایلرهای این زبان‌ها در نهایت با خود همون زبان‌ها نوشته شدن. اما از طرف دیگه، زبان‌هایی مثل پایتون یا جاوا اسکریپت خودمیزبان نیستن. مثلا خود پایتون با زبان C نوشته شده و این موضوع هیچ مشکلی هم برای جامعه پایتون یا C ایجاد نکرده.

    این مفهوم فقط به کامپایلرها محدود نمیشه. خیلی از نرم‌افزارهای دیگه هم خودمیزبان هستن:

    • سیستم‌عامل‌ها: یه سیستم‌عامل وقتی خودمیزبانه که ابزارهای لازم برای ساختن نسخه‌های جدیدش، روی خود همون سیستم‌عامل اجرا بشن. مثلا شما میتونید نسخه جدید ویندوز رو روی یه کامپیوتر که در حال حاضر ویندوز روش نصبه، بسازید و کامپایل کنید.
    • برنامه‌های دیگه: کرنل‌ها (هسته سیستم‌عامل)، اسمبلرها (برنامه‌هایی که کد اسمبلی رو به کد ماشین تبدیل میکنن)، مفسرهای خط فرمان (مثل ترمینال) و حتی نرم‌افزارهای کنترل نسخه (مثل گیت) هم معمولا خودمیزبان هستن.

    حالا این سوال پیش میاد: آیا خودمیزبانی یه جور نشونه بلوغ برای یه زبانه؟ یا فقط یه کار اضافیه که از اهداف اصلی منحرفمون میکنه؟ برای جواب دادن به این سوال، اول باید بزرگترین چالش این مسیر رو بشناسیم.

    معمای مرغ و تخم‌مرغ: مشکل بوت‌استرپینگ

    خب، رسیدیم به همون مشکل اصلی. اگه کامپایلر زبان اکس قراره با خود زبان اکس نوشته بشه، پس اولین نسخه این کامپایلر رو کی یا چی باید کامپایل کنه؟ ما که هنوز کامپایلری برای زبان اکس نداریم! این دقیقا همون مشکل «بوت‌استرپینگ» یا به قول معروف، معمای مرغ و تخم‌مرغه.

    برای اینکه یه سیستم بتونه به مرحله خودمیزبانی برسه، اولش به یه سیستم دیگه نیاز داره تا توسعه پیدا کنه. فرض کنید دارید برای یه کامپیوتر یا سیستم‌عامل کاملا جدید برنامه مینویسید. شما هم به یه سیستم برای اجرای نرم‌افزارهای توسعه نیاز دارید و هم به خود اون نرم‌افزارها برای نوشتن و ساختن سیستم‌عامل. این یه دور باطله.

    راه حل این مشکل استفاده از چیزی به اسم «کراس کامپایلر» (Cross Compiler) یا «کراس اسمبلر» هست. کراس کامپایلر یه کامپایلره که روی یه پلتفرم (مثلا ویندوز) اجرا میشه، اما کدی که تولید میکنه برای یه پلتفرم دیگه (مثلا یه کنسول بازی یا یه برد الکترونیکی) قابل اجراست. اینطوری میشه برای یه ماشینی که هنوز کامپایلر خودمیزبان نداره، نرم‌افزار ساخت.

    وقتی نرم‌افزار اولیه ساخته شد، میشه اون رو با استفاده از ابزارهایی مثل فلش مموری، دیسک یا کابل JTAG به سیستم مقصد منتقل کرد. این روش دقیقا همون کاریه که برای ساختن نرم‌افزار برای کنسول‌های بازی یا گوشی‌های موبایل انجام میدن؛ چون این دستگاه‌ها معمولا ابزارهای توسعه رو روی خودشون ندارن.

    وقتی سیستم به اندازه کافی بالغ شد و تونست کد خودش رو کامپایل کنه، دیگه نیازی به اون سیستم اولیه نیست و وابستگی از بین میره. در این نقطه میگیم اون سیستم «خودمیزبان» شده.

    فرآیند بوت‌استرپینگ برای یک کامپایلر

    این فرآیند برای کامپایلرها هم دقیقا به همین شکله. چون کامپایلرهای خودمیزبان هم با همون مشکل بوت‌استرپینگ درگیرن، اولین نسخه از کامپایلر یه زبان جدید باید با یه زبان موجود نوشته بشه. توسعه‌دهنده‌ها ممکنه از اسمبلی، C/C++ یا حتی زبان‌های اسکریپتی مثل پایتون یا Lua برای ساختن نسخه اولیه استفاده کنن.

    وقتی زبان جدید به اندازه کافی کامل و قدرتمند شد، توسعه کامپایلر به خود اون زبان منتقل میشه. از اون به بعد، کامپایلر میتونه خودش رو بسازه و کامپایل کنه.

    یه مثال خیلی جالب، داستان ساخت کامپایلر زبان اسکالا (Scala) هست. نسخه اولیه کامپایلر اسکالا با جاوا نوشته شده بود. اما نسخه‌های بعدی (مثلا نسخه ۲) خودمیزبان شدن، یعنی با خود اسکالا نوشته شدن. یا مثلا زبان کافی‌اسکریپت (CoffeeScript) که در ابتدا کامپایلرش با زبان روبی (Ruby) نوشته شده بود.

    پس اگه یه نفر به شما گفت «کامپایلر کافی‌اسکریپت با کافی‌اسکریپت نوشته شده»، این جمله یه کم گمراه‌کننده‌ست. جمله دقیق‌تر اینه:

    • نسخه ۶ کامپایلر کافی‌اسکریپت با نسخه ۵ نوشته شده، نسخه ۷ با نسخه ۶، نسخه ۸ با نسخه ۷ و همینطور الی آخر.

    این فرآیند مثل بالا رفتن از یه نردبونه. شما با استفاده از نسخه فعلی، یه نسخه جدید و بهتر از نردبون رو میسازید، بعد روی نردبون جدید میرید و نردبون قبلی رو دور میندازید. این چرخه همینطور ادامه پیدا میکنه.

    یه مثال عملی (و یه کم خنده‌دار): زبان برنامه‌نویسی گلابی!

    برای اینکه این فرآیند رو بهتر بفهمیم، بیاید با هم یه زبان برنامه‌نویسی خیالی و مسخره به اسم «گلابی» (Gluby) بسازیم و کامپایلرش رو خودمیزبان کنیم. این مثال رو رابرت هیتون برای آموزش همین مفهوم ساخته.

    قوانین زبان گلابی خیلی ساده‌ست:

    • این زبان از نظر سینتکس دقیقا مثل زبان روبی (Ruby) هست.
    • فقط یه فرق کوچیک داره: به جای علامت مساوی (=)، باید از کلمه انگلیسی EQUALS استفاده کنید.
    • شما حق ندارید از کلمه EQUALS در هیچ جای دیگه‌ای از برنامه‌تون استفاده کنید، وگرنه همه چیز خراب میشه!

    حالا میخوایم برای این زبان یه کامپایلر خودمیزبان بنویسیم.

    مرحله اول: نسخه صفر کامپایلر گلابی (نوشته شده با پایتون)

    همونطور که گفتیم، برای شروع به یه زبان دیگه نیاز داریم. ما اینجا از پایتون استفاده می‌کنیم. پس نسخه صفر (v0) کامپایلر گلابی ما یه برنامه پایتونیه. کار این برنامه خیلی ساده‌ست:

    • یه فایل با پسوند .gl (فایل سورس گلابی) رو به عنوان ورودی میگیره.
    • تمام کلمات EQUALS رو پیدا میکنه و اونها رو با علامت = جایگزین میکنه.
    • خروجی رو توی یه فایل جدید با پسوند .blc ذخیره میکنه.

    این فایل خروجی در واقع یه کد روبی معتبره که میشه با مفسر روبی اجراش کرد. کد پایتونش چیزی شبیه این میشه:

    from functools import reduce
    import sys
    if __name__ == '__main__':
        input_filename = sys.argv[1]
        input_filename_chunks = input_filename.split('.')
        output_filename = "%s.blc" % "".join(input_filename_chunks[0:-1])
        # "=" is 61 in ASCII
        swaps = [(chr(61), 'EQUALS')]
        with open(input_filename) as input_f:
            with open(output_filename, 'w+') as output_f:
                # Read all the lines in the source code
                for l in input_f.readlines():
                    # Make the swaps
                    new_l = reduce(
                        (lambda running_l, sw: running_l.replace(swap[1], swap[0])),
                        swaps,
                        l
                    )
                    # Write out a line to the compiled file
                    output_f.write(new_l)

    خب، ما الان یه کامپایلر اولیه داریم. این کامپایلر میتونه کد گلابی رو به کد روبی تبدیل کنه. حالا وقت مرحله بعده.

    مرحله دوم: نسخه یک کامپایلر گلابی (نوشته شده با خود گلابی!)

    حالا که زبان گلابی به اندازه کافی قدرتمند شده (چون تمام قدرت روبی رو به ارث برده)، میتونیم ازش برای بازنویسی خود کامپایلر استفاده کنیم. نسخه یک (v1) کامپایلر گلابی، با سینتکس خود گلابی نوشته میشه. یعنی به جای = از EQUALS استفاده می‌کنیم.

    input_filename EQUALS ARGV[1]
    input_filename_chunks EQUALS input_filename.split('.')
    output_filename EQUALS "#{input_filename_chunks[0...-1].join('')}.blc"
    # Use ASCII 69 instead of "E" to make sure we don’t replace the string
    #"EQUALS" when compiling this program.
    swaps EQUALS [[61.chr, 69.chr + 'QUALS']]
    File.open(input_filename, "r") do |input_f|
        File.open(output_filename, "w+") do |output_f|
            input_f.each_line do |l|
                new_l EQUALS swaps.reduce(l) do |memo, swap|
                    memo.gsub(swap[1], swap[0])
                end
            end
            output_f.puts(new_l)
        end
    end

    حالا اون لحظه جادویی فرا میرسه. ما این کد (که سورس نسخه ۱ کامپایلره) رو به کامپایلر نسخه صفر (همون برنامه پایتونی) میدیم. برنامه پایتونی تمام EQUALS ها رو با = عوض میکنه و یه فایل خروجی به ما میده. این فایل خروجی، یه برنامه روبی کاملا قابل اجراست.

    و این برنامه قابل اجرا چیه؟ این خود کامپایلر نسخه یک گلابیه

    از این لحظه به بعد، ما دیگه هیچ نیازی به اون کد پایتونی اولیه نداریم. میتونیم برای همیشه حذفش کنیم. چرا؟ چون الان یه کامپایلر جدید داریم که هم سورس کدش به زبان گلابیه و هم نسخه قابل اجراش موجوده. برای کامپایل کردن نسخه‌های بعدی کامپایلر (مثلا نسخه ۲)، از همین نسخه ۱ استفاده می‌کنیم. زبان گلابی رسما خودمیزبان شد!

    سازنده این زبان خیالی در ادامه به شوخی میگه که داره روی نسخه ۲ کار میکنه و میخواد به جای کلمه end از عبارت ALL_HAIL_ROBERT استفاده کنه.

    چرا این همه دردسر؟ مزایای خودمیزبانی چیه؟

    خب، حالا که فهمیدیم خودمیزبانی چیه و چطور کار میکنه، سوال اصلی اینه: چرا یه تیم باید این همه هزینه و ریسک رو قبول کنه و کامپایلرش رو خودمیزبان کنه؟ این کار چه فایده‌ای داره؟

    شرکت مایکروسافت یه تجربه بزرگ در این زمینه داره. کامپایلرهای زبان سی‌شارپ از نسخه ۱.۰ تا ۶.۰ با زبان C++ نوشته شده بودن. اما برای نسخه ۶.۰، تیم رو به دو بخش تقسیم کردن: یه تیم به توسعه ویژگی‌های جدید روی همون کدبیس C++ ادامه داد و تیم دوم وظیفه داشت کل کامپایلر رو از اول با خود سی‌شارپ بازنویسی کنه. این یه تصمیم فوق‌العاده پرهزینه و پرریسک برای یکی از مهمترین محصولات مایکروسافت بود. پس حتما دلایل خیلی خوبی براش داشتن. بیاید این دلایل رو بررسی کنیم:

    ۱. بهترین تست ممکن برای زبان (Dogfooding)

    این یکی از مهمترین مزایای خودمیزبانیه که تقریبا همه بهش اشاره میکنن. اصطلاح «Dogfooding» یعنی «غذای سگ خودت رو بخوری». یعنی از محصولی که خودت تولید میکنی، خودت هم استفاده کنی.

    • یه تست واقعی و پیچیده: یه کامپایلر برنامه خیلی پیچیده‌ایه. اگه یه زبان اونقدر قدرتمند باشه که بشه باهاش یه کامپایلر نوشت، این نشون میده که احتمالا برای نوشتن طیف وسیعی از برنامه‌های پیچیده دیگه هم مناسبه. این یه جور «آزمون تورنسل» برای زبان محسوب میشه.
    • پیدا کردن سریع باگ‌ها و مشکلات عملکردی: وقتی توسعه‌دهنده‌های کامپایلر هر روز از کامپایلر خودشون برای کامپایل کردن خود کامپایلر استفاده میکنن، خیلی سریع با باگ‌ها، مشکلات عملکردی و نقاط ضعف زبان روبرو میشن. تیم سی‌شارپ میخواست کامپایلر جدیدشون بتونه برنامه‌های چند میلیون خطی رو به راحتی مدیریت کنه. داشتن خود کامپایلر به عنوان یه کیس تستی بزرگ، بهشون خیلی کمک کرد تا مشکلات رو سریع پیدا و حل کنن.
    • بررسی جامع سازگاری: کامپایلر باید بتونه کد آبجکت خودش رو بازتولید کنه. این یه بررسی سازگاری خیلی کامله که نشون میده کامپایلر کارش رو درست انجام میده.

    یه نویسنده در این مورد از تجربه شخصی خودش میگه. اون مجبور بوده با یه کامپایلر معروف که خودمیزبان نیست کار کنه و میگه تقریبا هر دو روز یک بار با خطای segfault (یه نوع کرش کردن برنامه) مواجه میشده. اون با خودش فکر میکنه که اگه طراحان اون کامپایلر مجبور بودن هر روز ازش استفاده کنن، حتما این مشکلات خیلی زودتر حل میشد.

    ۲. راحتی و بهره‌وری تیم توسعه

    • تخصص در یک زبان: وقتی کامپایلر خودمیزبانه، توسعه‌دهنده‌ها و کسایی که باگ‌ها رو گزارش میدن، فقط کافیه به همون زبان مسلط باشن. این کار باعث میشه تعداد زبان‌هایی که تیم باید بدونه کمتر بشه. در حالت عادی، تیم باید زبان ماشین (یا اسمبلی)، زبان هدف (که کامپایلر براش ساخته میشه) و زبان سورس کامپایلر رو بلد باشه. اما در حالت خودمیزبان، این تعداد به دو زبان کاهش پیدا میکنه.
    • استفاده از ویژگی‌های سطح بالا: توسعه‌دهنده‌ها میتونن از ویژگی‌های راحت‌تر و سطح بالاتر زبان خودشون برای توسعه کامپایلر استفاده کنن. تیم سی‌شارپ همگی برنامه‌نویس‌های متخصص سی‌شارپ بودن و شکی نبود که میتونن با این زبان خیلی بهره‌وری بالایی داشته باشن. سی‌شارپ هم به طور خاص طوری طراحی شده بود که یه جایگزین امن‌تر و پربازده‌تر برای کدبیس‌های بزرگ C++ باشه.

    ۳. بهبود خودکار کامپایلر

    این یکی از جالب‌ترین مزایاست. هر بهبودی که در بخش بک‌اند (Backend) کامپایلر ایجاد میشه، نه تنها روی برنامه‌هایی که کاربران مینویسن تاثیر مثبت داره، بلکه روی خود کامپایلر هم تاثیر میذاره. یعنی وقتی شما کامپایلر رو طوری بهینه میکنید که کد سریع‌تری تولید کنه، دفعه بعدی که خود کامپایلر رو با خودش کامپایل میکنید، نسخه جدید کامپایلر هم سریع‌تر اجرا میشه! این یه چرخه بهبود مستمر ایجاد میکنه.

    ۴. تاثیر در طراحی خود زبان

    استفاده از زبان برای ساختن کامپایلر خودش، میتونه روی طراحی ویژگی‌های جدید زبان هم تاثیر بذاره. البته تیم سی‌شارپ مراقب بود که در دام طراحی زبان فقط برای نیازهای تیم کامپایلر نیفته، اما در طول مسیر به چند تا مشکل برخوردن که باعث شد ویژگی‌های جدیدی به زبان اضافه بشه.

    برای مثال، آندرس هایلزبرگ (طراح اصلی سی‌شارپ) همیشه با اضافه کردن «فیلترهای استثنا» (exception filters) مخالف بود، در حالی که این ویژگی در زبان ویژوال بیسیک وجود داشت. اما تیم کامپایلر در حین کار چند تا مورد استفاده خیلی خوب براش پیدا کردن و تونستن آندرس رو قانع کنن که این ویژگی به سی‌شارپ هم اضافه بشه.

    ۵. مشارکت بیشتر جامعه

    اگه کامپایلر با یه زبان شناخته‌شده و محبوب نوشته شده باشه، احتمال اینکه جامعه برنامه‌نویس‌ها در توسعه‌ش مشارکت کنن خیلی بیشتره. زبان سی‌شارپ میلیون‌ها کاربر داشت. وقتی کامپایلر جدیدش به اسم «رازلین» (Roslyn) به صورت اوپن سورس منتشر شد، حمایت و مشارکت جامعه در ده سال گذشته برای این پروژه خیلی مفید بوده.

    ۶. ساخت اکوسیستم ابزارها

    یکی از اهداف اصلی تیم سی‌شارپ از بازنویسی کامپایلر، فقط خودمیزبانی نبود. اونها میخواستن تحلیل‌گرهای لغوی، سینتکسی و معنایی کامپایلر رو به صورت یه سری سرویس در بیارن که هر کسی بتونه ازشون استفاده کنه، نه فقط تیم IDE. اونها میدونستن که داخل خود مایکروسافت نیاز زیادی به یه کتابخونه از سرویس‌های کامپایلر وجود داره.

    اونها پیش‌بینی کردن که یه اکوسیستم بزرگ از افزونه‌های تحلیل کد برای IDE ها به وجود میاد. و زبان طبیعی برای نوشتن این افزونه‌ها چی بود؟ خود سی‌شارپ. پس منطقی بود که خود «کامپایلر به عنوان سرویس» هم با سی‌شارپ نوشته بشه.

    نگاهی به تاریخ: اولین‌ها و مهم‌ترین‌ها

    ایده خودمیزبانی یه ایده جدیده نیست و تاریخچه جالبی داره. بیاید چند تا از موارد مهم رو با هم مرور کنیم.

    • Lisp (۱۹۶۲): اولین کامپایلر خودمیزبان (به جز اسمبلرها) برای زبان لیسپ توسط هارت و لوین در MIT در سال ۱۹۶۲ نوشته شد. داستانش خیلی جالبه. اونها یه کامپایلر لیسپ رو با خود لیسپ نوشتن و اون رو داخل یه مفسر لیسپ که از قبل وجود داشت تست کردن. اونها اینقدر کامپایلر رو بهبود دادن تا به جایی رسید که تونست سورس کد خودش رو کامپایل کنه. در اون لحظه، کامپایلر رسما خودمیزبان شد. این تکنیک وقتی عملیه که از قبل یه مفسر برای اون زبان وجود داشته باشه.
    • Unix و زبان C: کن تامپسون توسعه یونیکس رو در سال ۱۹۶۸ شروع کرد. اون برنامه‌ها رو روی یه کامپیوتر بزرگ GE-635 مینوشت و کامپایل میکرد، بعد اونها رو به یه کامپیوتر کوچیکتر به اسم PDP-7 منتقل میکرد تا تستشون کنه. بعد از اینکه هسته اولیه یونیکس، مفسر فرمان، ویرایشگر، اسمبلر و چند تا ابزار دیگه کامل شدن، سیستم‌عامل یونیکس خودمیزبان شد. یعنی از اون به بعد میشد برنامه‌ها رو روی خود همون PDP-7 نوشت، کامپایل کرد و تست کرد.
    • TMG: یه داستان فوق‌العاده دیگه مربوط به داگلاس مک‌ایلروی هست. اون یه کامپایلر-کامپایلر (برنامه‌ای که کامپایلر میسازه) به اسم TMG رو روی کاغذ با خود سینتکس TMG نوشت. بعدش به قول خودش «تصمیم گرفت تیکه کاغذش رو به تیکه کاغذش بده». یعنی خودش شخصا و به صورت دستی، فرآیند کامپایل رو روی کاغذ انجام داد و یه خروجی اسمبلی تولید کرد. بعد اون کد اسمبلی رو تایپ کرد و روی PDP-7 کن تامپسون اسمبل کرد و اجرا کرد!
    • پروژه گنو (GNU): توسعه سیستم گنو به شدت به GCC (مجموعه کامپایلرهای گنو) و گنو ایمکس (یه ویرایشگر محبوب) وابسته است. این ابزارها امکان توسعه پایدار و مستقل نرم‌افزارهای آزاد رو برای پروژه گنو فراهم کردن.

    امروزه زبان‌های خیلی زیادی کامپایلرهای خودمیزبان دارن. این لیست فقط بخشی از اونهاست:

    AdaCC++C#
    GoHaskellJavaKotlin
    LispPython (PyPy)RustScala
    SwiftTypeScriptZigو خیلی‌های دیگه…

    آیا خودمیزبانی همیشه بهترین راهه؟

    با تمام مزایایی که گفتیم، خودمیزبانی یه سری چالش هم داره. همونطور که توسعه‌دهنده زبان Leaf اشاره کرد، «دردسر بوت‌استرپینگ» یه مشکل واقعیه و میتونه تمرکز تیم رو از اهداف اصلی زبان، مثل اضافه کردن ویژگی‌های جدید، منحرف کنه.

    یه سوال جالب دیگه هم در این مورد مطرح میشه: آیا زبانی که برای کامپایل شدن به یه کتابخونه بزرگ مثل LLVM وابسته است، واقعا خودمیزبانه؟

    بعضی‌ها معتقدن که اگه کامپایلر شما نتونه سورس کد LLVM رو هم کامپایل کنه، پس کاملا خودمیزبان نیست. شاید خودمیزبانی واقعی زمانی اتفاق بیفته که زبان شما بک‌اند (Backend) خودش رو هم داشته باشه، حتی اگه خیلی ضعیف باشه. در این صورت، LLVM فقط یه هدف (Target) دیگه در کنار بقیه هدف‌ها محسوب میشه. این بحث نشون میده که مفهوم خودمیزبانی میتونه لایه‌های مختلفی داشته باشه.

    از کجا شروع کنیم؟ راهنمای عملی برای کنجکاوها

    اگه به این موضوع علاقه‌مند شدید و دوست دارید بدونید چطور میشه یه کامپایلر رو خودمیزبان کرد، اینجا یه نقشه راه کلی بر اساس تجربیات دیگران وجود داره. فرآیند برای زبان‌های مفسری و کامپایلری یه کم متفاوته.

    برای زبان‌های مفسری/دینامیک:

    1. یه رانتایم (Runtime) اولیه با یه زبان موجود مثل C، راست یا گو بنویسید.
    2. این رانتایم رو گسترش بدید تا بتونه با فایل سیستم کار کنه و فرمت‌های اجرایی نیتیو رو بفهمه.
    3. حالا دوباره همون رانتایم رو این بار با استفاده از زبان خودتون بازنویسی کنید.
    4. رانتایمی که تازه نوشتید رو با استفاده از رانتایم اولیه اجرا کنید و اون رو به یه فایل اجرایی خروجی بگیرید.
    5. تبریک میگم! مفسر یا REPL شما خودمیزبان شد!

    یه مثال خوب در این زمینه، زبان اینکو (Inko) هست. کامپایلر فعلیش با روبی نوشته شده و سازنده‌ش داره تلاش میکنه اون رو خودمیزبان کنه. در اینکو، عملیات‌های سطح پایین (مثل باز کردن فایل) به صورت دستورات ماشین مجازی (VM instructions) پیاده‌سازی شدن. برای مثال، کدی که پروسس در حال اجرا رو برمیگردونه این شکلیه:

    def current -> Process {
      _INKOC.process_current
    }

    اینجا _INKOC.process_current یه دستور اولیه‌ست که کامپایلر اون رو به یه دستور ماشین مجازی تبدیل میکنه. این روش به سازنده اینکو اجازه میده بدون تغییر سینتکس زبان، این قابلیت‌های سطح پایین رو اضافه کنه.

    برای زبان‌های کامپایلری (با استفاده از LLVM):

    1. یه فرانت‌اند (Frontend) بنویسید که زبان شما رو بگیره و اون رو به یه نمایش میانی (Intermediate Representation یا IR) برای یه بک‌اند مثل LLVM یا GCC تبدیل کنه.
    2. یه بک‌اند با زبان خودتون بنویسید که این نمایش میانی رو بگیره و به اسمبلی یا بایت‌کد تبدیل کنه. این بک‌اند جدید رو با استفاده از فرانت‌اند اولیه کامپایل کنید.
    3. اگه بک‌اند جدید شما از نمایش میانی متفاوتی استفاده میکنه، فرانت‌اند رو طوری تغییر بدید که باهاش سازگار باشه.
    4. حالا فرانت‌اند رو هم با زبان خودتون بازنویسی کنید و اون رو با استفاده از فرانت‌اند قدیمی و بک‌اند جدید کامپایل کنید.
    5. الان شما یه تولچین (toolchain) کاملا نیتیو دارید که با زبان خودتون نوشته شده!

    یک پروژه واقعی: استارفورث (Starforth)

    برای اینکه ببینیم این ایده‌ها در عمل چطور پیاده میشن، بیاید نگاهی به پروژه استارفورث بندازیم. این پروژه توسط یه برنامه‌نویس شروع شده که همیشه به زبان فورث (Forth) علاقه داشته. فورث یه زبان خیلی خاصه که فقط با یه استک کار میکنه و از نوشتار لهستانی معکوس استفاده میکنه. یعنی به جای 2 + 2 مینویسید 2 2 +.

    نقطه عطف برای این برنامه‌نویس زمانی بود که فهمید در زبان فورث، وقتی اسم یه متغیر (مثلا foo) رو مینویسید، آدرس اون متغیر روی استک قرار میگیره. بعد با یه عملگر به اسم @ (fetch) میشه اون آدرس رو از روی استک خوند و به مقدار داخلش دسترسی پیدا کرد. اونجا بود که متوجه شد: فورث اشاره‌گر (pointer) داره!

    این کشف باعث شد که تصمیم بگیره یه کامپایلر جدید به اسم استارفورث بنویسه و این اهداف رو برای خودش مشخص کرد:

    • تولید کد ماشین واقعی: برخلاف پروژه‌های قبلیش که برای ماشین‌های مجازی بودن، این بار میخواست کد ماشین واقعی تولید کنه.
    • خودمیزبانی: کامپایلر باید بتونه سورس کد خودش رو کامپایل کنه.
    • کامپایلر پیش از اجرا (Ahead-of-Time): برخلاف اکثر پیاده‌سازی‌های فورث که مفسری هستن، این کامپایلر باید کارش رو انجام بده و از مسیر خارج بشه.
    • بوت‌استرپ فقط با یک اسمبلر: فایل باینری اولیه باید تا حد ممکن کوچیک باشه و فقط با یه اسمبلر ساده قابل ساخت باشه.

    تصمیمات فنی پروژه هم اینها بودن:

    • محیط هدف: لینوکس.
    • معماری: x86 ۳۲ بیتی (چون کدش کوچیکتره و حس و حال روزهای قدیم رو داره!).
    • خروجی: فایل‌های باینری ELF کاملا مستقل، بدون هیچ وابستگی به کتابخانه‌های اشتراکی مثل libc.

    این پروژه نشون میده که چطور یه علاقه شخصی به یه زبان خاص میتونه به یه پروژه چالش‌برانگیز و آموزنده برای ساخت یه کامپایلر خودمیزبان تبدیل بشه.

    پرسش و پاسخ

    سوال ۱: پس خلاصه، یه کامپایلر خودمیزبان یعنی با همون زبانی نوشته شده که خودش کامپایل میکنه. این چطور ممکنه؟

    جواب: این کار از طریق یه فرآیندی به اسم «بوت‌استرپینگ» انجام میشه. شما نسخه اولیه کامپایلر (نسخه صفر) رو با یه زبان دیگه که از قبل وجود داره (مثلا پایتون یا C++) مینویسید. بعد با استفاده از این کامپایلر اولیه، نسخه جدید کامپایلر (نسخه یک) رو که با زبان خودش نوشته شده، کامپایل میکنید. وقتی نسخه یک ساخته شد، دیگه نیازی به نسخه صفر ندارید و از اون به بعد کامپایلر میتونه خودش رو کامپایل و به‌روزرسانی کنه.

    سوال ۲: اصلی‌ترین فایده این همه زحمت چیه؟

    جواب: مهمترین فایده‌ش «Dogfooding» هست. یعنی شما از محصول خودتون استفاده میکنید. این کار بهترین تست ممکن برای زبان شماست. چون کامپایلر یه برنامه خیلی پیچیده‌ست، اگه زبان شما بتونه از پس نوشتن خودش بربیاد، یعنی به بلوغ و قدرت کافی رسیده. این فرآیند به پیدا کردن سریع باگ‌ها، مشکلات عملکردی و حتی بهبود طراحی خود زبان کمک میکنه.

    سوال ۳: آیا همه زبان‌های بزرگ مثل پایتون خودمیزبان هستن؟

    جواب: نه لزوما. مثلا مفسر اصلی پایتون (CPython) با زبان C نوشته شده. کامپایلر جاوا اسکریپت هم همینطور. خودمیزبان نبودن یه زبان به هیچ وجه نشونه ضعف اون نیست و چیزی از ارزش‌های اون زبان یا زبانی که باهاش نوشته شده کم نمیکنه. این فقط یه انتخاب در مسیر توسعه‌ست.

    سوال ۴: اولین کامپایلر خودمیزبان برای چه زبانی ساخته شد؟

    جواب: اولین کامپایلر خودمیزبان (به جز اسمبلرها که از ابتدا خودمیزبان بودن) برای زبان Lisp در سال ۱۹۶۲ در دانشگاه MIT توسط هارت و لوین ساخته شد. اونها کامپایلر لیسپ رو داخل یه مفسر لیسپ توسعه دادن تا به نقطه‌ای رسید که تونست خودش رو کامپایل کنه.

    منابع

    • [2] What are the benefits to self-hosting compilers? – Programming Language Design and Implementation Stack Exchange
    • [4] Why would we want a self-hosting compiler? – Computer Science Stack Exchange
    • [6] Why are self-hosting compilers considered a rite of passage for new languages? – Software Engineering Stack Exchange
    • [8] elektito | Starforth: A Minimal Self-Hosting Compiler
    • [1] Self Hosting? : r/ProgrammingLanguages
    • [3] Self-hosting (compilers) – Wikipedia
    • [5] What is a self-hosting compiler? | Robert Heaton
    • [7] What is self-hosting, and is there value in it? – DEV Community
  • gRPC-Web چیست؟ ارتباط وب با سرویس‌های gRPC

    خب gRPC-Web یک کتابخانه جاوااسکریپتیه. کتابخانه یعنی یک سری کد آماده که کار ما رو راحت میکنه. حالا کار این کتابخانه چیه؟ کارش اینه که به کلاینت‌های مرورگر، یعنی همون اپلیکیشن‌هایی که توی کروم یا فایرفاکس شما باز میشن، اجازه میده که بتونن به یک سرویس gRPC وصل بشن و باهاش حرف بزنن. پس این یه جور پل ارتباطی بین دنیای وب و مرورگرها با دنیای سرویس‌های gRPC حساب میشه.

    شاید الان بپرسید خود gRPC چیه؟ عجله نکنید، به اون هم میرسیم. فقط در همین حد بدونید که gRPC یک فریمورک یا چارچوب مدرن و خیلی پرسرعته که گوگل ساختتش و برای ارتباط بین سرویس‌های مختلف در یک سیستم بزرگ استفاده میشه.

    یک نکته مهم که باید بدونید اینه که gRPC-Web الان به مرحله «عرضه عمومی» یا همون «Generally Available» رسیده. این یعنی چی؟ یعنی دیگه یک پروژه آزمایشی و نصفه و نیمه نیست. کاملا پایداره و شرکت‌ها و برنامه‌نویس‌ها میتونن با خیال راحت در محصولات نهایی و تجاری خودشون ازش استفاده کنن.

    نکته کلیدی اینه که کلاینت‌های gRPC-Web نمیتونن مستقیم با سرویس‌های gRPC صحبت کنن. این وسط به یک واسطه یا یک جور مترجم نیاز دارن. این مترجم یک «پراکسی» یا «gateway» مخصوصه. به طور پیش‌فرض، کتابخانه gRPC-Web از پراکسی به اسم Envoy استفاده میکنه که پشتیبانی از gRPC-Web به صورت داخلی در اون تعبیه شده. پس روند کار اینطوری میشه: اپلیکیشن توی مرورگر شما درخواستش رو به زبان gRPC-Web به Envoy میفرسته، بعد Envoy اون درخواست رو ترجمه میکنه و به زبان gRPC اصلی به سرویس پشتیبان یا همون بک‌اند میفرسته. جواب رو هم به همین صورت برعکس ترجمه میکنه و به مرورگر برمیگردونه.

    نگران نباشید، در آینده قراره این وضعیت بهتر هم بشه. تیم توسعه‌دهنده gRPC-Web انتظار داره که پشتیبانی از این تکنولوژی مستقیما به فریمورک‌های تحت وب در زبان‌های مختلف مثل پایتون، جاوا و نود جی‌اس اضافه بشه. این یعنی شاید در آینده دیگه نیازی به اون پراکسی جداگانه نباشه. اگه دوست دارید بیشتر در مورد برنامه‌های آینده بدونید، میتونید سند نقشه راه یا «roadmap» این پروژه رو مطالعه کنید.

    چرا اصلا باید از gRPC و gRPC-Web استفاده کنیم؟

    خب، سوال خوبیه. بیایید ببینیم مزیت این کار چیه. با gRPC شما میتونید سرویس خودتون رو فقط یک بار در یک فایلی به نام .proto تعریف کنید. این فایل مثل یک قرارداد یا یک نقشه ساختمون میمونه. بعد از اینکه این نقشه رو تعریف کردید، میتونید با استفاده از ابزارهای gRPC، کلاینت‌ها و سرورهای مربوط به اون سرویس رو در هر زبانی که gRPC ازش پشتیبانی میکنه، بسازید. این زبان‌ها میتونن خیلی متنوع باشن و در محیط‌های مختلفی هم اجرا بشن، از سرورهای غول‌پیکر در دیتاسنترهای بزرگ گرفته تا تبلت شخصی شما.

    تمام پیچیدگی‌های ارتباط بین این زبان‌ها و محیط‌های مختلف توسط خود gRPC مدیریت میشه و شما دیگه درگیر جزئیات نمیشید. علاوه بر این، شما از تمام مزایای کار با «پروتکل بافر» یا همون «Protocol Buffers» هم بهره‌مند میشید. این مزایا شامل سریال‌سازی بهینه (یعنی تبدیل داده‌ها به فرمتی فشرده و سریع برای انتقال)، یک زبان تعریف رابط کاربری ساده (IDL) و قابلیت به‌روزرسانی آسان رابط‌ها میشه.

    حالا gRPC-Web این وسط چه نقشی داره؟ gRPC-Web به شما این امکان رو میده که از داخل مرورگرها، با یک API کاملا طبیعی و آشنا برای برنامه‌نویس‌های وب، به همین سرویس‌های gRPC که ساختید دسترسی پیدا کنید.

    محدودیت‌های مرورگر و راه حل‌های موجود

    یک حقیقت مهم وجود داره که باید بدونیم: امکان فراخوانی مستقیم یک سرویس gRPC از مرورگر وجود نداره. چرا؟ چون gRPC از ویژگی‌های پروتکل HTTP/2 استفاده میکنه و هیچ مرورگری اون سطح از کنترل دقیق روی درخواست‌های وب رو که برای پشتیبانی از یک کلاینت gRPC لازمه، در اختیار ما قرار نمیده. مثلا ما نمیتونیم مرورگر رو مجبور کنیم حتما از HTTP/2 استفاده کنه و حتی اگه میتونستیم، به فریم‌های خام HTTP/2 در مرورگرها دسترسی نداریم.

    اینجا gRPC روی ASP.NET Core دو تا راه حل سازگار با مرورگر ارائه میده:

    • gRPC-Web
    • gRPC JSON transcoding

    آشنایی با gRPC-Web

    این همون تکنولوژی هست که داریم در موردش صحبت میکنیم. gRPC-Web به اپلیکیشن‌های مرورگر اجازه میده تا با استفاده از کلاینت gRPC-Web و پروتکل بافر، سرویس‌های gRPC رو فراخوانی کنن.

    • این روش خیلی شبیه به gRPC معمولیه، اما یک پروتکل انتقال داده کمی متفاوت داره که باعث میشه با HTTP/1.1 و مرورگرها سازگار باشه.
    • برای استفاده از این روش، اپلیکیشن مرورگر باید یک کلاینت gRPC رو از روی همون فایل .proto که تعریف کردیم، تولید کنه.
    • این روش به اپلیکیشن‌های مرورگر اجازه میده از مزایای پیام‌های باینری که عملکرد بالا و مصرف شبکه کمی دارن، بهره‌مند بشن.

    خبر خوب اینه که دات نت (.NET) به صورت داخلی از gRPC-Web پشتیبانی میکنه.

    آشنایی با gRPC JSON transcoding

    این یک راه حل جایگزینه. این روش به اپلیکیشن‌های مرورگر اجازه میده تا سرویس‌های gRPC رو طوری فراخوانی کنن که انگار دارن با یک RESTful API معمولی با فرمت JSON کار میکنن.

    • در این حالت، اپلیکیشن مرورگر نیازی به تولید کلاینت gRPC نداره و اصلا لازم نیست چیزی در مورد gRPC بدونه.
    • RESTful API‌ها به صورت خودکار از روی سرویس‌های gRPC ساخته میشن. این کار با اضافه کردن یک سری حاشیه‌نویسی یا «metadata» مربوط به HTTP به فایل .proto انجام میشه.
    • این روش به یک اپلیکیشن اجازه میده که هم از gRPC و هم از JSON web API‌ها پشتیبانی کنه، بدون اینکه لازم باشه برای هر کدوم سرویس‌های جداگانه‌ای بسازه و کار تکراری انجام بده.

    دات نت همچنین از ساخت JSON web API از روی سرویس‌های gRPC هم پشتیبانی داخلی داره. فقط یادتون باشه که برای استفاده از gRPC JSON transcoding به دات نت ۷ یا بالاتر نیاز دارید.

    یک آموزش پایه‌ای: بیایید دست به کار بشیم

    خب، تئوری کافیه. بیایید با یک مثال عملی ببینیم چطور میشه از gRPC-Web استفاده کرد. در این آموزش یاد میگیریم که:

    • چطور یک سرویس رو در یک فایل .proto تعریف کنیم.
    • چطور با استفاده از کامپایلر پروتکل بافر، کد کلاینت رو تولید کنیم.
    • چطور از API ی gRPC-Web برای نوشتن یک کلاینت ساده برای سرویسمون استفاده کنیم.

    فرض ما اینه که شما یک آشنایی اولیه با پروتکل بافرها دارید.

    مرحله ۱: تعریف سرویس در فایل echo.proto

    اولین قدم در ساخت یک سرویس gRPC، تعریف متدهای سرویس و انواع پیام‌های درخواست و پاسخ اونها با استفاده از پروتکل بافرهاست. در این مثال، ما یک سرویس به نام EchoService رو در فایلی به اسم echo.proto تعریف میکنیم. این فایل مثل یک نقشه اولیه برای ارتباط ما عمل میکنه.

    message EchoRequest {
      string message = 1;
    }
    
    message EchoResponse {
      string message = 1;
    }
    
    service EchoService {
      rpc Echo(EchoRequest) returns (EchoResponse);
    }

    این تعریف خیلی ساده است. ما یک درخواست به نام EchoRequest داریم که یک پیام متنی میگیره. یک پاسخ به نام EchoResponse داریم که اون هم یک پیام متنی برمیگردونه. و یک سرویس به نام EchoService داریم که یک متد به نام Echo داره. این متد یک EchoRequest میگیره و یک EchoResponse برمیگردونه. کارش اینه که هر پیامی بهش بدی، همون رو بهت برگردونه. مثل یک اکو یا پژواک صدا.

    مرحله ۲: پیاده‌سازی سرور بک‌اند gRPC

    حالا که نقشه رو داریم، باید سرور رو بسازیم. در مرحله بعد، ما رابط EchoService رو با استفاده از Node.js در بک‌اند پیاده‌سازی میکنیم. این سرور که اسمش رو EchoServer میذاریم، درخواست‌های کلاینت‌ها رو مدیریت میکنه. برای دیدن جزئیات کامل کد، میتونید به فایل node-server/server.js در مثال‌های رسمی gRPC-Web مراجعه کنید.

    یک نکته مهم اینه که شما میتونید سرور رو با هر زبانی که gRPC ازش پشتیبانی میکنه پیاده‌سازی کنید. این یکی از قدرت‌های gRPC هست.

    یک تیکه کد از سرور نود جی‌اس این شکلیه:

    function doEcho(call, callback) {
      callback(null, {message: call.request.message});
    }

    همونطور که میبینید، این تابع خیلی ساده است. یک درخواست (call) میگیره، پیام داخلش رو برمیداره و در یک پیام جدید به عنوان پاسخ (callback) برمیگردونه.

    مرحله ۳: پیکربندی پراکسی Envoy

    همونطور که قبلا گفتیم، برای اینکه درخواست مرورگر به سرور بک‌اند ما برسه، به یک مترجم یا پراکسی نیاز داریم. در این مثال، ما از پراکسی Envoy استفاده میکنیم. فایل پیکربندی کامل Envoy رو میتونید در envoy.yaml ببینید.

    برای اینکه Envoy درخواست‌های gRPC رو به سرور بک‌اند ما فوروارد کنه، به یک بلوک تنظیمات شبیه به این نیاز داریم:

    admin:
      address:
        socket_address: { address: 0.0.0.0, port_value: 9901 }
    static_resources:
      listeners:
      - name: listener_0
        address:
          socket_address: { address: 0.0.0.0, port_value: 8080 }
        filter_chains:
        - filters:
          - name: envoy.http_connection_manager
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
              codec_type: auto
              stat_prefix: ingress_http
              route_config:
                name: local_route
                virtual_hosts:
                - name: local_service
                  domains: ["*"]
                  routes:
                  - match: { prefix: "/" }
                    route: { cluster: echo_service }
              http_filters:
              - name: envoy.grpc_web
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
              - name: envoy.filters.http.router
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
      clusters:
      - name: echo_service
        connect_timeout: 0.25s
        type: LOGICAL_DNS
        typed_extension_protocol_options:
          envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
            "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
            explicit_http_config:
              http2_protocol_options: {}
        lb_policy: ROUND_ROBIN
        load_assignment:
          cluster_name: echo_service
          endpoints:
          - lb_endpoints:
            - endpoint:
                address:
                  socket_address:
                    address: node-server
                    port_value: 9090

    این تنظیمات شاید در نگاه اول پیچیده به نظر بیاد، ولی بیایید با هم بررسیش کنیم:

    • listeners: این بخش تعریف میکنه که Envoy روی چه آدرس و پورتی منتظر درخواست‌های ورودی باشه. اینجا روی پورت 8080 منتظر میمونه.
    • http_filters: اینجاست که جادو اتفاق میفته. ما دو تا فیلتر مهم داریم. یکی envoy.grpc_web که درخواست‌های gRPC-Web رو میشناسه و پردازش میکنه. دومی envoy.filters.http.router هست که درخواست رو به مقصد مناسبش هدایت میکنه.
    • clusters: این بخش تعریف میکنه که سرور بک‌اند ما کجاست. ما یک کلاستر به اسم echo_service تعریف کردیم که به آدرس node-server و پورت 9090 اشاره میکنه.

    پس سناریو اینطوریه: مرورگر یک درخواست gRPC-Web به پورت 8080 میفرستسه. Envoy این درخواست رو دریافت میکنه، با استفاده از فیلتر grpc_web اون رو ترجمه میکنه و به سرور gRPC بک‌اند ما که روی پورت 9090 قرار داره، ارسال میکنه. پاسخ سرور رو هم به همین ترتیب برعکس ترجمه میکنه و برای مرورگر میفرسته.

    گاهی اوقات لازمه یک سری تنظیمات مربوط به CORS هم اضافه کنید تا مرورگر اجازه داشته باشه محتوا رو از یک مبدا دیگه درخواست بده.

    مرحله ۴: تولید پیام‌های پروتوباف و کلاینت سرویس

    حالا وقتشه که از روی فایل echo.proto خودمون، کلاس‌های پیام جاوااسکریپتی رو تولید کنیم. این کار با یک دستور در ترمینال انجام میشه:

    protoc -I=$DIR echo.proto \
    --js_out=import_style=commonjs:$OUT_DIR
    • protoc: این همون کامپایلر پروتکل بافر هست.
    • -I=$DIR: به کامپایلر میگه فایل‌های .proto رو کجا پیدا کنه.
    • --js_out=import_style=commonjs:$OUT_DIR: این قسمت میگه که خروجی جاوااسکریپت بساز. import_style=commonjs باعث میشه که فایل‌های تولید شده از سیستم ماژول require() ی CommonJS استفاده کنن که در دنیای Node.js خیلی رایجه. $OUT_DIR هم پوشه خروجی رو مشخص میکنه.

    خب، این فقط کلاس‌های مربوط به پیام‌ها رو ساخت. ما به کدهای مربوط به کلاینت سرویس هم نیاز داریم. برای این کار، به یک پلاگین مخصوص برای protoc به اسم protoc-gen-grpc-web نیاز داریم.

    اول باید این پلاگین رو دانلود و نصب کنید. میتونید فایل باینری protoc رو از صفحه رسمی پروتکل بافر و پلاگین protoc-gen-grpc-web رو از صفحه گیت‌هاب gRPC-Web دانلود کنید. بعد باید مطمئن بشید که هر دوی این فایل‌ها اجرایی هستن و در PATH سیستم شما قرار دارن تا از هر جایی قابل دسترس باشن.

    یک راه دیگه برای نصب پلاگین اینه که از سورس کد کامپایلش کنید. برای این کار باید از ریشه مخزن gRPC-Web دستور زیر رو اجرا کنید:

    cd grpc-web
    sudo make install-plugin

    بعد از اینکه پلاگین آماده شد، با دستور زیر میتونیم کد کلاینت سرویس رو تولید کنیم:

    protoc -I=$DIR echo.proto \
    --grpc-web_out=import_style=commonjs,mode=grpcwebtext:$OUT_DIR

    این دستور خیلی شبیه دستور قبلیه، ولی از --grpc-web_out استفاده میکنه که مخصوص پلاگین ماست. بیایید پارامترهاش رو بررسی کنیم:

    • mode: این پارامتر میتونه grpcwebtext (که پیش‌فرض هست) یا grpcweb باشه. این دو حالت در نحوه کدگذاری داده‌ها تفاوت دارن که بعدا بیشتر در موردش صحبت میکنیم.
    • import_style: این پارامتر هم میتونه closure (که پیش‌فرض هست) یا commonjs باشه. ما از commonjs استفاده کردیم تا با خروجی قبلیمون هماهنگ باشه.

    این دستور به طور پیش‌فرض یک فایل به نام echo_grpc_web_pb.js تولید میکنه که شامل کد کلاینت ماست.

    مرحله ۵: نوشتن کد کلاینت جاوااسکریپت

    بالاخره رسیدیم به قسمت شیرین ماجرا. حالا آماده‌ایم که کد جاوااسکریپت سمت کلاینت رو بنویسیم. این کد رو در یک فایلی به نام client.js قرار میدیم.

    const {EchoRequest, EchoResponse} = require('./echo_pb.js');
    const {EchoServiceClient} = require('./echo_grpc_web_pb.js');
    
    var echoService = new EchoServiceClient('http://localhost:8080');
    
    var request = new EchoRequest();
    request.setMessage('Hello World!');
    
    echoService.echo(request, {}, function(err, response) {
      // اینجا میتونیم با پاسخ سرور کار کنیم
      // مثلا response.getMessage() رو چاپ کنیم
    });

    بیایید این کد رو با هم تحلیل کنیم:

    1. در دو خط اول، ما کلاس‌هایی که در مرحله قبل تولید کردیم (EchoRequest, EchoResponse, EchoServiceClient) رو با استفاده از require وارد برنامه‌مون میکنیم.
    2. بعد یک نمونه جدید از EchoServiceClient میسازیم و آدرس پراکسی Envoy خودمون (http://localhost:8080) رو بهش میدیم.
    3. یک نمونه جدید از EchoRequest میسازیم و پیام «Hello World!» رو داخلش قرار میدیم.
    4. در نهایت، متد echo رو روی سرویسمون فراخوانی میکنیم. به عنوان ورودی، درخواست (request)، یک آبجکت خالی برای متادیتا ({}) و یک تابع callback بهش میدیم. این تابع زمانی اجرا میشه که پاسخی از سرور دریافت بشه. این پاسخ میتونه خطا (err) یا جواب موفقیت‌آمیز (response) باشه.

    برای اینکه این کد کار کنه، به یک سری پکیج دیگه هم نیاز داریم. باید یک فایل package.json در پروژه‌مون داشته باشیم:

    {
      "name": "grpc-web-commonjs-example",
      "dependencies": {
        "google-protobuf": "^3.6.1",
        "grpc-web": "^0.4.0"
      },
      "devDependencies": {
        "browserify": "^16.2.2",
        "webpack": "^4.16.5",
        "webpack-cli": "^3.1.0"
      }
    }

    این فایل مشخص میکنه که پروژه ما به پکیج‌های google-protobuf و grpc-web نیاز داره. همچنین برای ساختن فایل نهایی برای مرورگر، از ابزارهایی مثل browserify یا webpack استفاده میکنیم.

    مرحله ۶: کامپایل کتابخانه جاوااسکریپت

    در مرحله آخر، باید تمام فایل‌های جاوااسکریپت مرتبط رو با هم ترکیب کنیم و یک فایل کتابخانه واحد بسازیم که بتونیم در مرورگر ازش استفاده کنیم.

    اول با دستور npm install پکیج‌های مورد نیاز رو نصب میکنیم.

    بعد با دستوری مثل این، فایل نهایی رو میسازیم:

    npx webpack client.js

    این دستور فایل client.js ما و تمام وابستگی‌هاش رو در یک فایل به نام main.js در پوشه dist قرار میده. حالا کافیه این فایل dist/main.js رو در صفحه HTML خودمون قرار بدیم و نتیجه رو ببینیم!

    یک راه سریع برای شروع

    اگر حوصله انجام تمام این مراحل رو به صورت دستی ندارید، یک راه سریع‌تر هم وجود داره. میتونید از مثال‌های آماده خود gRPC-Web استفاده کنید:

    $ git clone https://github.com/grpc/grpc-web
    $ cd grpc-web
    $ docker-compose up node-server envoy commonjs-client

    این دستورات با استفاده از داکر، همه چیز رو براتون آماده میکنه: سرور نود جی‌اس، پراکسی Envoy و یک کلاینت نمونه. بعد کافیه مرورگر خودتون رو باز کنید و به آدرس http://localhost:8081/echotest.html برید تا همه چیز رو در عمل ببینید.

    نگاهی عمیق‌تر به ویژگی‌ها و گزینه‌ها

    حالا که با اصول اولیه آشنا شدیم، بیایید کمی جزئی‌تر به گزینه‌هایی که در اختیار داریم نگاه کنیم.

    انواع RPC و پشتیبانی در gRPC-Web

    gRPC در حالت کلی چهار نوع متد یا RPC رو پشتیبانی میکنه:

    1. Unary RPCs: یک درخواست میفرستی و یک پاسخ میگیری. مثل همین مثال Echo ما.
    2. Server-side Streaming RPCs: یک درخواست میفرستی و یک جریان از پاسخ‌ها رو به صورت پشت سر هم دریافت میکنی.
    3. Client-side Streaming RPCs: یک جریان از درخواست‌ها رو میفرستی و در نهایت یک پاسخ میگیری.
    4. Bi-directional Streaming RPCs: یک جریان دوطرفه از درخواست‌ها و پاسخ‌ها به صورت همزمان داری.

    gRPC-Web در حال حاضر فقط از دو نوع اول پشتیبانی میکنه. یعنی Unary RPC و Server-side Streaming RPC. استریمینگ سمت کلاینت و دوطرفه فعلا پشتیبانی نمیشن. البته برای استریمینگ سمت سرور هم یک شرط وجود داره: باید حتما از حالت grpcwebtext استفاده کنید.

    حالت‌های مختلف انتقال داده (mode)

    وقتی داشتیم کد کلاینت رو تولید میکردیم، یک پارامتر به اسم mode دیدیم. این پارامتر دو تا مقدار میتونه داشته باشه:

    • mode=grpcwebtext: این حالت پیش‌فرض هست.
      • Content-type درخواست میشه application/grpc-web-text.
      • داده‌ها یا همون payload به صورت base64 کدگذاری میشن. این یعنی داده‌های باینری به فرمت متنی تبدیل میشن.
      • هم از Unary و هم از Server-side streaming پشتیبانی میکنه.
    • mode=grpcweb: این حالت از فرمت باینری پروتوباف استفاده میکنه.
      • Content-type درخواست میشه application/grpc-web+proto.
      • داده‌ها به صورت باینری و خام پروتوباف فرستاده میشن. این حالت معمولا بهینه‌تر و کم‌حجم‌تره.
      • فقط از Unary call پشتیبانی میکنه. استریمینگ سمت سرور در این حالت کار نمیکنه.

    استایل‌های مختلف ایمپورت (import_style)

    یک پارامتر دیگه هم به اسم import_style داشتیم. این پارامتر نحوه وارد کردن ماژول‌ها در کد تولید شده رو مشخص میکنه:

    • import_style=closure: این حالت پیش‌فرض هست و از سیستم ماژول goog.require() کتابخانه Closure گوگل استفاده میکنه.
    • import_style=commonjs: این حالت از require() ی CommonJS استفاده میکنه که برای کار با ابزارهایی مثل Webpack و Browserify خیلی مناسبه.
    • import_style=commonjs+dts: (آزمایشی) این حالت علاوه بر کد CommonJS، یک فایل تایپینگ .d.ts هم برای پیام‌های پروتوباف و کلاینت سرویس تولید میکنه. این برای کار با TypeScript خیلی مفیده.
    • import_style=typescript: (آزمایشی) این حالت مستقیما کد کلاینت سرویس رو به زبان TypeScript تولید میکنه.

    پشتیبانی از TypeScript

    خبر خوب برای طرفدارهای TypeScript اینه که gRPC-Web به صورت آزمایشی از این زبان پشتیبانی میکنه. حالا ماژول grpc-web رو میشه به عنوان یک ماژول TypeScript وارد کرد.

    برای استفاده از این قابلیت، باید موقع تولید کد از پلاگین protoc-gen-grpc-web، یکی از این دو گزینه رو بهش بدید:

    • import_style=commonjs+dts: کد CommonJS به همراه فایل‌های تایپینگ .d.ts تولید میکنه.
    • import_style=typescript: کد کاملا TypeScript تولید میکنه.

    یک نکته خیلی مهم: شما نباید import_style=typescript رو برای فلگ --js_out استفاده کنید. این فلگ فقط باید روی import_style=commonjs تنظیم بشه. در واقع --js_out کد جاوااسکریپت پیام‌ها (echo_pb.js) رو تولید میکنه و --grpc-web_out فایل‌های TypeScript مربوط به سرویس (EchoServiceClientPb.ts) و تایپینگ پیام‌ها (echo_pb.d.ts) رو میسازه. این یک راه حل موقتیه تا زمانی که خود --js_out به صورت کامل از TypeScript پشتیبانی کنه.

    پس دستور کامل برای تولید کد TypeScript با فرمت باینری این شکلی میشه:

    protoc -I=$DIR echo.proto \
    --js_out=import_style=commonjs,binary:$OUT_DIR \
    --grpc-web_out=import_style=typescript,mode=grpcweb:$OUT_DIR

    و کد سمت کلاینت در TypeScript میتونه این شکلی باشه:

    import * as grpcWeb from 'grpc-web';
    import {EchoServiceClient} from './EchoServiceClientPb';
    import {EchoRequest, EchoResponse} from './echo_pb';
    
    const echoService = new EchoServiceClient('http://localhost:8080', null, null);
    
    const request = new EchoRequest();
    request.setMessage('Hello World!');
    
    const call = echoService.echo(request, {'custom-header-1': 'value1'},
      (err: grpcWeb.RpcError, response: EchoResponse) => {
        if (err) {
          console.log(`Received error: ${err.code}, ${err.message}`);
        } else {
          console.log(response.getMessage());
        }
      });
    
    call.on('status', (status: grpcWeb.Status) => {
      // ...
    });

    همونطور که میبینید، همه چیز تایپ-سیف و مشخصه.

    کلاینت مبتنی بر Promise

    علاوه بر مدل callback که دیدیم، میتونید از یک کلاینت مبتنی بر Promise هم استفاده کنید. این مدل کدنویسی برای خیلی‌ها خواناتر و مدرن‌تره.

    // Create a Promise client instead
    const echoService = new EchoServicePromiseClient('http://localhost:8080', null, null);
    
    // ... (request is the same as above)
    
    echoService.echo(request, {'custom--header-1': 'value1'})
      .then((response: EchoResponse) => {
        console.log(`Received response: ${response.getMessage()}`);
      }).catch((err: grpcWeb.RpcError) => {
        console.log(`Received error: ${err.code}, ${err.message}`);
      });

    فقط یک نکته مهم رو در نظر داشته باشید: وقتی از Promise استفاده میکنید، دیگه نمیتونید به callback‌های .on(...) (مثلا برای metadata و status) دسترسی داشته باشید.

    تاریخچه و وضعیت فعلی gRPC در مرورگر

    جالبه بدونید که داستان gRPC در مرورگر چطور شروع شد. در تابستان ۲۰۱۶، یک تیم در گوگل و یک شرکت به نام Improbable به صورت مستقل از هم شروع به کار روی چیزی کردن که میشد اسمش رو گذاشت «gRPC برای مرورگر». خیلی زود از وجود هم باخبر شدن و با هم همکاری کردن تا یک مشخصات فنی یا «spec» برای این پروتکل جدید تعریف کنن.

    مشخصات فنی gRPC-Web

    همونطور که گفتیم، پیاده‌سازی کامل مشخصات gRPC مبتنی بر HTTP/2 در مرورگرها غیرممکنه. به خاطر همین، مشخصات gRPC-Web با در نظر گرفتن این محدودیت‌ها و با تعریف تفاوت‌هاش با gRPC اصلی نوشته شد. این تفاوت‌های کلیدی عبارتند از:

    • پشتیبانی از هر دو پروتکل HTTP/1.1 و HTTP/2.
    • ارسال هدرهای تریلر gRPC در انتهای بدنه درخواست/پاسخ.
    • الزامی بودن استفاده از یک پراکسی برای ترجمه بین درخواست‌های gRPC-Web و پاسخ‌های gRPC HTTP/2.

    دو پیاده‌سازی اصلی

    تیم‌های گوگل و Improbable هر کدوم پیاده‌سازی خودشون رو از این مشخصات ارائه دادن. این دو پیاده‌سازی در دو مخزن جداگانه قرار داشتن و برای مدتی با هم سازگار نبودن.

    • کلاینت Improbable:
      • با زبان TypeScript نوشته شده.
      • در npm با نام @improbable-eng/grpc-web موجوده.
      • یک پراکسی به زبان Go هم داره که هم به صورت پکیج و هم به صورت یک برنامه مستقل قابل استفاده است.
      • از هر دو Fetch و XHR برای ارسال درخواست‌ها استفاده میکنه و به صورت خودکار بر اساس قابلیت‌های مرورگر یکی رو انتخاب میکنه.
    • کلاینت Google:
      • با زبان جاوااسکریپت و با استفاده از کتابخانه Google Closure نوشته شده.
      • در npm با نام grpc-web موجوده.
      • در ابتدا با یک افزونه برای NGINX به عنوان پراکسی عرضه شد، ولی بعدا روی فیلتر HTTP پراکسی Envoy تمرکز کرد.
      • فقط از XHR برای ارسال درخواست‌ها استفاده میکنه.

    بیایید این دو رو در یک جدول با هم مقایسه کنیم:

    کلاینت / ویژگیروش انتقالUnaryاستریم سمت سروراستریم سمت کلاینت و دوطرفه
    ImprobableFetch/XHR✔️✔️❌ (با یک روش آزمایشی وب‌سوکت)
    Google (grpcwebtext)XHR✔️✔️
    Google (grpcweb)XHR✔️❌ (فقط در انتها نتیجه رو برمیگردونه)

    خوشبختانه، مشکلات سازگاری بین این دو پیاده‌سازی اخیرا برطرف شده و الان شما میتونید هر کدوم از کلاینت‌ها رو با هر کدوم از پراکسی‌ها استفاده کنید.

    آینده و مسیر پیش رو

    در اکتبر ۲۰۱۸، پیاده‌سازی گوگل به نسخه ۱.۰ رسید و به صورت عمومی عرضه شد. تیم گوگل یک نقشه راه برای اهداف آینده منتشر کرده که شامل این موارد میشه:

    • یک فرمت کدگذاری پیام‌ها شبیه JSON ولی بهینه‌تر.
    • پراکسی‌های درون-فرایندی برای Node، پایتون، جاوا و غیره (تا نیاز به پراکسی جدا مثل Envoy کمتر بشه).
    • ادغام با فریمورک‌های محبوب مثل React، Angular و Vue.
    • استفاده از Fetch API برای استریمینگ بهینه‌تر از نظر حافظه.
    • پشتیبانی از استریمینگ دوطرفه.

    بعد از مذاکرات بین دو تیم، تصمیم بر این شد که کلاینت گوگل و پراکسی Envoy به عنوان راه حل‌های پیشنهادی برای کاربران جدید معرفی بشن. کلاینت و پراکسی Improbable به عنوان پیاده‌سازی‌های جایگزین و آزمایشی باقی میمونن.

    پس اگه امروز میخواید با gRPC-Web شروع کنید، بهترین گزینه کلاینت گوگل هست. این کلاینت تضمین‌های سازگاری API قوی‌ای داره و توسط یک تیم اختصاصی پشتیبانی میشه.

    مزایای استفاده از gRPC-Web

    حالا که با جزئیات فنی آشنا شدیم، بیایید یک بار دیگه مزایای معماری gRPC-Web رو مرور کنیم.

    • gRPC سرتاسری (End-to-end gRPC): به شما اجازه میده کل خط لوله RPC خودتون رو با استفاده از پروتکل بافرها طراحی کنید. دیگه لازم نیست یک لایه اضافه برای تبدیل درخواست‌های HTTP/JSON به gRPC در بک‌اند داشته باشید.
    • هماهنگی بیشتر بین تیم‌های فرانت‌اند و بک‌اند: وقتی کل ارتباط با پروتکل بافر تعریف میشه، دیگه مرز بین تیم «کلاینت» و تیم‌های «میکروسرویس‌ها» کمرنگ‌تر میشه. ارتباط کلاینت-بک‌اند فقط یک لایه gRPC دیگه در کنار بقیه لایه‌هاست.
    • تولید آسان کتابخانه‌های کلاینت: وقتی سروری که با دنیای بیرون در ارتباطه، یک سرور gRPC باشه، تولید کتابخانه‌های کلاینت برای زبان‌های مختلف (روبی، پایتون، جاوا و …) خیلی راحت‌تر میشه و دیگه نیازی به نوشتن کلاینت‌های HTTP جداگانه برای هر کدوم نیست.

    دیدگاه دنیای واقعی: gRPC-Web در مقابل REST

    جالبه بدونید که همیشه همه با یک تکنولوژی موافق نیستن. در یک بحث در وبسایت ردیت، یک مهندس ارشد پیشنهاد کرده بود که تیمشون از gRPC-Web به سمت استفاده از REST Handler‌های معمولی حرکت کنه. دلیل این پیشنهاد این بود که در یک استارتاپ که سرعت توسعه و رسیدن به بازار اولویت داره، این کار میتونه مفید باشه.

    نگرانی‌هایی که در مورد این تغییر مطرح شده بود اینها بودن:

    • از دست دادن یک تعریف نوع (type definition) یکپارچه که پروتوباف فراهم میکنه.
    • نیاز به ابداع مجدد چرخ و نوشتن کدهای تکراری.
    • نیاز به ارتباط و مستندسازی بیشتر بین تیم‌ها.

    در مقابل، تنها مزیت مسیر HTTP/REST این عنوان شده بود که درک و فهم اون برای بعضی‌ها ساده‌تره. این بحث نشون میده که انتخاب بین این تکنولوژی‌ها همیشه یک سری بده‌بستان (trade-off) داره و به شرایط پروژه بستگی داره. هر دو روش، چه استفاده از پروتوباف برای تولید کلاینت gRPC-Web و چه استفاده از OpenAPI برای تولید کلاینت REST، در سطح بالا یک هدف مشترک دارن: تولید خودکار کلاینت از روی یک تعریف مشخص.

    پرسش و پاسخ

    خب بچه‌ها، بحث ما تقریبا تموم شد. برای اینکه مطمئن بشیم همه چیز خوب جا افتاده، بیایید چند تا سوال مهم رو با هم مرور کنیم.

    1. سوال ۱: gRPC دقیقا چیه؟

    جواب: gRPC یک چارچوب RPC (Remote Procedure Call) مدرن، متن‌باز و با کارایی بالاست که توسط گوگل ساخته شده. به زبان ساده، یک روش خیلی سریع و بهینه برای اینه که سرویس‌های مختلف در یک سیستم کامپیوتری بتونن با هم صحبت کنن و از هم سرویس بگیرن، حتی اگه در کامپیوترهای مختلف و با زبان‌های برنامه‌نویسی متفاوتی نوشته شده باشن. این چارچوب از پروتکل HTTP/2 برای انتقال داده استفاده میکنه.

    1. سوال ۲: چرا نمیتونیم مستقیم از gRPC توی مرورگر استفاده کنیم و به gRPC-Web نیاز داریم؟

    جواب: چون gRPC روی ویژگی‌های سطح پایین پروتکل HTTP/2 ساخته شده. مرورگرهای وب امروزی به برنامه‌نویس‌ها اجازه دسترسی و کنترل مستقیم روی این ویژگی‌ها رو نمیدن. برای همین، یک «پل» یا «مترجم» به اسم gRPC-Web ساخته شده که یک پروتکل کمی متفاوت و سازگار با محدودیت‌های مرورگر داره. این پروتکل بعدا توسط یک پراکسی (مثل Envoy) به gRPC استاندارد ترجمه میشه.

    1. سوال ۳: فایل .proto چیه و چه نقشی داره؟

    جواب: فایل .proto که بهش فایل پروتکل بافر هم میگن، یک فایل متنیه که شما در اون ساختار داده‌ها و سرویس‌های خودتون رو تعریف میکنید. این فایل مثل یک «قرارداد» یا «نقشه» بین کلاینت و سرور عمل میکنه. شما پیام‌های درخواست، پیام‌های پاسخ و متدهای سرویس رو در این فایل تعریف میکنید. بعد با استفاده از کامپایلر پروتکل بافر (protoc)، میتونید از روی این فایل، کد مربوط به کلاینت و سرور رو به زبان‌های مختلف تولید کنید.

    1. سوال ۴: پراکسی Envoy چیه و چرا در معماری gRPC-Web مهمه؟

    جواب: Envoy یک پراکسی سرویس مدرن و با کارایی بالاست. در دنیای gRPC-Web، نقش یک مترجم رو بازی میکنه. درخواست‌هایی که از مرورگر با پروتکل gRPC-Web میان رو دریافت میکنه، اونها رو به پروتکل استاندارد gRPC (که روی HTTP/2 کار میکنه) تبدیل میکنه و به سرور بک‌اند میفرسته. پاسخ سرور رو هم به همین ترتیب برعکس ترجمه میکنه و برای مرورگر میفرسته. بدون وجود یک پراکسی مثل Envoy، ارتباط مستقیم بین مرورگر و سرور gRPC ممکن نیست. البته پراکسی‌های دیگه‌ای مثل پراکسی Go، Apache APISIX و Nginx هم این قابلیت رو دارن.

    1. سوال ۵: تفاوت اصلی بین دو حالت mode=grpcwebtext و mode=grpcweb چیه؟

    جواب: تفاوت اصلی در نحوه کدگذاری و انتقال داده‌هاست.

    • grpcwebtext داده‌ها رو به صورت متنی (Base64) کدگذاری میکنه و هم از درخواست‌های تکی (Unary) و هم از استریمینگ سمت سرور پشتیبانی میکنه.
    • grpcweb داده‌ها رو به صورت باینری و خام پروتوباف منتقل میکنه که بهینه‌تره، ولی فقط از درخواست‌های تکی (Unary) پشتیبانی میکنه.
    1. سوال ۶: آیا میتونم از gRPC-Web برای آپلود فایل یا چت دوطرفه استفاده کنم؟

    جواب: در حال حاضر، خیر. gRPC-Web از استریمینگ سمت کلاینت و استریمینگ دوطرفه پشتیبانی نمیکنه. این قابلیت‌ها در نقشه راه پروژه قرار دارن ولی هنوز پیاده‌سازی نشدن. پس برای کارهایی مثل آپلود فایل (که نیاز به استریم سمت کلاینت داره) یا یک اپلیکیشن چت زنده (که نیاز به استریم دوطرفه داره)، gRPC-Web فعلا راه حل کاملی نیست.

    منابع

    • [2] What Are gRPC & gRPC Web. Basics of Hacking Into gRPC-Web | by Amin Nasiri | Medium
    • [4] The state of gRPC in the browser | gRPC
    • [6] GitHub – grpc/grpc-web: gRPC for Web Clients
    • [8] My backfill Principal Engineer wants to move off of GRPC web and start using REST Handlers. Will this be a shit show? : r/golang
    • [10] gRPC vs. gRPC-Web: Key Differences Explained
    • [1] grpc-web – npm
    • [3] Use gRPC in browser apps | Microsoft Learn
    • [5] Go and gRPC is just so intuitive. Here’s a detailed full-stack flow with gRPC-Web, Go and React. Also, there is a medium story focused on explaining how such a setup might boost efficiency and the step-by-step implementation. : r/golang
    • [7] gRPC-Web is Generally Available | gRPC
    • [9] Basics tutorial | Web | gRPC
  • بلوتوث کم‌مصرف (BLE)؛ راهنمای تکنولوژی اینترنت اشیا

    تکنولوژی BLE که اولین بار سال ۲۰۱۲ معرفی شد، یک پروتکل خیلی انعطاف‌پذیره که برای خیلی از کاربردهای مهم اینترنت اشیا، ارتباط بی‌سیم فراهم میکنه. تمرکز اصلیش روی کار کردن با مصرف انرژی فوق‌العاده پایینه و همین باعث شده تو صنایع مختلفی مثل لوازم الکترونیکی مصرفی، بهداشت و درمان و حتی لجستیک و انبارداری ازش استفاده بشه. امروز میخوایم تمام نکات پایه‌ای BLE رو با هم یاد بگیریم تا شما هم بتونید برای پروژه‌های بعدیتون ازش استفاده کنید و سهمی از این بازار بزرگ ۳۸۴ میلیارد دلاری اینترنت اشیا داشته باشید.

    داستان بلوتوث از کجا شروع شد؟

    قبل از اینکه بریم تو دنیای BLE، بهتره یه نگاهی به پدرش یعنی همون بلوتوث معمولی بندازیم. مشخصات فنی بلوتوث از دهه ۹۰ میلادی وجود داشته. هدف اصلی از طراحی این پروتکل این بود که جای کابل‌ها رو برای انتقال داده بین دستگاه‌ها تو فاصله‌های کوتاه بگیره. جالبه که امروز هم اصلی‌ترین کاربردش همینه.

    بلوتوث یک تکنولوژی بی‌سیم با برد کوتاهه که تو باند فرکانسی ۲.۴ گیگاهرتز ISM کار میکنه. این باند فرکانسی برای استفاده عموم آزاده و نیازی به مجوز نداره. کارش هم انتقال داده و ساختن شبکه‌های شخصی کوچیک (PAN) هست.

    احتمالا همین الان دور و بر همه‌مون کلی دستگاه بلوتوثی هست: گوشی موبایل، لپ‌تاپ، هدفون و اسپیکر. جالبه بدونید که فقط تو سال ۲۰۲۱، بیشتر از ۴.۷ میلیارد دستگاه بلوتوثی تو کل دنیا تولید و عرضه شده. این نشون میده که بلوتوث یکی از پرکاربردترین تکنولوژی‌های دنیاست.

    اگه از مردم تو خیابون بپرسید بلوتوث چیه، اکثرشون یه شناخت کلی ازش دارن. اما پشت پرده، این یک استاندارد فنی نسبتا پیچیده‌ است که توسط یک گروه به اسم گروه علایق ویژه بلوتوث (Bluetooth Special Interest Group) یا به اختصار SIG مدیریت میشه. این گروه در طول سال‌ها، نسخه‌های مختلفی از مشخصات فنی بلوتوث رو منتشر کرده. دو تا از معروف‌ترین پروتکل‌های این استاندارد، «بلوتوث کلاسیک» و «بلوتوث کم‌مصرف» هستن.

    تا سال ۲۰۱۰، تمرکز اصلی روی بهتر کردن بلوتوث کلاسیک بود. اما تو همین سال، گروه SIG نسخه ۴.۰ بلوتوث رو منتشر کرد. این نسخه یک مسیر متفاوت رو در پیش گرفت و یک پروتکل جدید به اسم بلوتوث کم‌مصرف (BLE) رو به دنیا معرفی کرد.

    بلوتوث کم‌مصرف (BLE) دقیقا چیه؟

    با اینکه BLE خیلی از ویژگی‌هاش رو از جدش یعنی بلوتوث کلاسیک گرفته، اما به عنوان یک تکنولوژی متفاوت شناخته میشه. هدف اصلی BLE بازارهایی هست که نیاز اصلیشون مصرف انرژی فوق‌العاده پایینه، نه سرعت انتقال داده بالا.

    ارتباط داده با رادیوی LE (که مخفف Low Energy هست) در بسته‌های کوچیک و کوتاه اتفاق میفته که لازم نیست خیلی پشت سر هم باشن. یک سناریوی معمولی برای BLE این شکلیه: دستگاه رادیوش رو برای مدت کوتاهی روشن میکنه، چند بایت یا چند کیلوبایت داده رو منتقل یا دریافت میکنه، و بعد دوباره رادیو رو خاموش میکنه و به حالت خواب (Sleep Mode) برمیگرده.

    این دقیقا برعکس کاربردهای بلوتوث کلاسیکه. مثلا وقتی دارید با هدفون بلوتوثی به موسیقی گوش میدید، رادیوی بلوتوث کلاسیک همیشه روشنه تا ارتباط پایدار بمونه و کمترین تاخیر رو داشته باشه، یا مثلا وقتی میخواید یک فایل بزرگ رو بین دو تا گوشی منتقل کنید.

    مقایسه بلوتوث کلاسیک و بلوتوث کم‌مصرف (BLE)

    با اینکه این دو تا پروتکل شباهت‌های زیادی دارن، مثلا هر دو زیرمجموعه استاندارد بلوتوث هستن و هر دو تو باند فرکانسی ۲.۴ گیگاهرتز کار میکنن، اما دو تا پروتکل کاملا جدا و ناسازگار با هم هستن. یعنی یک دستگاه که فقط بلوتوث کلاسیک داره نمیتونه به یک دستگاه که فقط BLE داره وصل بشه.

    • بلوتوث کلاسیک برای انتقال حجم زیادی از داده طراحی شده، اما در عوض مصرف انرژیش هم بالاست. همون مثال گوش دادن به موسیقی با هدفون بی‌سیم رو در نظر بگیرید. این یک کاربرد کلاسیک برای بلوتوث کلاسیکه.
    • بلوتوث کم‌مصرف (BLE)، از طرف دیگه، برای کاربردهایی طراحی شده که نیازی به انتقال حجم بالای داده ندارن اما در عوض عمر باتری خیلی براشون مهمه. مثلا یک سنسور دما تو یک انبار بزرگ رو تصور کنید که میخواید نصبش کنید و برای ماه‌ها یا حتی سال‌ها دیگه بهش دست نزنید. برای چنین کاربردی، BLE انتخاب خیلی بهتریه.

    البته تفاوت‌های فنی بیشتری بین این دو وجود داره، اما اگه بخوایم خیلی سطح بالا و خودمونی بگیم، تفاوت اصلی بین بلوتوث کلاسیک و BLE تو مصرف انرژی و سرعت انتقال داده است.

    ویژگیبلوتوث کلاسیک (Classic Bluetooth)بلوتوث کم‌مصرف (BLE)
    هدف اصلیانتقال مداوم داده (مثل صدا)انتقال بسته‌های کوچک داده به صورت دوره‌ای
    مصرف انرژیبالابسیار پایین (تا ۱۰۰ برابر کمتر از کلاسیک)
    سرعت انتقال دادهبالاترپایین‌تر
    کاربرد اصلیهدفون، اسپیکر، انتقال فایلسنسورها، گجت‌های پوشیدنی، دستگاه‌های پزشکی
    حالت کاریهمیشه متصل و فعالبیشتر اوقات در حالت خواب، برای مدت کوتاه فعال

    چرا BLE اینقدر خوبه؟ (مزیت‌ها)

    تا اینجا فهمیدیم که BLE با فکر کردن به یک بازار خاص طراحی شده: بازار دستگاه‌هایی که نیاز به مصرف انرژی پایین و انتقال داده کم دارن. برای اینکه نیاز این بازار رو برآورده کنه، بلوتوث کم‌مصرف یک سری مزیت‌های مهم هم برای توسعه‌دهنده‌ها و هم برای مصرف‌کننده‌ها فراهم میکنه. بیایید چند تا از مهم‌ترین‌هاش رو ببینیم:

    • مصرف انرژی پایین: حتی وقتی با بقیه تکنولوژی‌های کم‌مصرف مقایسه‌اش میکنیم، BLE باز هم بهینه و کم‌مصرفه. راز این مصرف کم اینه که رادیوی دستگاه تا جای ممکن خاموش میمونه و فقط برای فرستادن مقدار کمی داده با سرعت پایین برای مدت کوتاهی روشن میشه.
    • هزینه پایین برای شروع توسعه: ماژول‌ها و چیپست‌های BLE در مقایسه با تکنولوژی‌های مشابه، قیمت پایین‌تری دارن. این به خاطر اینه که استفاده ازش خیلی زیاد شده و رقابت تو بازار بالا رفته.
    • دسترسی آزاد به مستندات فنی: برای بیشتر پروتکل‌ها و تکنولوژی‌های بی‌سیم دیگه، شما باید عضو رسمی اون گروه یا کنسرسیوم بشید تا بتونید به مشخصات فنیش دسترسی داشته باشید. عضویت تو این گروه‌ها میتونه خیلی گرون باشه (حتی تا هزاران دلار در سال). اما برای BLE، مستندات فنی نسخه‌های اصلی (مثل 4.0, 4.2, 5.0, 5.1, 5.2, 5.3 و غیره) رو میتونید به صورت رایگان از وب‌سایت Bluetooth.com دانلود کنید.
    • وجود گسترده در گوشی‌های هوشمند: این شاید بزرگترین مزیت BLE نسبت به رقباش مثل ZigBee، Z-Wave و Thread باشه. تقریبا همه مردم دنیا یک گوشی هوشمند دارن و تقریبا تمام این گوشی‌ها سخت‌افزار BLE رو داخلشون دارن. این به توسعه‌دهنده‌ها یک پایگاه کاربری بالقوه خیلی بزرگ برای اپلیکیشن‌هاشون میده.

    آیا BLE هیچ محدودیتی نداره؟

    به عنوان یک توسعه‌دهنده، فهمیدن محدودیت‌های یک تکنولوژی به اندازه فهمیدن مزیت‌هاش مهمه. اینطوری میتونید تصمیم بگیرید که آیا این تکنولوژی برای پروژه شما مناسبه یا نه. بیایید چند تا از مهم‌ترین محدودیت‌های BLE رو بررسی کنیم.

    • سرعت انتقال داده (Throughput): سرعت انتقال داده تو BLE توسط نرخ داده رادیوی فیزیکی محدود میشه. این نرخ به نسخه بلوتوثی که استفاده میشه بستگی داره.
      • برای نسخه‌های بلوتوث قبل از ۵.۰، این نرخ روی ۱ مگابیت بر ثانیه (Mbps) ثابته.
      • اما برای بلوتوث ۵.۰ و بالاتر، این نرخ بسته به حالت و لایه فیزیکی (PHY) که استفاده میشه، متغیره. میتونه مثل نسخه‌های قبلی ۱ مگابیت بر ثانیه باشه، یا وقتی از قابلیت سرعت بالا (high-speed) استفاده میشه به ۲ مگابیت بر ثانیه برسه.
      • وقتی هم از قابلیت برد بلند (long-range) استفاده میشه، این نرخ به ۵۰۰ یا ۱۲۵ کیلوبیت بر ثانیه (Kbps) کاهش پیدا میکنه.
      • نکته مهم: این نرخ‌ها مربوط به لایه رادیوییه. سرعتی که کاربر نهایی در سطح اپلیکیشن تجربه میکنه، خیلی کمتر از این حرف‌هاست.
    • برد (Range): تکنولوژی BLE برای کاربردهای با برد کوتاه طراحی شده، برای همین برد عملکردش محدوده. چند تا عامل روی برد BLE تاثیر میذارن:
      • فرکانس کاری: این تکنولوژی تو طیف فرکانسی ۲.۴ گیگاهرتز ISM کار میکنه که خیلی تحت تاثیر موانعی مثل اشیای فلزی، دیوارها و آب (مخصوصا بدن انسان) قرار میگیره.
      • طراحی آنتن: عملکرد و طراحی آنتن دستگاه BLE خیلی مهمه.
      • پوشش فیزیکی دستگاه: قاب و بدنه دستگاه روی عملکرد آنتن تاثیر میذاره، مخصوصا اگه آنتن داخلی باشه.
      • جهت‌گیری دستگاه: این مورد هم به موقعیت قرارگیری آنتن مربوط میشه (مثلا تو گوشی‌های هوشمند). به طور کلی برد BLE بین ۰ تا ۲۵ متر بهینه است و در شرایط ایده‌آل میتونه تا ۱۰۰ متر هم برسه.
    • نیاز به دروازه (Gateway) برای اتصال به اینترنت: برای اینکه داده رو از یک دستگاه که فقط BLE داره به اینترنت بفرستید، به یک دستگاه دیگه نیاز دارید که هم BLE داشته باشه و هم به اینترنت وصل باشه (مثلا یک گوشی هوشمند یا یک دستگاه مخصوص). این دستگاه واسط، داده رو از دستگاه BLE میگیره و بعد به اینترنت منتقل میکنه.

    BLE رو کجاها میبینیم؟ (کاربردهای واقعی)

    وقتی BLE تو سال ۲۰۱۰ معرفی شد، تمرکزش بیشتر روی کاربردهای اینترنت اشیا (IoT) بود که تو اونها حجم کمی از داده با سرعت پایین منتقل میشه. تو این ده سال اخیر، BLE تو کاربردهای خیلی متنوعی از دستگاه‌های مصرفی گرفته تا تولیدات صنعتی استفاده شده. بیایید چند تا از رایج‌ترین کاربردهاش رو ببینیم:

    • اتوماسیون خانگی: بخش بزرگی از بازار خانه هوشمند به لطف استفاده از بلوتوث LE ممکن شده. این تکنولوژی به دستگاه‌هایی مثل لامپ‌های هوشمند، ترموستات‌های هوشمند، قفل‌های هوشمند و سنسورهایی که دود یا باز بودن پنجره رو تشخیص میدن، اجازه میده با هم ارتباط برقرار کنن.
    • ردیاب‌های تناسب اندام: خیلی از ما ساعت‌های هوشمند یا مچ‌بندهای سلامتی داریم که ضربان قلب، تعداد قدم‌ها و چیزای دیگه رو ردیابی میکنن. این دستگاه‌های سلامتی و ردیاب فعالیت، با استفاده از BLE با اپلیکیشن‌های روی گوشیمون ارتباط برقرار میکنن. این انتقال‌های کوتاه و سریع داده در فاصله نزدیک، یک مثال عالی برای کاربرد BLE هست.
    • دستگاه‌های صوتی: همه ما با هدفون‌های بلوتوثی آشناییم، اما معمولا این دستگاه‌ها از بلوتوث کلاسیک استفاده میکنن. یکی از جدیدترین پیشرفت‌ها در زمینه بلوتوث کم‌مصرف، چیزی به اسم LE Audio هست. این استاندارد جدید چندین مزیت نسبت به بلوتوث سنتی داره، از جمله کیفیت صدای بهتر، مصرف انرژی کمتر و پشتیبانی از سمعک‌ها.
    • ردیابی تماس (Contact Tracing): سیستم‌های هوشمند ردیابی تماس دارن برای کمک به جلوگیری از شیوع بیماری‌های عفونی استفاده میشن. به جای گزارش‌دهی دستی، ردیابی تماس با استفاده از BLE به صورت مداوم «تگ»های BLE یا گوشی‌های هوشمند اطراف رو اسکن میکنه تا به صورت ناشناس تماس‌های نزدیک بین افراد رو ثبت کنه. مثلا در یک محیط کاری، به هر کارمند یک تگ BLE داده میشه و اگه یک نفر بیمار بشه، به راحتی میشه فهمید چه کسانی با اون در تماس نزدیک بودن.
    • تگ‌های پیدا کردن اشیا: با شلوغ شدن سفرها، بعضی‌ها تگ‌هایی مثل AirTag یا Tile رو به چمدونشون وصل میکنن تا اگه گم شد بتونن پیداش کنن. این دستگاه‌های ردیاب دقیق که با BLE کار میکنن، فقط برای چمدون نیستن. میتونید اونها رو به هر چیزی که فکر میکنید ممکنه گم بشه وصل کنید، مثل دوچرخه یا کلید ماشین، و موقعیتش رو از طریق یک اپلیکیشن روی گوشی پیدا کنید.
    • تبلیغات هدفمند: تصور کنید تو یک فروشگاه لباس هستید و یهو یک نوتیفیکیشن روی گوشیتون میاد که یک کوپن تخفیف برای همون فروشگاهی که توش هستید بهتون میده. این نوع تبلیغات شخصی‌سازی شده و مبتنی بر مکان، دقیقا کاریه که تبلیغ‌کننده‌ها و صاحبان فروشگاه‌ها میتونن انجام بدن. این کار به لطف پیشرفت‌های بلوتوث ۵.۰ و تکنولوژی پخش همگانی «بیکن»های بلوتوثی ممکنه.
    • مدیریت انبار: مدیران انبارها دارن از راهکارهای مبتنی بر BLE برای ردیابی دما و رطوبت محموله‌های حساس، تشخیص افتادن بسته‌های شکننده و حتی پیدا کردن بهینه‌ترین مکان برای نگهداری دارایی‌ها در انبار استفاده میکنن. پتانسیل زیادی وجود داره که هوش مصنوعی و BLE با هم ترکیب بشن و یک زنجیره لجستیک واقعا هوشمند ایجاد کنن.
    • ایمنی کارکنان: تگ‌های BLE میتونن به روش‌های مختلفی به حفظ ایمنی کارکنان کمک کنن. مثلا دکمه‌های وحشت (Panic buttons) برای کارمندان بانک یا هتل که در معرض خطر هستن. این افراد میتونن با فشار دادن تگ BLE به صورت نامحسوس درخواست کمک کنن. یا سیستم‌های تشخیص سقوط (Fall detection) در سایت‌های ساختمانی یا خانه‌های سالمندان که به محض تشخیص سقوط، به صورت خودکار هشدار ارسال میکنن.

    بیکن‌های BLE (BLE Beacons)

    بیکن‌های بلوتوث، فرستنده‌های کوچیک، بی‌سیم و باتری‌خور هستن که از پروتکل BLE برای ارسال سیگنال استفاده میکنن. نکته خاص در مورد بیکن‌ها اینه که معمولا یک‌طرفه کار میکنن. یعنی فقط به دستگاه‌های BLE اطرافشون سیگنال میفرستن (پخش همگانی یا Broadcast)، اما داده‌ای دریافت نمیکنن. بیکن‌ها برای این کار نیازی به اتصال اینترنت ندارن. یک سناریوی معمول اینه که یک بیکن به صورت مداوم داده رو به دستگاه‌های هوشمند اطرافش (مثل موبایل‌ها و ساعت‌های هوشمند) پخش میکنه.

    در حال حاضر، پشتیبانی گوشی‌های هوشمند از بیکن‌های بلوتوثی هنوز کامل نیست، برای همین پیاده‌سازی‌های واقعی اونها کمه. اما در آینده احتمالا میبینیم که از بیکن‌ها برای کارهایی مثل بازاریابی مجاورتی (Proximity marketing)، مسیریابی داخلی (مثلا تو یک مرکز خرید بزرگ) و ردیابی دارایی‌ها در صنعت لجستیک بیشتر استفاده میشه.

    خب، حالا بریم سراغ بخش فنی ماجرا: معماری BLE

    پروتکل بلوتوث کم‌مصرف، حتی برای توسعه‌دهنده‌های باتجربه هم ساده نیست. برای اینکه سفر شما برای یادگیری توسعه BLE رو شروع کنیم، میخوایم معماری پروتکل بلوتوث LE رو به صورت کلی و لایه‌های مختلفش رو با هم بررسی کنیم.

    بلوتوث کم‌مصرف یک پروتکل هست. مثل هر پروتکل دیگه‌ای، این هم مثل یک کتابچه قوانینه که دستگاه‌ها برای ارتباط و تبادل اطلاعات باید ازش پیروی کنن. مهمه که بدونید عملکرد کلی یک پروتکل به پروتکل‌های کوچیکتری تقسیم میشه که هر کدوم یک وظیفه خیلی تخصصی دارن. این پروتکل‌های کوچیکتر در یک معماری لایه‌ای به اسم پشته پروتکل (Protocol Stack) کنار هم قرار میگیرن.

    پشته پروتکل بلوتوث به طور کلی به سه بخش یا زیرسیستم اصلی تقسیم میشه: اپلیکیشن (Application)، میزبان (Host) و کنترلر (Controller). داخل هر کدوم از این بلوک‌ها، لایه‌های مشخصی وجود داره.

    لایه‌های پروتکل BLE

    اگه شما توسعه‌دهنده‌ای هستید که میخواید اپلیکیشن‌های BLE بنویسید، لازم نیست خیلی نگران لایه‌هایی که پایین‌تر از لایه مدیر امنیت (Security Manager) و پروتکل ویژگی (Attribute Protocol) هستن باشید. اما دونستن کلیات این لایه‌ها میتونه مفید باشه. بیایید یه نگاهی بهشون بندازیم.

    • لایه فیزیکی (Physical Layer – PHY):
      این لایه به رادیوی فیزیکی اشاره داره که برای ارتباط و مدوله/دمدوله کردن داده استفاده میشه. این لایه تو همون باند فرکانسی ISM (طیف ۲.۴ گیگاهرتز) کار میکنه.
    • لایه پیوند (Link Layer):
      این لایه با لایه فیزیکی (رادیو) در ارتباطه و برای لایه‌های بالاتر یک راه برای تعامل با رادیو فراهم میکنه. این لایه مسئول مدیریت وضعیت رادیو و همچنین الزامات زمانی برای پایبندی به مشخصات فنی بلوتوث کم‌مصرفه.
    • رابط کنترلر میزبان (Host Controller Interface – HCI):
      لایه HCI یک پروتکل استاندارد هست که توسط مشخصات بلوتوtoh تعریف شده و به لایه میزبان (Host) اجازه میده با لایه کنترلر (Controller) ارتباط برقرار کنه. این لایه‌ها میتونن روی چیپ‌های جداگانه باشن یا هر دو روی یک چیپ باشن.
    • پروتکل کنترل و تطبیق پیوند منطقی (L2CAP):
      لایه L2CAP مثل یک لایه تقسیم‌کننده پروتکل عمل میکنه. این لایه چندین پروتکل رو از لایه‌های بالاتر میگیره و اونها رو تو بسته‌های استاندارد BLE قرار میده. بعد این بسته‌ها رو به لایه‌های پایین‌تر میفرسته.
    • پروتکل ویژگی (Attribute Protocol – ATT):
      پروتکل ATT تعریف میکنه که یک سرور چطور داده‌هاش رو در اختیار یک کلاینت قرار میده و این داده‌ها چطور ساختاردهی شدن.
    • پروفایل ویژگی عمومی (Generic Attribute Profile – GATT):
      این لایه یکی از مهم‌ترین لایه‌ها برای توسعه‌دهنده‌هاست. GATT فرمت داده‌ای که توسط یک دستگاه BLE ارائه میشه رو تعریف میکنه. همچنین رویه‌های لازم برای دسترسی به این داده‌ها رو مشخص میکنه.

      تو GATT دو تا نقش اصلی وجود داره: سرور (Server) و کلاینت (Client).

      • سرور: دستگاهیه که داده‌هایی که کنترل میکنه یا در اختیار داره رو به بقیه نشون میده.

      • کلاینت: دستگاهیه که با سرور ارتباط برقرار میکنه تا داده‌های سرور رو بخونه یا رفتارش رو کنترل کنه.

      یادتون باشه که یک دستگاه BLE میتونه همزمان هم سرور باشه و هم کلاینت.

      برای فهمیدن GATT، باید با دو مفهوم کلیدی آشنا بشید: سرویس‌ها (Services) و مشخصه‌ها (Characteristics).


      • سرویس (Service): یک گروه از یک یا چند «ویژگی» (Attribute) هست. هدفش اینه که ویژگی‌های مرتبط که یک کارکرد خاص رو روی سرور انجام میدن، کنار هم جمع کنه. مثلا، «سرویس باتری» که توسط خود گروه SIG تعریف شده، شامل یک مشخصه به اسم «سطح باتری» هست.

      • مشخصه (Characteristic): همیشه بخشی از یک سرویسه و یک تیکه از اطلاعات یا داده رو نشون میده که سرور میخواد در اختیار کلاینت بذاره. مثلا، «مشخصه سطح باتری» میزان شارژ باقی‌مونده باتری رو نشون میده که کلاینت میتونه اون رو بخونه.

      در BLE، شش نوع عملیات روی مشخصه‌ها وجود داره:

      • دستورها (Commands)
      • درخواست‌ها (Requests)
      • پاسخ‌ها (Responses)
      • اعلان‌ها (Notifications)
      • نشانه‌ها (Indications)
      • تاییدها (Confirmations)
    • پروفایل دسترسی عمومی (Generic Access Profile – GAP):
      این هم یکی دیگه از لایه‌های بسیار مهم برای توسعه‌دهنده‌هاست. GAP یک چارچوب تعریف میکنه که میگه دستگاه‌های BLE چطور با هم تعامل کنن. این شامل موارد زیر میشه:

      • نقش‌های دستگاه‌های BLE

      • تبلیغات (Advertising) – (پخش همگانی، کشف، پارامترهای تبلیغ، داده تبلیغ)

      • برقراری ارتباط (Connection) – (شروع ارتباط، پذیرش ارتباط، پارامترهای ارتباط)

      • امنیت


      نقش‌های مختلف یک دستگاه BLE اینها هستن:



      • پخش‌کننده (Broadcaster): دستگاهی که تبلیغات (Advertisements) میفرسته اما بسته‌ای دریافت نمیکنه و اجازه اتصال هم به کسی نمیده. مثل یک بیکن.

      • ناظر (Observer): دستگاهی که به بسته‌های تبلیغاتی که بقیه میفرستن گوش میده اما با دستگاه تبلیغ‌کننده ارتباط برقرار نمیکنه.

      • مرکزی (Central): دستگاهی که دستگاه‌های تبلیغ‌کننده دیگه رو کشف میکنه و بهشون گوش میده. یک دستگاه مرکزی این قابلیت رو هم داره که به یک دستگاه تبلیغ‌کننده وصل بشه. معمولا گوشی‌های هوشمند یا کامپیوترها این نقش رو دارن.

      • پیرامونی (Peripheral): دستگاهی که تبلیغ میکنه و اتصال از دستگاه‌های مرکزی رو قبول میکنه. معمولا سنسورها، ساعت‌های هوشمند و دستگاه‌های کوچیک این نقش رو دارن.


      یادتون باشه که یک دستگاه میتونه همزمان چند تا نقش داشته باشه. مثلا گوشی هوشمند شما میتونه در نقش مرکزی باشه وقتی به ساعت هوشمندتون وصله، و همزمان در نقش پیرامونی باشه وقتی به کامپیوترتون وصله.


    ردیابی موقعیت با BLE

    یکی از جذاب‌ترین کاربردهای BLE، استفاده از اون برای ردیابی موقعیت در فضاهای داخلیه، جایی که GPS کار نمیکنه. این کار معمولا با دو روش انجام میشه: استفاده از سنسورها یا استفاده از بیکن‌ها.

    • موقعیت‌یابی با سنسورها: در این روش، سنسورهای BLE در مکان‌های ثابتی در یک فضای داخلی نصب میشن. این سنسورها به صورت غیرفعال به سیگنال‌های ارسالی از دستگاه‌های بلوتوثی مثل گوشی‌های هوشمند، تگ‌های ردیابی دارایی، بیکن‌ها و گجت‌های پوشیدنی گوش میدن. با توجه به قدرت سیگنال دریافتی (RSSI) از دستگاه فرستنده، موقعیت اون دستگاه تخمین زده میشه. این داده به یک سیستم موقعیت‌یاب داخلی (IPS) فرستاده میشه و اون سیستم با استفاده از الگوریتم‌های چندجانبه‌سازی (multilateration) موقعیت دقیق دستگاه رو محاسبه میکنه.
    • موقعیت‌یابی با بیکن‌ها: در این روش، بیکن‌ها در مکان‌های ثابت نصب میشن و به طور مداوم سیگنال‌هایی حاوی یک شناسه منحصر به فرد رو پخش میکنن. یک دستگاه مثل گوشی هوشمند که یک اپلیکیشن مخصوص روش نصب شده، وقتی در محدوده بیکن قرار میگیره، سیگنال رو دریافت میکنه. اگه دستگاه سیگنال حداقل سه بیکن رو دریافت کنه، میتونه با مقایسه قدرت سیگنال اونها، موقعیت خودش رو تخمین بزنه.

    دقت موقعیت‌یابی با BLE معمولا در حد چند متر (کمتر از ۵ متر در شرایط بهینه) هست. این دقت به اندازه تکنولوژی‌هایی مثل UWB (که دقت در حد سانتی‌متر داره) بالا نیست، اما برای خیلی از کاربردها کاملا کافیه و مزیت‌هایی مثل هزینه پایین و مصرف انرژی کم داره.

    آینده موقعیت‌یابی با BLE: با معرفی بلوتوث ۵.۱ و قابلیت جدیدش به اسم جهت‌یابی (Direction Finding)، قراره دقت موقعیت‌یابی با BLE به سطح زیر یک متر و حتی سانتی‌متر برسه. این قابلیت جدید به دستگاه‌ها اجازه میده نه تنها قدرت سیگنال، بلکه زاویه رسیدن سیگنال (Angle of Arrival – AoA) رو هم محاسبه کنن که باعث میشه موقعیت‌یابی خیلی دقیق‌تر بشه.

    پرسش و پاسخ‌های رایج در مورد BLE

    • سوال ۱: پس BLE همون بلوتوث معمولیه؟
      نه. با اینکه هر دو زیرمجموعه استاندارد بلوتوث هستن، اما دو تا پروتکل جدا و ناسازگار با هم هستن. بلوتوث کلاسیک برای انتقال مداوم داده مثل صدا طراحی شده و مصرف انرژی بالایی داره. BLE برای انتقال‌های کوتاه و کم‌حجم داده طراحی شده و مصرف انرژیش فوق‌العاده پایینه.
    • سوال ۲: چرا BLE برای اینترنت اشیا (IoT) اینقدر مهمه؟
      دو دلیل اصلی وجود داره: اول، مصرف انرژی خیلی پایینش که باعث میشه دستگاه‌های باتری‌خور بتونن برای ماه‌ها یا سال‌ها کار کنن. دوم، برای اکثر کاربردهای IoT مثل سنسورها، فقط لازمه حجم کمی از داده (مثلا فقط دمای فعلی) به صورت دوره‌ای ارسال بشه که BLE برای این کار کاملا بهینه است.
    • سوال ۳: BLE به زبان ساده چطور کار میکنه؟
      سه مرحله اصلی داره:
      1. تبلیغ (Advertising): دستگاه‌های پیرامونی (مثل یک سنسور) بسته‌های کوچیک داده رو به صورت مداوم پخش میکنن تا حضور خودشون رو اعلام کنن.
      2. اسکن (Scanning): دستگاه‌های مرکزی (مثل یک گوشی) به این بسته‌های تبلیغاتی گوش میدن تا دستگاه‌های اطراف رو پیدا کنن.
      3. اتصال (Connection): وقتی دستگاه مرکزی یک دستگاه پیرامونی رو پیدا کرد، میتونه بهش درخواست اتصال بده و بعد از اون، دو دستگاه میتونن داده رو به صورت دوطرفه رد و بدل کنن.
    • سوال ۴: نقش‌های مختلف دستگاه‌های BLE چی هستن؟
      چهار نقش اصلی وجود داره:
      • پیرامونی (Peripheral): دستگاهی که تبلیغ میکنه و منتظر اتصال میمونه (مثل ساعت هوشمند).
      • مرکزی (Central): دستگاهی که اسکن میکنه و اتصال رو برقرار میکنه (مثل گوشی موبایل).
      • پخش‌کننده (Broadcaster): دستگاهی که فقط تبلیغ میکنه و قابل اتصال نیست (مثل بیکن‌ها).
      • ناظر (Observer): دستگاهی که فقط به تبلیغات گوش میده و وصل نمیشه.
    • سوال ۵: چند تا مثال واقعی از کاربرد BLE میزنید؟
      حتما. ردیاب‌های تناسب اندام (مثل فیت‌بیت)، ساعت‌های هوشمند، تجهیزات پزشکی بی‌سیم (مثل مانیتورهای قند خون)، قفل‌های هوشمند در خانه، لامپ‌های هوشمند، تگ‌های پیدا کردن وسایل (مثل ایرتگ)، و سیستم‌های موقعیت‌یاب داخلی در فروشگاه‌ها و فرودگاه‌ها، همگی از BLE استفاده میکنن.

    منابع

    • [2] Bluetooth Low Energy (BLE) – Cisco Meraki Documentation
    • [4] Bluetooth RTLS: BLE Location Tracking & Positioning | Inpixon
    • [6] What is Medical BLE? | AiRISTA Blog
    • [8] BLE Scanner 4.0 on the App Store
    • [10] BLE Scanner (Connect & Notify) – Apps on Google Play
    • [1] BLE vs Bluetooth : r/embedded
    • [3] Bluetooth Low Energy (BLE): A Complete Guide
    • [5] Can someone explain BLE to me? (Bluetooth Modules) : r/embedded
    • [7] BLE | Bluetooth Low Energy – Why Everyone Is Using It?
    • [9] BLE (Bluetooth Low Energy): What Is BLE? | 7SIGNAL
  • آشنایی و کار با سرور دیتابیس مای‌اس‌کیو‌ال MySQL

    قبل از هر چیزی، بیاید کلمه‌ها رو بشکافیم تا همه چیز روشن بشه. مای‌اس‌کیو‌ال یه «سیستم مدیریت دیتابیس رابطه‌ای اوپن سورس» یا به قول خارجی‌ها RDBMS هست. میدونم، اسمش ترسناکه، ولی قول میدم خیلی ساده‌اس.

    دیتابیس یعنی چی؟

    خیلی ساده، دیتابیس یه انبار خیلی بزرگ و مرتب برای نگهداری اطلاعاته. هر نرم‌افزاری نیاز به یه همچین انباری داره. مثلا وقتی یه چیزی رو تو گوگل سرچ میکنید، وارد اکانتتون میشید، یا یه تراکنش مالی انجام میدید، یه دیتابیس این اطلاعات رو ذخیره میکنه تا بعدا بشه دوباره بهش دسترسی داشت. مای‌اس‌کیو‌ال توی این کار استاده.

    مدل رابطه‌ای یا Relational یعنی چی؟

    حالا چرا بهش میگن «رابطه‌ای»؟ چون این نوع دیتابیس، اطلاعات رو توی انبارهای درهم و برهم نمیریزه. به جاش، داده‌ها رو توی جدول‌های جداگونه و مرتبی سازماندهی میکنه، خیلی شبیه فایل‌های اکسل که همه باهاش آشناییم. هر جدول ردیف‌ها و ستون‌های خودشو داره. مثلا یه جدول برای اطلاعات کاربرا (اسم، فامیل، ایمیل) و یه جدول دیگه برای محصولات (اسم، قیمت، موجودی).

    این ساختار منطقی، که بهش میگن «اسکیما» (Schema)، تعریف میکنه که داده‌ها چطور سازماندهی بشن و جدول‌های مختلف چه رابطه‌ای با هم دارن. مثلا میشه تعریف کرد که هر کاربر میتونه چند تا محصول رو بخره. اینجوری برنامه‌نویس‌ها و مدیرای دیتابیس میتونن خیلی راحت داده‌ها رو ذخیره، بازیابی و تحلیل کنن. از متن ساده و عدد و تاریخ گرفته تا چیزهای جدیدتر مثل JSON و وکتورها.

    SQL چیه؟

    خب، حالا که یه انبار مرتب داریم، چطوری باهاش حرف بزنیم؟ چطوری بهش بگیم «لیست همه کاربرایی که اهل تهران هستن رو بهم بده»؟ اینجا SQL وارد میشه. اس‌کیو‌ال (SQL) که مخفف Structured Query Language یا «زبان پرس‌وجوی ساختاریافته» هست، یه زبان برنامه‌نویسیه که برای بازیابی، آپدیت، حذف و کلا مدیریت داده‌ها توی دیتابیس‌های رابطه‌ای استفاده میشه. مای‌اس‌کیو‌ال هم اسمش رو از همین SQL گرفته و از این زبان برای مدیریت و پرس‌وجو از داده‌ها استفاده میکنه.

    تلفظ درستش چیه؟

    تلفظ رسمی این اسم «مای‌اس‌کیو‌ال» (My S-Q-L) هست، ولی خیلی‌ها بهش «مای‌سیکوئل» (My Sequel) هم میگن که یه تلفظ رایجه.

    پس به طور خلاصه، مای‌اس‌کیو‌ال یه سیستم مدیریت دیتابیسه که داده‌ها رو توی جدول‌های منظم نگهداری میکنه و با استفاده از زبان SQL به ما اجازه میده با این داده‌ها کار کنیم.

    بخش دوم: چرا اینقدر طرفدار داره و کجاها به کار میاد؟

    محبوبیت مای‌اس‌کیو‌ال اتفاقی نیست. چند تا دلیل کلیدی وجود داره که باعث شده این سیستم بعد از حدود ۳۰ سال هنوزم یکی از اولین انتخاب‌ها برای خیلی از پروژه‌ها باشه.

    ۱. اوپن سورس بودن و جامعه بزرگ

    یکی از بزرگترین مزیت‌های مای‌اس‌کیو‌ال اینه که اوپن سورسه. یعنی چی؟ یعنی هر کسی میتونه نرم‌افزارش رو از اینترنت دانلود کنه و بدون هیچ هزینه‌ای ازش استفاده کنه. شرکت‌ها حتی میتونن کد منبعش رو تغییر بدن تا با نیازهای خاص خودشون هماهنگ بشه.

    این نرم‌افزار تحت مجوزی به اسم GNU General Public License (GPL) منتشر میشه که یه سری قوانین مشخص داره. البته اگه شرکتی نخواد از این مجوز استفاده کنه یا بخواد کد مای‌اس‌کیو‌ال رو توی یه محصول تجاری قرار بده، میتونه نسخه تجاریش رو بخره.

    این اوپن سورس بودن باعث شده یه جامعه جهانی خیلی بزرگ و فعال دورش شکل بگیره. این جامعه کلی دانش و منبع تولید میکنه؛ از آموزش‌های مختلف گرفته تا راهنمایی توی فروم‌ها. همین جامعه با تست کردن نرم‌افزار توی سناریوهای مختلف، به پیدا کردن و رفع باگ‌ها کمک زیادی کرده و مای‌اس‌کیو‌ال رو به یه سیستم خیلی قابل اعتماد تبدیل کرده.

    ۲. کارایی، پایداری و مقیاس‌پذیری بالا

    مای‌اس‌کیو‌ال به سریع، قابل اعتماد و مقیاس‌پذیر بودن معروفه. این سیستم از اول برای این ساخته شده که بتونه دیتابیس‌های بزرگ رو به سرعت مدیریت کنه و سال‌هاست که توی محیط‌های کاری خیلی سنگین و حساس استفاده میشه.

    • مقیاس‌پذیری (Scalability): یکی از ویژگی‌های مهم مای‌اس‌کیو‌ال، معماری تکثیر (Replication) داخلیشه. این ویژگی به شرکت‌های بزرگی مثل فیسبوک اجازه میده که اپلیکیشن‌هاشون رو برای پشتیبانی از میلیاردها کاربر مقیاس‌پذیر کنن. یعنی وقتی کسب‌وکار رشد میکنه و تعداد کاربرها زیاد میشه، مای‌اس‌کیو‌ال هم میتونه پا به پاش بزرگ بشه.
    • تراکنش‌های ACID: برنامه‌نویس‌ها روی دو تا قابلیت کلیدی مای‌اس‌کیو‌ال خیلی حساب میکنن: یکی همین مقیاس‌پذیری و اون یکی پشتیبانی از تراکنش‌های ACID. این کلمه مخفف چهارتا خاصیته: «اتمی بودن (Atomicity)، سازگاری (Consistency)، ایزوله‌سازی (Isolation) و دوام (Durability)». این چهارتا ویژگی تضمین میکنن که تراکنش‌های دیتابیس به شکل قابل اعتماد و دقیقی پردازش بشن. با این قابلیت، مای‌اس‌کیو‌ال میتونه تضمین کنه که همه تغییرات داده‌ها به شکلی پایدار و مطمئن انجام میشن، حتی اگه وسط کار سیستم به مشکل بخوره یا برق بره.

    ۳. سادگی در استفاده و سازگاری گسترده

    خیلی‌ها مای‌اس‌کیو‌ال رو به خاطر سادگی در نصب و استفاده تحسین میکنن. در عین حال، به اندازه‌ای قابل اعتماد و مقیاس‌پذیره که برای سازمان‌هایی با حجم داده بسیار بزرگ و تعداد کاربران زیاد هم مناسبه.

    این سیستم با پلتفرم‌های تکنولوژی و زبان‌های برنامه‌نویسی مختلفی مثل جاوا، پایتون، پی‌اچ‌پی (PHP) و جاوااسکریپت سازگاری بالایی داره. یه نکته جالب دیگه اینه که از تکثیر (replication) بین نسخه‌های مختلف هم پشتیبانی میکنه. یعنی یه اپلیکیشن که با مای‌اس‌کیو‌ال نسخه ۵.۷ کار میکنه، میتونه به راحتی به نسخه ۸.۰ تکثیر بشه.

    علاوه بر این، مای‌اس‌کیو‌ال انعطاف‌پذیری خوبی برای توسعه اپلیکیشن‌های دیتابیس سنتی (SQL) و اپلیکیشن‌های بدون اسکیما (NoSQL) داره. این یعنی برنامه‌نویس‌ها میتونن داده‌های رابطه‌ای و اسناد JSON رو توی یک دیتابیس و یک اپلیکیشن با هم ترکیب کنن.

    ۴. مقرون به صرفه بودن

    چون مای‌اس‌کیو‌ال اوپن سورسه، استفاده ازش رایگانه و هزینه‌ای نداره، به جز هزینه سخت‌افزاری که روش نصب میشه و آموزشی که برای یادگیریش لازمه. برای آموزش هم که جامعه جهانی بزرگش کلی منابع آموزشی و تخصص برای حل مشکلات رو به شکل ارزونی فراهم میکنه. البته خود شرکت اوراکل هم دوره‌های آموزشی متنوعی رو ارائه میده.

    کاربردهای واقعی مای‌اس‌کیو‌ال

    توانایی مای‌اس‌کیو‌ال در ذخیره و تحلیل حجم عظیمی از داده‌ها باعث شده که توی کارهای خیلی متنوعی، از کمک به تصمیم‌گیری‌های پیچیده تجاری گرفته تا پیدا کردن یه رستوران محلی برای قرار شام، کاربرد داشته باشه. بعضی از کاربردهای اصلیش ایناست:

    • وب‌سایت‌های فروشگاهی (Ecommerce): برای مدیریت اطلاعات مشتریان و محصولات.
    • سیستم‌های مدیریت محتوا (CMS): برای ارائه محتوای وب‌سایت‌ها.
    • اپلیکیشن‌های مالی: برای ردیابی امن تراکنش‌ها و داده‌های مالی.
    • شبکه‌های اجتماعی: برای ذخیره پروفایل کاربران و تعاملاتشون.

    بخش سوم: سرور چیه و چرا مای‌اس‌کیو‌ال بهش نیاز داره؟

    خب، حالا که فهمیدیم مای‌اس‌کیو‌ال چیه، بیاید در مورد یه مفهوم کلیدی دیگه حرف بزنیم: «سرور». شاید شنیده باشید که میگن «سرور مای‌اس‌کیو‌ال». این یعنی چی؟

    مفهوم موتور (Engine) دیتابیس

    هر سیستم مدیریت دیتابیس رابطه‌ای (RDBMS) یه چیزی به اسم «موتور» (Engine) داره. این موتور در واقع اون بخشیه که کوئری‌های شما رو تفسیر میکنه و نتایج رو برمیگردونه. بدون این موتور، دیتابیس شما چیزی بیشتر از یه فضای ذخیره‌سازی ساده نیست. به این موتور به طور کلی میگن «سرور».

    این سرور لزوما نباید روی یه سخت‌افزار جداگونه و اختصاصی اجرا بشه، هرچند که معمولا این کار مزایای زیادی داره. اکثر RDBMSها یه نسخه‌ای از موتورشون رو دارن که میشه به صورت محلی (locally) روی همون کامپیوتر خودتون اجرا کرد. پس در اصل، شما همیشه به این موتور نیاز دارید تا بتونید از داده‌هاتون پرس‌وجو کنید، حتی اگه در قالب یه کتابخونه (library) محلی یا یه فایل اجرایی روی سیستم خودتون باشه.

    چرا از یه فایل متنی ساده استفاده نکنیم؟

    شاید بپرسید چرا اینقدر پیچیده‌اش کنیم؟ چرا داده‌ها رو توی یه فایل متنی ساده نریزیم؟ خب، میتونید این کار رو بکنید. میتونید داده‌هاتون رو سریالایز کنید و توی یه فایل متنی ذخیره کنید. ولی وقتی این کار رو میکنید، تمام مسئولیت ذخیره‌سازی و مدیریت داده‌ها میفته گردن کد خودتون.

    یه مفهوم کلیدی توی دیتابیس‌های مبتنی بر SQL، همون اصول ACID هست که قبلا در موردش حرف زدیم. سرور دیتابیس این توانایی رو داره که چندین کوئری همزمان رو مدیریت و صف‌بندی کنه و در عین حال، این اصول رو حفظ کنه. دیتابیس‌ها برای کارایی بالا به حافظه (RAM) و پردازنده (CPU) زیادی نیاز دارن و باید به فضای ذخیره‌سازی با تاخیر کم (low-latency) دسترسی داشته باشن.

    مدل کلاینت/سرور

    مای‌اس‌کیو‌ال یه سیستم کلاینت/سرور هست. این سیستم از یه سرور SQL چند رشته‌ای (multithreaded) تشکیل شده که از بک‌اند‌های مختلفی پشتیبانی میکنه. در کنارش، چندین برنامه و کتابخونه کلاینت، ابزارهای مدیریتی و رابط‌های برنامه‌نویسی اپلیکیشن (API) متنوعی هم وجود داره.

    اگه دیتابیس شما فقط قراره توسط یه برنامه و روی یه دستگاه مستقل استفاده بشه، شاید استفاده از یه نسخه محلی RDBMS کافی باشه. اما توی دنیای متصل امروزی، خیلی از اپلیکیشن‌ها از این سود میبرن که چندین دستگاه از یک دیتابیس مشترک استفاده کنن. وقتی این اتفاق میفته، شما یا باید یکی از دستگاه‌ها رو به عنوان سرور اختصاص بدید (و احتمالا همیشه روشنش بذارید)، یا سرور رو روی یه سخت‌افزار اختصاصی یا توی فضای ابری (cloud) اجرا کنید.

    چرا سرور رو روی یه سخت‌افزار جدا میذارن؟

    چند تا دلیل مهم برای این کار وجود داره:

    1. منابع سیستم: دیتابیس‌ها به شدت به ورودی/خروجی (IO) وابسته‌ان. اگه حافظه کافی برای بارگذاری همه چیز توی رم وجود نداشته باشه، باید از فایل سیستم استفاده بشه. ممکنه روی کامپیوتر شما منابع کافی برای اجرای همزمان دیتابیس و برنامه اصلی با کارایی مطلوب وجود نداشته باشه.
    2. امنیت: نسخه‌های تجاری و سازمانی موتورهای دیتابیس برای رسیدن به کارایی بالاتر، نیاز دارن که به سطح پایین‌تری از سیستم دسترسی داشته باشن و امتیازات امنیتی بیشتری بگیرن. این موضوع میتونه یه ریسک امنیتی بزرگ برای داده‌های شرکتی باشه. به همین دلیل، موتور دیتابیس معمولا روی یه سرور اختصاصی با یه زمینه امنیتی خاص میزبانی میشه که کاربرای عادی اصلا اجازه لاگین به کنسولش رو ندارن. چون این سرورها میتونن آسیب‌پذیر باشن، معمولا از فایروال‌ها برای مقاوم‌سازیشون در برابر حملات استفاده میشه.
    3. مدیریت: مدیریت همه این موارد روی یه کامپیوتر شخصی یا ایستگاه کاری میتونه خیلی دردسرساز باشه.

    بحث مرکزی‌سازی: آیا همیشه خوبه که یه سرور دیتابیس برای همه سرویس‌ها داشته باشیم؟

    یه سوالی که برای خیلی از مدیران سیستم پیش میاد اینه که آیا بهتره یه ماشین مجازی (VM) یا سرور اختصاصی فقط برای مای‌اس‌کیو‌ال داشته باشیم و بقیه سرویس‌ها (مثل Nextcloud و…) به اون وصل بشن، یا اینکه برای هر سرویس، یه سرور مای‌اس‌کیو‌ال جدا روی همون ماشین مجازی خودش نصب کنیم؟

    جواب کوتاه اینه که «نه، مرکزی‌سازی همیشه بهترین راه نیست». رویکردهای مختلفی برای شرایط مختلف وجود داره و این یه تصمیمه که به نیازهای خاص هر پروژه بستگی داره.

    بخش چهارم: چطوری مای‌اس‌کیو‌ال رو به دست بیاریم؟

    خب، حالا که با مفاهیم اولیه آشنا شدیم، بیاید ببینیم چطوری میشه مای‌اس‌کیو‌ال رو دانلود و نصب کرد. مای‌اس‌کیو‌ال در چند نسخه مختلف ارائه میشه که هر کدوم برای یه سری کاربردها مناسبن.

    نسخه‌های مختلف مای‌اس‌کیو‌ال

    • MySQL Enterprise Edition: این نسخه جامع‌ترین مجموعه از ویژگی‌های پیشرفته، ابزارهای مدیریتی و پشتیبانی فنی رو برای مای‌اس‌کیو‌ال شامل میشه. هدفش رسیدن به بالاترین سطح از مقیاس‌پذیری، امنیت، قابلیت اطمینان و آپ‌تایم (uptime) هست.
    • MySQL NDB Cluster CGE: این نسخه یه دیتابیس تراکنشی اوپن سورس و real-time هست که برای دسترسی سریع و همیشه روشن به داده‌ها در شرایطی با توان عملیاتی بالا (high throughput) طراحی شده. این نسخه شامل MySQL NDB Cluster Manager و همه چیزهایی که در نسخه Enterprise Edition هست هم میشه.
    • MySQL Community (GPL) Downloads: این همون نسخه اوپن سورس و رایگان مای‌اس‌کیو‌ال هست که تحت مجوز GPL منتشر میشه و اکثر افراد از این نسخه برای پروژه‌هاشون استفاده میکنن.
    • MySQL برای ISVها، OEMها و VARها: جالبه بدونید که بیش از ۲۰۰۰ تا ISV (فروشنده نرم‌افزار مستقل)، OEM (سازنده تجهیزات اصلی) و VAR (نماینده فروش با ارزش افزوده) به مای‌اس‌کیو‌ال به عنوان دیتابیس تعبیه شده (embedded) در محصولاتشون اعتماد میکنن. این کار بهشون کمک میکنه تا اپلیکیشن‌ها، سخت‌افزارها و دستگاه‌هاشون رو رقابتی‌تر کنن، سریع‌تر به بازار عرضه کنن و هزینه تمام شده کالاهاشون رو کاهش بدن.

    راهنمای نصب با MySQL Installer

    برای نصب مای‌اس‌کیو‌ال روی ویندوز، یه ابزار خیلی راحت به اسم MySQL Installer وجود داره. این ابزار یه تجربه نصب جادوگر-محور (wizard-based) رو برای تمام نیازهای نرم‌افزاری مای‌اس‌کیو‌ال شما فراهم میکنه.

    • نسخه 8.0.43: اینستالرهای نسخه‌های ۵.۷ تا ۸.۰ شامل آخرین ورژن‌های محصولات مای‌اس‌کیو‌ال هستن.
    • نکته مهم در مورد نسخه‌های جدید: توجه داشته باشید که سری ۸.۰ آخرین سری هست که MySQL Installer داره. از نسخه ۸.۱ به بعد، باید از فایل MSI یا آرشیو Zip خود محصول مای‌اس‌کیو‌ال برای نصب استفاده کنید. همچنین، سرور مای‌اس‌کیو‌ال نسخه ۸.۱ و بالاتر، ابزاری به اسم MySQL Configurator رو هم همراه خودش داره که به پیکربندی سرور کمک میکنه.
    کدوم فایل رو انتخاب کنیم؟

    وقتی میخواید اینستالر رو دانلود کنید، دو تا گزینه اصلی دارید:

    1. mysql-installer-web-community: اگه موقع اجرای اینستالر به اینترنت وصل هستید، این فایل رو انتخاب کنید. این نسخه حجم کمتری داره و فایل‌های مورد نیاز رو موقع نصب دانلود میکنه.
    2. mysql-installer-community: اگه موقع اجرای اینستالر به اینترنت دسترسی ندارید، این فایل رو انتخاب کنید. این نسخه همه فایل‌های لازم رو داخل خودش داره و حجمش بیشتره.

    یه نکته فنی هم اینه که خود برنامه MySQL Installer ۳۲ بیتی هست، ولی میتونه هم باینری‌های ۳۲ بیتی و هم ۶۴ بیتی رو نصب کنه.

    بخش پنجم: یه کیس استادی واقعی: ساختن یه سرور قدرتمند برای مای‌اس‌کیو‌ال

    تئوری کافیه، بیاید یه مثال واقعی رو با هم بررسی کنیم. فرض کنید صاحب یه کسب‌وکار کوچیک هستید و میخواید یه سرور دیتابیس جدید برای میزبانی یه دیتابیس تحلیل صنعت و تحقیقات بازار راه بندازید. این سناریو از یه فروم واقعی به اسم Level1Techs برداشته شده.

    مشخصات دیتابیس مورد نظر:

    • نسخه مای‌اس‌کیو‌ال: ۸.۴
    • اندازه دیتابیس: حدود ۱ ترابایت، پخش شده در حدود ۱۵۰ تا جدول.
    • مشخصات جداول: طولانی‌ترین جدول حدود ۱۰ میلیارد ردیف داره و میانگین طول جداول ۱۰۰ میلیون ردیفه.
    • نوع کاربری:
      • نوشتن (Writes) خیلی کم: به جز بارگذاری اولیه، آپدیت‌ها به صورت ساعتی یا روزانه توسط خزنده‌های وب (crawlers) مختلف انجام میشه و فقط یه کاربر مینویسه.
      • کوئری‌های (Queries) کم ولی پیچیده: کوئری‌ها شامل تعداد زیادی JOIN و WHERE هستن و فقط یه کاربر برای گزارش‌گیری روزانه و تحلیل‌های موردی ازشون استفاده میکنه.

    سخت‌افزار جدید پیشنهادی:

    بر اساس این نیازها، کاربر یه سخت‌افزار خیلی جالب رو پیشنهاد داده. بیاید قطعاتش رو با هم بررسی کنیم:

    • پردازنده (CPU): AMD Ryzen 9 7900X
      • چرا این انتخاب شده؟ بر اساس نوع کاربری که کوئری‌های پیچیده ولی تکی داره، عملکرد تک‌هسته‌ای (single core performance) خیلی کلیدیه. این پردازنده میتونه تا فرکانس ۵.۶ گیگاهرتز بوست بشه که برای این کار عالیه.
    • حافظه (RAM): 4x 32GB DDR5 ECC UDIMM 2Rx8 4800
      • چرا ECC؟ عبارت ECC مخفف Error-Correcting Code هست. این نوع رم میتونه خطاهای کوچیک حافظه رو به صورت خودکار شناسایی و تصحیح کنه. برای یه سرور دیتابیس که پایداری داده‌ها حیاتیه، استفاده از رم ECC یه تصمیم هوشمندانه است.
    • مادربورد (Motherboard): AsRock Rack B650D4U-2L2T/BCM
    • فضای ذخیره‌سازی (Storage):
      • درایوهای اصلی: 4x Samsung PM9A3 1920GB 2.5″ in a ZFS RAID 10
      • کش نوشتن (SLOG): 1x Intel Optane P4800X as ZFS SLOG vdev
    • سیستم عامل (OS): Debian 12

    مقایسه با سخت‌افزار فعلی:

    سخت‌افزار فعلی این کاربر یه Intel Xeon E3-1230 v6 با ۳۲ گیگابایت رم غیر-ECC و یه SSD معمولی بوده. ارتقای پیشنهادی یه جهش عظیم در عملکرد محسوب میشه.

    یه سوال مهم: Ryzen یا EPYC؟

    کاربر یه سوال خوب هم پرسیده: آیا بهتر نیست به جای این سیستم، یه سرور مبتنی بر پردازنده استفاده شده EPYC (مثلا مدل 7F52) ببندم؟

    • مزایای EPYC: این پردازنده ۴ برابر کش L3 بیشتری داره و از رم بیشتری هم پشتیبانی میکنه.
    • معایب EPYC: فرکانس بوستش فقط تا ۳.۹ گیگاهرتز میرسه، در حالی که Ryzen تا ۵.۶ گیگاهرتز میره.

    اینجا یه بده‌بستان (trade-off) وجود داره. برای کاربری خاص این شخص که عملکرد تک‌هسته‌ای مهمه، Ryzen 7900X با فرکانس بالاترش احتمالا انتخاب بهتریه. اما برای سناریوهایی با تعداد کاربران همزمان زیاد، EPYC با کش و هسته‌های بیشترش میتونه برنده باشه.

    بخش ششم: مدیریت مای‌اس‌کیو‌ال با وب‌مین (Webmin) – یه راهنمای کامل

    خب، سرور رو راه انداختیم، مای‌اس‌کیو‌ال رو هم نصب کردیم. حالا چطوری مدیریتش کنیم؟ یکی از ابزارهای عالی برای این کار وب‌مین (Webmin) هست. وب‌مین یه پنل تحت وب هست که به شما اجازه میده دیتابیس‌ها، جدول‌ها، کاربران و خیلی چیزای دیگه رو از طریق یه رابط کاربری گرافیکی ساده مدیریت کنید. بیاید ببینیم چطوری میشه باهاش کار کرد.

    شروع کار با ماژول مای‌اس‌کیو‌ال در وب‌مین

    وقتی وارد ماژول مای‌اس‌کیو‌ال در وب‌مین میشید، اگه همه چیز درست باشه، یه صفحه با آیکون‌هایی برای دیتابیس‌های موجود میبینید. اگه وب‌مین نتونه با پسورد درست به سرور دیتابیس وصل بشه، یه فرم لاگین ازتون میخواد. معمولا باید با نام کاربری root و پسوردی که برای کاربر روت مای‌اس‌کیو‌ال تعریف کردید وارد بشید.

    ساختن یه دیتابیس جدید

    وقتی مای‌اس‌کیو‌ال برای اولین بار نصب میشه، یه دیتابیس به اسم mysql ساخته میشه که اطلاعات مربوط به کاربران و دسترسی‌ها رو تو خودش نگه میداره. بهتره برای داده‌های خودتون یه دیتابیس جدا بسازید. مراحلش اینه:

    1. روی لینک «Create a new database» کلیک کنید.
    2. یه اسم برای دیتابیس جدیدتون توی فیلد «Database name» وارد کنید. اسم باید فقط شامل حروف و اعداد باشه و فاصله نداشته باشه.
    3. روی دکمه «Create» کلیک کنید. به همین راحتی!

    ساختن یه جدول جدید

    حالا که دیتابیس رو داریم، باید توش جدول بسازیم.

    1. روی آیکون دیتابیسی که ساختید کلیک کنید.
    2. تعداد فیلدهایی (ستون‌هایی) که میخواید جدولتون داشته باشه رو وارد کنید و روی دکمه «Create a new table» کلیک کنید.
    3. یه اسم برای جدولتون توی فیلد «Table name» وارد کنید.
    4. نوع جدول (Table type): اینجا میتونید نوع موتور ذخیره‌سازی جدول رو انتخاب کنید. رایج‌ترین‌ها اینان:
    5. تعریف فیلدها (Initial fields):
    6. وقتی همه فیلدها رو تعریف کردید، روی دکمه «Create» کلیک کنید.

    مشاهده و ویرایش محتوای جدول

    اگه میخواید داده‌های داخل یه جدول رو ببینید، ویرایش کنید، یا ردیف جدیدی اضافه کنید:

    1. روی آیکون دیتابیس و بعد روی آیکون جدول مورد نظرتون کلیک کنید.
    2. روی دکمه «View Data» کلیک کنید.
    3. لیستی از ردیف‌های جدول به شما نشون داده میشه. اگه جدول شما کلید اصلی داشته باشه، میتونید:

    نکته مهم: اگه یه جدول کلید اصلی نداشته باشه، وب‌مین نمیتونه ردیف‌های خاصی رو برای ویرایش یا حذف شناسایی کنه. پس همیشه برای جدول‌هاتون یه کلید اصلی تعریف کنید.

    پشتیبان‌گیری (Backup) و بازیابی (Restore)

    بکاپ گرفتن از دیتابیس‌های مهم یکی از حیاتی‌ترین کارهاست. وب‌مین این کار رو خیلی ساده کرده.

    برای ساختن بکاپ:

    1. وارد صفحه دیتابیس مورد نظر بشید.
    2. روی دکمه «Backup Database» کلیک کنید.
    3. توی فیلد «Backup to file»، آدرس فایلی که میخواید بکاپ توش ذخیره بشه رو وارد کنید (مثلا /tmp/backup.sql).
    4. یه گزینه مهم به اسم «Add drop table statements to backup?» وجود داره. اگه این رو روی «Yes» بذارید، موقع بازیابی بکاپ، اگه جدولی با همون اسم از قبل وجود داشته باشه، اول حذف میشه و بعد داده‌های جدید جایگزین میشن. این برای بکاپ‌های معمولی خوبه. اگه روی «No» بذارید، داده‌های بکاپ به داده‌های موجود اضافه میشن.
    5. روی «Backup Now» کلیک کنید.

    فایل بکاپ مای‌اس‌کیو‌ال در واقع یه فایل متنیه که پر از دستورات SQL برای ساختن دوباره جدول‌ها و وارد کردن داده‌هاست.

    برای بازیابی بکاپ:

    1. وارد صفحه دیتابیسی بشید که میخواید بکاپ رو توش بازیابی کنید.
    2. روی دکمه «Execute SQL» کلیک کنید.
    3. به بخش «Select SQL commands file to execute on database» برید.
    4. فایل بکاپتون رو از روی سرور یا کامپیوتر خودتون انتخاب کنید.
    5. روی «Execute» کلیک کنید.

    مدیریت کاربران و دسترسی‌ها (Permissions)

    مای‌اس‌کیو‌ال سیستم کاربران و دسترسی‌های مخصوص به خودشو داره که از کاربران سیستم عامل جداست. شما میتونید برای هر کاربر تعریف کنید که به کدوم دیتابیس‌ها، از کدوم کامپیوترها (هاست‌ها) و با چه سطح دسترسی (مثلا فقط خوندن، یا خوندن و نوشتن) بتونه وصل بشه.

    برای مدیریت کاربران، روی آیکون «User Permissions» در صفحه اصلی ماژول کلیک کنید. از اونجا میتونید کاربر جدید بسازید، پسوردها رو عوض کنید، و دسترسی‌ها رو برای هر کاربر به صورت دقیق مشخص کنید. مثلا برای یه اپلیکیشن، بهتره یه کاربر جدا بسازید که فقط به دیتابیس همون اپلیکیشن دسترسی داشته باشه و فقط بتونه کارهای لازم مثل خوندن و نوشتن رو انجام بده.

    بخش هفتم: مای‌اس‌کیو‌ال در دنیای ابری: آشنایی با HeatWave

    حالا که با نسخه سنتی مای‌اس‌کیو‌ال آشنا شدیم، بیاید یه نگاهی به آینده و نسخه‌های ابریش بندازیم. اوراکل یه سرویس ابری خیلی قدرتمند برای مای‌اس‌کیو‌ال به اسم HeatWave ارائه میده.

    HeatWave چیه؟

    HeatWave در واقع یه شتاب‌دهنده کوئری درون-حافظه‌ای (in-memory) برای دیتابیس مای‌اس‌کیو‌ال هست. این تنها سرویس دیتابیس ابری مای‌اس‌کیو‌اله که چنین شتاب‌دهنده‌ای رو ارائه میده و میتونه تراکنش‌ها (transactions) رو با تحلیل‌های همزمان (real-time analytics) ترکیب کنه.

    این یعنی چی؟ یعنی دیگه نیازی به فرآیندهای پیچیده، زمان‌بر و پرهزینه ETL (Extract, Transform, Load) برای انتقال داده‌ها به یه دیتابیس تحلیلی جداگونه نیست. شما میتونید روی همون داده‌های تراکنشی خودتون، به صورت همزمان تحلیل‌های سنگین انجام بدید. این کار باعث افزایش فوق‌العاده زیاد عملکرد مای‌اس‌کیو‌ال برای کارهای تحلیلی و ترکیبی میشه.

    ویژگی‌های پیشرفته HeatWave:

    • HeatWave AutoML: به توسعه‌دهنده‌ها و تحلیل‌گرای داده اجازه میده که مدل‌های یادگیری ماشین (Machine Learning) رو به صورت کاملا خودکار داخل HeatWave MySQL بسازن، آموزش بدن، پیاده‌سازی کنن و خروجی‌هاشون رو توضیح بدن.
    • HeatWave GenAI: کاربران میتونن از هوش مصنوعی مولد (Generative AI) یکپارچه و خودکار هم استفاده کنن.
    • HeatWave Autopilot: این ویژگی با استفاده از اتوماسیون مبتنی بر یادگیری ماشین، به صورت خودکار به بهبود عملکرد مای‌اس‌کیو‌ال و کاهش هزینه‌ها کمک میکنه، بدون اینکه به تخصص در زمینه تیونینگ دیتابیس نیاز باشه.

    این سرویس روی پلتفرم‌های ابری مختلفی مثل Oracle Cloud Infrastructure (OCI)، Amazon Web Services (AWS) و Microsoft Azure در دسترسه.

    بخش هشتم: وقتی همه چیز خراب میشه: راهنمای عیب‌یابی (Troubleshooting)

    هیچ سیستمی بی‌نقص نیست و گاهی وقتا مای‌اس‌کیو‌ال هم به مشکل میخوره. بیاید چند تا از مشکلات رایج و راه‌های حلشون رو بررسی کنیم.

    چطور بفهمیم سرور مای‌اس‌کیو‌ال کار میکنه یا نه؟

    گاهی وقتا یه برنامه نمیتونه به دیتابیس وصل بشه و خطای «Unable to connect to MySQL server» میده. اولین قدم اینه که ببینیم اصلا سرور مای‌اس‌کیو‌ال در حال اجرا هست یا نه. چند تا راه برای این کار توی ترمینال لینوکس وجود داره:

    • sudo service mysql status یا sudo service mysqld status
    • ps aux | grep mysql (این دستور همه پروسه‌هایی که کلمه mysql توشون هست رو نشون میده)
    • lsof -i :3306 (این دستور چک میکنه که آیا پروسه‌ای به پورت پیش‌فرض مای‌اس‌کیو‌ال یعنی ۳۳۰۶ گوش میده یا نه)

    یه نکته مهم: «پروسه در حال اجراست» همیشه به معنی «سرویس در دسترس است» نیست. ممکنه پروسه بالا باشه ولی به خاطر مشکلات پیکربندی یا چیزای دیگه، از بیرون نشه بهش وصل شد.

    اگه سرور در حال اجرا بود، مشکل میتونه از جای دیگه باشه. مثلا:

    • خطای احراز هویت: نام کاربری یا پسورد اشتباهه.
    • اسم اشتباه دیتابیس: اسم دیتابیسی که میخواید بهش وصل بشید رو اشتباه وارد کردید.
    • فایروال: ممکنه فایروال سرور یا کلاینت، اتصال به پورت ۳۳۰۶ رو مسدود کرده باشه.

    بهترین راه برای تست، اینه که سعی کنید از طریق خود ترمینال به صورت دستی به مای‌اس‌کیو‌ال وصل بشید:

    mysql -u <username> -p <database-name>

    یه مشکل رایج در XAMPP (روی مک)

    یه مشکل رایج که برای توسعه‌دهنده‌ها پیش میاد، مخصوصا اونایی که از پکیج‌هایی مثل XAMPP استفاده میکنن، اینه که مای‌اس‌کیو‌ال بعد از ری‌استارت کردن کامپیوتر دیگه روشن نمیشه. توی پنل مدیریت XAMPP چراغش قرمز میمونه و وقتی سعی میکنید وارد phpMyAdmin بشید، با خطای #2002 - No such file or directory مواجه میشید.

    این مشکل معمولا به این دلیله که یه پروسه قدیمی از مای‌اس‌کیو‌ال هنوز توی پس‌زمینه در حال اجراست و جلوی اجرا شدن پروسه جدید رو میگیره. راه حلش اینه که اون پروسه قدیمی رو به صورت دستی از بین ببرید (kill کنید).

    راه حل قدم به قدم در ترمینال مک:

    1. ترمینال رو باز کنید و دستور sudo su رو تایپ کنید و پسوردتون رو وارد کنید تا دسترسی روت بگیرید.
    2. دستور ps aux | grep mysql رو وارد کنید. این دستور لیستی از پروسه‌های مربوط به مای‌اس‌کیو‌ال رو به شما نشون میده.
    3. توی لیست، باید شناسه پروسه (process ID یا PID) رو پیدا کنید. این یه عدد هست که معمولا در ستون دوم قرار داره.
    4. حالا با دستور kill -9 {process id} اون پروسه رو از بین ببرید. مثلا: kill -9 739.
    5. حالا به پنل XAMPP برگردید و دوباره سعی کنید مای‌اس‌کیو‌ال رو استارت کنید. به احتمال زیاد مشکل حل میشه.

    پرسش و پاسخ‌های متداول

    سوال: مای‌اس‌کیو‌ال چیست و چرا استفاده میشود؟

    جواب: مای‌اس‌کیو‌ال محبوب‌ترین دیتابیس اوپن سورس دنیاست. توسعه‌دهنده‌ها و مدیران دیتابیس از اون برای ذخیره، آپدیت و تحلیل داده‌ها در اپلیکیشن‌هاشون استفاده میکنن.

    سوال: تفاوت بین SQL و مای‌اس‌کیو‌ال چیست؟

    جواب: SQL یه زبان برنامه‌نویسیه که برای مدیریت و تحلیل داده‌های ذخیره شده در دیتابیس‌ها طراحی شده. مای‌اس‌کیو‌ال یه سیستم مدیریت دیتابیسه که بخشی از اسمش رو از SQL گرفته و از زبان SQL برای مدیریت داده‌ها در دیتابیس‌ها استفاده میکنه.

    سوال: آیا نسخه ابری از مای‌اس‌کیو‌ال وجود دارد؟

    جواب: بله. HeatWave MySQL یه سرویس دیتابیس کاملا مدیریت شده است و تنها سرویس ابریه که بر اساس MySQL Enterprise Edition ساخته شده. این سرویس عملکرد کوئری‌های مای‌اس‌کیو‌ال رو به شدت بهبود میده و تحلیل‌های همزمان روی داده‌های تراکنشی رو ممکن میکنه. این سرویس روی OCI، AWS و Microsoft Azure در دسترسه.

    سوال: مای‌اس‌کیو‌ال در مقایسه با سایر دیتابیس‌ها چگونه است؟

    جواب: مای‌اس‌کیو‌ال یه دیتابیس رابطه‌ای اوپن سورسه. این یعنی داده‌ها رو در ردیف‌ها و ستون‌ها ذخیره میکنه و روابط بین اونها رو در اسکیماها تعریف میکنه. دیتابیس‌های رابطه‌ای محبوب دیگه‌ای هم وجود دارن که اوپن سورس نیستن، مثل Oracle Database. همچنین دیتابیس‌های محبوبی وجود دارن که اصلا رابطه‌ای نیستن. به این‌ها دیتابیس‌های NoSQL میگن، مثل MongoDB.

    منابع

    • [2] Ryzen build for MySQL database server – Hardware Hub / Build a PC – Level1Techs Forums
    • [4] MySQL Database Server | Webmin
    • [6] php – MySQL Database won’t start in XAMPP Manager-osx – Stack Overflow
    • [8] Is centralizing MySQL/mariadb databases on one server best-practice ? : r/sysadmin
    • [10] ssh – How to check if MySQL server is working or not? – Server Fault
    • [1] MySQL
    • [3] MySQL: Understanding What It Is and How It’s Used
    • [5] MySQL :: MySQL Downloads
    • [7] MySQL :: Download MySQL Installer
    • [9] sql – Why do we use servers with MySql? – Stack Overflow

  • همه چیز درباره دیتابیس اوراکل؛ Oracle Database

    اول از همه بیاید ببینیم این اوراکل اصلا چی هست. اوراکل یک سیستم مدیریت پایگاه داده چند مدلی و اختصاصی هست که توسط شرکتی به همین نام یعنی «شرکت اوراکل» ساخته شده و به فروش میرسه. «چند مدلی» یعنی میتونه انواع مختلف داده رو مدیریت کنه. معمولا ازش برای کارهای سنگینی مثل پردازش تراکنش‌های آنلاین (OLTP)، انبار داده (DW) و کارهای ترکیبی استفاده میشه. حالا اینا یعنی چی؟

    • پردازش تراکنش آنلاین (OLTP): فکر کنید به خرید و فروش‌های لحظه‌ای توی یه فروشگاه آنلاین یا تراکنش‌های بانکی. این‌ها کارهایی هستن که باید سریع و دقیق انجام بشن.
    • انبار داده (DW): تصور کنید یه شرکت میخواد تمام داده‌های فروش چند سال گذشته‌اش رو تحلیل کنه تا ببینه چه محصولاتی بیشتر فروش رفتن. این حجم عظیم از داده‌ها توی انبار داده نگهداری و تحلیل میشه.

    اوراکل رو میشه روی سرورهای خودتون، روی فضای ابری (Cloud) یا به صورت ترکیبی (Hybrid Cloud) نصب و استفاده کرد. زبونی هم که برای کار با این پایگاه داده استفاده میشه، زبون معروف SQL هست که باهاش میشه داده‌ها رو به‌روزرسانی یا بازیابی کرد.

    یه نگاه کوتاه به تاریخچه

    داستان اوراکل از سال ۱۹۷۷ شروع شد. لری الیسون به همراه دو تا از دوست‌ها و همکارای سابقش، باب ماینر و اد اوتس، یه شرکت مشاوره به اسم «آزمایشگاه‌های توسعه نرم‌افزار» یا همون SDL رو راه انداختن. این شرکت بعدا به شرکت اوراکل تبدیل شد. SDL اولین نسخه نرم‌افزار اوراکل رو توسعه داد. جالبه بدونید که اسم «اوراکل» از اسم رمز یه پروژه میاد که CIA بودجه‌اش رو تامین میکرد و الیسون قبلا توی شرکت Ampex روی اون کار کرده بود. حتی اولین مشتری اوراکل هم خود CIA بود و بهشون اجازه داد از این اسم رمز برای محصول جدیدشون استفاده کنن.

    یه نکته جالب اینه که الیسون میخواست پایگاه داده‌اش با System R شرکت IBM سازگار باشه، اما IBM کدهای خطای نرم‌افزارش رو منتشر نکرد. با این حال، تا سال ۱۹۸۵ اوراکل تبلیغ میکرد که برنامه‌هایی که برای SQL/DS یا DB2 نوشته شدن، بدون هیچ تغییری روی اوراکل هم اجرا میشن.

    هیچوقت نسخه‌ای به اسم Oracle v1 وجود نداشت. دلیلش هم این بود که الیسون معتقد بود «هیچکس دلش نمیخواد نسخه ۱ یه محصول رو بخره».

    بخش دوم: معماری اوراکل؛ چطور کار میکنه؟

    خب، حالا که فهمیدیم اوراکل چیه، بیاید بریم سراغ بخش جذاب ماجرا: معماری و ساختارش. یه سرور پایگاه داده مثل اوراکل، کلید حل مشکلات مدیریت اطلاعاته. یه سرور خوب باید بتونه حجم زیادی از داده رو توی یه محیط چندکاربره مدیریت کنه؛ یعنی چندین نفر بتونن همزمان به یک داده دسترسی داشته باشن، اون هم با عملکرد بالا. تازه باید جلوی دسترسی‌های غیرمجاز رو بگیره و راه‌حل‌های خوبی هم برای بازیابی اطلاعات بعد از خرابی داشته باشه.

    اوراکل برای این کارها یه سری ویژگی‌ها داره. مثلا میتونه پایگاه داده‌های خیلی بزرگ (حتی در حد ترابایت) رو مدیریت کنه و کنترل کاملی روی مصرف فضا به ما بده. میتونه تعداد زیادی کاربر همزمان رو پشتیبانی کنه و عملکرد بالایی در پردازش تراکنش‌ها داشته باشه. حتی توی بعضی جاها، اوراکل ۲۴ ساعته و بدون وقفه کار میکنه.

    دو بخش اصلی: پایگاه داده و نمونه (Instance)

    1. پایگاه داده: مجموعه‌ای از داده‌هاست که به عنوان یک واحد در نظر گرفته میشن. هدفش هم ذخیره و بازیابی اطلاعات مرتبطه. پایگاه داده یه ساختار فیزیکی و یه ساختار منطقی داره.
    2. نمونه (Instance): هر بار که یه پایگاه داده استارت میخوره، یه قسمتی از حافظه به اسم System Global Area (SGA) بهش اختصاص داده میشه و یه سری فرایندهای پس‌زمینه (Background Processes) هم شروع به کار میکنن. به ترکیب این فرایندها و حافظه میگیم یه «نمونه اوراکل».

    این دو تا از هم جدا هستن. این جدایی به ما اجازه میده که نحوه ذخیره‌سازی فیزیکی داده‌ها رو بدون اینکه روی دسترسی به ساختارهای منطقی تاثیری بذاره، مدیریت کنیم.

    بخش سوم: ساختار فیزیکی؛ فایل‌های واقعی روی دیسک

    ساختار فیزیکی یه پایگاه داده اوراکل از فایل‌هایی تشکیل شده که روی سیستم‌عامل شما قرار دارن. این فایل‌ها محل ذخیره‌سازی واقعی اطلاعات پایگاه داده هستن. سه نوع فایل اصلی داریم:

    1. فایل‌های داده (Datafiles): هر پایگاه داده اوراکل حداقل یه فایل داده داره. تمام داده‌های پایگاه داده، مثل داده‌های جدول‌ها و ایندکس‌ها، به صورت فیزیکی توی این فایل‌ها ذخیره میشن. ویژگی‌های این فایل‌ها اینه که میتونن به یه پایگاه داده تعلق داشته باشن، اندازه‌شون میتونه به صورت خودکار زیاد بشه و میشه اونها رو به صورت آنلاین (در دسترس) یا آفلاین (غیرقابل دسترس) قرار داد. وقتی یه کاربر اطلاعاتی رو میخواد، اگه اون اطلاعات توی حافظه موقت (Cache) نباشه، از روی این فایل‌ها خونده و در حافظه ذخیره میشه. برای بالا بردن عملکرد، داده‌های جدید یا تغییر کرده فورا روی دیسک نوشته نمیشن، بلکه توی حافظه جمع میشن و بعدا به صورت یکجا توسط یه فرایند پس‌زمینه به اسم DBWn روی فایل‌ها نوشته میشن.
    2. فایل‌های لاگ دوباره‌کاری (Redo Log Files): هر پایگاه داده اوراکل حداقل دو تا از این فایل‌ها داره. به مجموعه این فایل‌ها میگیم Redo Log. کار اصلی Redo Log اینه که تمام تغییراتی که روی داده‌ها اعمال میشه رو ثبت کنه. اگه یه مشکلی پیش بیاد (مثلا برق بره) و داده‌های تغییر کرده روی فایل‌های داده نوشته نشن، میشه از روی این فایل‌ها تغییرات رو بازیابی کرد تا هیچ کاری از دست نره. این فایل‌ها برای محافظت از پایگاه داده در برابر خرابی خیلی حیاتی هستن. اوراکل حتی اجازه میده چند نسخه از این فایل‌ها رو روی دیسک‌های مختلف داشته باشید تا اگه یکی خراب شد، بقیه سالم بمونن. به فرایند اعمال اطلاعات این فایل‌ها در زمان بازیابی میگن Rolling Forward.
    3. فایل‌های کنترل (Control Files): هر پایگاه داده اوراکل یه فایل کنترل داره. این فایل اطلاعات مربوط به ساختار فیزیکی پایگاه داده رو نگه میداره. مثلا:

      هر بار که یه نمونه از پایگاه داده استارت میخوره، از این فایل برای شناسایی فایل‌های داده و Redo Log استفاده میشه. اگه ساختار فیزیکی پایگاه داده تغییر کنه (مثلا یه فایل داده جدید اضافه بشه)، این فایل به صورت خودکار توسط اوراکل آپدیت میشه. این فایل در زمان بازیابی پایگاه داده هم خیلی مهمه.

      • اسم پایگاه داده
      • اسم و مکان فایل‌های داده و فایل‌های Redo Log
      • اطلاعات مربوط به زمان ایجاد پایگاه داده

    بخش چهارم: ساختار منطقی؛ سازماندهی داده‌ها به شکل مجازی

    حالا بریم سراغ ساختار منطقی. این ساختار به ما میگه که فضای فیزیکی پایگاه داده چطور استفاده میشه.

    1. فضای جدولی (Tablespaces): یه پایگاه داده به واحدهای ذخیره‌سازی منطقی به اسم Tablespace تقسیم میشه. این فضاها ساختارهای منطقی مرتبط رو با هم گروه‌بندی میکنن. مثلا میشه تمام آبجکت‌های یه اپلیکیشن رو توی یه Tablespace جدا گذاشت تا مدیریت‌شون راحت‌تر بشه. هر پایگاه داده حداقل یه Tablespace به اسم SYSTEM داره. یه Tablespace میتونه آنلاین (در دسترس) یا آفلاین (غیرقابل دسترس) باشه.
    2. اسکیما (Schema): اسکیما مجموعه‌ای از آبجکت‌های پایگاه داده هست. آبجکت‌های اسکیما مستقیما به داده‌های پایگاه داده اشاره دارن. این آبجکت‌ها شامل چیزهایی مثل جدول‌ها، ویوها، سکانس‌ها، رویه‌های ذخیره شده، مترادف‌ها، ایندکس‌ها، کلاسترها و لینک‌های پایگاه داده هستن. هیچ رابطه‌ای بین Tablespace و Schema وجود نداره؛ یعنی آبجکت‌های یه اسکیما میتونن توی Tablespaceهای مختلف باشن و یه Tablespace هم میتونه آبجکت‌هایی از اسکیماهای مختلف رو نگه داره.
    3. بلوک‌های داده، اکستنت‌ها و سگمنت‌ها (Data Blocks, Extents, and Segments): اوراکل برای کنترل دقیق مصرف فضای دیسک از این سه ساختار منطقی استفاده میکنه.

      وقتی اکستنت‌های یه سگمنت پر میشن، اوراکل به صورت پویا فضای جدیدی رو تخصیص میده. برای همین ممکنه اکستنت‌های یه سگمنت روی دیسک پشت سر هم نباشن.

      • بلوک داده (Data Block): کوچک‌ترین واحد ذخیره‌سازی داده در اوراکل هست. هر بلوک داده معادل تعداد مشخصی بایت از فضای فیزیکی دیسک هست. اندازه این بلوک‌ها موقع ساختن پایگاه داده مشخص میشه.
      • اکستنت (Extent): سطح بعدی، اکستنت هست. اکستنت تعداد مشخصی بلوک داده پشت سر هم هست که در یک تخصیص واحد برای ذخیره نوع خاصی از اطلاعات به دست میاد.
      • سگمنت (Segment): سطح بالاتر از اکستنت، سگمنت هست. سگمنت مجموعه‌ای از اکستنت‌هاست که برای یه ساختار منطقی خاص تخصیص داده شده. انواع مختلف سگمنت داریم:
        • سگمنت داده (Data Segment): هر جدول غیرکلاستری یه سگمنت داده داره که تمام داده‌هاش اونجا ذخیره میشه.
        • سگمنت ایندکس (Index Segment): هر ایندکس یه سگمنت ایندکس داره که داده‌هاش رو ذخیره میکنه.
        • سگمنت بازگشتی (Rollback Segment): برای ذخیره موقت اطلاعات «undo» یا بازگشتی استفاده میشه. این اطلاعات برای بازیابی تراکنش‌های ناتمام یا ایجاد نماهای سازگار با خواندن (Read-Consistent Views) به کار میره.
        • سگمنت موقت (Temporary Segment): وقتی یه دستور SQL برای اجرا به یه فضای کاری موقت نیاز داره، اوراکل این سگمنت‌ها رو ایجاد میکنه. بعد از اتمام دستور، این فضا آزاد میشه.

    بخش پنجم: آبجکت‌های اسکیما؛ ابزارهای ما برای کار با داده

    حالا بیاید با ابزارهایی که توی یه اسکیما داریم بیشتر آشنا بشیم. این‌ها همون چیزهایی هستن که یه برنامه‌نویس یا مدیر پایگاه داده مستقیما باهاشون سر و کار داره.

    • جدول (Table): واحد اصلی ذخیره‌سازی داده توی پایگاه داده اوراکل هست. داده‌ها توی سطرها و ستون‌ها ذخیره میشن. هر جدول یه اسم و مجموعه‌ای از ستون‌ها داره. هر ستون هم اسم، نوع داده (مثلا CHAR, DATE, NUMBER) و عرض مشخصی داره.
    • ویو (View): یه ویو مثل یه نمایش سفارشی از داده‌های یک یا چند جدول هست. میشه بهش به عنوان یه «کوئری ذخیره شده» هم نگاه کرد. ویوها خودشون داده‌ای رو ذخیره نمیکنن، بلکه داده‌ها رو از جدول‌های پایه‌ای که روی اون‌ها ساخته شدن، میگیرن. از ویوها معمولا برای ساده‌سازی دسترسی به داده، ایجاد امنیت (مثلا فقط ستون‌های خاصی رو نشون بدیم) یا نمایش داده از چند جدول به صورت یکجا استفاده میشه.
    • ویوی محقق شده (Materialized View): این نوع ویو، برخلاف ویوهای عادی، نتایج یه کوئری رو توی یه آبجکت جدا ذخیره میکنه. یعنی واقعا فضا اشغال میکنه و داده داره. این کار باعث میشه عملکرد کوئری‌ها، مخصوصا توی محیط‌های انبار داده، خیلی بهتر بشه. اسم دیگه‌اش «اسنپ‌شات» (Snapshot) هست.
    • سکانس (Sequence): یه لیست سریالی از اعداد منحصر به فرد تولید میکنه. معمولا برای ستون‌هایی مثل شماره کارمندی یا کد محصول استفاده میشه تا مطمئن باشیم هیچ دو سطری شماره یکسان ندارن. کار برنامه‌نویسی رو خیلی راحت میکنه چون دیگه لازم نیست خودمون نگران تولید اعداد منحصر به فرد باشیم.
    • ایندکس (Index): یه ساختار اختیاریه که برای بالا بردن سرعت بازیابی داده‌ها ساخته میشه. دقیقا مثل فهرست آخر یه کتاب که به شما کمک میکنه یه مطلب رو سریع‌تر پیدا کنید، ایندکس هم به اوراکل کمک میکنه سطر مورد نظر رو سریع‌تر پیدا کنه. ایندکس‌ها روی یک یا چند ستون از یه جدول ساخته میشن و بعد از ساخته شدن، به صورت خودکار توسط اوراکل نگهداری و استفاده میشن.
    • کلاستر و هش کلاستر (Cluster and Hash Cluster): اینها هم ساختارهای اختیاری برای ذخیره‌سازی داده‌های جدول هستن. کلاسترها گروهی از جدول‌ها هستن که چون ستون‌های مشترکی دارن و معمولا با هم استفاده میشن، به صورت فیزیکی کنار هم ذخیره میشن. این کار زمان دسترسی به دیسک رو کم میکنه.
    • مترادف (Synonym): یه اسم مستعار برای یه جدول، ویو، سکانس یا واحد برنامه هست. از مترادف‌ها برای ساده کردن دسترسی به آبجکت‌ها یا مخفی کردن اسم و مالک واقعی اون‌ها استفاده میشه.
    • لینک پایگاه داده (Database Link): یه آبجکت نام‌گذاری شده هست که یه «مسیر» از یه پایگاه داده به پایگاه داده دیگه رو توصیف میکنه. این لینک‌ها توی پایگاه داده‌های توزیع شده برای دسترسی به داده‌های روی سرورهای دیگه استفاده میشن.
    • واحدهای برنامه (Program Units): این‌ها شامل رویه‌ها (Procedures)، توابع (Functions) و پکیج‌ها (Packages) میشن. این واحدها مجموعه‌ای از دستورات SQL و PL/SQL هستن که به عنوان یه واحد قابل اجرا برای انجام یه کار خاص گروه‌بندی میشن.
      • PL/SQL: این زبان رویه‌ای اوراکل، یه افزونه برای SQL هست. به شما اجازه میده منطق برنامه‌نویسی مثل IF...THEN یا حلقه‌ها رو به دستورات SQL اضافه کنید. استفاده از PL/SQL ذخیره شده توی پایگاه داده باعث میشه ترافیک شبکه کم بشه و امنیت و عملکرد برنامه بالا بره.

    بخش ششم: مغز متفکر اوراکل؛ حافظه و فرایندها

    اوراکل برای مدیریت و دسترسی به پایگاه داده از ساختارهای حافظه و فرایندها استفاده میکنه. همه این ساختارها توی حافظه اصلی (RAM) کامپیوترهایی که سیستم پایگاه داده رو تشکیل میدن، وجود دارن.

    ساختارهای حافظه

    1. System Global Area (SGA): این یه ناحیه حافظه مشترکه که داده‌ها و اطلاعات کنترلی یه نمونه اوراکل رو نگه میداره. وقتی یه نمونه استارت میخوره، SGA تخصیص داده میشه و وقتی خاموش میشه، آزاد میشه. کاربرانی که به سرور وصل هستن، داده‌های توی SGA رو به اشتراک میذارن. برای عملکرد بهتر، SGA باید تا جای ممکن بزرگ باشه (البته به شرطی که توی حافظه واقعی جا بشه). SGA خودش چند تا بخش داره:
      • Database Buffer Cache: جدیدترین بلوک‌های داده‌ای که استفاده شدن اینجا ذخیره میشن. چون داده‌های پراستفاده توی حافظه نگه داشته میشن، نیاز به خوندن و نوشتن از روی دیسک (I/O) کم میشه و عملکرد بالا میره.
      • Redo Log Buffer: ورودی‌های Redo Log (لیست تغییرات) قبل از اینکه روی فایل‌های Redo Log نوشته بشن، اینجا ذخیره میشن.
      • Shared Pool: این بخش شامل ساختارهای حافظه مشترک مثل نواحی SQL مشترک هست. هر دستور SQL منحصر به فردی که به پایگاه داده فرستاده میشه، باید پردازش بشه. اطلاعات پردازش اون، مثل درخت تجزیه و نقشه اجرا، توی یه ناحیه SQL مشترک ذخیره میشه. اگه چند اپلیکیشن همون دستور رو اجرا کنن، از همین ناحیه مشترک استفاده میکنن و اینطوری در مصرف حافظه صرفه‌جویی میشه.
      • Large Pool: یه ناحیه اختیاری در SGA هست که برای کارهای سنگینی مثل بکاپ و بازیابی، فرایندهای I/O سرور و حافظه نشست‌ها در پیکربندی سرور چند رشته‌ای استفاده میشه.
    2. Program Global Area (PGA): این یه بافر حافظه هست که داده‌ها و اطلاعات کنترلی یه فرایند سرور رو نگه میداره. هر فرایند سرور PGA مخصوص به خودش رو داره و این حافظه مشترک نیست.

    فرایندها (Processes)

    یه فرایند مثل یه «رشته کنترلی» توی سیستم‌عامل هست که میتونه یه سری مراحل رو اجرا کنه. اوراکل دو نوع کلی فرایند داره:

    1. فرایندهای کاربر (User Processes): این فرایندها کد یه برنامه کاربردی (مثلا یه برنامه نوشته شده با Pro*C/C++) یا یه ابزار اوراکل (مثل Oracle Enterprise Manager) رو اجرا میکنن. فرایند کاربر با فرایندهای سرور ارتباط برقرار میکنه.
    2. فرایندهای اوراکل (Oracle Processes): اینها خودشون دو دسته‌ان:
      • فرایندهای سرور (Server Processes): اوراکل این فرایندها رو برای رسیدگی به درخواست‌های فرایندهای کاربر متصل ایجاد میکنه. فرایند سرور با فرایند کاربر ارتباط برقرار میکنه و با اوراکل تعامل میکنه تا درخواست‌ها رو انجام بده. مثلا اگه یه کاربر داده‌ای رو بخواد که توی بافرهای پایگاه داده نیست، فرایند سرور مرتبط، بلوک‌های داده مناسب رو از فایل‌های داده میخونه و توی SGA میذاره.
      • فرایندهای پس‌زمینه (Background Processes): اوراکل برای هر نمونه یه سری فرایند پس‌زمینه ایجاد میکنه. این فرایندها به صورت ناهمزمان I/O انجام میدن و بر سایر فرایندهای اوراکل نظارت میکنن تا موازی‌سازی رو افزایش بدن و عملکرد و قابلیت اطمینان رو بهتر کنن. بعضی از این فرایندهای مهم اینها هستن:
        • DBWn (Database Writer): بلوک‌های تغییر کرده رو از Database Buffer Cache روی فایل‌های داده مینویسه. این کار رو معمولا زمانی انجام میده که حافظه بافر آزاد کم باشه.
        • LGWR (Log Writer): ورودی‌های Redo Log رو روی دیسک مینویسه.
        • CKPT (Checkpoint): در زمان‌های مشخص، به DBWn سیگنال میده که تمام بافرهای تغییر کرده رو روی دیسک بنویسه. به این رویداد میگن «چک‌پوینت».
        • SMON (System Monitor): وقتی یه نمونه که خراب شده دوباره استارت میخوره، بازیابی رو انجام میده. همچنین سگمنت‌های موقت بی‌استفاده رو پاک میکنه.
        • PMON (Process Monitor): وقتی یه فرایند کاربر با شکست مواجه میشه، بازیابی فرایند رو انجام میده. یعنی حافظه کش رو پاک میکنه و منابعی که اون فرایند استفاده میکرده رو آزاد میکنه.
        • ARCn (Archiver): فایل‌های Redo Log آنلاین رو وقتی پر میشن، در محل ذخیره‌سازی آرشیو کپی میکنه. این فرایند فقط وقتی فعاله که پایگاه داده در حالت ARCHIVELOG باشه.
        • RECO (Recoverer): تراکنش‌های توزیع شده‌ای که به خاطر مشکلات شبکه یا سیستم بلاتکلیف موندن رو حل میکنه.

    بخش هفتم: تراکنش‌ها و یکپارچگی داده؛ چطور اوراکل نظم رو حفظ میکنه؟

    یکی از دغدغه‌های اصلی یه سیستم مدیریت پایگاه داده چندکاربره، کنترل همزمانی (Concurrency) هست؛ یعنی دسترسی همزمان چند کاربر به یک داده. اگه کنترل درستی وجود نداشته باشه، ممکنه داده‌ها به اشتباه آپدیت بشن و یکپارچگی داده‌ها به خطر بیفته.

    اوراکل این مشکلات رو با استفاده از قفل‌ها (Locks) و یه مدل سازگاری چند نسخه‌ای (Multiversion Consistency Model) حل میکنه. اساس این ویژگی‌ها مفهوم تراکنش (Transaction) هست.

    تراکنش (Transaction) چیه؟

    یه تراکنش یه واحد منطقی از کاره که شامل یک یا چند دستور SQL میشه که توسط یه کاربر اجرا میشن. یه تراکنش با اولین دستور SQL قابل اجرای کاربر شروع میشه و وقتی به صراحت Commit (ثبت نهایی) یا Rollback (لغو و بازگشت به حالت قبل) بشه، تموم میشه.

    مثال بانکی:

    فرض کنید یه مشتری میخواد از حساب پس‌اندازش به حساب جاریش پول منتقل کنه. این تراکنش میتونه شامل سه تا عملیات جدا باشه:

    1. کاهش موجودی حساب پس‌انداز.
    2. افزایش موجودی حساب جاری.
    3. ثبت این تراکنش در دفتر روزنامه تراکنش‌ها.

    اوراکل باید تضمین کنه که هر سه تا دستور انجام میشن تا حساب‌ها در تعادل باقی بمونن. اگه یه مشکلی (مثلا خرابی سخت‌افزاری) جلوی اجرای یکی از این دستورها رو بگیره، بقیه دستورهای این تراکنش هم باید لغو بشن. به این کار میگن Rollback.

    • Commit: تغییرات ناشی از تمام دستورات SQL توی یه تراکنش رو دائمی میکنه.
    • Rollback: هر تغییری که در نتیجه دستورات SQL در تراکنش ایجاد شده رو لغو میکنه.
    • Savepoint: برای تراکنش‌های طولانی، میشه نشانگرهای میانی به اسم Savepoint تعریف کرد. اینطوری میشه یه تراکنش رو به بخش‌های کوچیک‌تر تقسیم کرد و در صورت نیاز، فقط تا یه Savepoint مشخص کار رو به عقب برگردوند.

    سازگاری خواندن (Read Consistency)

    اوراکل تضمین میکنه که داده‌ای که یه کاربر میبینه، با یه نقطه زمانی خاص سازگاره و توسط کاربرای دیگه‌ای که همزمان دارن داده‌ها رو تغییر میدن، تحت تاثیر قرار نمیگیره. ساده‌ترین راه برای درک این موضوع اینه که تصور کنید هر کاربر داره روی یه کپی شخصی از پایگاه داده کار میکنه.

    وقتی یه آپدیت اتفاق میفته، مقادیر اصلی داده که تغییر کردن، توی سگمنت‌های بازگشتی (Rollback Segments) پایگاه داده ثبت میشن. تا وقتی این آپدیت به عنوان بخشی از یه تراکنش Commit نشده باقی بمونه، هر کاربری که بعدا اون داده‌های تغییر کرده رو کوئری بگیره، مقادیر اصلی رو میبینه. اوراکل از اطلاعات توی SGA و سگمنت‌های بازگشتی استفاده میکنه تا یه نمای سازگار با خواندن از داده‌های یه جدول برای یه کوئری بسازه.

    قفل‌ها (Locks)

    اوراکل از قفل‌ها هم برای کنترل دسترسی همزمان به داده‌ها استفاده میکنه. قفل‌ها مکانیزم‌هایی هستن که برای جلوگیری از تعاملات مخرب بین کاربرانی که به داده‌های اوراکل دسترسی دارن، طراحی شدن. قفل‌گذاری به صورت خودکار انجام میشه و نیازی به دخالت کاربر نداره. اوراکل داده‌های جدول رو در سطح سطر (Row Level) قفل میکنه. این کار رقابت برای دسترسی به یک داده رو به حداقل میرسونه.

    دو نوع اصلی قفل وجود داره: قفل انحصاری (Exclusive Lock) و قفل اشتراکی (Share Lock). روی یه منبع (مثل یه سطر یا جدول) فقط یه قفل انحصاری میشه گذاشت، اما میشه چندین قفل اشتراکی روی همون منبع داشت.

    بخش هشتم: امنیت در اوراکل

    سیستم‌های پایگاه داده چندکاربره مثل اوراکل، ویژگی‌های امنیتی دارن که نحوه دسترسی و استفاده از پایگاه داده رو کنترل میکنن. امنیت پایگاه داده رو میشه به دو دسته تقسیم کرد:

    1. امنیت سیستم (System Security): مکانیزم‌هایی که دسترسی و استفاده از پایگاه داده رو در سطح سیستم کنترل میکنن. مثل:
      • نام کاربری و رمز عبور معتبر برای اتصال به پایگاه داده.
      • تخصیص فضای دیسک برای کاربران.
      • محدودیت منابع سیستم برای کاربران.
      • ممیزی (Auditing) اقدامات کاربران.
    2. امنیت داده (Data Security): مکانیزم‌هایی که دسترسی و استفاده از پایگاه داده رو در سطح آبجکت‌های اسکیما کنترل میکنن. مثل:
      • اینکه چه کاربرانی به چه آبجکت‌هایی دسترسی دارن.
      • چه عملیاتی روی اون آبجکت‌ها میتونن انجام بدن.

    اوراکل امنیت رو با استفاده از چند ابزار مختلف مدیریت میکنه:

    • کاربران (Users): هر پایگاه داده اوراکل یه لیست از نام‌های کاربری داره. برای دسترسی به پایگاه داده، کاربر باید با یه نام کاربری و رمز عبور معتبر وصل بشه.
    • امتیازات (Privileges): امتیاز یعنی حق اجرای یه نوع خاص از دستور SQL. دو نوع امتیاز داریم:
      • امتیازات سیستم (System Privileges): به کاربر اجازه میده یه کار خاص در سطح کل سیستم انجام بده. مثلا امتیاز ساختن یه Tablespace.
      • امتیازات آبجکت (Schema Object Privileges): به کاربر اجازه میده یه کار خاص روی یه آبجکت مشخص انجام بده. مثلا امتیاز حذف کردن سطرها از یه جدول خاص.
    • نقش‌ها (Roles): نقش‌ها گروه‌های نام‌گذاری شده از امتیازات مرتبط هستن که به کاربران یا نقش‌های دیگه داده میشن. مدیریت امتیازات از طریق نقش‌ها خیلی راحت‌تره. مثلا میشه یه نقش برای یه اپلیکیشن ساخت و تمام امتیازات لازم برای اجرای اون اپلیکیشن رو به اون نقش داد. بعد اون نقش رو به کاربرانی که باید از اپلیکیشن استفاده کنن، تخصیص داد.

    بخش نهم: نسخه‌های مختلف اوراکل

    اوراکل در طول سال‌ها نسخه‌های مختلفی رو منتشر کرده. نام‌گذاری نسخه‌ها هم یه قرارداد خاصی داره. مثلا پسوندهای «c»، «g» و «i» به ترتیب به معنی «Cloud»، «Grid» و «Internet» بودن. در نسخه فعلی یعنی Oracle Database 23ai، پسوند «ai» به معنی «هوش مصنوعی» (Artificial Intelligence) هست. در ادامه یه جدول از نسخه‌های مهم اوراکل و ویژگی‌های کلیدی‌شون رو میبینید:

    نسخه پایگاه داده اوراکلتاریخ انتشار اولیهویژگی‌های برجسته
    Oracle v21979اولین پایگاه داده رابطه‌ای SQL تجاری موجود.
    Oracle v61988قفل‌گذاری در سطح سطر، بکاپ و بازیابی آنلاین.
    Oracle7ژوئن 1992رویه‌های ذخیره شده PL/SQL، تریگرها.
    Oracle8i Database1998پروتکل‌های اینترنتی بومی و جاوا.
    Oracle9i Database2001Oracle Real Application Clusters (RAC)، Oracle XML DB.
    Oracle Database 10g2003مدیریت خودکار پایگاه داده، زیرساخت Grid، Oracle ASM.
    Oracle Database 11gسپتامبر 2007Active Data Guard، Secure Files، Exadata.
    Oracle Database 12cژوئیه 2013معماری چندمستاجری (Multitenant)، In-Memory Column Store، JSON بومی.
    Oracle Database 18cفوریه 2018یکپارچه‌سازی با Active Directory، توابع جدول چندریختی.
    Oracle Database 19c (LTR)فوریه 2019ایجاد خودکار ایندکس، نگهداری آمار به صورت Real-Time.
    Oracle Database 21c (IR)دسامبر 2020جداول بلاک‌چین، اجرای جاوا اسکریپت در پایگاه داده.
    Oracle Database 23ai (LTR)۲ می ۲۰۲۴جستجوی برداری هوش مصنوعی (AI Vector Search)، دوگانگی رابطه‌ای JSON، پشتیبانی از میکروسرویس‌های تراکنشی.

    (LTR مخفف Long Term Release و IR مخفف Innovation Release هست)

    بخش دهم: پرسش و پاسخ از دنیای واقعی

    حالا که با کلیات اوراکل آشنا شدیم، بیاید چند تا سوال واقعی که برای کاربرها پیش اومده رو با هم ببینیم. این سوال‌ها از فروم‌ها و کامیونیتی‌های مختلف جمع‌آوری شدن.

    سوال ۱: من یه مدیر پایگاه داده SQL Server هستم. یاد گرفتن اوراکل چقدر سخته؟

    این سوالی هست که خیلی‌ها میپرسن. بر اساس تجربه کاربری که در این زمینه سوال پرسیده، اونها با دو سال سابقه کار با SQL Server، از اوراکل به خاطر نیازمندی‌های بالای مدیرانش و حقوق بهترشون کمی واهمه داشتن. اما واقعیت اینه که گذار از یه پایگاه داده به پایگاه داده دیگه شدنیه، مخصوصا اگه پس‌زمینه لینوکسی قوی‌تری داشته باشید، چون اوراکل خیلی جاها روی لینوکس اجرا میشه. خیلی از شرکت‌های بزرگ مثل شرکت‌های دفاعی، دولتی، پزشکی و بانکی از اوراکل استفاده میکنن. ممکنه دلیلش این باشه که اپلیکیشن‌های قدیمی‌شون روی اوراکل بوده و به یه استاندارد تبدیل شده. اگه به یادگیری علاقه دارید، شجاع باشید و شاخه کاریتون رو گسترش بدید.

    سوال ۲: چطور میتونم اسم سروری که پایگاه داده اوراکل روش میزبانی میشه رو پیدا کنم؟

    این یه سوال فنی رایجه. چند تا راه برای این کار وجود داره. یه راه ساده استفاده از این کوئری هست:

    select sys_context('USERENV','SERVER_HOST') from dual

    این دستور نیاز به هیچ امتیاز خاصی نداره و برای همین استفاده ازش توی رویه‌های ذخیره شده راحته. البته این پارامتر یعنی SERVER_HOST فقط از نسخه 10G به بعد در دسترسه. با استفاده از sys_context میشه اطلاعات مفید دیگه‌ای هم به دست آورد:

    select
      sys_context ( 'USERENV', 'DB_NAME' ) db_name,
      sys_context ( 'USERENV', 'SESSION_USER' ) user_name,
      sys_context ( 'USERENV', 'SERVER_HOST' ) db_host,
      sys_context ( 'USERENV', 'HOST' ) user_host
    from dual

    این کوئری اسم پایگاه داده، اسم کاربر نشست، هاست پایگاه داده و هاست کاربر رو برمیگردونه.

    سوال ۳: نمیتونم سرور رو متوقف کنم و پیام «Cannot stop/start server – Oracle database server is in existing mode» رو میگیرم. مشکل چیه؟

    یه کاربری با نسخه 9.0.00 با این مشکل مواجه شده بود. وقتی از دستورات stop_all و start_all استفاده میکرد، این پیام رو دریافت میکرد. به نظر میرسید که با وجود این پیام، تمام فرایندهای EM واقعا متوقف میشدن. برای start_all هم این پیام اول نشون داده میشد ولی بعد از چند ثانیه رمز DBO رو میپرسید و فرایندها رو شروع میکرد. این کاربر اشاره کرده بود که پایگاه داده‌اش روی یه سرور اختصاصی نیست و با پایگاه داده‌های دیگه به اشتراک گذاشته شده. این پیام از اسکریپت‌های CM میاد و مدیران پایگاه داده (DBA) نتونسته بودن توضیحش بدن. اینجور مشکلات معمولا به پیکربندی خاص اون محیط برمیگرده.

    سوال ۴: آیا جاوا حتما باید روی سرورهای پایگاه داده اوراکل نصب باشه؟

    یه کاربری که سرورهاش فقط میزبان پایگاه داده اوراکل (نسخه 11g) بودن، این سوال رو پرسیده بود. نصب اوراکل به همراه جاوا انجام شده بود (مثلا در مسیر \OraHome_1\product\11.2.0\dbhome_1\jdk). تیم عملیات شبکه بهش گفته بود که باید تمام نسخه‌های جاوا رو نگهداری و آپدیت کنه. اون کاربر ترجیح میداد اگه جاوا ضروری نیست، اون رو حذف کنه تا از زحمت نگهداریش خلاص بشه. واقعیت اینه که خیلی از ویژگی‌های داخلی اوراکل به جاوا وابسته هستن. بنابراین، جاوا به عنوان بخشی از نصب پایگاه داده اوراکل مورد نیازه و حذف کردنش میتونه مشکلات جدی ایجاد کنه.

    سوال ۵: بکاپ پایگاه داده روی سرور فیزیکی اوراکل در لینوکس چطور کار میکنه؟

    یه کاربر که با نرم‌افزار Veeam کار میکرد، میخواست بدونه بکاپ‌گیری از اوراکل روی سرورهای فیزیکی لینوکس چطوریه، چون Veeam بیشتر برای ماشین‌های مجازی بهینه شده. نرم‌افزارهایی مثل Veeam Agent for Linux (VAL) میتونن از سرورهای فیزیکی لینوکس بکاپ بگیرن. این بکاپ‌ها کل ماشین رو شامل میشن و به صورت فایل‌سیستمی سازگار هستن. در نسخه‌های جدیدتر این ابزارها، ویژگی‌هایی برای اطمینان از سازگاری تراکنشی (Transaction Consistency) پایگاه داده اوراکل هم اضافه شده. این یعنی قبل از بکاپ، پایگاه داده در حالتی قرار میگیره که بکاپ گرفته شده سالم و قابل بازیابی باشه.

    منابع

    • [2] Oracle Database – Wikipedia
    • [4] Java on Oracle Database Server? – Oracle Forums
    • [6] SQL Server DBA – How Hard is Oracle Database? : r/Database
    • [8] How database backup works on physical Oracle Database server in Linux
    • [10] Find the server name for an Oracle database – Stack Overflow
    • [1] Database | Oracle
    • [3] Introduction to the Oracle Server
    • [5] Database Software Downloads | Oracle
    • [7] Introduction to the Oracle Server
    • [9] Cannot stop server – Oracle database server is in existing mode – Discussion – BMC Community
  • پست‌گرس‌کیوال PostgreSQL چیست؟ راهنمای استفاده اولیه

    طبق گفته سازنده‌هاش، پست‌گرس‌کیوال یک سیستم مدیریت پایگاه داده شی‌گرا-رابطه‌ای و متن‌بازه. میدونم، میدونم، این جمله خودش کلی کلمه قلمبه سلمبه داره. بیاین تیکه‌تیکه‌ش کنیم:

    • پایگاه داده (Database): فکر کنین یه دفترچه یادداشت خیلی خیلی بزرگ و هوشمند دارین که میتونین اطلاعات رو خیلی مرتب و منظم توش ذخیره کنین. مثلا اطلاعات دانشجوهای یه دانشگاه، محصولات یه فروشگاه آنلاین، یا لیست آهنگ‌های یه اپلیکیشن موسیقی. به این دفترچه هوشمند میگن پایگاه داده. کارش اینه که اطلاعات رو نگه داره، بهمون اجازه بده توش جستجو کنیم، اطلاعات جدید اضافه کنیم یا اطلاعات قبلی رو تغییر بدیم.
    • سیستم مدیریت پایگاه داده (Database System): حالا اون نرم‌افزاری که به ما اجازه میده اون دفترچه هوشمند (پایگاه داده) رو بسازیم و مدیریتش کنیم، میشه سیستم مدیریت پایگاه داده. پست‌گرس‌کیوال دقیقا همین کار رو میکنه. یه جورایی مثل اون برنامه دفترچه یادداشت توی کامپیوتر یا گوشیتونه، ولی هزاران بار قوی‌تر و پیشرفته‌تر.
    • رابطه‌ای (Relational): این کلمه یعنی اطلاعات توی جدول‌های مختلفی ذخیره میشن که به هم ربط دارن. مثلا یه جدول داریم برای دانشجوها، یه جدول دیگه برای درس‌ها. بعد میتونیم بین این دوتا جدول یه رابطه برقرار کنیم تا مشخص بشه هر دانشجویی چه درس‌هایی رو برداشته. اینجوری همه چیز خیلی منظم و دسته‌بندی شده باقی میمونه.
    • شی‌گرا (Object-Relational): این یه ویژگی پیشرفته‌تره. یعنی پست‌گرس‌کیوال فقط به مدل رابطه‌ای محدود نیست و میتونه ساختارهای داده پیچیده‌تری رو هم مدیریت کنه. فعلا خیلی درگیر این قسمتش نشین، همینقدر بدونین که این ویژگی دستش رو برای کارهای پیچیده‌تر باز میذاره.
    • متن‌باز (Open Source): این یعنی کد اصلی برنامه پست‌گرس‌کیوال در دسترس همه هست. هر کسی میتونه اون رو ببینه، تغییر بده و حتی در بهتر شدنش کمک کنه. این باعث میشه یه جامعه بزرگ از متخصص‌ها در سراسر دنیا روی توسعه‌ش کار کنن و همیشه در حال پیشرفت باشه.

    این سیستم بیشتر از ۳۵ ساله که داره به صورت فعال توسعه داده میشه. این زمان طولانی باعث شده که به عنوان یه ابزار خیلی قابل اعتماد، پر از امکانات و با عملکرد خوب شناخته بشه. به خاطر همین متن‌باز بودنش، کلی اطلاعات و راهنمای رسمی برای نصب و استفاده ازش وجود داره. جامعه کاربری خیلی بزرگی هم داره که همیشه آماده کمک کردن هستن و میتونین از طریق اونها با طرز کارش آشنا بشین یا حتی فرصت‌های شغلی پیدا کنین.

    بخش دوم: سرور، کلاینت، اس‌کیوال؛ مفاهیم پایه رو یاد بگیریم

    وقتی برای اولین بار با ابزارهایی مثل پست‌گرس‌کیوال کار میکنین، یه سری کلمه‌ها مثل «سرور» مدام به چشمتون میخوره. یکی از کاربرها توی ردیت دقیقا همین سوال رو پرسیده بود که «این سرورهایی که توی pgAdmin (یه ابزار برای مدیریت پست‌گرس) میبینیم چی هستن؟» این سوال خیلی خوبیه، چون به قلب ماجرا میزنه.

    سرور چیه و چه ربطی به پایگاه داده داره؟

    بیایم با تعریف اصلی شروع کنیم.
    یک سرور (Server) میتونه یه قطعه سخت‌افزاری باشه (مثلا یه کامپیوتر خیلی قوی) یا یه نرم‌افزار که به بقیه برنامه‌ها یا دستگاه‌ها سرویس میده. به اون برنامه‌هایی که سرویس میگیرن میگن کلاینت (Client).

    حالا، سرور پایگاه داده (Database Server) یه سروره که یه برنامه پایگاه داده (مثل پست‌گرس‌کیوال) روش نصبه و داره سرویس‌های مربوط به پایگاه داده رو به بقیه برنامه‌ها ارائه میده.

    تصور کنین شما یه اپلیکیشن روی گوشیتون دارین (مثلا اینستاگرام). این اپلیکیشن کلاینته. وقتی شما میخواین عکس‌های جدید رو ببینین، اپلیکیشن شما یه درخواست به سرورهای اینستاگرام میفرسته. روی اون سرورها، یه سرور پایگاه داده نصبه که اطلاعات عکس‌ها، کامنت‌ها و لایک‌ها رو نگه میداره. سرور پایگاه داده اطلاعات رو پیدا میکنه و برای اپلیکیشن شما میفرسته.

    پس وقتی توی ابزاری مثل pgAdmin یه چیزی به اسم «Servers» میبینین، منظور همون اتصال به یک سرور پایگاه داده هست. شما میتونین از کامپیوتر خودتون به چندین سرور پایگاه داده مختلف وصل بشین. مثلا یکی ممکنه روی کامپیوتر خودتون نصب باشه برای تمرین (که بهش میگن سرور محلی یا Local Server) و یکی دیگه ممکنه یه کامپیوتر اون سر دنیا باشه که اطلاعات واقعی یه سایت روشه (سرور راه دور یا Remote Server).

    گاهی هم ممکنه ببینین کنار اسم سرور یه عدد نوشته شده، مثلا «PostgreSQL 13». این عدد معمولا به نسخه اون نرم‌افزار پست‌گرس‌کیوال که روی سرور نصبه اشاره داره.

    پست‌گرس‌کیوال زبانه یا سرور؟ قصه SQL چیه؟

    اینم یه سوال خیلی رایجه. خیلیا گیج میشن که فرق بین SQL و PostgreSQL چیه.
    بذارین اینطوری بگم:

    • SQL (Structured Query Language): این اسم یک زبانه. یه زبان استاندارد برای حرف زدن با پایگاه داده‌های رابطه‌ای. شما با استفاده از دستورهای این زبان، از پایگاه داده میخواین که یه کاری براتون انجام بده. مثلا «این اطلاعات رو بهم نشون بده» یا «این کاربر جدید رو اضافه کن».
    • PostgreSQL: این اسم یک نرم‌افزاره. یک سیستم مدیریت پایگاه داده. این نرم‌افزار زبان SQL رو میفهمه. شما دستورهای SQL رو بهش میدین و اون براتون اجراشون میکنه.

    پس پست‌گرس‌کیوال هم یک سروره (نرم‌افزاری که سرویس میده) و هم میشه گفت یه جورایی یه «زبانه» چون نسخه مخصوص به خودش از SQL رو پیاده‌سازی کرده.

    یه نکته جالب اینه که شرکت‌های مختلف، نرم‌افزارهای پایگاه داده خودشون رو ساختن. مثلا:

    • Oracle
    • MySQL (که الان مال اوراکله)
    • MariaDB
    • Microsoft SQL Server
    • و البته PostgreSQL

    همه اینها زبان استاندارد SQL رو به عنوان پایه قبول دارن، ولی هر کدوم یه سری دستورها و ویژگی‌های مخصوص به خودشون رو هم اضافه کردن. مثل لهجه‌های مختلف یه زبان میمونه. هسته اصلی یکیه، ولی تو جزئیات تفاوت دارن. اگه بخوایم با نمودار ون تصور کنیم، یه دایره بزرگ هست به اسم SQL که دستورهای اصلی توشه، و بعد دایره‌های کوچیکتری برای هر کدوم از این نرم‌افزارها (PostgreSQL, MySQL, …) وجود داره که بخش زیادی‌شون با هم همپوشانی داره.

    یه نکته دیگه هم اینکه حواستون باشه اسم «SQL Server» که مال مایکروسافته رو با مفهوم کلی «سرور SQL» اشتباه نگیرین. اولی اسم یه محصول خاصه، دومی یه مفهوم کلی.

    دو نوع دستور مهم در SQL

    وقتی با کد SQL سر و کار دارین، خوبه که بدونین دستورهاش معمولا به دو دسته اصلی تقسیم میشن:

    1. DML (Data Manipulation Language): زبان دستکاری داده‌ها. این دستورها کارشون با خود داده‌هاست. یعنی داده‌ها رو «تغییر» میدن. مثلا:
      • INSERT: یه ردیف داده جدید اضافه میکنه.
      • UPDATE: داده‌های موجود رو به‌روز میکنه.
      • DELETE: داده‌ها رو حذف میکنه.
    2. DDL (Data Definition Language): زبان تعریف داده‌ها. این دستورها با ساختار پایگاه داده کار دارن. یعنی اون جدول‌ها و روابط بینشون رو «تعریف» یا «تغیبر» میدن. مثلا:
      • CREATE TABLE: یه جدول جدید میسازه.
      • ALTER TABLE: ساختار یه جدول موجود رو تغییر میده.
      • DROP TABLE: یه جدول رو کلا حذف میکنه.

    درک این تفاوت بهتون کمک میکنه که بهتر بفهمین هر دستور داره چیکار میکنه.

    بخش سوم: چطوری پست‌گرس‌کیوال رو نصب و راه‌اندازی کنیم؟

    خب، حالا که با مفاهیم اولیه آشنا شدیم، ببینیم چطوری میشه این نرم‌افزار رو روی کامپیوترمون داشته باشیم. راه‌های مختلفی برای این کار وجود داره.

    راه‌های مختلف برای دریافت پست‌گرس‌کیوال

    شما میتونین پست‌گرس‌کیوال رو به چند شکل مختلف دانلود کنین:

    • بسته‌های آماده (Ready-to-use packages) یا نصب‌کننده‌ها (Installers): این ساده‌ترین راهه. برای سیستم‌عامل‌های مختلف مثل ویندوز، مک و توزیع‌های مختلف لینوکس، فایل‌های نصب آماده‌ای وجود داره که شما فقط دانلود و اجراشون میکنین و مراحل رو دنبال میکنین.
    • سورس کد (Source code archive): اگه خیلی حرفه‌ای هستین و دوست دارین خودتون نرم‌افزار رو از پایه بسازین (کامپایل کنین)، میتونین سورس کدش رو دانلود کنین. دستورالعمل‌های ساختنش هم توی راهنمای رسمیش هست. مخزن سورس کدش هم روی git.postgresql.org قرار داره.
    • نسخه‌های آزمایشی (Beta and release candidates): اگه دوست دارین ویژگی‌های جدیدی که هنوز به طور رسمی منتشر نشدن رو تست کنین، میتونین نسخه‌های بتا یا کاندیدای انتشار رو دانلود کنین. خیلی مهمه که بدونین این نسخه‌ها فقط برای تست هستن و نباید روی سیستم‌های واقعی و کاری ازشون استفاده کنین.

    پشته‌های نرم‌افزاری آماده

    گاهی اوقات شما برای راه‌اندازی یه وبسایت یا برنامه، فقط به پایگاه داده نیاز ندارین. به یه وب سرور (مثل آپاچی) و یه زبان برنامه‌نویسی (مثل PHP) هم احتیاج دارین. به مجموعه این نرم‌افزارها که با هم کار میکنن میگن «پشته» یا Stack.

    شرکتی به اسم BitNami پشته‌های آماده‌ای رو درست کرده که کار رو خیلی راحت میکنه. این پشته‌ها شامل این موارد هستن:

    • LAPP: لینوکس + آپاچی + پی‌اچ‌پی + پست‌گرس‌کیوال
    • MAPP: مک + آپاچی + پی‌اچ‌پی + پست‌گرس‌کیوال
    • WAPP: ویندوز + آپاچی + پی‌اچ‌پی + پست‌گرس‌کیوال

    با نصب این پشته‌ها، همه ابزارهای لازم برای شروع کار به صورت یکجا و هماهنگ با هم نصب میشن.

    نرم‌افزارهای جانبی و کاتالوگ

    دنیای پست‌گرس‌کیوال خیلی بزرگه و کلی نرم‌افزار دیگه هم وجود داره که باهاش کار میکنن ولی به صورت پیش‌فرض همراهش نیستن. توی سایت رسمی پست‌گرس‌کیوال یه بخشی به اسم «کاتالوگ نرم‌افزار» (Software Catalogue) وجود داره که لیست بزرگی از برنامه‌های تجاری و متن‌باز، رابط‌ها و افزونه‌های مختلف رو میتونین توش پیدا کنین. اگه خودتون هم محصولی ساختین که با پست‌گرس‌کیوال کار میکنه، میتونین با پر کردن یه فرم، اون رو به این کاتالوگ اضافه کنین.

    یک راه ساده برای تمرین: Docker

    اگه تازه دارین یاد میگیرین، شاید نخواین کلی نرم‌افزار روی سیستم‌عامل اصلیتون نصب کنین. اینجا ابزاری به اسم داکر (Docker) خیلی به درد میخوره. داکر به شما اجازه میده برنامه‌ها رو توی محیط‌های ایزوله‌ای به اسم «کانتینر» اجرا کنین. اینجوری میتونین یه پایگاه داده پست‌گرس‌کیوال رو خیلی سریع راه بندازین، باهاش تمرین کنین و بعد با یه دستور ساده همه چیز رو پاک کنین، بدون اینکه کامپیوترتون شلوغ بشه.

    مثلا با دستور زیر میشه یه کانتینر پست‌گرس نسخه ۱۳.۳ رو راه انداخت:

    docker run --rm -p 5432:5432 --name some-postgres-container-name -e POSTGRES_PASSWORD=mysecretpassword postgres:13.3

    بیاین این دستور رو با هم بررسی کنیم:

    • docker run: به داکر میگه یه کانتینر جدید رو اجرا کن.
    • --rm: میگه وقتی کارم با کانتینر تموم شد و متوقفش کردم، خودکار حذفش کن. این برای تمرین عالیه.
    • -p 5432:5432: این بخش مربوط به پورت‌هاست. میگه پورت 5432 کامپیوتر من رو به پورت 5432 داخل کانتینر وصل کن. پورت 5432 پورت استاندارد پست‌گرس‌کیواله.
    • --name some-postgres-container-name: یه اسم برای کانتینرمون انتخاب میکنیم.
    • -e POSTGRES_PASSWORD=mysecretpassword: یه متغیر محیطی به اسم POSTGRES_PASSWORD رو تنظیم میکنه و مقدارش رو برابر با mysecretpassword قرار میده. این پسورد کاربر اصلی پایگاه داده میشه.
    • postgres:13.3: اسم و نسخه ایمیجی که میخوایم از روش کانتینر رو بسازیم. اینجا یعنی ایمیج رسمی پست‌گرس با نسخه 13.3.

    یه نکته مهم اینه که همیشه سعی کنین نسخه مشخصی از ایمیج رو استفاده کنین (مثلا 13.3) و از latest استفاده نکنین، چون ممکنه در آینده آپدیت بشه و رفتارش تغییر کنه.

    بخش چهارم: وقتی اوضاع خراب میشه؛ آموزش عیب‌یابی (Troubleshooting)

    هیچ سیستمی همیشه بی‌نقص کار نمیکنه. گاهی وقتا به مشکل میخوریم. مهم اینه که بدونیم چطوری مشکل رو پیدا و حل کنیم. تو این بخش میخوایم دو تا سناریوی واقعی از مشکلاتی که برای کاربرا پیش اومده رو با هم بررسی کنیم و ببینیم چطوری میشه مثل یه کارآگاه، رد خطاها رو گرفت و به جواب رسید.

    سناریو اول: «بعد از آپدیت، سیستم بالا نمیاد و میگه سرور پست‌گرس استارت نشد!»

    این مشکل برای یه کاربر سیستم‌عامل مانجارو لینوکس پیش اومده بود. کامپیوترش که برای کار ازش استفاده میکرد، بعد از یه آپدیت دیگه بالا نمیومد و روی لوگوی ASRock (مارک مادربوردش) گیر میکرد. پیام خطای اصلی این بود: Failed to start PostgreSQL database server (سرور پایگاه داده پست‌گرس‌کیوال شروع به کار نکرد).

    اینجا کاربر با کمک بقیه، شروع به تحقیق میکنه. اولین قدم اینه که ببینیم سیستم دقیقا داره چه خطاهایی میده. برای این کار از یه دستور به اسم journalctl استفاده میشه. این دستور، گزارش‌ها و رویدادهای سیستم (که بهشون میگن log) رو نشون میده.

    دستوری که استفاده شد این بود: journalctl -xep 0..3

    • journalctl: خود برنامه.
    • -x: اطلاعات بیشتری در مورد هر خطا میده.
    • -e: مستقیم میره به آخر گزارش‌ها که جدیدترین خطاها اونجا هستن.
    • -p 0..3: میگه فقط پیام‌هایی با اولویت بالا رو نشون بده (از ۰ تا ۳ که شامل Emergency, Alert, Critical, Error میشه).

    حالا بیاین با هم لاگ‌هایی که این دستور نشون داده رو بررسی کنیم. این لاگ‌ها خیلی طولانی و ترسناک به نظر میرسن، ولی اگه با دقت و حوصله بخونیمشون، سرنخ‌های خوبی بهمون میدن.

    کالبدشکافی لاگ‌های سیستم

    من بخش‌های مهم و تکراری لاگ رو براتون جدا کردم تا تحلیلشون کنیم.

    سرنخ اول: مشکلات مربوط به Firmware و Microcode

    Jun 01 12:43:27 user-pc kernel: [Firmware Bug]: TSC_DEADLINE disabled due to Errata; please update microcode to version: 0x3a (or later)
    • kernel: هسته اصلی سیستم‌عامل. این پیام از پایین‌ترین سطح نرم‌افزاری سیستم میاد.
    • Firmware Bug: یعنی یه باگ توی سفت‌افزار (نرم‌افزار سطح پایینی که روی سخت‌افزارها مثل CPU یا مادربورد اجرا میشه) وجود داره.
    • please update microcode: سیستم داره پیشنهاد میده که میکروکد سی‌پی‌یو رو آپدیت کنیم. میکروکد یه جورایی مثل یه آپدیت برای خود سی‌پی‌یو هست که بعضی از باگ‌هاش رو برطرف میکنه.

    نتیجه‌گیری اولیه:

    همین اول کار، سیستم داره بهمون میگه که یه مشکل سطح پایین سخت‌افزاری/نرم‌افزاری وجود داره. این خودش یه زنگ خطره.

    سرنخ دوم: پیدا نشدن ماژول‌های کرنل

    این خطا بارها و بارها توی لاگ‌ها تکرار شده:

    Jun 01 12:43:27 user-pc systemd-modules-load[337]: Failed to find module 'vboxdrv'
    Jun 01 12:43:27 user-pc systemd-modules-load[337]: Failed to find module 'vboxnetadp'
    Jun 01 12:43:27 user-pc systemd-modules-load[337]: Failed to find module 'vboxnetflt'
    Jun 01 14:59:29 user-pc systemd-modules-load[319]: Failed to find module 'nvidia'
    Jun 01 14:59:29 user-pc systemd-modules-load[319]: Failed to find module 'nvidia-drm'
    Jun 01 14:59:29 user-pc systemd-modules-load[319]: Failed to find module 'zfs'
    • systemd-modules-load: یه بخشی از سیستم‌عامل که مسئول بارگذاری ماژول‌های کرنله.
    • ماژول کرنل چیه؟ فکر کنین کرنل سیستم‌عامل مثل یه موتور ماشینه. ماژول‌ها مثل قطعات اضافی هستن که به این موتور وصل میشن تا کارهای خاصی رو انجام بدن. مثلا درایور کارت گرافیک، درایور کارت شبکه و… .
    • Failed to find module: یعنی سیستم نتونسته این ماژول‌ها رو پیدا و بارگذاری کنه.
    • vboxdrv, vboxnetadp, vboxnetflt: اینها مربوط به نرم‌افزار VirtualBox هستن که برای ساخت ماشین‌های مجازی استفاده میشه.
    • nvidia, nvidia-drm: اینها مربوط به درایور کارت گرافیک Nvidia هستن.
    • zfs: این مربوط به یه نوع سیستم فایل پیشرفته به اسم ZFS هست.

    نتیجه‌گیری دوم:

    به نظر میاد بعد از اون آپدیت، درایورهای مهمی مثل درایور کارت گرافیک و ابزارهای مجازی‌سازی به درستی نصب نشدن یا با نسخه جدید کرنل سازگار نیستن. این میتونه باعث بی‌ثباتی کل سیستم بشه.

    سرنخ سوم: خطاهای مربوط به حافظه و سخت‌افزار

    این خطا هم خیلی زیاد تکرار شده:

    Jun 01 12:43:44 user-pc kernel: EDAC sbridge: CPU SrcID #0, Ha #0, Channel #0 has DIMMs, but ECC is disabled
    Jun 01 12:43:44 user-pc kernel: EDAC sbridge: Couldn't find mci handler
    Jun 01 12:43:44 user-pc kernel: EDAC sbridge: Failed to register device with error -19.
    • EDAC (Error Detection and Correction): یه قابلیتی توی سخت‌افزارها برای پیدا کردن و تصحیح خطاهای حافظه.
    • ECC is disabled: یعنی حافظه ECC (که نوع خاصی از رم برای سرورهاست و قابلیت تصحیح خطا داره) غیرفعاله. این ممکنه برای یه کامپیوتر شخصی عادی باشه، ولی خود پیام خطا نشون میده که سیستم در حال بررسی عمیق سخت‌افزاره.
    • Failed to register device with error -19: این پیام خیلی کلیه ولی نشون میده که کرنل نتونسته یه قطعه سخت‌افزاری رو به درستی شناسایی و راه‌اندازی کنه.

    نتیجه‌گیری سوم:

    علاوه بر مشکلات درایور، به نظر میاد سیستم در ارتباط با بعضی از قطعات سخت‌افزاری هم مشکل داره.

    سرنخ چهارم: خطای نهایی پست‌گرس

    و بالاخره میرسیم به خطایی که کاربر از اول دیده بود:

    Jun 01 12:43:46 user-pc systemd[1]: Failed to start PostgreSQL database server.

    این پیام توسط systemd صادر شده که مدیر سیستم و سرویس‌ها در لینوکسه. این پیام به ما نمیگه چرا پست‌گرس استارت نشده، فقط میگه که تلاشش برای این کار ناموفق بوده.

    جمع‌بندی کارآگاهی سناریو اول:

    مشکل اصلی به احتمال زیاد خود پست‌گرس‌کیوال نیست. مشکل اینه که کل سیستم‌عامل بعد از آپدیت به هم ریخته و بی‌ثبات شده. وقتی درایورهای اصلی مثل درایور گرافیک بارگذاری نمیشن و کرنل در شناسایی سخت‌افزارها مشکل داره، سیستم نمیتونه یه محیط پایدار برای اجرای سرویس‌های دیگه مثل پست‌گرس‌کیوال فراهم کنه. راه‌حل در این مورد، احتمالا تعمیر سیستم‌عامل، نصب مجدد درایورها، یا برگردوندن آپدیت‌هاست، نه دستکاری کردن تنظیمات خود پست‌گرس. این یه درس مهمه: گاهی اوقات ریشه مشکل جاییه که اصلا انتظارش رو نداریم.


    سناریو دوم: «نمیتونم به سرور وصل بشم، میگه همچین فایلی وجود نداره!»

    این یکی مشکل رایج‌تریه و معمولا مستقیم به خود پست‌گرس ربط داره. یه کاربر روی اوبونتو ۱۸.۰۴ با این خطا مواجه شده:

    psql: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket “/var/run/postgresql/.s.PGSQL.5432”?

    این خطا یعنی برنامه psql (که ابزار خط فرمان برای وصل شدن به پست‌گرسه) نتونسته به سرور پست‌گرس وصل بشه. داره میپرسه که آیا سرور به صورت محلی (locally) روشنه و روی یه چیزی به اسم «سوکت دامنه یونیکس» داره گوش میده یا نه.

    بیاین مراحل عیب‌یابی این کاربر رو دنبال کنیم:

    قدم اول: وضعیت سرویس رو چک کنیم

    اولین کاری که باید بکنیم اینه که ببینیم آیا سرویس پست‌گرس‌کیوال اصلا روشنه یا نه.

    sudo systemctl status postgresql

    کاربر این دستور رو زده و دیده که سیستم میگه سرویس «فعاله». حتی با دستور restart هم سرویس رو دوباره راه‌اندازی کرده ولی مشکل حل نشده. این یکم عجیبه.

    قدم دوم: لیست کلاسترهای پست‌گرس رو ببینیم

    در سیستم‌عامل‌های مبتنی بر دبیان (مثل اوبونتو)، پست‌گرس با مفهومی به اسم «کلاستر» کار میکنه. هر کلاستر یه نمونه جدا از سرور پست‌گرسه که میتونه تنظیمات، پورت و مسیر داده‌های خودشو داشته باشه. با دستور زیر میشه لیست کلاسترها رو دید:

    pg_lsclusters

    وقتی کاربر این دستور رو میزنه، با این خروجی مواجه میشه:

    Ver Cluster Port Status Owner Data directory Log file
    10 main 5432 down postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log
    11 main 5433 down postgres /var/lib/postgresql/11/main /var/log/postgresql/postgresql-11-main.log
    12 main 5434 down postgres /var/lib/postgresql/12/main /var/log/postgresql/postgresql-12-main.log

    این خروجی خیلی مهمه! ستون Status (وضعیت) برای همه کلاسترها down (خاموش) رو نشون میده. پس بر خلاف چیزی که systemctl میگفت، سرورهای پست‌گرس در واقع خاموش هستن!

    قدم سوم: تلاش برای روشن کردن دستی کلاستر

    حالا کاربر سعی میکنه یکی از کلاسترها رو دستی روشن کنه:

    sudo pg_ctlcluster 10 main start

    اما این دستور هم خطا میده و میگه سرویس نتونسته استارت بشه و برای جزئیات بیشتر لاگ‌ها رو چک کنین.

    قدم چهارم: خوندن فایل لاگ پست‌گرس

    این مهم‌ترین مرحله‌ست. ما باید بریم سراغ فایل لاگی که خود پست‌گرس‌کیوال مینویسه تا ببینیم دردش چیه. مسیر فایل لاگ توی خروجی pg_lsclusters مشخص شده بود.

    sudo nano /var/log/postgresql/postgresql-10-main.log

    (nano یه ویرایشگر متن ساده در خط فرمانه)

    و بالاخره، سرنخ اصلی پیدا میشه. داخل فایل لاگ این خطا نوشته شده:

    2020-09-29 02:27:06.445 WAT [25041] FATAL: data directory "/var/lib/postgresql/10/main" has group or world access
    2020-09-29 02:27:06.445 WAT [25041] DETAIL: Permissions should be u=rwx (0700).
    • FATAL: یعنی یه خطای خیلی جدی که جلوی اجرای برنامه رو گرفته.
    • data directory ... has group or world access: میگه پوشه‌ای که داده‌های پست‌گرس توش ذخیره میشه (/var/lib/postgresql/10/main)، دسترسی‌های بیش از حدی داره. یعنی بقیه کاربرهای سیستم (group یا world) هم میتونن بهش دسترسی داشته باشن.
    • Permissions should be u=rwx (0700): خود پست‌گرس داره راه‌حل رو هم میگه. میگه سطح دسترسی (Permission) این پوشه باید 0700 باشه.

    سطح دسترسی یا Permission چیه؟

    در سیستم‌عامل‌های لینوکسی، برای هر فایل و پوشه مشخص میشه که چه کسانی چه کارهایی میتونن روش انجام بدن. این افراد به سه دسته تقسیم میشن:

    • User (u): مالک فایل.
    • Group (g): گروهی که مالک فایل عضو اون هست.
    • Others/World (o): بقیه کاربران سیستم.

    کارها هم سه نوع هستن:

    • Read (r): خوندن
    • Write (w): نوشتن
    • Execute (x): اجرا کردن

    سطح دسترسی 0700 یعنی:

    • User: دسترسی کامل برای خوندن، نوشتن و اجرا کردن داره (rwx).
    • Group: هیچ دسترسی‌ای نداره.
    • Others: هیچ دسترسی‌ای نداره.

    چرا پست‌گرس اینقدر حساسه؟

    چون داده‌های داخل پایگاه داده خیلی مهمن. اگه هر کاربری توی سیستم بتونه فایل‌های داده رو بخونه یا تغییر بده، یه فاجعه امنیتی رخ میده. برای همین پست‌گرس قبل از اینکه روشن بشه، چک میکنه و اگه ببینه پوشه داده‌هاش امن نیست، اصلا روشن نمیشه.

    قدم پنجم: تصحیح سطح دسترسی و راه‌اندازی مجدد

    حالا که مشکل پیدا شد، راه‌حلش ساده‌ست. باید سطح دسترسی پوشه‌ها رو درست کنیم.

    sudo chmod -R 0700 /var/lib/postgresql/10/main
    sudo chmod -R 0700 /var/lib/postgresql/11/main
    sudo chmod -R 0700 /var/lib/postgresql/12/main
    • chmod: دستوری برای تغییر سطح دسترسی.
    • -R: یعنی این تغییر رو روی خود پوشه و تمام فایل‌ها و پوشه‌های داخلش هم اعمال کن (Recursive).

    بعد از اجرای این دستورها، کاربر دوباره سعی میکنه کلاسترها رو روشن کنه:

    sudo pg_ctlcluster 10 main start
    sudo pg_ctlcluster 11 main start
    sudo pg_ctlcluster 12 main start

    و این بار موفقیت‌آمیز بود. در نهایت با چک کردن دوباره وضعیت کلاسترها، میبینه که همه online شدن:

    Ver Cluster Port Status Owner Data directory Log file
    10 main 5432 online postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log
    11 main 5433 online postgres /var/lib/postgresql/11/main /var/log/postgresql/postgresql-11-main.log
    12 main 5434 online postgres /var/lib/postgresql/12/main /var/log/postgresql/postgresql-12-main.log

    و مشکل حل میشه.


    سناریو سوم: خطای «authentication failed» با داکر

    یه مشکل رایج دیگه وقتی پیش میاد که شما هم روی کامپیوتر خودتون (مثلا ویندوز ۱۱) پست‌گرس رو نصب کردین، و هم دارین سعی میکنین یه نسخه دیگه از پست‌گرس رو با داکر اجرا کنین.

    مشکل اینه: هر دوتاشون به صورت پیش‌فرض سعی میکنن از پورت 5432 استفاده کنن.

    پورت شبکه چیه؟

    فکر کنین آدرس آی‌پی کامپیوتر شما مثل آدرس یه ساختمون بزرگه. پورت‌ها مثل شماره واحد‌های توی اون ساختمون هستن. وقتی یه برنامه میخواد با یه برنامه دیگه روی شبکه حرف بزنه، باید هم آدرس ساختمون (IP) و هم شماره واحد (Port) رو بدونه.

    وقتی شما دو تا سرور پست‌گرس رو همزمان روشن میکنین که هر دو میخوان از پورت 5432 استفاده کنن، مثل این میمونه که دو نفر بخوان توی یه آپارتمان با شماره واحد یکسان زندگی کنن. سیستم قاطی میکنه و نمیدونه درخواست‌ها رو باید به کدوم یکی بفرسته.

    علامت مشکل چیه؟

    معمولا خطایی مثل p1000 authentication failed میگیرین. دلیلش اینه که ابزار شما (مثلا Prisma که یه ابزار برای کار با پایگاه داده‌ست) داره سعی میکنه با اطلاعات کاربری پست‌گرسِ داخل داکر، به پست‌گرسِ نصب شده روی کامپیوتر اصلیتون وصل بشه (چون اون پورت 5432 رو اشغال کرده). طبیعتا اطلاعات کاربری با هم نمیخونه و خطا میده.

    راه‌حل چیه؟

    راه‌حل ساده‌ست: باید شماره پورت یکی از اونها رو عوض کنیم. توی سناریوی داکر، این کار خیلی راحته. فقط کافیه موقع اجرای کانتینر، نگاشت پورت رو تغییر بدیم.

    دستور قبلی این بود:

    docker run ... -p 5432:5432 ...

    دستور جدید این میشه:

    docker run ... -p 5433:5432 ...

    این تغییر یعنی چی؟

    • -p 5433:5432: به داکر میگه «هر درخواستی به پورت 5433 کامپیوتر من اومد، اون رو بفرست به پورت 5432 داخل کانتینر».

    اینجوری، پست‌گرس نصب شده روی سیستم اصلی شما روی پورت 5432 کار میکنه و پست‌گرس داخل داکر روی پورت 5433. دیگه با هم تداخلی ندارن و شما میتونین با مشخص کردن پورت درست، به هر کدوم که خواستین وصل بشین.

    بخش پنجم: مدیریت روزمره پایگاه داده

    خب، حالا که سرورمون راه افتاده و مشکلات احتمالی رو هم بلدیم حل کنیم، بیاین یه نگاهی به کارهای روزمره بندازیم.

    پایگاه داده‌های پیش‌فرض: postgres, template1, template0

    وقتی پست‌گرس‌کیوال برای اولین بار نصب میشه، چند تا پایگاه داده رو به صورت خودکار میسازه. شاید از خودتون بپرسین اینها به چه دردی میخورن.

    • postgres: این پایگاه داده به عنوان نقطه اتصال پیش‌فرض برای ابزارها و کاربرها ساخته شده. وقتی شما برنامه‌ای مثل psql رو باز میکنین و مشخص نمیکنین به کدوم پایگاه داده میخواین وصل بشین، به صورت خودکار به postgres وصل میشه. یه جورایی مثل لابی یه هتله. شما اول وارد لابی میشین، بعد تصمیم میگیرین به کدوم اتاق برین. خود سرور پست‌گرس برای کار کردنش به این پایگاه داده نیازی نداره، ولی خیلی از ابزارهای جانبی فرض میکنن که این پایگاه داده وجود داره. پس بهتره حذفش نکنین.
    • template1: این یکی خیلی جالبه. اسمش یعنی «قالب شماره ۱». هر وقت شما یه پایگاه داده جدید میسازین، پست‌گرس در واقع یه کپی کامل از template1 درست میکنه. پس اگه شما یه جدول یا یه تنظیم خاصی رو توی template1 ایجاد کنین، تمام پایگاه داده‌های جدیدی که از اون به بعد میسازین، اون جدول یا تنظیم رو به ارث میبرن. این یه ابزار قدرتمند برای استانداردسازی پایگاه داده‌هاتونه.
    • template0: اینم یه قالبه، ولی یه قالب دست‌نخورده و تمیز. یه جورایی نسخه «تنظیمات کارخانه» محسوب میشه. گاهی اوقات ممکنه شما template1 رو خراب کنین (مثلا یه چیزی توش اضافه کنین که نباید میکردین). از اونجایی که برای ساختن یه کپی از یه قالب، نباید هیچ اتصال دیگه‌ای به اون قالب وجود داشته باشه، اگه template1 خراب بشه، درست کردنش سخته. اینجا template0 به کمکتون میاد. میتونین template1 رو حذف کنین و یه template1 جدید از روی template0 بسازین.

    پس به طور خلاصه:

    • postgres: برای اتصال اولیه.
    • template1: قالب پیش‌فرض برای ساخت پایگاه داده‌های جدید.
    • template0: نسخه پشتیبان و تمیز از قالب، برای روز مبادا.

    کپی کردن یک پایگاه داده از یه سرور به سرور دیگه

    یکی از کارهای خیلی رایج، کپی کردن یه پایگاه داده از یه محیط به محیط دیگه‌ست. مثلا از سرور اصلی (Production) به یه سرور تستی (Development) تا بتونین بدون ریسک، روی داده‌های واقعی کار کنین. راه‌های مختلفی برای این کار هست.

    روش اول: استفاده از pg_dump و psql (روش کلاسیک)

    این روش خیلی محبوبه و از دو تا ابزار خط فرمان استفاده میکنه: pg_dump برای گرفتن خروجی (بکاپ) و psql برای برگردوندن اون خروجی (ریستور).

    میشه این دوتا رو با هم ترکیب کرد تا بدون ساختن فایل واسطه، کار انجام بشه. به این کار میگن «پایپ کردن» (Piping) که با علامت | انجام میشه.

    pg_dump -C -h localhost -U localuser dbname | psql -h remotehost -U remoteuser dbname

    بیاین این دستور رو بشکافیم:

    • pg_dump: ابزار بکاپ‌گیری.
    • -C: به pg_dump میگه که دستور CREATE DATABASE رو هم توی خروجی بذاره. اینجوری لازم نیست پایگاه داده مقصد رو از قبل بسازیم.
    • -h localhost: میگه به سروری که روی همین کامپیوتر (localhost) هست وصل شو.
    • -U localuser: با کاربر localuser وصل شو.
    • dbname: اسم پایگاه داده‌ای که میخوایم ازش بکاپ بگیریم.
    • |: این علامت جادوییه. خروجی دستور سمت چپش رو به عنوان ورودی به دستور سمت راستش میده.
    • psql: ابزار کلاینت پست‌گرس که اینجا برای ریستور کردن استفاده میشه.
    • -h remotehost: میگه به سرور مقصد که آدرسش remotehost هست وصل شو.
    • -U remoteuser: با کاربر remoteuser به سرور مقصد وصل شو.

    اگه پایگاه داده بزرگ باشه یا سرعت شبکه کم باشه، شاید بهتر باشه اول خروجی رو توی یه فایل ذخیره کنین، فایل رو فشرده کنین، به سرور مقصد منتقل کنین و بعد اونجا ریستور کنین.

    # روی سرور مبدا
    pg_dump -C -Fp -f dump.sql -U postgres some_database_name
    scp dump.sql development:
    rm dump.sql
    
    # روی سرور مقصد
    ssh development
    psql -U postgres -f dump.sql

    روش دوم: استفاده از تونل فشرده با SSH

    اگه میخواین همزمان هم کار فشرده‌سازی و هم انتقال امن رو انجام بدین، میتونین از این روش استفاده کنین:

    pg_dump -C dbname | bzip2 | ssh remoteuser@remotehost "bunzip2 | psql dbname"

    اینجا خروجی pg_dump اول با bzip2 فشرده میشه، بعد از طریق یه اتصال امن ssh به سرور مقصد فرستاده میشه، اونجا از حالت فشرده خارج میشه (bunzip2) و در نهایت با psql ریستور میشه.

    روش سوم: pg_basebackup (برای حرفه‌ای‌ها و دیتابیس‌های بزرگ)

    این ابزار برای وقتیه که شما میخواین یه کپی کامل و دقیق از کل «کلاستر» پایگاه داده بگیرین، نه فقط یه پایگاه داده خاص. این روش سریع‌تره، مخصوصا برای دیتابیس‌های خیلی بزرگ. این کار یه جورایی مثل کلون کردن هارد دیسک سرور پایگاه داده‌ست.

    برای استفاده از این روش باید یه سری تنظیمات روی سرور مبدا انجام بدین:

    1. در فایل postgresql.conf، گزینه listen_addresses رو روی '*' تنظیم کنین تا سرور از آی‌پی‌های دیگه هم اتصال قبول کنه.
    2. باز هم در همین فایل، wal_level رو حداقل روی replica بذارین.
    3. و max_wal_senders رو روی یه عددی بزرگتر از صفر (مثلا ۱ یا بیشتر) تنظیم کنین.
    4. در فایل pg_hba.conf، یه خط اضافه کنین که به سرور مقصد اجازه اتصال برای «replication» (همانندسازی) بده.
      host replication postgres DST_IP/32 trust
      (به جای DST_IP باید آی‌پی سرور مقصد رو بذارین).
    5. بعد از این تغییرات، سرور پست‌گرس رو ریستارت کنین.

    حالا روی سرور مقصد:

    1. سرویس پست‌گرس رو متوقف کنین (sudo service postgresql stop).
    2. تمام محتویات پوشه داده‌های پست‌گرس رو پاک کنین (مثلا /var/lib/postgresql/12/main/*). مواظب باشین این کار رو روی سرور اشتباهی انجام ندین!
    3. دستور pg_basebackup رو اجرا کنین:
    sudo -u postgres pg_basebackup -h SRC_IP -U postgres -D /var/lib/postgresql/12/main/ --progress

    (به جای SRC_IP آی‌پی سرور مبدا رو بذارین).

    1. بعد از اینکه کارش تموم شد، سرویس پست‌گرس رو روی سرور مقصد روشن کنین (sudo service postgresql start).

    حالا شما یه کپی دقیق از کل سرور مبدا روی سرور مقصد دارین.

    روش چهارم: استفاده از رابط گرافیکی (GUI) مثل pgAdmin

    اگه با خط فرمان راحت نیستین، همیشه میتونین از ابزارهای گرافیکی استفاده کنین. با pgAdmin مراحل خیلی ساده‌ست:

    1. به هر دو سرور مبدا و مقصد وصل بشین.
    2. روی پایگاه داده مبدا کلیک راست کنین و گزینه «Backup» رو بزنین. یه فایل بکاپ براتون میسازه.
    3. روی سرور مقصد کلیک راست کنین، «Create» و بعد «Database» رو بزنین و یه پایگاه داده جدید با همون مشخصات پایگاه داده مبدا بسازین.
    4. روی پایگاه داده جدیدی که ساختین کلیک راست کنین و «Restore» رو بزنین. فایل بکاپی که در مرحله ۲ ساختین رو بهش بدین تا اطلاعات رو برگردونه.

    بخش ششم: چطوری سرعت رو بالا نگه داریم؟ نگاهی به بهینه‌سازی عملکرد

    گاهی اوقات ممکنه پایگاه داده شما کند بشه، مخصوصا وقتی حجم داده‌ها زیاد میشه و تعداد کاربرها بالا میره. به این وضعیت میگن «بار بالا» (High Load). مدیریت این وضعیت یه بحث خیلی بزرگه، ولی بیاین چند تا نکته کلیدی رو با هم مرور کنیم.

    ۱. اول بفهمین دیتابیس داره چیکار میکنه.
    مشکلات عملکردی معمولا به خاطر چند تا «کوئری» (Query) یا همون پرس‌وجوی سنگین و پرهزینه‌ست که زیاد اجرا میشن. اولین قدم اینه که این کوئری‌ها رو پیدا کنین.

    ۲. از EXPLAIN ANALYZE استفاده کنین.
    این یکی از قدرتمندترین ابزارهای شماست. وقتی قبل از هر کوئری SELECT، عبارت EXPLAIN ANALYZE رو بنویسین، پست‌گرس به جای اجرای عادی کوئری، به شما یه گزارش کامل از «نقشه اجرا» (Execution Plan) اون کوئری میده. یعنی بهتون میگه که برای پیدا کردن جواب، دقیقا چه قدم‌هایی رو برداشته و هر قدم چقدر زمان برده.

    ۳. حواستون به «Sequential Scans» باشه.
    وقتی توی خروجی EXPLAIN دیدین که روی یه جدول بزرگ داره «Sequential Scan» انجام میشه، باید حواستون رو جمع کنین. این یعنی پست‌گرس داره کل جدول رو ردیف به ردیف از اول تا آخر میخونه تا داده مورد نظر شما رو پیدا کنه. این کار برای جدول‌های بزرگ خیلی خیلی کنده.

    ۴. از ایندکس (Index) استفاده کنین.
    راه‌حل Sequential Scan معمولا ساختن «ایندکس» هست. ایندکس مثل فهرست آخر یه کتاب قطوره. شما برای پیدا کردن یه مطلب، کل کتاب رو صفحه به صفحه نمیخونین، بلکه میرین سراغ فهرست و مستقیم به صفحه مورد نظر میرین. ایندکس هم برای پایگاه داده همین کار رو میکنه. شما روی ستون‌هایی که معمولا توی شرط WHERE کوئری‌هاتون استفاده میکنین، ایندکس میسازین. اینجوری پست‌گرس میتونه خیلی سریع‌تر ردیف‌های مورد نظر رو پیدا کنه.

    ۵. VACUUM و ANALYZE رو فراموش نکنین.
    وقتی شما داده‌ها رو توی پست‌گرس UPDATE یا DELETE میکنین، فضای اونها فورا آزاد نمیشه. به مرور زمان این فضاهای مرده جمع میشن و باعث میشن جدول‌ها بزرگتر از اندازه واقعی‌شون بشن (به این میگن Bloat). دستور VACUUM این فضاهای مرده رو تمیز و قابل استفاده مجدد میکنه.

    دستور ANALYZE هم اطلاعات آماری در مورد توزیع داده‌ها توی جدول‌ها جمع‌آوری میکنه. پست‌گرس از این آمارها استفاده میکنه تا بهترین و بهینه‌ترین نقشه اجرا رو برای کوئری‌های شما انتخاب کنه.

    در خیلی از تنظیمات پیش‌فرض، سرویس «autovacuum» فعاله و این کارها رو خودکار انجام میده، ولی خوبه که بدونین این دستورها وجود دارن و گاهی اوقات لازمه به صورت دستی اجرا بشن.

    بخش هفتم: پرسش و پاسخ (سوالات متداول شما)

    در طول این مقاله به سوالات مختلفی اشاره کردیم. بیاین اینجا چند تا از مهم‌ترین‌هاشون رو به صورت خلاصه مرور کنیم.

    سوال ۱: بالاخره پست‌گرس‌کیوال یه زبانه یا یه سرور؟
    پست‌گرس‌کیوال یک نرم‌افزار مدیریت پایگاه داده هست که به عنوان یک سرور عمل میکنه. این نرم‌افزار، زبان SQL (زبان استاندارد کوئری‌نویسی) رو میفهمه و اجرا میکنه. پس خودش زبان نیست، بلکه اجراکننده زبانه.

    سوال ۲: این «سرورهایی» که توی pgAdmin میبینم چی هستن؟ یعنی چند تا کامپیوتر مختلفن؟
    هر «سرور» توی pgAdmin نشون‌دهنده یک اتصال به یک نمونه (instance) از سرور پایگاه داده پست‌گرس‌کیواله. این سرور میتونه روی کامپیوتر خود شما باشه (localhost) یا روی یه کامپیوتر دیگه در شبکه یا اینترنت. شما میتونین به چندین سرور مختلف به صورت همزمان متصل باشین.

    سوال ۳: من پایگاه داده‌هایی به اسم postgres و template1 میبینم. اینها چی هستن و میتونم پاکشون کنم؟

    • postgres: پایگاه داده پیش‌فرض برای اتصال اولیه ابزارها و کاربران. بهتره پاکش نکنین چون خیلی از برنامه‌ها به وجودش تکیه میکنن.
    • template1: قالبی که تمام پایگاه داده‌های جدید از روی اون کپی میشن. پاک کردنش ایده خوبی نیست، مگه اینکه بخواین از روی template0 (قالب پشتیبان) یه نسخه جدید ازش بسازین.

    سوال ۴: ساده‌ترین راه برای کپی کردن یه پایگاه داده از کامپیوتر خودم به یه سرور دیگه چیه؟
    برای دیتابیس‌های کوچیک و متوسط، استفاده از ترکیب pg_dump و psql با پایپ کردن خیلی ساده و سریعه:
    pg_dump -C -h [آدرس مبدا] -U [کاربر مبدا] [اسم دیتابیس مبدا] | psql -h [آدرس مقصد] -U [کاربر مقصد] [اسم دیتابیس مقصد]

    سوال ۵: سرور پست‌گرس من بعد از آپدیت سیستم‌عامل روشن نمیشه و کلی خطای عجیب در مورد nvidia و vboxdrv میبینم. مشکل چیه؟
    به احتمال خیلی زیاد مشکل از خود پست‌گرس نیست. این خطاها نشون میدن که کل سیستم‌عامل شما بعد از آپدیت دچار بی‌ثباتی شده و درایورهای مهمی بارگذاری نشدن. در چنین شرایطی، سیستم نمیتونه محیط پایداری برای اجرای سرویس پست‌گرس فراهم کنه. شما باید اول مشکلات سیستم‌عامل و درایورهاتون رو حل کنین.

    سوال ۶: میخوام وصل بشم ولی خطای authentication failed یا could not connect to server میگیرم. اولین چیزایی که باید چک کنم چی هستن؟

    • آیا سرویس پست‌گرس اصلا روشنه؟ با دستورهایی مثل systemctl status postgresql یا pg_lsclusters وضعیتش رو چک کنین.
    • آیا سطح دسترسی پوشه داده‌ها درسته؟ همونطور که دیدیم، پست‌گرس به این موضوع خیلی حساسه. لاگ‌های پست‌گرس رو چک کنین تا ببینین خطایی در این مورد وجود نداره.
    • آیا تداخل پورت وجود نداره؟ مطمئن بشین که هیچ برنامه دیگه‌ای (مثلا یه نسخه دیگه از پست‌گرس) در حال استفاده از همون پورتی که شما میخواین بهش وصل بشین (معمولا 5432) نیست.
    • آیا اطلاعات اتصال (آدرس سرور، نام کاربری، پسورد) رو درست وارد میکنین؟ این مورد خیلی ساده به نظر میرسه ولی زیاد اتفاق میفته

    منابع

    • [2] After Upgrading, Can’t Boot “Failed to start PostgreSQL database server” – Computer Used for Work – Support – Manjaro Linux Forum
    • [4] Default database named postgres on Postgresql server – Stack Overflow
    • [6] linux – managing high load of a postgresql database – Server Fault
    • [8] PostgreSQL: Why psql can’t connect to server? – Stack Overflow
    • [10] p1000 authentication failed against database server · prisma/prisma · Discussion #8925 · GitHub
    • [1] Noob Question: What are “servers” in postgreSQL/pgAdmin? : r/PostgreSQL
    • [3] PostgreSQL: The world’s most advanced open source database
    • [5] sql – If I’m using PostgreSQL, do I need a server too? Like AWS RDS? – Stack Overflow
    • [7] PostgreSQL: Downloads
    • [9] Copying PostgreSQL database to another server – Stack Overflow
  • آشنایی با MariaDB Server؛ جایگزین اوپن‌سورس MySQL

    ماریا دی‌بی سرور (MariaDB Server) یک سیستم مدیریت پایگاه داده رابطه‌ای هست. حالا این یعنی چی؟ یعنی یک نرم‌افزاره که به شما اجازه میده داده‌ها رو به صورت ساختاریافته و منظم، مثل جدول‌هایی که به هم ربط دارن، ذخیره کنید و بعدا بهشون دسترسی داشته باشید. فکر کنید یه عالمه اطلاعات دارید، از اطلاعات کاربرا گرفته تا محصولات یه فروشگاه. ماریا دی‌بی اینا رو براتون مرتب و منظم نگه میداره.

    جالبی ماجرا اینجاست که ماریا دی‌بی از یه خانواده خیلی معروف میاد. اون در واقع یه «فورک» (Fork) یا انشعاب از سرور مای‌اس‌کیوال (MySQL) هست. فورک یعنی چی؟ یعنی یه عده از توسعه‌دهنده‌های اصلی یه پروژه نرم‌افزاری، یه کپی از کد اون پروژه برمیدارن و مسیر توسعه خودشون رو جداگونه ادامه میدن.

    داستان اینجوری شروع شد که یه سری از اعضای اصلی تیم مای‌اس‌کیوال، بعد از اینکه شرکت اوراکل (Oracle Corporation) مای‌اس‌کیوال رو خرید، نگران آینده‌اش شدن. اونا میخواستن مطمئن بشن که این پایگاه داده همیشه متن‌باز و رایگان باقی میمونه. برای همین، پروژه ماریا دی‌بی رو شروع کردن. اسمش هم جالبه؛ مایکل وایدنیوس (Michael “Monty” Widenius) که یکی از بنیان‌گذارهای اصلی مای‌اس‌کیوال و ماریا دی‌بی هست، اسم دختر کوچیکترش، «ماریا»، رو روی این پروژه گذاشت. جالبه بدونید اسم دختر دیگه‌اش «مای» (My) بود که اسم مای‌اس‌کیوال هم از اون گرفته شده.

    هدف اصلی از ساخت ماریا دی‌بی این بود که به عنوان یه جایگزین مستقیم یا «drop-in replacement» برای مای‌اس‌کیوال عمل کنه. یعنی شما بتونید خیلی راحت مای‌اس‌کیوال رو از روی سرورتون بردارید و ماریا دی‌بی رو به جاش نصب کنید، بدون اینکه نیاز باشه کد برنامه‌هاتون رو تغییر بدید. البته ماریا دی‌بی فقط یه کپی ساده نیست؛ توسعه‌دهنده‌ها سعی کردن ویژگی‌های جدید، موتورهای ذخیره‌سازی (Storage Engines) تازه، باگ‌های کمتر و عملکرد بهتری رو بهش اضافه کنن.

    این پروژه توسط جامعه برنامه‌نویس‌ها توسعه داده میشه و با توسعه‌دهنده‌های خارجی هم همکاری فعالی داره تا یه سرور SQL متن‌باز با بیشترین امکانات، پایداری و لایسنس منطقی رو ارائه بده.

    کی پشت ماریا دی‌بی ایستاده؟

    دو تا نهاد اصلی پشت این پروژه هستن:

    1. بنیاد ماریا دی‌بی (MariaDB Foundation): این یه سازمان غیرانتفاعی هست که وظیفه‌اش نظارت بر توسعه و حفاظت از ماهیت متن‌باز و رایگان ماریا دی‌بی هست. اونا تضمین میکنن که این پروژه همیشه در دسترس همه باشه و هیچ شرکت تجاری نتونه کنترل کاملش رو به دست بگیره.
    2. شرکت ماریا دی‌بی (MariaDB Corporation): این یه شرکت تجاریه که محصولات و خدمات حرفه‌ای بر پایه ماریا دی‌بی ارائه میده. خیلی از توسعه‌دهنده‌های اصلی ماریا دی‌بی توی این شرکت کار میکنن. این شرکت نسخه‌های تجاری با امکانات بیشتر و پشتیبانی تخصصی میفروشه و از این راه درآمد کسب میکنه.

    پس یادتون باشه، خود سرور ماریا دی‌بی رایگان و متن‌بازه، اما یه شرکت هم هست که خدمات پولی حول اون ارائه میده.

    ویژگی‌های کلیدی و تفاوت‌ها

    ماریا دی‌بی تلاش میکنه سازگاری بالایی با مای‌اس‌کیوال داشته باشه. رابط برنامه‌نویسی (API) و پروتکل‌هاش دقیقا با مای‌اس‌کیوال مطابقت دارن. این یعنی همه ابزارها، کتابخانه‌ها و برنامه‌هایی که با مای‌اس‌کیوال کار میکنن، باید با ماریا دی‌بی هم کار کنن. به همین دلیل، خیلی از توزیع‌های لینوکس مثل فدورا (Fedora)، دبیان (Debian) و رد هت (Red Hat Enterprise Linux) به جای مای‌اس‌کیوال، به صورت پیش‌فرض از ماریا دی‌بی استفاده میکنن.

    با این حال، با گذر زمان و اضافه شدن ویژگی‌های جدید، مسیر این دو پروژه داره از هم کمی جدا میشه. مثلا ماریا دی‌بی موتورهای ذخیره‌سازی جدیدی مثل Aria، ColumnStore و MyRocks رو معرفی کرده. همچنین تو نسخه‌های جدیدش، امکانات مربوط به داده‌های جغرافیایی (GIS) و JSON هم اضافه شده.

    بنیاد ماریا دی‌بی: نگهبان کد

    همونطور که گفتیم، بنیاد ماریا دی‌بی یه نهاد غیرانتفاعی هست که توی دلاور (Delaware) آمریکا ثبت شده و هدفش اینه که از آینده ماریا دی‌بی محافظت کنه. ماموریت این بنیاد روی سه تا اصل بنا شده:

    • باز بودن (Openness): تضمین میکنن که کدهای ماریا دی‌بی همیشه برای استفاده و مشارکت همه باز باقی بمونه و تصمیم‌های فنی بر اساس شایستگی گرفته بشه.
    • پذیرش (Adoption): تلاش میکنن تا استفاده از ماریا دی‌بی توسط کاربرها و در پلتفرم‌های مختلف بیشتر بشه.
    • تداوم (Continuity): مستقل از هر نهاد تجاری، تداوم اکوسیستم ماریا دی‌بی رو فراهم میکنن.

    کارمندهای این بنیاد با انجام کارهای زیر از پروژه پشتیبانی میکنن:

    • تشویق به پذیرش، مشارکت و توزیع سرور ماریا دی‌بی.
    • کمک به مشارکت‌کننده‌های جدید تا کدها رو بهتر بفهمن.
    • مشارکت در طراحی ویژگی‌های جدید و تضمین کیفیت کد.
    • اطمینان از به‌روز بودن مستندات.
    • پورت کردن و بسته‌بندی ماریا دی‌بی برای پلتفرم‌ها و سیستم‌عامل‌های مختلف.
    • صحبت در رویدادها برای افزایش آگاهی و استفاده.

    این بنیاد از طریق حامیان مالی شرکتی و فردی تامین میشه. این حامی‌ها به دسته‌های مختلفی مثل الماس، پلاتینیوم، طلا و نقره تقسیم میشن.

    حامیان مالی بنیاد ماریا دی‌بی

    اینجا لیست برخی از سازمان‌هایی که از این بنیاد حمایت مالی قابل توجهی میکنن رو میبینیم:

    • حامیان الماس (Diamond sponsors):
      • DBS: یک گروه خدمات مالی پیشرو در آسیا با بیش از ۲۸۰ شعبه در ۱۸ بازار. دفتر مرکزی اون در سنگاپور قرار داره.
    • حامیان پلاتینیوم (Platinum sponsors):
      • MariaDB Corporation: عضو موسس بنیاد و مشارکت‌کننده اصلی کد. محصولات و خدمات تجاری حول ماریا دی‌بی ارائه میده.
      • Acronis: شرکتی که حفاظت از داده و امنیت سایبری رو با هم ترکیب میکنه.
      • Alibaba Cloud: ارائه‌دهنده خدمات رایانش ابری جهانی.
      • Intel: غول فناوری و سازنده پردازنده‌ها که در پیشرفت‌های محاسباتی نقش داشته.
      • ServiceNow: پلتفرمی که به کارمندها اجازه میده اونطور که میخوان کار کنن.
      • Constructor: پلتفرمی برای آموزش و پژوهش با تخصص در هوش ماشینی و علم داده.
      • WebPros: ارائه‌دهنده اکوسیستم کامل برای توانمندسازی حرفه‌ای‌های وب.
    • حامیان طلا (Gold Sponsors):
      • Hetzner: یکی از بزرگترین شرکت‌های میزبانی وب در اروپا که در سال ۱۹۹۷ تاسیس شده.
      • IONOS: شریک دیجیتالی‌سازی برای کسب‌وکارهای کوچک و متوسط در اروپا.
      • Scarf: پیشگام در زمینه تحلیل استفاده از نرم‌افزارهای متن‌باز.
    • حامیان نقره (Silver Sponsors):
      • این لیست شامل شرکت‌های زیادی مثل ArbauDie.IT، Automattic (سازنده WordPress.com)، Crest Infosolutions، Kinsta، Nexedi، Nextcloud، RAVATAR، Releem، Rumahweb، SkySQL، team.blue، Tempesta Technologies، Tencent Cloud، Vettabase، Wikimedia movement و Cyber Leo میشه که هر کدوم در زمینه‌های مختلف فناوری فعالیت دارن.

    نحوه مدیریت و تصمیم‌گیری در پروژه

    یکی از سوال‌های مهم اینه که تصمیم‌ها توی این پروژه چطور گرفته میشه. بنیاد ماریا دی‌بی یه ساختار مدیریتی شفاف داره:

    • تصمیم‌های فنی: تصمیم‌های مربوط به مشارکت در کدها توسط خود مشارکت‌کننده‌ها گرفته میشه. اگه نیاز به اجماع عمومی باشه، موضوع در لیست‌های ایمیل عمومی ماریا دی‌بی و بقیه کانال‌های شفاف آنلاین بحث میشه تا اکثریت توسعه‌دهنده‌ها به توافق برسن. هیچ فرد یا شرکتی نمیتونه اولویت‌ها یا کد رو به جامعه دیکته کنه.
    • هیئت مدیره (Board of directors): بنیاد به صورت قانونی توسط هیئت مدیره کنترل میشه. این هیئت تصمیم میگیره که بنیاد چطور میتونه به بهترین شکل به جامعه ماریا دی‌بی خدمت کنه، اما تصمیم‌های فنی نمیگیره.

    اعضای هیئت مدیره بنیاد ماریا دی‌بی

    هیئت مدیره از افراد مختلفی تشکیل شده که هر کدوم نماینده بخش خاصی هستن. در اینجا به چند نفر از اعضای کلیدی اشاره میکنیم:

    • مدیران موسس (Ex officio):
      • Sergei Golubchik: معمار ارشد سرور ماریا دی‌بی در شرکت ماریا دی‌بی.
      • Michael “Monty” Widenius: بنیان‌گذار ماریا دی‌بی و مای‌اس‌کیوال.
    • مدیران نماینده شرکت‌ها:
      • Jignesh Shah: مدیر بخش RDS Open Source در آمازون وب سرویسز (AWS).
      • Rohit De Souza: مدیرعامل شرکت MariaDB plc.
    • مدیران فردی:
      • Kaj Arnö: رئیس اجرایی بنیاد.
      • Todd Boyd: عضو ارشد فنی در IBM.
      • Eric Herman: رئیس هیئت مدیره از سال ۲۰۱۶ تا ۲۰۲۵.
      • و افراد دیگه‌ای مثل Espen Håkonsen، Sean Peng و Steve Shaw.

    هر کدوم از این افراد سابقه طولانی در دنیای نرم‌افزار، پایگاه داده و مدیریت دارن. برای مثال، Kaj Arnö قبل از پیوستن به بنیاد، در شرکت MySQL AB و Sun Microsystems سمت‌های مختلفی داشته و یکی از بنیان‌گذارهای شرکت ماریا دی‌بی هم بوده. یا Sergei Golubchik که از سال ۱۹۹۸ توسعه‌دهنده مای‌اس‌کیوال بوده و تقریبا روی همه بخش‌های سرور کار کرده.

    نسخه‌بندی و چرخه‌های انتشار

    ماریا دی‌بی یک سیاست مشخص برای انتشار نسخه‌هاش داره. این به کاربرها کمک میکنه تا بدونن هر نسخه تا کی پشتیبانی میشه و کی باید سیستم‌هاشون رو آپدیت کنن.

    نسخه‌های با پشتیبانی بلندمدت (LTS)

    هر سال یک نسخه جدید با پشتیبانی بلندمدت یا LTS معرفی میشه. این نسخه‌ها برای مدت طولانی‌تری (معمولا ۳ تا ۵ سال) آپدیت‌های امنیتی و رفع باگ دریافت میکنن. این برای شرکت‌ها و کاربرانی که به پایداری نیاز دارن و نمیتونن هر چند ماه یکبار پایگاه داده‌شون رو آپدیت کنن، خیلی مهمه.

    برای مثال، نسخه‌هایی مثل 10.6، 10.11 و 11.4 نسخه‌های LTS هستن.

    نسخه‌های غلتان (Rolling releases)

    این نسخه‌ها به صورت فصلی (هر سه ماه) منتشر میشن و شامل آخرین ویژگی‌ها، رفع باگ‌ها و بهبودها هستن. این نسخه‌ها برای کسانی مناسبن که میخوان همیشه از جدیدترین امکانات استفاده کنن.

    شماره‌گذاری نسخه‌ها چطوریه؟

    شماره نسخه‌ها معمولا به صورت a.b.c هست. مثلا 11.4.7.

    • a (Major version): نسخه اصلی رو نشون میده (مثلا سری ۱۱). این عدد معمولا سالی یک بار زیاد میشه و ممکنه تغییرات بزرگی که با نسخه‌های قبلی ناسازگار هستن رو شامل بشه.
    • b (Minor version): نسخه فرعی رو نشون میده که امکانات جدید بهش اضافه شده ولی با نسخه‌های قبلی همون سری سازگاره. این عدد هر سه ماه زیاد میشه.
    • c (Patch version): این عدد با هر آپدیت برای رفع باگ یا مشکلات امنیتی زیاد میشه و هیچ ویژگی جدیدی بهش اضافه نمیشه.

    اینجا یه جدول از نسخه‌های مختلف و تاریخ پایان پشتیبانی اونها رو میبینید:

    نسخهتاریخ انتشار اولیهپایان پشتیبانی (Community)
    11.8۴ ژوئن ۲۰۲۵۴ ژوئن ۲۰۲۸
    11.4۲۹ می ۲۰۲۴۲۹ می ۲۰۲۹
    10.11۱۶ فوریه ۲۰۲۳۱۶ فوریه ۲۰۲۸
    10.6۶ ژوئیه ۲۰۲۱۶ ژوئیه ۲۰۲۶
    10.5۲۴ ژوئن ۲۰۲۰۲۴ ژوئن ۲۰۲۵
    10.4۱۸ ژوئن ۲۰۱۹۱۸ ژوئن ۲۰۲۴
    10.3۲۵ می ۲۰۱۸۲۵ می ۲۰۲۳

    نکته مهم: در همه آپدیت‌ها، حتی آپدیت‌های بزرگ، تیم ماریا دی‌بی تضمین میکنه که ابزار mariadb-upgrade به درستی کار میکنه و شما میتونید فایل‌های پایگاه داده رو از هر نسخه قدیمی‌تری (حتی مای‌اس‌کیوال قبل از نسخه ۸.۰) آپدیت کنید.

    چطور ماریا دی‌بی رو نصب و استفاده کنیم؟

    ماریا دی‌بی یکی از محبوب‌ترین پایگاه داده‌های رابطه‌ای متن‌بازه و توی مخازن استاندارد همه توزیع‌های اصلی لینوکس پیدا میشه. کافیه با استفاده از مدیر بسته سیستم‌عاملتون دنبال بسته mariadb-server بگردید و نصبش کنید.

    اما گاهی اوقات ممکنه به مشکلاتی بربخورید. بیاید چند تا از مشکلات رایجی که کاربرها باهاش مواجه شدن رو بررسی کنیم.

    مشکل ۱: چرا نصب KDE باعث نصب ماریا دی‌بی میشه؟

    یه کاربر در ردیت (Reddit) سوال جالبی پرسیده بود. اون میخواست روی سیستم عامل فدورا که فقط محیط دسکتاپ گنوم (GNOME) داشت، محیط کی‌دی‌ای (KDE Plasma Workspaces) رو هم نصب کنه. وقتی دستور نصب رو زد، متوجه شد که mariadb-server هم به عنوان یکی از بسته‌های مورد نیاز (dependency) داره نصب میشه.

    این براش عجیب بود که چرا یه محیط دسکتاپ باید به یه سیستم مدیریت پایگاه داده کامل وابسته باشه. این موضوع نشون میده که گاهی اوقات وابستگی‌های بین بسته‌ها در سیستم‌عامل‌های لینوکس میتونه پیچیده و غیرمنتظره باشه. در این مورد خاص، احتمالا یکی از برنامه‌های زیرمجموعه کی‌دی‌ای برای مدیریت اطلاعاتش از یک پایگاه داده محلی استفاده میکنه و توسعه‌دهنده‌ها ماریا دی‌بی رو به عنوان گزینه پیش‌فرض انتخاب کردن.

    مشکل ۲: رمز عبور پیش‌فرض ماریا دی‌بی در فدورا چیه؟

    این یکی از سوال‌های خیلی پرتکرار در سایت Stack Overflow هست. یه کاربر میگه که ماریا دی‌بی رو روی فدورا نصب کرده ولی ازش رمز عبور روت (root) پرسیده نشده. هر رمزی رو هم که امتحان کرده، جواب نداده.

    جواب اینه: رمز عبور پیش‌فرض خالیه!

    اما قضیه به همین سادگی نیست. در نسخه‌های جدید ماریا دی‌بی روی لینوکس، برای بالا بردن امنیت، به صورت پیش‌فرض از یه پلاگین احراز هویت به اسم unix_socket استفاده میشه. این پلاگین میگه: «اگه کاربری که داره سعی میکنه به عنوان root وارد پایگاه داده بشه، همون کاربر root سیستم‌عامل باشه، دیگه نیازی به رمز عبور نیست.»

    پس برای اینکه به عنوان کاربر root وارد ماریا دی‌بی بشید، باید خود دستور رو هم با دسترسی root اجرا کنید. به این صورت:

    sudo mysql

    با این دستور، بدون نیاز به رمز عبور وارد محیط ماریا دی‌بی میشید.

    اگه بخواید یه رمز عبور برای کاربر root تنظیم کنید تا از راه‌های دیگه هم بشه بهش وصل شد، باید از اسکریپت mysql_secure_installation استفاده کنید. این اسکریپت هم باید با sudo اجرا بشه:

    sudo mysql_secure_installation

    این اسکریپت از شما چند تا سوال امنیتی میپرسه، مثل تنظیم رمز عبور روت، حذف کاربرهای ناشناس، غیرفعال کردن ورود روت از راه دور و حذف پایگاه داده تستی. در مرحله اول که رمز عبور فعلی رو میپرسه، چون خالیه، فقط کافیه کلید Enter رو بزنید.

    مشکل ۳: خطای عدم نصب به خاطر وابستگی‌ها

    گاهی اوقات موقع نصب، ممکنه با خطای unmet dependencies مواجه بشید. یه کاربر در Stack Overflow گزارش داده بود که موقع نصب mariadb-server روی اوبونتو ۱۲.۰۴، با این خطا مواجه شده که بسته mariadb-server-5.5 نصب نمیشه. مشکل از اینجا بود که یه نسخه از کتابخانه libmysqlclient18 روی سیستمش نصب بود که با نسخه‌ای که ماریا دی‌بی نیاز داشت، تداخل داشت.

    اینجور مشکلات معمولا وقتی پیش میاد که شما از مخازن نرم‌افزاری مختلفی استفاده میکنید و نسخه‌های بسته‌ها با هم هماهنگ نیستن. این یه نمونه خوبه که نشون میده مدیریت بسته‌ها و وابستگی‌هاشون چقدر میتونه حساس باشه.

    شرکت ماریا دی‌بی و نسخه تجاری

    همونطور که گفتیم، علاوه بر بنیاد، یه شرکت تجاری هم به اسم MariaDB Corporation وجود داره. این شرکت در سال ۲۰۱۰ توسط تعدادی از بنیان‌گذاران اصلی پروژه تاسیس شد تا بتونه کسب‌وکاری حول این نرم‌افزار متن‌باز بسازه.

    این شرکت یه پلتفرم به اسم MariaDB Enterprise Platform ارائه میده که برای استفاده‌های تجاری و حساس طراحی شده. این پلتفرم شامل موارد زیره:

    • MariaDB Enterprise Server: یه نسخه تقویت‌شده، امن و پایدار از سرور کامیونیتی.
    • MariaDB MaxScale: یک پروکسی پایگاه داده پیشرفته که برای افزایش دسترسی‌پذیری (high availability)، مقیاس‌پذیری و امنیت استفاده میشه.
    • MariaDB Xpand: یک موتور ذخیره‌سازی توزیع‌شده برای مقیاس‌پذیری بسیار بالای بارهای کاری تراکنشی.
    • MariaDB ColumnStore: یک موتور ذخیره‌سازی ستونی برای تحلیل داده‌های حجیم به صورت تعاملی.

    این شرکت ادعا میکنه که ۷۵ درصد از شرکت‌های لیست Fortune 500 از ماریا دی‌بی استفاده میکنن و مهاجرت از پایگاه داده‌های انحصاری به ماریا دی‌بی میتونه تا ۹۰ درصد در هزینه‌ها صرفه‌جویی کنه. یکی از مشتری‌های بزرگشون بانک DBS هست که ۵۴ درصد از برنامه‌های بانکی حیاتی خودش رو به ماریا دی‌بی منتقل کرده.

    در فوریه ۲۰۲۲، این شرکت اعلام کرد که قصد داره از طریق ترکیب با یک شرکت دیگه، وارد بورس نیویورک (NYSE) بشه.

    پلاگین بازخورد کاربر (User Feedback Plugin)

    از اکتبر ۲۰۱۱، ماریا دی‌بی یه پلاگین به اسم «بازخورد کاربر» رو معرفی کرد. این پلاگین به صورت پیش‌فرض غیرفعاله، اما اگه فعالش کنید، به صورت دوره‌ای یه سری اطلاعات مربوط به پیکربندی و نحوه استفاده از ماریا دی‌بی رو به سایت mariadb.org میفرسته.

    هدف از این کار چیه؟
    هدف اصلی اینه که به تیم توسعه کمک کنه تا مسیر مهندسی و توسعه جامعه رو در جهت درستی هدایت کنن. این اطلاعات بهشون نشون میده که:

    • ماریا دی‌بی روی چه پلتفرم‌ها و سخت‌افزارهایی اجرا میشه.
    • توزیع جهانی کاربرها چطوریه.
    • چه نسخه‌هایی از ماریا دی‌بی بیشتر استفاده میشن.
    • کدوم ویژگی‌ها محبوب‌تر هستن.

    چه اطلاعاتی جمع‌آوری میشه؟
    این پلاگین فقط اطلاعات غیرحساس رو جمع میکنه. مثل:

    • نوع و سرعت پردازنده و تعداد هسته‌ها.
    • اطلاعات سیستم‌عامل و توزیع.
    • لیست موتورهای ذخیره‌سازی و پلاگین‌های در حال استفاده.

    خیالتون راحت باشه! این پلاگین هیچ‌وقت اطلاعات شخصی یا حساس مثل نام کاربری، اسم پایگاه داده‌ها، محتوای جداول یا هر چیزی که بشه باهاش کاربر رو ردیابی کرد، ارسال نمیکنه.

    یک سوال مهم در معماری: پایگاه داده متمرکز یا غیرمتمرکز؟

    یه مدیر سیستم تازه‌کار سوال خوبی در ردیت پرسیده بود: «آیا بهترین کار اینه که همه پایگاه داده‌های MySQL/MariaDB رو روی یک سرور متمرکز کنیم؟»

    اون توضیح داده بود که برای هر سرویس وبی که راه میندازه (مثل Nextcloud)، یه ماشین مجازی جدید میسازه و روی همون ماشین یه سرور مای‌اس‌کیوال هم نصب میکنه. حالا به این فکر افتاده که آیا بهتر نیست یه ماشین مجازی جدا فقط برای پایگاه داده داشته باشه و بقیه سرویس‌ها از طریق شبکه به اون وصل بشن؟

    این یه سوال معماری خیلی مهمه. جواب کوتاهی که بقیه کاربرها بهش دادن این بود: «نه، این لزوما بهترین راه نیست.»

    دلایل مختلفی برای این جواب وجود داره:

    • نقطه شکست واحد (Single Point of Failure): اگه اون سرور پایگاه داده مرکزی به هر دلیلی از کار بیفته، تمام سرویس‌های شما با هم از کار میفتن.
    • تداخل منابع: سرویس‌های مختلف ممکنه نیازهای متفاوتی به پایگاه داده داشته باشن. یه سرویس ممکنه فشار زیادی به دیسک بیاره، یکی دیگه به پردازنده. وقتی همه روی یه سرور باشن، ممکنه برای منابع با هم رقابت کنن و عملکرد هم رو مختل کنن.
    • امنیت و ایزوله‌سازی: وقتی هر سرویس پایگاه داده خودش رو داره، اگه یکی از سرویس‌ها هک بشه، فقط داده‌های همون سرویس در خطره. اما در مدل متمرکز، ممکنه نفوذ به یک پایگاه داده راه رو برای دسترسی به بقیه داده‌ها هم باز کنه.

    البته مدل متمرکز مزایایی مثل مدیریت راحت‌تر و کاهش هزینه‌های نگهداری هم داره. در نهایت، انتخاب بین این دو مدل بستگی به اندازه، حساسیت و نیازهای هر پروژه داره.

    پرسش و پاسخ نهایی

    حالا که با کلیات ماریا دی‌بی آشنا شدیم، بیاید چند تا سوال کلیدی رو مرور کنیم تا مطمئن بشیم همه چیز خوب جا افتاده.

    سوال ۱: فرق اصلی بین بنیاد ماریا دی‌بی و شرکت ماریا دی‌بی چیه؟
    جواب: بنیاد ماریا دی‌بی یک سازمان غیرانتفاعی هست که وظیفه‌اش حفاظت از ماهیت متن‌باز و رایگان پروژه و مدیریت جامعه توسعه‌دهنده‌هاست. اما شرکت ماریا دی‌بی یک نهاد تجاری هست که محصولات و خدمات پولی مثل پشتیبانی تخصصی و نسخه‌های تجاری با امکانات بیشتر رو بر پایه ماریا دی‌بی ارائه میده.

    سوال ۲: آیا ماریا دی‌بی فقط یه کپی از مای‌اس‌کیواله؟
    جواب: نه. ماریا دی‌بی به عنوان یک «فورک» از مای‌اس‌کیوال شروع شد و هدفش سازگاری بالا با اون بود. اما در طول زمان، ویژگی‌ها، بهینه‌سازی‌ها و موتورهای ذخیره‌سازی جدیدی بهش اضافه شده که در مای‌اس‌کیوال وجود نداره. پس در حالی که ریشه مشترکی دارن، الان دو پروژه جدا با مسیر توسعه متفاوت هستن.

    سوال ۳: چرا میگن ماریا دی‌بی یه جایگزین «drop-in» برای مای‌اس‌کیواله؟
    جواب: چون API و پروتکل‌هاش با مای‌اس‌کیوال سازگاره. این یعنی شما میتونید سرور مای‌اس‌کیوال رو با سرور ماریا دی‌بی جایگزین کنید و برنامه‌های شما (مثل سایت وردپرسی یا هر برنامه دیگه‌ای که به پایگاه داده وصل میشه) باید بدون هیچ تغییری به کارشون ادامه بدن.

    سوال ۴: آیا برای استفاده از سرور ماریا دی‌بی باید پول بدم؟
    جواب: نه. سرور ماریا دی‌بی (MariaDB Community Server) تحت لایسنس GNU General Public License نسخه ۲ (GPLv2) منتشر میشه که یعنی کاملا رایگان و متن‌بازه. شما میتونید آزادانه اون رو دانلود، نصب، استفاده و تغییر بدید. نسخه‌های پولی مربوط به پلتفرم تجاری شرکت ماریا دی‌بی هست که امکانات اضافی و پشتیبانی ارائه میده.

    سوال ۵: چرا روی سیستم من وقتی ماریا دی‌بی رو نصب کردم، رمز عبور روت نداشت؟
    جواب: در بسیاری از توزیع‌های لینوکس، ماریا دی‌بی به صورت پیش‌فرض از پلاگین احراز هویت unix_socket استفاده میکنه. این پلاگین به کاربر root سیستم‌عامل اجازه میده بدون نیاز به رمز عبور به عنوان کاربر root پایگاه داده وارد بشه. برای این کار باید از دستور sudo mysql استفاده کنید. این یک اقدام امنیتیه تا جلوی حملات به رمز عبور روت از طریق شبکه گرفته بشه.

    منابع

    • [2] Why does installing KDE plasma workspaces install mariadb server? : r/Fedora
    • [4] ubuntu – Installing MariaDB – Unmet dependencies, mariadb-server-5.5 – Stack Overflow
    • [6] Is centralizing MySQL/mariadb databases on one server best-practice ? : r/sysadmin
    • [8] mysql – What’s the default password of mariadb on fedora? – Stack Overflow
    • [10] MariaDB – Wikipedia
    • [1] MariaDB Foundation – MariaDB.org
    • [3] MariaDB Enterprise Open Source Database | MariaDB
    • [5] Download MariaDB Server – MariaDB.org
    • [7] GitHub – MariaDB/server: MariaDB server is a community developed fork of MySQL server. Started by core members of the original MySQL team, MariaDB actively works with outside developers to deliver the most featureful, stable, and sanely licensed open SQL server in the industry.
    • [9] About MariaDB Server – MariaDB.org