راکت

جلوگیری از بیش از حد پست شدن یک فرم

16 پاسخ

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

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

ثبت پرسش جدید

پاسخ‌ها

16
mahdi khanzadi
mahdi khanzadi
@khanzadimahdi

تخصص: Software engineer

لاراول یه چیزی داره به نام throttle که میتونی ازش استفاده کنی. یه middleware هست که بررسی میکنه یه درخواست تعدادش توی یه بازه زمانی خاص (که خودت مشخص میکنی) از یه حدی بالاتر نره. اگه بالاتر بره اون کاربر رو تا یه تایمی مسدود میکنه.

HRH
HRH
@h.r.hassani

تخصص: back-end developer , switching to AI

خب کَش ها به همین درد می خورند. شما می تونید هر بار که user فرم رو سابمیت می کنه توی کش ذخیره کنید و اگه مثلا از یه حدی زیاد شد اجازه بهش ندید

شاید پاسخ شما همین‌جا باشد

علیرضا دینی
علیرضا دینی
@alirezadini

تخصص: برنامه نویس

@khanzadimahdi
اینکارو با ذخیره اطلاعات روی redis یا یه کش سیستم شبیه اون انجام میده؟

علیرضا دینی
علیرضا دینی
@alirezadini

تخصص: برنامه نویس

@h.r.hassani
اوکی ، بیا این روش و یکم بازش کنیم ، فرض مثال روی ردیس آی پی طرفو نگه میدارم و این بررسی رو انجام میدم. و بعد از اون کاربر مثلا با apache بن میشه.
انجام همین پروسه مدام ریسورس میگیره از سرور. (البته قطعا به دلیل درگیر نشدن io خیلی بهینه تر از کوئری زدن به دیتابیسه)

HRH
HRH
@h.r.hassani

تخصص: back-end developer , switching to AI

@dinihooman می تونی توی فایل ذخیره کنی .(البته کند تره)

علیرضا دینی
علیرضا دینی
@alirezadini

تخصص: برنامه نویس

@h.r.hassani

اوه اوه این کار توی ریکوئست های بالا واقعا میتونه منجر به قطع شدن سرویس بشه.

به نظرم این موضوع جالبه ، به تحقیق اش می ارزه. بررسی کنیم ببینیم سایتای بزرگ چیکار میکنن.

HRH
HRH
@h.r.hassani

تخصص: back-end developer , switching to AI

@dinihooman
پس لاراول چجوری این کار رو می کنه و مشکلی هم نداره؟؟
ولی کلا برای کنترل این کار مجبور resource بیشتری مصرف کنی

مهدی عقیقی
مهدی عقیقی
@MehdiAghighi

تخصص: برنامه نویس وب

سلام وقتتون بخیر.

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

این فایل اون میدلویری هست که چک می‌کنه:
Illuminate\Routing\Middleware\ThrottleRequests.php

حالا اگر دقت بکنید این فایل از train ی استفاده کرده به نام InteractsWithTime که namespaceش اینه:

Illuminate\Support\InteractsWithTime.php

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

و در آخر توی کانستراکتور میدلویری که بالا گزاشتم رو اگر نگاه کنیم، یک کلاسی رو اینجکت کرده به اسم RateLimiter که namespaceش این هست:

Illuminate\Cache\RateLimiter

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

فایل اول که middleware هست یعنی نقطه آغازش میشه اون تابع handle که داره از اونجا اگر پله پله برید جلو کاملا متوجه می‌شید.

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

در کل throttle لاراول خیلی قدرتمنده و اونجوری هم نیست که بگیم منابع زیاد از سرور می‌خواد. نه موقعی که از فایل استفاده می‌کنه و نه حتی موقعی که از چیز‌هایی مثل redis استفاده می‌کنه. ( در واقع مدیریت منابع رو خوب انجام می‌ده‌ )

این مقاله هم می‌تونه کمکتون کنه بخونیدش به نظرم.

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

علیرضا دینی
علیرضا دینی
@alirezadini

تخصص: برنامه نویس

@MehdiAghighi
بیا اینو تحلیل کنیم ،

یه سوال دارم درباره ساختار درونی این Middleware :
Throttle اطلاعات هرکاربر که چندبار در چه زمانی لاگین شده رو کجا ذخیره میکنه؟ روی دیتابیس ، فایل ، ردیس یا ...

مهدی عقیقی
مهدی عقیقی
@MehdiAghighi

تخصص: برنامه نویس وب

@dinihooman

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

علی بیات
علی بیات
@ali.bayat

تخصص: توسعه دهنده ارشد وب

جدا از امکانات لاراول برای این کار (throttle) خودت هم میتونی همچین چیز هایی رو بررسی کنی.
مثلا درخواست های ۱ ساعت آخر رو در کش داشته باشی و درخواست جدید میرسه چک کنی که چندمین درخواست اون کاربر در ۵ دقیقه گذشته هست..
کاری که لاراول هم کم و بیش به همین شکل (البته خیلی شیوا تر) انجام میده.

علیرضا دینی
علیرضا دینی
@alirezadini

تخصص: برنامه نویس

@ali.bayat

عزیز ، به نظر خودت چجوری کشی برای این منظور بهتره؟
میدونی دنبال اینم تا جای ممکن برای چک کردن این مورد به دیتابیس کوئری نزنم ، چون فرقی نمیکنه به کاربر اجازه انجام کارش داده میشه یا نه ، به هرحال برای سیستم سرباز هزینه ای ایجاد میکنه.
فایل به نظر من بدتر از دیتابیس هست ، چون io بیشتر درگیر میشه. تا اینجا که سرچ کردم ردیس بهترین گزینه بوده ، ولی میخوام ببینم سولوشن بهتری هم هست که من نمیشناسم.
فرض مثال شاید انجین ایکش یا آپاچی خودشون یه راه حل برای این منظور داشته باشن (صرف نظر از فایروال های سخت افزاری) .

علی بیات
علی بیات
@ali.bayat

تخصص: توسعه دهنده ارشد وب

ردیس قاعدتا سریع تر هست

علیرضا دینی
علیرضا دینی
@alirezadini

تخصص: برنامه نویس

@MehdiAghighi

اطلاعات خیلی خوبی بهم دادی ، ممنونم

مهدی عقیقی
مهدی عقیقی
@MehdiAghighi

تخصص: برنامه نویس وب

@dinihooman خواهش می‌کنم :)

ردیس یه نکته خیلی مهمش اینه که می‌تونی برای مقدار‌هایی که ذخیره می‌کنی expire time بزاری و خب این موضوع هم خیلی می‌تونه کمکت کنه.
تابع INCR که داره هم که برای این کار خیلی خوبه ....

علیرضا دینی
علیرضا دینی
@alirezadini

تخصص: برنامه نویس

@MehdiAghighi چقدر عالی !
این خیلی خوبه

برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام