رضا شادمان
رضا شادمان
خواندن ۹ دقیقه·۴ سال پیش

چطور هزینه‌های ارسال ایمیلمون رو «صفر» کردیم

اگه شما هم اپلیکیشنی دارین که تعداد زیادی ایمیل ارسال می‌کنین، حتما در جریان هستین که ساخت Reputation و بالا نگه‌داشتن Deliver-ability هنگام ارسال به ESP ها مانند یاهو و Gmail کاریه که علاوه بر کیفیت محتوای ایمیل نیاز به تکنیک و دانستن سوراخ سمبه‌های ایمیل داره. ما هم تو شروع ساخت جابینجا این دغدغه رو از خودمون گرفتیم و با پرداخت هزینه واگذارش کردیم به سرویس‌های جایگزین مانند Sendgrid, Postmark و.... .

توضیح مشکل

تا اینجا به نظر خودمون تصمیم خوبی گرفته بودیم تا اینکه چند تا اتفاق افتاد:

  • هزینه ارسال ایمیل از طریق سرویس‌های بالا برای ما تا دو هزار دلار در ماه بالا رفت این عدد برای ما به ذات مشکلی درست نمیکرد ولی جزو هزینه‌های سنگینمون محسوب میشد که به مرور زمان هم شدیدا افزایش پیدا میکنه از این رو دغدغه کم‌کردن این هزینه برامون وجود داشت.
  • اصولا ESP ها در مقابل Reputation شون خیلی حساس هستن که خب منطقیه ولی از راه‌های غیر متعارفی برای کنترل مشتری‌هاشون استفاده میکنن، بخش عمده‌ای از ایمیل‌هایی که ما ارسال می‌کنیم مربوط به شرکت‌های B2B هستن که خودشون سرویس ایمیلشون رو مدیریت می‌کنن با توجه به اوضاع اینترنت ایران خیلی پیش میاد که زیر ساخت شرکت‌ها برا دقایقی در دسترس نباشه. اصولا ESP ها توی این شرایط اون دامنه و آی‌پیش رو داخل Softfail قرار میدن و دیگه -- یا تا چند ماه آینده -- بهش ایمیل ارسال نمیکنن و عموما هم تنها راه نجات حذف دستی از داخل لیسته.
  • بر خلاف چیزی که فکر میکنیم اکثر این شرکت‌ها به جز معروف‌هاشون مثل Mailgun, Sendgrid, Mandrill, Postmark و Sparkpost -- که خیلی گرون هستن --- اونقدری که به نظر میاد برای مشتری‌هایی که حجم ارسال‌هاشون نسبتا بالاست مناسب نیستن. ما به صورت مقطعی و این آخرها به صورت مداوم مشکل Durability داشتیم یعنی ایمیل‌هامون با تاخیر زیادی می‌رسیدن. دلیلش اینه که اینا از یه Shared IP Pool عموما استفاده میکنن، خیلی‌هاشون این قابلیت رو دارن که بشه آی‌پی‌های اختصاصی خودت رو بگیری ولی اون‌ها پروسه Warmup شون عموما پیچیده است، در مجموع اگه از ابتدای رشد محصول با این منطق ازشون استفاده کنین خیلی راحت‌تره تا اینکه به صورت آنی بخواین سرویس‌دهنده ایمیلتون رو عوض کنین یا بهش IP اختصاص بدین.

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

بررسی راهکارهای موجود و حل مشکل

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

نیاز داشتیم که طبق استانداردی که توی این صنعت وجود داره IP هامون رو برای حجم مد نظرمون Warmup کنیم. این دو تا پیش نیاز داشت، توی بخشی از اپلیکیشنمون که وظیفه ارسال ایمیل رو به عهده داره این قابلیت وجود نداشت که بتونیم بر اساس وزن، ایمیل‌های ارسالی رو به سرویس‌دهنده‌های مختلف پخش کنیم و علاوه بر این برای شروع باید از نوع ایمیل‌هایی استفاده می‌کردیم که Engagement Rate بالایی دارن تا بتونیم اعتماد ESP ها رو به خودمون جلب کنیم. این شروع راهکاریه که برای ما کار کرد و به صورت میانگین تا ۱۵۰۰ دلار در ماه هزینه‌هامون رو کاهش داد:

اولش سعی کردیم که یه سرور Postfix درست کنیم با چند Network Interface و از اونجایی که می‌خواستیم این راه حل برامون جواب بده و محدودیتی نداشته باشیم فکر این رو هم کرده بودیم که با داشتن یه کانفیگ یکسان می‌تونیم با یه TCP Proxy ساده ترافیک رو بین سرورهای مختلف پخش کنیم، هر چند که برای شروع برای ما یک سرور ساده با دوتا IP عمومی کافی بود. پیکربندی Postifx کار پیچیده و سختیه، علاوه بر این راهی هم برای مانیتور کردن ایمیل‌های ارسالیمون و دنبال کردن چیزهایی مثل OpenRate نبود و مجبور بودیم اگه بخوایم از Postfix استفاده کنیم این بخشش رو براش اپلیکیشن جداگانه بنویسیم که خب منطقا این کارو نکردیم و پرونده Postifx همینجا بسته شد و از این به بعد خوشحال‌تر برای ایمیل هزینه می‌کردیم :)).

چند وقت پیش به صورت اتفاقی توی گشت‌و‌گذارهام داخل اینترنت با نرم‌افزاری آشنا شدم به اسم Postal که با Rails نوشته شده و از RabbitMQ و Procodile برای ارائه یه نرم‌افزار Self-Hosted شبیه به Sendgrid و امثالهم استفاده میکنه. یه کانفیگ خیلی ساده‌داره و از اونجایی که اکثر کمپوننت‌هاش مثل Worker ها، MySQL و RabbitMQ مقیاس‌پذیر هستن و تا حدی از قبل هم با مدیریت زیر ساختشون آشنا بودیم برای ما یه انتخاب خوب بود. پیکربندی خیلی ساده‌ای داشت و قابلیت‌های خیلی خوبی هم برای مدیریت سرور میداد مثلا به راحتی میتونستی لاگ‌ها رو بخونی یا از وضعیت ورکرهات خبر داشته باشی تا اینجا یه سرور Postal رو کانفیگ کردیم و با ابزارهای موجود روی اینترنت از این مطمئن شدیم که کانفیگ DNS ها مشکلی ندارن.

ولی این مشکل مارو به صورت کلی حل نمیکرد، هنوز پروسه مهاجرت از یه سرویس‌دهنده دیگه روی Postal برای ما دردسر داشت قبل از مهاجرت کلی می‌بایست IP هایی که روی Postal داشتیم رو Warmup میکردیم و داخل اپلیکیشنمون زیر ساختی برای این قضیه نداشتیم. دو تا نیاز ساده داشتیم:

  • اول بشه به هر سرور SMTP وزن داد مثلا ۲ درصد ایمیل‌ها در روز با Postal ارسال بشه و مابقیش با سرویس قدیمی‌ که داشتیم
  • دوم بشه یه سری ایمیل خاص که Engagment بالایی دارن مثل ایمیل بازیابی رمز عبور از سرور جدیدمون ارسال بشه تا ESP ها زودتر بهمون اعتماد کنن.

نهایتا با نوشتن یه درایور ساده برای ارسال ایمیل با یه کانفیگ ساده شبیه به عکس زیر این مشکل هم برطرف شد، تنها تغییری که توی کدمون لازم بود انجام بشه این بود که آدرس‌های From رو همونطور که توی عکس زیر میبینید مختص به اون نوع از ایمیل که Engagement Rate بالایی داره تعریف کنیم و نهایتا اون ایمیل‌ها توسط درایور مرتبطشون با همین کلید Capture میشدن:

