ترگمان سوار ابرها شد

ت
ترگمان سوار ابرها شد

ترگمان از سال ۱۳۹۰ در پژوهشگاه ارتباطات و فناوری اطلاعات راه‌اندازی شده و همانجا هاست می‌شد. خلاصه‌ای از تاریخچه ترگمان را می‌توانید اینجا بخوانید. بعد از ارتقای ترگمان از سامانه آماری به نورونی، سرویس‌دهی به صورت کامل به پردازند‌های گرافیکی (GPU) وابسته شد و در نتیجه انتقال سرویس به خارج از پژوهشگاه هزینه بسیار زیادی داشت و عملا امکان‌پذیر نبود.

متاسفانه از ابتدای سال ۹۷ شبکه ارتباطی پژوهشگاه با اختلالات متعدد مواجه شد به نحوی که درخواست‌های connection از هر سه نوع HTTP, HTTPS, SSH با تاخیر زیاد به سرورها می‌رسیدند و باعث می‌شد تا کاربر در ارتباط اول تاخیر زیادی ببیند و در نتیجه bounce rate ترگمان به شدت بالا رفت. 

از طرف دیگر ارتباط با ترگمان از IP های خارج از کشور با اختلالات شدید مواجه شد و این موضوع باعث گردید تا از آبان‌ماه به مرور رتبه ما در گوگل برای جستجوی لغات پرکاربردی همچون «ترجمه»، «مترجم» و «ترجمه انگلیسی به فارسی» از رتبه ۲ به رتبه ۶ و حتی ۱۲ و بیشتر افت کند. 

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

انتقال ترگمان به ابر آروان

صفحه وب ترگمان یک صفحه بسیار ساده است که تماما سمت client پیاده‌سازی شده و با فراخوانی API سرویس ترجمه و سایر سرویس‌ها را ارایه می‌دهد. از این رو با یک کانتیر کوچک nginx و یک کانتینر haproxy کار ما راه می‌افتاد. به همین دلیل ابتدا بنا داشتیم تا از سرویس فندق استفاده کنیم. اما با صحبتی که با دوستان داشتیم متوجه شدیم که امکان ارایه سرویس در مراکز داده ایران را ندارند و با توجه به مشکلات ارتباطی با IP های خارجی منصرف شدیم. گزینه بعدی ما ابرآروان بود که امکان استفاده از یک ماشین مجازی بسیار کوچک و ارزان‌قیمت (ابرک شخصی‌سازی شده به قیمت ماهانه ۴۰ هزار تومان) را برایمان فراهم می‌کرد.

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

مشکل ارتباط با سرورهای GPU را چه کنیم؟

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

از آنجایی که واسط کاربر و API ترجمه در دو مرکز داده متفاوت بودند ساده‌ترین راهکار برقراری یک تونل ارتباطی بین این دو مرکز داده بود. اما چه تونلی؟

تونل‌های GRE, IPinIP, L2TP و IPSec را امتحان کردیم اما هر کدام به دلایلی جوابگو نبودند اصل مشکل هم رابط ارتباطی بین دو مرکز داده و دیواره‌های آتش موجود بود که کار را سخت و در شرایطی غیر ممکن می‌کرد.

تونل SSH؟ مگه میشه؟ مگه داریم؟

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

  • Local Port Forward: این تونل یک پورت در مقصد را به پورتی در مبدا نگاشت می‌کند به عنوان مثال ssh USER@SERVER -L8080:127.0.0.1:80 پورت ۸۰ در مقصد را به پورت ۸۰۸۰ در مبدا نگاشت می کند و با ارتباط با پورت ۸۰۸۰ عملا ارتباط با پورت ۸۰ مقصد برقرار می‌شود.
  • Remote Port Forward: این تونل معکوس عمل فوق را انجام می‌دهد و پورت مبدا را بر روی مقصد نگاشت می‌کنند. از این تونل معمولا زمانی استفاده می‌شود که رایانه مبدا بخواهد پورتی را برای ارتباط از بیرون باز کند اما IP یا پورت مبدا مستقیما از بیرون در دسترس نباشد.
  • Dynamic Port Forward: از این تونل برای پراکسی کردن ارتباط استفاده می‌شود و برنامه‌های متعدد می‌توانند با پورت‌های متفاوت به پورتی در مقصد و از آنجا به اینترنت متصل شوند. از این روش برای ایجاد تونل Socks استفاده می‌شود.

در کاربرد ما چون هردو سرور دارای Valid IP با امکان اتصال از بیرون هستند تونل از نوع Local Port Forward کفایت می‌کند. به این ترتیب کافیست پورت ۸۰ سرور API را به پورتی دلخواه (مثلا ۸۰۹۰) روی سرور واسط کاربر نگاشت کنیم.

چگونه یک ارتباط ssh پایدار ایجاد کنیم؟

تونل‌های ssh با یک ایراد بزرگ مواجه هستند و آن‌هم قطع شدن در صورت عدم فعالیت. هرچند در پروتوکل ssh امکان پینگ برای افزایش پایداری ارتباط پیش‌بینی شده اما در ایران قطعی تونل‌های مبتنی بر این پروتوکل بسیار شایع است. به همین منظور به جای ssh از autossh استفاده کردیم.

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

# ssh-keygen
# ssh-copy-id USER@SERVER
# autossh -M12345 -L8090:127.0.0.1:80 USER@SERVER

به این ترتیب یک تونل پایدار ایجاد می‌شود. برای تضمین اینکه این تونل در صورت ریست شدن سرور هم برقرار شود بهتر است آن را به عنوان یک سرویس پس از راه‌اندازی شبکه معرفی کنید یا اینکه آن را در crontab برای زمان boot معرفی نمایید. همچنین برای افزایش ایمنی ارتباط بهتر است نام کاربری مورد استفاده در تونل فاقد bash باشند.

فرض که تونل ایجاد شد، API را چه کنیم؟

تونل ssh فقط ارتباط شبکه را برایمان برقرار می‌کند و موجب می‌شود تا در هزینه ایجاد connection صرفه‌جویی شود چون هر ارتباط با پورت تونل به مشابه ایجاد ارتباط در سرور مقصد بوده و هزینه ایجاد ارتباط از بیرون به سرور پرداخته نمی‌شود. اما برای استفاده از این تونل لازم است تا API را بر روی این پورت پراکسی کنیم. یکی از ساده‌ترین راه‌ها برای ایجاد این پراکسی استفاده از haproxy است. هرچند خود nginx هم می‌تواند به عنوان پراکسی تنظیم شود اما تنظیم کردن haproxy به مراتب ساده‌تر است و از طرفی ما همیشه برای تسهیل ارتباطات و تنظیمات یک haproxy را در لبه قرار می‌دهیم. برای پراکسی کردن API تنظیمات زیر به تنظیمات haproxy اضافه شدند

frontend https-in
...
        acl isAPI path_beg /API
        use_backend API if isAPI
...
backend API
        timeout server 30s
        option forwardfor
        option http-keep-alive
        timeout http-keep-alive 3600s

        http-request set-header X-Parent-Proxy-IP SERVER_IP

        reqrep ^([^\ :]*)\ /API[/]?(.*)  \1\ /ACTIVE_API_VERSION/?cip=CLIENT_IP\2
        reqrep ^Host: Host:\ api.targoman.com
        server api1 127.0.0.1:8090  check

به این ترتیب هر درخواست به سمت سرور که مسیر آن با API/ شروع شود به سمت تونل هدایت شده و آدرس هم با ACTIVE_API_VERSION/?cip=CLIENT_IP/ جایگزین می‌شود.

نتیجه

نزدیک به ۲ هفته است که واسط کاربر ترگمان به ابرآروان منتقل شده و ارتباط با پژوهشگاه نیز از طریق تونل برقرار شده است. در این مدت رتبه ترگمان در گوگل و رنک الکسای آن تا حدودی بهبود یافته. اما هرچند برای نتیجه‌گیری هنوز زود است و گوگل هنوز ما را از تنبیه در نیاورده اما رشد آمار کاربران سایت و کاهش Bounce Rate نشان‌دهنده آن است که این تغییر باعث بهبود عملکرد سایت و سرویس دهی آن شده است.

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

درباره نویسنده

مهران ضیابری

افزودن دیدگاه

نوشته‌های تازه

آخرین دیدگاه‌ها