چند نکته که باید در هنگام ساختن صف بدانید

صف queue از مواردی هست که در برنامه نویسی خیلی مورد استفاده قرار میگیره , مثلا از موارد مورد استفاده صف میشه در ارسال ایمیل ، سیستم زمانبندی و اجرای یک مورد خاص ، یا ارسال sms در صورتی که تعداد بالا باشد و نمی خوایم کاربر رو منتظر نگه داریم اشاره کرد.

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

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

userStory :

ما میخواستیم یه سیستمی را بندازیم که بتونه کاربر ارسال sms خودش رو زمانبندی کنه و تو اون زمان خاص ارسالش رو انجام بده . یه مورد دیگه هم ارسال گروهی sms بود . برا همین وقتی کاربر میخواست sms ارسال کنه به حدود ۵۰۰۰ کاربر حدود چهار دقیقه باید منتظر میشد تا همه sms ها ارسال بشه . خب باید چیکار کرد :

راه حل ما صف بود

زمانی که کاربر درخواست خودش رو میداد ما همه شماره هایی که میخواست و زمان ارسالش رو تو دیتابیس ذخیره میکردیم و با استفاده از Cron هر یه دقیقه یه  اسکریپت رو اجرا میکردیم  و اون چک میکرد که تو صف همون دیتابیس ما smsای هست که باید ارسال بشه اونو فچ میکرد و اون رو ارسال میکرد.

همه چی خوب بود و داشت مثل سوایچیم کار میکرد . سوایچیم “کلمه ترکی است ، سوایچیم به معنی این هست که مثل آب خوردن و درست کار  میکرد” .

مشکل کجا بود ، اونجا بود که نزدیک عید همه کاربرا داشتند تبلیغات میکردند و هرکدوم دو سه میلیون شارژ کرده بودند و می خواستند ارسال کنند . دقیق یادم بود اولین کسی که شارژ کرد و ده دقیقه بعد به دو میلیون کاربر ارسال خودش رو انجام داد ، بعد از نیم ساعت زنگ زد نفسش در نمیومد نمیدونست فحش بده یا چی . خلاصه مشکل این بود که به اون شماره هایی که ارسال داشت انجام میشد به هرکدوم داشت هر ثانیه یه sms میرفت 😐

WTF 😐 چه جوری ممکنه ، سریع سرور رو داون کردیم و نام کاربری و پسورد وب سرویسمون رو عوض کردیم تا همه چی بخوابه .

هنگام تست محصول به همه جوانب و شرایط توجه داشته باشید. شرایط production با development خیلی متفاوت هست.

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

مهم ترین مشکل :

در صف باید حواستون به نحوه ورود و خروج داده به صف باشه.

زمانی که cron اجرا میشد تمام داده هایی که زمان ارسالشون رسیده بود رو ورمی داشتیم و شروع به ارسال می کردیم . تا اینجا خوبه . اون موقع بد میشه که داده هایی که فچ شدند و در حال ارسال هستند بعد از یه دقیقه توسط cron دیگه ای فچ بشه و اونم شروع به ارسال کنه ، حالا در نظر بگیرید که ۱۰۰۰ تا فچ کردند و دارند کارشون رو انجام میدند. خدا بخیر کرد که یه مشتری فقط ارسال انجام داده بود و گرنه همه مشتریهامون از دست می رفتند.

راه حل :

flag

با یه فلگ اگه به سیستم میفهموندیم که داره روش کار میشه و اینو فچ نکن ، راه حل مسیله بود. یعنی هنگامی که cron اولی که اجرا میشد قبل از ارسال flag اونایی که فچ شده بودند به doing تغییر پیدا میکرد و بعد از اتمام اون به done دیگه این مسیله پیش نمیومد . ما فقط حالت do و done رو داشتیم و به doing توجهی نکرده بودیم.

بعد از این اتفاق به مسایلی هم فکر کردیم که شاید در آینده اتفاق بیفته .

یکی php execution time بود که باید زیادش میکردیم تا اگه طول کشید وسط کار از کار نیفته.

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

اگه واسه شما هم همچین مشکلی پیش اومده یا راه حل بهتری دارید و یا مشکلاتی که من فکرشو نکردم به ذهنتون رسیده ،ممنون میشم تو قسمت کامنت ها به منم بگید.

از امیر حبیب‌زاده

از سال 89 برنامه‌نویسی رو شروع کردم، ساختن رو خیلی دوست دارم، قبلا ایوند رو کمک کردم بسازیم الان هم دارم به ساختن تريژر کمک میکنم. پیگیر بلاک‌چین و غیرمتمرکز سازی هستم و محیط‌زیست دغدغه الان من هستش.