
وقتی system design یا طراحی سیستم رو برای اولین بار میشنوین، ممکنه پیش خودتون فکر کنین که باید کلی مفاهیم پیچیده و عجیب و غریب یاد بگیرین، یا شایدم تصمیم بگیرین فعلا ازش فرار کنین تا یکم تجربه کاریتون بره بالاتر اونوقت خودتون متوجه میشین، حتی ممکنه با دیزاین سیستم (design system) قاطیش کنین و جای همدیگه استفادشون کنین.
اما توی این مطلب قراره بصورت خیلی ساده توضیحش بدیم، تا هم اهمیتش رو درک کنیم و هم از این به بعد بتونیم یه مسئله رو بصورت مرحله به مرحله تحلیل کنیم تا به یه معماری مناسب برسیم.
برای اینکه بتونیم راحتتر موضوع رو درک کنیم من از ai خواستم برای این مقاله بهم پیشنهاد یه پروژه ساده بده که بتونم مفاهیم طراحی سیستم رو مرحله به مرحله باهاش پیاده سازی کنم و اونم بهم گفت چی بهتر از پیادهسازی “سرویس کوتاه کننده لینک”
۱- طراحی سیستم یا System Design چیه؟
به فرایندی گفته میشه که قراره توش مشخص کنیم که:
- نرم افزار ما قراره از چه اجزایی تشکیل بشه.
- این اجزا چطوری باهمدیگه ارتباط برقرار کنن.
- و در نهایت معماری کلی سیستم چطوری میخواد نیازمندیهامون رو برطرف کنه.
یکم خودمونیتر:
قبل اینکه یهو بریم سروقت پیادهسازی کنیم، باید مشخص کنیم که قراره چی بسازیم؟ چه بخشهایی نیاز داریم؟ و هر بخش چه مسئولیتی بر عهده داره؟
برای مثال یه فروشگاه اینترنتی رو در نظر بگیرین، از چه اجزایی تشکیل شده؟
- سرویسی که بتونه کاربران رو مدیریت کنه و احراز هویت رو انجام بده
- سرویسی که محصولات رو مدیریت کنه
- سرویسی که سفارشهارو کنترل کنه
- رابط کاربری که برای این موارد طراحی میشه
- دیتابیسی که قراره اطلاعات رو ذخیره کنه
- زیرساختی که بتونه این پروژه رو هندل کنه
حالا طراحی سیستم مشخص میکنه این اجزایی که گفتیم چطوری کنارهم قرار بگیرن و چطوری باهم ارتباط برقرار کنن و اطلاعات رو بین خودشون جابجا کنن.
مفهوم Trade off در طراحی سیستم
توی طراحی سیستم پاسخی که کامل و بی نقص باشه، وجود نداره!
یعنی ما هر تصمیم فنی که میگیریم مزایا و معایب خودش رو داره و انتخاب ما همیشه باید براساس نیازهای پروژه باشه
به این تحلیل Trade off گفته میشه!
بیاین یه مثال ساده و عمومی بزنیم که برای همه قابل فهم باشه:
فرض کن تو میخوای همبرگر بخوری و میخوای همزمان هم همبرگرت خیلی ارگانیک باشه و هم خیلی سریع آماده بشه و قیمتش هم زیر ۲۰۰ هزارتومن باشه، قطعا تو نمیتونی همینه اینارو داشته باشی و باید براساس یا موجودی جیبت بری همبرگر بی کیفیت اما ارزون بخوری، یا نه حتما ارگانیک بودن مهمه پس باید جیبت رو خالی کنی، یعنی تو براساس شرایط و نیازت باید یکی رو فدا کنی. توی طراحی هم همیشه با توجه به نیاز باید انتخاب کنیم و لزوما انتخاب بهترین ابزار پاسخگو نیست.
حالا یه مثال توی دنیای واقعی برنامه نویسی:
جدال همیشگی بین سرعت توسعه و کدنویسی تمیز
کارفرما میگه درسته این feature خیلی زمان میبره اما من اینو سریع میخوام و باید تحویل بدی و تو مجبوری برای اینکه سریعتر بهش برسونی کد کثیفتری بنویسی
بهای trade off میشه اینکه تو feature رو خیلی سریع رسوندی، اما اگر بعدا بخوای تغییرش بدی خیلی اذیتت میکنه.
حالا که کامل متوجهش شدیم، برسیم به عواملی که باید توی این تصمیمها بررسیشون کنیم:
- کارایی (Performance): سیستم با چه سرعتی پاسخ بده؟
- تاخیر (Latency): چه مدت طول میکشه تا درخواستی که فرستادیم پاسخش برسه؟
- هزینه (Cost): نگهداری و اجرای همچین سیستمی چقدر هزینه داره؟
- پیچیدگی (Complexity): پیاده سازی و نگهداری معماری چقدر پیچیدگی و دشواری داره؟
- مقایسپذیری (Scalability): سیستمی که طراحی کردیم میتونه اگر تعداد کاربران یا درخواستها بیشتر شد، بازم اونارو مدیریت کنه؟
هدف طراحی سیستم این نیست که ما توی تمام مواردی که بالا گفتیم بهترین نتیجه رو بگیریم و اجراییش کنیم، هدف اینه که با توجه به نیازهای واقعی پروژه، تصمیم منطقی و درست رو بگیریم.
۲- مراحل طراحی سیستم
تا الان هرچی حرف زدیم، تعریفی از طراحی سیستم و بررسی مفهوم trade off بود.
حالا وقتشه برسیم به مراحلی که باید توی طراحی سیستم انجام بدیم
۱- مرحله اول: درک کامل و دقیق مسئله
اولین قدم ما توی طراحی سیستم، انتخاب تکنولوژی یا شروع کار با کد و دیتابیس نیست، اول مسئلهای که میخوایم براش راهحل بدیم رو کامل درک کنیم.
توی این مقاله که ai توی مثالش بهمون کمک کرده و پیشنهاد داده قراره یک سرویس کوتاه کننده لینک طراحی کنیم
فرض کنیم که کاربر میخواد آدرس طولانی و بلند زیر رو به سرویس ما بده:
example.com/blog/cars/sell/best-cars-in-world
و سرویس ما هم یه لینک کوتاه براش تولید کنه:
short.example/bC74d
و بعدش هر کسی هر جایی روی لینک کوتاه تولید شده کلیک کنه به آدرس اصلی هدایت یا redirect بشه.
فرایند کلی سیستم دو عملیات اصلی داره:
۱- کاربر یک URL طولانی رو توی سیستم وارد کنه و سیستم یک URL کوتاه براش بسازه.
۲- کاربر وقتی URL کوتاه رو باز کنه، سیستم اون رو به URL اصلی هدایت کنه.
توی پشت صحنه سیستم باید ارتباط بین لینک کوتاه و آدرس اصلی رو ذخیره کنه تا وقتی لینک کوتاه باز شد، بتونه آدرس اصلی رو درست تشخیص بده.
بعد از درک مسئله اصلا نباید سراغ کدنویسی برید!
اگر بخوایم بدون درک کامل مسئله مستقیم بریم سراغ کدنویسی ممکنه چند روز بعد از شروع توسعه متوجه بشیم که هنوز یک سری قابلیتهارو در نظر نگرفتیم یا مسیری کدنویسیمون جوری پیش رفته که وقتی نیازهای اصلی پروژه رو متوجه شدیم نمیتونیم به راحتی ساختار اولیه کدهامون رو تغییر بدیم و مجبوریم زمان خیلی زیادی برای تغییر اونا بذاریم چون هیچکدوم مسائل رو پیشبینی نکرده بودیم و یا درکی ازش نداشتیم و فقط شروع کردیم به کد زدن.
پس بجای شروع با کد لازمه سوالهای دیگهای هم بپرسیم. مثلا:
- کاربر میتونه لینکهای ساخته شده رو هم فعال یا غیرفعال کنه؟
- کاربر باید برای مدیریت این لینکها داشبورد یا پیشخوان داشته باشه؟
- لینکهایی که تولید میکنیم تاریخ انقضا داشته باشند یا دائمی باشن؟
- و خیلی سوالای دیگه…
پیدا کردن جواب این سوالا خیلی میتونه روی معماری سیستم تاثیر بذاره، پس بعد از درک مسئله باید بریم سراغ نیازمندیهای اصلی و اینجا میرسیم به مرحله ۲
۲- مرحله دوم: شناسایی نیازمندیهای سیستم
یکی از مهمترین اصولی که باید توی طراحی سیستم رعایت کنیم اینه که فرضایت خودمون رو قطعی در نظر نگیریم و اونقدر سوال کنیم تا تمام ابعاد پروژه مشخص بشه و متوجه بشیم محصول ما چه قابلیتهایی داره، چه محدودیتهایی داره و در کل نیازمندیهامون چی هستن!
این نیازمندیها معمولا به دو گروه اصلی تقسیم میشن: نیازمندیهای عملکردی و غیرعملکردی
۲.۱ – نیازمندیهای عملکردی یا Functional Requirements
نیازمندیهای عملکردی مشخص میکنن که سیستم چه قابلیتهایی رو باید ارائه بده و کاربران چه کارهایی میتونن انجام بدن
مثلا برای سرویس کوتاه کننده لینک، این نیازمندیهای اولیه شامل موارد زیر میشه:
- کاربر بتونه لینک URL دلخواه و طولانی رو ارسال کنه
- سیستم یک URL کوتاه تولید کنه و اون رو به کاربر بده
- با باز شدن URL کوتاه، کاربر به اون URL اصلی هدایت بشه
بعد از فهمیدن نیازمندی اولیه حالا میتونیم قابلیتهای بیشتری هم برای این سرویس در نظر بگیریم مثلا کاربر بتونه توی سایت ثبت نام کنه تا آدرسهاشو مدیریت کنه!؟ یا بتونه لینکهایی که تولید کرده رو فعال و غیرفعال کنه!؟ و کلی قابلیت دیگه که با سوال کردن و تحقیق کردن میتونیم بهش برسیم و کاملترش کنیم
بعد از اینکه قابلیتهای جدید رو هم بهش رسیدیم، اونارم به اون نیازمندیهای اولیه اضافه میکنیم حالا میرسیم به نیازمندیهای عملکردی جدید که شامل این موارد میشه:
- کاربرا بتونن ثبت نام کنن و حساب کاربری داشته باشن
- کاربرا بتونن لینکهایی که ساختن رو مدیریت کنن
- کاربرا بتونن لینکهاشون رو فعال و غیرفعال کنن
- کاربرا بتونن لینکهاشون رو حذف کنن
دقت کنید! ما اول گفتیم نیازمندیهای اولیه و بعد چندتا جدید هم بهش اضافه کردیم! چون میخواستیم نشون بدیم نیازمندیها صرفا نیازمندیهای اولیه نیستن و ممکنه توی بررسی بیشتر محصول نیازمندیهای دیگه هم اضافه بشه.
۲.۲ – نیازمندیهای غیرعملکردی یا Non-functional Requirements
نیازمندیهای غیرعملکردی بیشتر حول محور مباحث فنی میچرخه و مشخص میکنه که سیستم با چه کیفیت کار کنه و چه استانداردهایی رو باید رعایت کنه.
مهمترین مواردی که میتونیم تو مثال خودمون بهش اشاره کنیم (باتوجه به محصول ممکنه این نیازمندیها عوض بشن) :
کارایی و تاخیر پایین (Performance & Latency)
سیستم باید بتونه درخواستهارو توی مدت زمان مناسبی پردازش کنه، مثلا بگیم هدف اولیه این باشه که پاسخگویی و پردازش زیر ۱۰۰ میلی ثانیه باشه. هر چند این عدد صرفا یه هدف فرضیه و با توجه به شرایط واقعی باید اندازهگیری و ارزیابی بشه.
دسترسپذیری بالا (High Availability)
باید سیستم تا حد امکان در دسترس باشه و توقف سرویس به حداقل برسه.
تحمل خطا و بازیابی (Resilience)
اگر بخشی از زیرساخت دچار مشکل شد، سیستم بتونه از این اختلال عبور کنه یا به وضعیت عادیش برگرده.
یکتایی لینکها و صحت دادهها
هر شناسه کوتاه باید به مقصد مشخصی اشاره کنه و تولید شناسه تکراری نباید باعث بشه لینک اشتباهی به کاربر دیگهای اختصاص داده بشه.
امنیت (Security)
اطلاعات حساب کاربران باید محافظت بشه و هر کاربر فقط به منابعی دسترسی داشته باشه که مجاز باشه اونارو ببینه و یا تغییرشون باشه.
۳- مرحله سوم: پیشبینی الگوی ترافیک
تا اینجای کار، توی مرحله اول مسئله رو به خوبی درک کردیم و توی مرحله دوم فهمیدیم نیازمندیهای سیستم (عملکردی و غیرعملکردی) چی هستن.
و حالا توی این مرحله باید تخمین بزنیم توی این سرویس کوتاه کننده لینک با چه حجمی از درخواستها و دادهها قراره روبرو بشیم. چونکه طراحی سیستمی که روزانه ۱۰۰ تا درخواست دریافت میکنه با سیستمی که روزانه ۱ میلیون درخواست بهش میرسه تفاوت زیادی داره.
خب ما چطوری میتونیم به این تخمین برسیم؟ این تخمین رو میشه از رفتار کاربران سایت، میزان نیازی که ازشون برآورده میکنه و قابلیت رشدی که محصولمون داره تا حدی بدست اورد.
توی سرویس ما فرض کنیم که در روز ۱ میلیون لینک کوتاه ایجاد میشه اما در روز هم ۱۰۰ میلیون بار روی اون لینک کوتاه کلیک میشه تا به آدرس اصلی هدایت بشن. خب به یه نسبت تقریبی درخواستهای خواندن به نوشتن برابر ۱۰۰ به ۱ رسیدیم.
منظور از نوشتن (Write): ایجاد کردن لینک کوتاه و ذخیره کردنش
منظور از خواندن (Read): پیدا کردن لینک کوتاه و هدایت کاربر
خب ما چرا این داده رو تخمین زدیم؟ تا متوجه بشیم این بخش از سیستم قراره پر ترافیکترین بخش سیستم باشه و باید توجه ویژهای بهش داشته باشیم. مثلا فرض کنیم که هر بار لینک کوتاهی روش کلیک بشه باید یه جستجویی توی دیتابیس انجام بشه تا ادرس اصلی پیدا بشه و کاربر رو هدایت کنه به ادرس اصلی، حالا اگر این جستجو کردن خیلی کند باشه و تعداد کاربران هم خیلی زیاد بشه باعث میشه سیستم کندتر بشه و منابعی هم که استفاده میکنیم تحت فشار باشن.
خب به این نکته میرسیم که هدف از این تخمینها اینه که بخشهایی که ممکنه بیشتر استفاده بشن رو شناسایی کنیم و بهشون منابع بیشتری رو اختصاص بدیم و چطوری بتونیم در صورت نیاز ظرفتیشون رو افزایش بدیم.
۳.۱ – مقیاسپذیری (Scalability) چیه؟
مقیاسپذیری (Scalability) یعنی سیستم بتونه با افزایش بار کاری، ظرفیت خودش رو افزایش بده تا همچنان عملکرد قابل قبولی داشته باشه. این افزایش ظرفیت میتونه با اضافهکردن منابع به یک سرور یا اضافهکردن سرورهای بیشتر انجام بشه.
فرضا، اگه توی ساعتهای خاصی تعداد درخواستها بیشتر شد، منابع بیشتری رو در اختیار سرویس قرار بدیم و وقتی که ترافیک کمتر و سبکتر شد، منابع اضافی را آزاد کنیم.
دو رویکرد رایج برای مقیاسپذیری وجود داره:
- مقیاسپذیری عمودی (Vertical Scaling): افزایش منابع یک سرور، مثل CPU و حافظه.
- مقیاسپذیری افقی (Horizontal Scaling): اضافهکردن نمونههای بیشتری از سرویس یا سرور.
توی scaleهای بزرگ، مقیاسپذیری افقی میتونه امکان توزیع بار و افزایش ظرفیت رو فراهم کنه، البته به شرطی که معماری و اجزای سیستم واسه این کار آماده باشن.
۳.۲ – معماری یکپارچه یا میکروسرویسها؟
وقتی حجم ترافیک مشخص شد، وقتشه که درباره ساختار کلی بکاند هم تصمیم بگیریم.
معماری یکپارچه (Monolithic Architecture)
توی این معماری، بخشهای مختلف برنامه رو در قالب یک واحد نرمافزاری توسعه میدن و اجرا میشه. این روش معمولاً برای شروع پروژهها سادهتره و پیچیدگی کمتری هم داره.
ولی بازم اگه بخشهای مختلف به منابع خیلی متفاوتی نیاز داشته باشن، ممکنه نتونیم فقط همون بخش پرترافیک رو مستقل از بقیه مقیاسدهی کنیم چون تمام بخشهای پروژه رو همونجور که گفتیم توی قالب یک واحد داریم توسعه میدیم.
معماری میکروسرویسها (Microservices Architecture)
توی این معماری، سیستم رو به سرویسهای کوچکتر و مستقل تقسیم میکنیم که هرکدومشون مسئولیت مشخصی دارن.
برای مثال، توی سرویس کوتاهکننده لینک میتونیم بخش ایجاد لینک، تغییر مسیر و مدیریت حساب کاربران رو به سرویسهای جدا از هم تقسیم کرد و هر بخش رو جدا توسعه بدیم.
توی این ساختار امکان مقیاسدهی مستقل بخشها رو داریم. مثلاً میتونیم ظرفیت سرویس تغییر مسیر رو افزایش بدیم، بدون اینکه لازم باشه سرویسهای دیگه رو هم به همون نسبت افزایش بدیم.
البته این استقلال به قیمت پیچیدگی بیشتر در ارتباط بین سرویسها، مدیریت خطاهای شبکه، استقرار و مانیتورینگ به دست میاد.
مثلاً میتونیم ظرفیت سرویس تغییر مسیر رو افزایش بدیم، بدون اینکه لازم باشه سرویسهای دیگه رو به همون نسبت افزایش بدیم.
البته توی معماری میکروسرویس، ارتباط بین سرویسها، مدیریت خطاهای شبکه، مانیتورینگ، استقرار و هماهنگی دادهها پیچیدهتر از معماری یکپارچهاس.
پس، صرفا بزرگ بودن پروژه به این معنی نیست که باید از اول سراغ میکروسرویسها بریم. انتخاب معماری باید با نیازمندیها، حجم ترافیک، ساختار تیم و هزینه نگهداری متناسب باشه.
۴- مرحله چهارم: طراحی اجزای اصلی سیستم
بعد از پیدا شدن نیازمندیها و الگوی ترافیکی که پیدا کردیم، حالا میتونیم اجزای اصلی معماری رو طراحی کنیم.
البته توی این مرحله هم هنوز نیازی نیست وارد جزییات پیادهسازی بشیم، مثلا بگیم از چه زبان برنامه نویسی استفاده کنیم یا چه مدل دیتابیسی میخوایم، نیازی به صحبت از اینها نیست. توی این مرحله هدف اصلی اینه که بفهمیم سیستم از چه بخشهایی تشکیل شده و هر بخش چه مسئولیتی داره.
واسه سرویس کوتاه کننده لینک میتونیم اجزای زیر رو در نظر بگیریم:
4.1- Frontend
همون کلاینت یا بخشی که کاربر باهاش تعامل داره، از طراحی رابط کاربری تا تعاملها و …
۴.۲- API یا API Gateway
API Gateway در معماریهایی که ازش استفاده میکنن، نقطه ورود درخواستهای کلاینت به سرویسهای بکاند محسوب میشه.
این بخش میتونه مسئولیتهایی مثل مسیریابی درخواستها، اعمال سیاستهای دسترسی، محدودکردن نرخ درخواستها و ثبت اطلاعات درخواستها رو عهده دار باشه.
مثلا، درخواست ایجاد لینک باید به سرویس مربوط به کوتاهکردن URL هدایت بشه، اما درخواست مشاهده لینکهای کاربر باید به بخش مدیریت لینکها برسه.
اگر معماری سادهتر باشه، ممکنه به API Gateway مستقل نیاز نداشته باشیم، اما توی معماری موردبحث ما، این جزء به مدیریت متمرکز درخواستها کمک میکنه.
۴.۳- سرویس ایجاد لینک کوتاه
این سرویس مسئول دریافت URL اصلی، تولید شناسه کوتاه و ذخیره ارتباط بین شناسه و URL اصلی میشه.
بعد از اینکه ذخیره اطلاعات موفق بود، شناسه یا لینک کوتاه تولیدشده رو به کلاینت برمیگردونه.
۴.۴- سرویس تغییر مسیر (Redirect Service)
این سرویس وقتی فعال میشه که کاربری یه لینک کوتاه رو باز میکنه.
اول شناسه کوتاه از درخواست استخراج میشه، بعدش مقصد اصلی رو توی دیتابیس یا کش جستوجو و پیدا میکنه. اگر لینک معتبر بود، پاسخ تغییر مسیر به مرورگر ارسال میشه و کار تمومه.
همونطورم که توی بخش تخمین گفتیم چون این عملیات پرتکراره، سرعت دسترسی به اطلاعات توی این بخش اهمیت زیادی برامون داره.
۴.۵- سرویس احراز هویت (Authentication Service)
این سرویس مسئول ثبتنام و ورود کاربران و صدور اطلاعات احراز هویته.
بعد از ورود موفق، کلاینت میتونه اطلاعات احراز هویت رو توی درخواستهای محافظتشده ارسال کنه تا سرور هویت کاربر هارو بررسی کنه.
توی این مثال، سرویس احراز هویت میتونه از راهکار آماده استفاده کنه تا نیازی به پیادهسازی تمام جزئیات امنیتی از ابتدا نباشه. (سرویس آمادهای که من باهاش تستی کار کردم Clerk بوده)
۴.۶- دیتابیس (Database)
توی مثال ما دیتابیس اطلاعاتی که باید نگهداری کنه ایناس:
- شناسه کوتاه هر لینک
- URL اصلی
- شناسه مالک لینک، در صورت وجود حساب کاربری
- وضعیت فعال یا غیرفعال لینک
۴.۷- ارتباط بین اجزا
توی سرویس ما اجزای مختلف باید به صورت زیر باهم در ارتباط باشن:
۱. کاربر URL اصلی رو توی رابط کاربری وارد میکنه.
۲. کلاینت درخواست رو به API Gateway ارسال میکنه.
۳. درخواست به سرویس ایجاد لینک هدایت میشه.
۴. سرویس، شناسه کوتاه رو تولید میکنه و اطلاعات رو توی دیتابیس ذخیره میکنه.
۵. لینک کوتاه به کلاینت برگردانده میشه.
اما وقتی لینک باز شد:
۱. کاربر لینک کوتاه رو باز میکنه.
۲. درخواست به سرویس تغییر مسیر میرسه.
۳. سرویس مقصد لینک رو از کش یا دیتابیس پیدا میکنه.
۴. در صورت معتبر بودن لینک، پاسخ HTTP Redirect به مرورگر ارسال میشه.
توی این مرحله فقط شکل معماری مشخص شد، جزئیات بیشتر مثل پروتکل ارتباطی بین سرویس و ساختار دیتابیس و نحوه استقرار رو میشه توی مراحل بعدی راجع بهش صحبت کرد.
۵- مرحله پنجم: تعریف APIها
بعد اینکه اجزای سیستم رو مشخص کردیم، باید قرارداد ارتباطی بین کلاینت و سرور رو هم تعریف کنیم.
API مشخص میکنه کلاینت چه درخواستی ارسال کنه، چه اطلاعاتی در اختیار سرور قرار بده و چه پاسخی دریافت کنه.
حالا API هایی که توی سرویس کوتاه کننده لینک نیاز داریم:
۵.۱- ایجاد لینک کوتاه
متد: POST
مسیر: /shorten
نمونه درخواستی که کاربر وارد میکنه تا آدرسش رو کوتاه کنه
{
"url": "https://falsy.ir/blog/system-design-in-simple-terms"
}و جوابی که سرور بعنوان پاسخ ارسال میکنه:
{
"shortUrl": "https://short.link/fL24m"
}۵.۲- تغییر مسیر به URL اصلی
متد: GET
مسیر: /{shortCode}
مثال: /fL24m
حالا نیازه وقتی کاربر آدرس fL24m/ رو باز کرد سرور این مقدار رو بررسی کنه و اگر معتبر بود به آدرس اصلی هدایتش کنه و اگر هم مسیر پیدا نشد میشه ۴۰۴ یا Not Found رو از سمت سرور به برگردوند.
۵.۳- ثبتنام کاربر
متد: POST
مسیر: /users/register
از این API برای ثبت نام کاربران استفاده میشه.
۵.۴- ورود کاربر
متد: POST
مسیر: /users/login
از این API برای ورود کاربران و احرازهویت میتونیم استفاده کنیم.
۵.۵- دریافت فهرست لینکهای کاربر
متد: GET
مسیر: /users/me/urls
وقتی کاربر لاگین شده بود میتونه از این آدرس برای دریافت لینکهایی که ساخته استفاده کرد.
۵.۶- ویرایش یا غیرفعالکردن لینک
متد: PATCH
مسیر: /users/me/urls/{shortCode}
از این API میتونیم برای تغییر وضعیت لینک استفاده کنیم.
۵.۷- حذف لینک
متد: DELETE
مسیر: /users/me/urls/{shortCode}
از این API برای حذف لینک انتخاب شده استفاده میکنیم.
۶- مرحله ششم: انتخاب تکنولوژی و زیرساخت
تا اینجا مسئله، نیازمندیها، الگوی ترافیک، اجزای معماری و APIهای اصلی رو مشخص کردیم.
اشتباهی که عموما توی طراحی سیستم میکنیم اینه که از همون اول وارد مرحله ششم میشیم، در واقع درستش اینه که ما خوب مسئله و نیازمندیهارو بشناسیم و بعد از تمام بررسیهایی که انجام دادیم برسیم به مرحله انتخاب تکنولوژی
توی سرویس کوتاه کننده لینک فرض میکنیم میخوایم از سرویسهای ابری AWS استفاده کنیم.
- AWS Amplify برای میزبانی فرانتاند
- Amazon API Gateway برای ورود و مسیریابی درخواستها
- سرویسهای بکاند روی Amazon EC2 یا AWS Lambda
- Elastic Load Balancing برای توزیع بار در معماری مبتنی بر سرورهای مدیریتشده
- Amazon Cognito برای احراز هویت
- Amazon DynamoDB برای ذخیره ارتباط بین شناسههای کوتاه و URLهای اصلی
اگر مثل با این سرویس ها کار نکردین و دقیقا نمیدونین هر کدوم چیکار میکنه میتونین جدا راجع بهش بخونین اما لازم نیست زیاد درگیرش بشین، هدف فقط فهمیدن فرایند طراحی سیستمه نه اینکه AWS چیکار میکنه
۷- مرحله هفتم: بررسی محدودیتهای پیادهسازی و بازبینی معماری
توی این مرحله، معماری پیشنهادی رو دوباره با فهرست نیازمندیها مقایسه میکنیم.
این کار کمک میکنه مشکلاتی رو پیدا کنیم که ممکنه موقع طراحی سطح بالا از قلم افتاده باشن.
۷.۱- همه نیازمندیهای عملکردی (Functional Requirements) رو پوشش دادیم؟
اصلا نیازمندیهامون چی بودن؟
- آیا کاربر میتواند URL طولانی ارسال کند و لینک کوتاه دریافت کند؟
- آیا بازکردن لینک کوتاه باعث هدایت کاربر به URL اصلی میشود؟
- آیا کاربران میتوانند ثبتنام و وارد حساب خود شوند؟
- آیا هر کاربر میتواند لینکهای خودش را مشاهده و مدیریت کند؟
- آیا امکان فعالکردن، غیرفعالکردن و حذف لینکها وجود دارد؟
اگر برای هر کدوم از مواردی که تو فهرستمون داشتیم یه مسیر اجرایی داشته باشیم پس میتونیم نتیجه بگیریم که طراحی اولیهمون این قابلیتهارو به خوبی پوشش داده!
اما بررسی نیازمندیهای غیرعملکردی یا همون Non-functional Requirements تحلیل بیشتری نیاز دارن
- چون تغییر مسیر لینکها پرتکرارترین عملیاتیه که تو سیستم انجام میشه چطوری زمان تاخیر رو پایین حفظ کنیم و پاسخها سریعتر به کاربران برسه!
- چطوری بتونیم دسترسپذیری بالایی داشته باشیم تا سیستم به راحتی از کار نیوفته و اگر هم مشکلی پیش اومد بتونیم سرویس رو stable نگه داریم!
- چطوری بتونیم جلوی تولید لینکهای تکراری رو بگیریم، یعنی ما یک شناسه رو نتونیم به چندتا آدرس اصلی تبدیل کنیم و جلوی این اشتباه رو بگیریم!
- و در نهایت کلی نکتههای دیگه که ممکنه به ذهن شما رسیده باشه و به ذهن من نه …
۸- داریم به آخرش میرسیم
شاید این مطلب رو بخونین و برگردین سر کار خودتون، یا بگین دیگه باید انجام بدم اما وقتش که برسه دیگه فراموش کنین که باید از کجا شروع کنین و خب حفظ نشدن این مطلب کاملا طبیعیه، اما سعی کنین برای اینکه فرایند توی ذهنتون بشینه و صرفا حفظ کردن نشه میتونین شما هم پروژههایی که ساده باشن رو انتخاب کنین و یکی یکی این مراحل رو پیاده سازی کنین دقیقا مثل کاری که من کردم، وقتی چندتا مقاله راجع به طراحی سیستم خوندم، تصمیم گرفتم همشون رو جمع کنم و یه مطلب ازش بنویسم و برای اینکه بتونم این مطلب رو با یه پروژه جلو ببرم از هوش مصنوعی خواستم که بهم یه پروژه پیشنهاد بده و قدم به قدم باهم جلو بریم تا به پیاده سازی برسه و شما هم میتونین همین کارو کنین.
میتونین برای شروع شما هم از این نمونه ها استفاده کنین:
- سرویس کوتاه کننده لینک
- اپ مربوط به چت یا یه سوشال مدیای خیلی ساده
- سیستم رزرو
- و …
وقتی مسائل مختلف رو بتونیم حل کنیم کم کم به یه الگوی مشترک بین همه اینها میرسیم که میتونیم از همون راهحلها برای تحلیل مسئلههای جدید هم استفاده کنیم
جمعبندی
System Design این نیست که چندتا تکنولوژی که خیلی محبوبن یا جدیدن رو انتخاب کنین و کنارهم بذارین، طراحی سیستم یعنی فرایندی که طی اون یک مسئله رو تحلیل کنین و طراحی معماری رو انجام بدین به طوریکه بتونه نیازهاش رو برآورده کنه.
توی این مقاله، با مثالی که از سرویس کوتاهکننده لینک زدیم دیدیم که چطور میتونیم از درک مسئله شروع کنیم، نیازمندیها رو مشخص کنیم، ترافیک و حجم دادهها رو تخمین بزنیم، اجزای اصلی رو طراحی کنیم و در نهایت به انتخاب APIها، دیتابیس و زیرساخت برسیم.
دیدگاهتان را بنویسید