حالا همه‌چی آماده بود و فقط نیاز بود که پروسه Warmup رو به صورت Industry Standard شروع کنیم. برای این حرکت از یه فایل راهنما که Sendgrid توی بلاگش معرفی کرده استفاده کردیم که به شما میگه توی هر روز با هر IP چقدر ایمیل بزنید، تنها چیزی که لازم داره اینه که محتوای ایمیلتون Legit و مناسب باشه، برای ما این پروسه به سادگی کار کرد، به صورت رزوانه درصد و وزن سرویس جدید ایمیلمون رو توی کانفیگ افزایش میدادیم تا اینکه نهایتا به حجم مورد نظرمون رسید.

مانیتور کردن و مطمئن شدن از راهکار جدید

اما این پایان ماجرا نبود هنوز مطمئن نشده بودیم که ایمیل‌هامون مانند قبل با همون درصد داخل اینباکس قرار میگیرن حالا که تقریبا به نظر میومد تو تست‌های خودمون مشکل حل شده لازم بود که به حالت استانداردتری بشه این قضیه رو پیگیری کرد. برای این کار از دو روش استفاده کردیم اول از سرویسی استفاده کردیم به نام Glockapps که بهتون یه لیست ایمیل از سرویس‌دهنده‌های مختلف مانند Zoho، Gmail، یاهو، ماکروسافت، پروتون و... میده که با ارسال ایمیل واقعیتون به اون آدرس‌ها چک میکنه که ایمیل‌هاتون داخل اون سرویس‌دهنده به اینباکس میره یا Spam. برای ما با درصد زیادی به اینباکس می‌رفت و با پیشنهادهایی که داده بود مثل رجیستر کردن IP در یه سامانه‌ای که مایکروسافت ارائه میده بخش دیگه‌ایش هم بهبود پیدا کرد و از قبل هم بهتر شد.

دومین روشی که برای این مقایسه استفاده کردیم درصد ترافیک Source ایمیل از داخل Google Analyitics بود. انتظار داشتیم که درصد ترافیک ایمیلمون تغییر نکرده باشه، با بررسی درصد ترافیک متوجه شدیم که اون هم از حالت قبل خودش کمی بهتر شده و همه‌چی خوب پیش می‌رفت (البته این بررسی زیاد دقیق نیست و فقط به شما نشون میده که مشکل خیلی بزرگی وجود نداره).

حالا وقت این بود که به قابلیت‌های مانیتورینگی که لازم داشتیم برسیم. از اونجایی که Postal از MySQL استفاده میکنه به راحتی تونستیم به Grafana وصلش کنیم و Open Rate , Sending Rate رو بهتر از قبل دنبال کنیم و همینطور بتونیم در کنار بقیه سرویس‌هامون از قابلیت‌های Alerting گرافانا برای اطلاع‌ از مشکل ها استفاده کنیم.


توضیحات کاربردی

یه نکته‌ای هم بگم ما برای ارسال ایمیل از سرورهای Hetzner Cloud استفاده میکنیم که میذاره تا ۱۰ تا آی‌پی رو به هر دراپلت Attach کنید برای Run کردن پستال حداقل به ۲ آی پی عمومی نیاز هست.

از طریق سرویس‌هایی مانند Senderscore و TalosIntelligence میتونید به صورت کلی IP Reputation و Domain Reputation تون رو برای ایمیل چک کنید برای مثال این الان برای ما هست، درصورتی که به صورت پیوسته Hardbounce ها رو مانیتور کنید و دیگه بهشون ایمیل نفرستین این عدد تو بهترین حالت خودش میمونه.

یه عددی بین ۰ تا ۱۰۰ رو سندر اسکور به عنوان امتیاز میده
یه عددی بین ۰ تا ۱۰۰ رو سندر اسکور به عنوان امتیاز میده


این عکس هم مربوط به Shared IP Pool ای هست که سرویس‌دهنده قدیم ایمیلمون داشته:


نهایتا با نرم‌افزار فوق‌العاده‌ای که به صورت Opensource و آزاد در اختیار ما بود ما تونستیم هزینه ارسال ایمیلمون رو تقریبا به صفر برسونیم.

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






ایمیلجابینجاjobinjaSMTP
بنیانگذار و مدیر فنی جابینجا
شاید از این پست‌ها خوشتان بیاید