m_97260858
m_97260858
خواندن ۲۹ دقیقه·۱۰ ماه پیش

بررسی معماری چند نرم‌افزار موفق

مقدمه

یکی از موارد موثر در موفقیت نرم‌افزار تولید شده، معماری آن است. اگر معماری یک نرم‌افزار مناسب و خوب باشد می‌تواند منجر به موفقیت‌های چشمگیری شده و در غیر این صورت ممکن است منجر به شکست و ضررهای بزرگی شود. هدف از انجام پروژه درس معماری نرم‌افزار، بررسی و مرور معماری چند نرم‌افزار موفق و معروف است. بررسی معماری‌های موفق کمک می‌کند تا الگوهای مرسوم شناسایی شوند و در توسعه نرم‌افزارهای جدید مورد استفاده قرار گیرند. در این نوشته به بررسی معماری LinkedIn، Amazon، TikTok، Uber و Telegram پرداخته شده است.

معماری LinkedIn

برنامه LinkedIn در سال 2003 با هدف برای پیدا کردن فرصت‌های شغلی بهتر و با 2700 نفر از کاربران کار خود را آغاز کرد و تا سال 2023 دارای 930 میلیون کاربر بود. یعنی در هر ثانیه به ده‌ها هزار صفحه در وب خدمات می‌دهد. همچنین به خاطر داشتن نسخه تلفن همراه، چیزی حدود 50 درصد از کل ترافیک در دنیا را شامل می‌شود. در همه این موارد، اطلاعاتی از سرورهای لینکدین دریافت می‌شود که به معنی پاسخ به میلیون‌ها کوئری در هر ثانیه است. با توجه به این موارد می‌توان گفت که معماری نرم‌افزار آن دچار تحولات زیادی شده تا بتواند این حجم از کاربران و درخواست‌ها را مدیریت کند.

1. معماری یکنواخت

معماری LinkedIn در چندین مرحله تکامل یافته است. در ابتدا معماری آن به صورت یکنواخت (monolithic) بود. به این برنامه، Leo گفته می‌شد و تعداد کمی پایگاه داده داشت. این ساختار بسیار ساده بود و در این برنامه نیاز به مدیریت ارتباطات بین افراد بود. به همین دلیل، به سراغ Service Graph رفتند.

2. استفاده از Service Graph

یکی از کارهایی که باید در این برنامه به عنوان شبکه اجتماعی انجام می‌شد، مدیریت ارتباط افراد بود. در واقع به سیستمی در حافظه نیاز بود که داده‌های مرتبط با ارتباطات را با استفاده از پیمایش گراف (با efficiency و کارایی بالا) بازیابی کند. این ساختار باید مستقل از Leo ایجاد می‌شد تا بتواند این کارکرد متفاوت را عملی کند. بنابراین یک سیستم جداگانه برای Member Graph به نام Cloud ایجاد شد که اولین سرویس لینکدین بود. برای جداسازی این بخش از Leo نیز از ارتباطات Java RPC استفاده کردند. سپس برای پاسخگویی به درخواست‌های جستجو از Lucene (نرم‌افزار متن‌باز جستجوی آپاچی) استفاده کردند که داده‌های آن از Member Graph می‌آمد.

استفاده از Service Graph در لینکدین
استفاده از Service Graph در لینکدین


3. مقیاس‌بندی پایگاه داده

در ادامه، با افزایش تعداد کاربران، پیچیدگی Leo نیز افزایش یافت و برای کمک به load balancing، چندین کپی از Leo ایجاد شد. اما این کار منجر شد که DB (مربوط به اطلاعات کاربران) تبدیل به گلوگاه سیستم شود. در ابتدا CPU و مموری را به صورت vertical مقیاس کردند (scale out) یعنی این منابع را به سیستم اضافه کردند. اما این روش هم نتوانست مشکل را حل کند. به همین دلیل پایگاه‌های داده را scale کردند. علت این کار، این بود که پایگاه داده هم کار خواندن و هم نوشتن را مدیریت می‌کرد، برای همین از تکنیک Replica استفاده کردند. یعنی کپی دقیق از پایگاه داده کاربران ایجاد کردند که از طریق نسخه اولیه data bus با منبع اصلی sync می‌ماند. این کپی‌ها صرفا برای درخواست‌های خواندن بودند و به صورت master-slave مدیریت می‌شد. این راه‌حل برای میان‌مدت در نظر گرفته شده بود زیرا برای کوئری‌های نوشتن راهکاری ارائه نداده بود. راه حل اصلی، partition کردن پایگاه داده بود.

با افزایش تعداد کاربران، ترافیک سایت افزایش یافت. با اینکه از مهم‌ترین ویژگی‌های کیفی لینکدین دسترس‌پذیری بود، Leo اغلب از دسترس خارج می‌شد و بازیابی آن بسیار سخت بود. به همین دلیل به معماری به SOA تغییر پیدا کرد.

4. معماری سرویس‌گرا

برای داشتن دسترس‌پذیری به خصوص در ترافیک بالا، معماری مونولیتیک به چندین سرویس کوچک stateless تبدیل شد. این سرویس‌ها در سه دسته frontend (نمایش منطق و ارتباط مدل‌های داده حوزه‌های مختلف)، mid-tier (APIهایی برای دسترسی به مدل‌های داده‌ها فراهم می‌کردند) و backend (دسترسی به پایگاه داده) قرار می‌گرفتند. با این تغییر در معماری در سال 2010، حدود 150 سرویس مجزا ایجاد شد که در 2015 به 750 سرویس افزایش پیدا کرده است. سرویس‌ها نیز stateless بودند تا امکان scale-out را ایجاد کپی‌ها ممکن باشد.

معماری سرویس گرا
معماری سرویس گرا


5. استفاده از caching

با افزایش بیشتر تعداد کاربران، نیاز به مقیاس‌پذیری بیشتری بود. در همین راستا از تکنیک caching استفاده کردند و لایه‌های cache را افزایش دادند. علاوه بر استفاده از کش، لینکدین از Voldemort به عنوان یک data store توزیع شده (به شکل key-value) استفاده کرد که بسیار مقایس‌پذیر بود.

6. ایجاد Kafka

لینکدین برای اینکه بتواند حجم زیادی از داده‌ها را جمع‌آوری کند، خط لوله‌های زیادی برای صف‌بندی داده‌ها ایجاد کرد. برای مثال نیاز به جریان داده‌ها به Hadoop و data warehouse برای کاربردهای تحلیل بود. در نتیجه Kafka به عنوان بستری برای پیام‌رسانی pub-sub، ایجاد شد. اما این پلتفرم مختص لینکدین نبود و به تبدیل به خط لوله‌ای جهانی شد که با مفهوم commit log ساخته شده بود. (commit log شامل مجموعه‌ای از رکوردها با شناسه منحصر به فرد است که تغییر ناپذیر و ترتیبی است. کافکا این مفهوم را با انعطاف‌پذیری در یکپارچه‌سازی با منابع داده، تغییر داده‌ها و نوشتن در سیستم‌های دیگر ترکیب کرد) این امکان دسترسی تقریبا بلادرنگ به هر منبع داده‌ای را فراهم کرد. در سال 2015، Kafka قادر بود بیش از 500 میلیارد رویداد در روز را مدیریت کند.

7. پدیده وارونگی (Inversion)

در سال 2011 برای تمرکز روی بهبود ابزارها، زیرساخت‌ها و فرایند استقرار، لینکدین توسعه امکانات جدید را متوقف کرد. این کار منجر به ایجاد چابکی در فرایند توسعه شده و همچنین منجر به مقیاس‌پذیری تیم‌ها شد.

8. ایجاد چارچوب Rest.li

زمانی هنگامی که معماری به SOA تغییر پیدا کرد، APIها به صورت RPC در نظر گرفته شده بودند. این نوع API منجر به بروز ناسازگاری بین تیم‌ها شد زیرا کاملا وابسته به لایه presentation بود. برای رفع این مشکل APIجدید به نام Rest.li ایجاد کردند. Rest.li سبب شد که به سمت معماری data model centric بروند و یک مدل API Restful که stateless بود را تضمین کرد. در واقع این کار باعث decoupling سرویس‌ها شد.

در این روش جدید، از JSON در HTTP برای ارسال درخواست و دریافت پاسخ استفاده می‌شد که کار را برای کاربران غیر Java آسان کرده بود. حذف APIهای RPC مشکلات backward compatibility را حل کرد. همچنین با استفاده از Dynamic Discovery (D2) در کنار Rest.li، به صورت خودکار load balancing، کشف و مقیاس‌پذیری هر سرویس API نیز ممکن شد. D2 از نظر عملکردی به نوعی کار DNS را انجام می‌دهد و یک URI را به آدرس دیگری ترجمه می‌کند و همچنین کار load balancing را سمت کاربر انجام می‌دهد.

9. مفهوم Super blocks

استفاده از معماری SOA منجر به جداسازی نسبتا خوب دامنه‌ها و امکان مقیاس‌پذیری سرویس‌ها به صورت مستقل شد. اما مشکلاتی وجود داشت. برای مثال، هر درخواست نمایش صفحه پروفایل نیازمند اطلاعات زیادی مانند عکس‌ها، لینک‌ها، پست‌ها، توصیه‌ها و ... بود. این مشکل به نام fanout یا call graph شناخته می‌شد. مدیریت این call graph بسیار مشکل بود. برای حل این مشکل، مفهوم super block توسط لینکدین معرفی شد که به معنی دسته‌بندی سرویس‌های backend با یک API برای دسترسی به آنها بود.

10. چندین data center

برای اینکه لینکدین بتواند دسترس‌پذیری بالایی داشته باشد و از single point of failure جلوگیری کند، چندین مرکز داده در مکان‌های مختلف دنیا ایجاد کرد. بسیاری از پایگاه‌های داده روی Espresso اجرا می‌شدند. Espresso یک پایگاه داده NoSQL آنلاین و توزیع شده لینکدین است که در حال حاضر از تقریبا 30 برنامه کاربردی لینکدین (پروفایل کاربران، پیامرسانی بین افراد یا InMail و...) پشتیبانی می‌کند. این مراکز داده، باعث site-up شده و دسترس‌پذیری بالایی را تضمین می‌کنند. در سال 2015 لینکدین دارای سه مرکز داده اصلی به همراه PoPدر سراسر جهان بود. استفاده از PoP (Points of Presents) سبب می‌شود که زمان دانلود محتوای داینامیک بهتر شود. PoP در واقع مراکز داده در مقیاس کوچک و دارای تجهیزات شبکه و سرورهای proxy هستند. همچنین در هنگام دریافت اطلاعات درخواستی، ارتباط را برقرار نگه می‌دارد.

11. کنار گذاشتن JSON

داده‌های JSON و سریال کردن آنها، تبدیل به یک گلوگاه از نظر کارایی شد. به همین دلیل و برای کاهش تاخیر ایجاد شده به جای JSON از Protobuf استفاده کردند.

با توجه به توضیحات هر یک از تغییرات معماری لینکدین، می‌توان گفت که همه این تغییرات در جهت بهبود مقیاس‌پذیری و فراهم کردن دسترس‌پذیری بالا بوده است.


یکی دیگر از تغییراتی که در معماری LinkedIn رخ داد، تغییر معماری Lambda بود. WVYP (به معنی Who Viewed Your Profile) یکی از ویژگی‌های خاص لینکدین است که با معماری Lambda پیاده‌سازی شده بود. معماری Lambda یکی از الگوهای معماری در زمینه Big Data است که از آن برای پردازش داده‌ها به صورت batch و محاسبات مرتبط با آنها استفاده می‌شود. در عمل پیاده‌سازی Lambda منجر به بروز پیچیدگی و سربار عملیاتی شد و توسعه در هر تکرار را کُند کرد. به این دلایل بود که مهندسان لینکدین تصمیم گرفتند به معماری بدون Lambda مهاجرت کنند و در نتیجه سرعت توسعه به صورت قابل توجهی بهبود یافت.

برای این کار، بخش مرتبط با مجموعه کارهای آفلاین به صورت batch از معماری حذف شد و از پردازشگر پیام‌های جدیدی به نام Samza استفاده شد. Samza توسط خود لینکدین و با استفاده از Kafka توسعه یافت و مسئول پردازش جریان توزیع شده است. همچنین Samza از مدل برنامه نویسی Beam پشتیبانی کرده و APIهایی برای آن نیز پیاده سازی کرده است. APIهای Beam امکان ایجاد خط لوله پردازش داده مانند فیلتر، تبدل‌ها و ... را فراهم می‌کند.

همچنین لینکدین از GraphQL استفاده کرد که منجر به افزایش سرعت توسعه APIها شد. یکی از اهدافی که لینکدین داشت، ارتباط با سازمان‌ها از طریق ارائه PaaS (platform as a service) بود. GraphQL یک زبان کوئری برای APIهای داده است و به هیچ پایگاه داده خاصی وابسته نیست و توسط اطلاعات سمت سرور پشتیبانی می‌شود.

پیش از استفاده از این رویکرد، باید برای هر خواسته کاربران در ارائه سرویس یک APIجداگانه ایجاد می‌شد چون این افراد خواسته‌های متفاوتی (جستجو از طریق ایمیل و ...) داشتند. این کار هزینه بسیار بالایی داشت. راه حل استفاده از GraphQL بود. با سرویس GraphQL کلاینت مشخص می‌کند دقیقا چه داده‌هایی از یک API می‌خواهد و نیاز به مهندسی اضافه‌تری نخواهد بود. به این ترتیب در هزینه‌ها هم صرفه‌جویی خواهد شد.

منابع

https://newsletter.systemdesign.one/p/scalable-software-architecture

https://engineering.linkedin.com/architecture/brief-history-scaling-linkedin

https://www.linkedin.com/blog/engineering/architecture/how-linkedin-adopted-a-graphql-architecture-for-product-developm#:~:text=The%20GraphQL%20architecture%20we%20use,at%20LinkedIn%20is%20completely%20autogenerated.

https://www.linkedin.com/blog/engineering/data-science/lambda-to-lambda-less-architecture

https://www.linkedin.com/blog/engineering/infrastructure/linkedin-s-graphql-journey-for-integrations-and-partnerships


معماری آمازون

آمازون یک برنامه در حوزه تجارت الکترونیک است. برنامه‌هایی که در این حوزه هستند برخی از الزامات غیرکارکردی مانند تاخیر کم، دسترسی بالا و پایداری بالا داشته باشد. همچنین باید قابلیت‌هایی نظیر امکان جستجوی کالاها، ایجاد سبد خرید، پرداخت، مشاهده تاریخچه سفارشات و ... ارائه دهد.

در طی یک مصاحبه با مدیر ارشد آمازون، اطلاعاتی از معماری نرم‌افزار آن به دست آمده است. آمازون از یک کتابفروشی آنلاین کوچک به یکی از بزرگترین فروشگاه های دنیا تبدیل شد. در حال حاضر، بیش از 55 میلیون حساب کاربری فعال و بیش از 1 میلیون فروشنده در سراسر جهان دارد.

در ابتدا معماری آمازون به صورت دو لایه‌ای و مونولیتیک بود. تغییری که در معماری آن رخ داد، باعث شد که به صورت توزیع شده و غیر متمرکز خدمات خود را ارائه دهد. معماری دو لایه آن شامل یک برنامه کاربردی به همراه backend (به زبان C++) بود. سال‌ها تلاش آمازون برای ایجاد مقیاس بندی پایگاه داده جهت نگهداری اطلاعات پشتیبان بود. تغییرات معماری سبب شد که معماری آنها به صورت loosely coupled و با استفاده از سرویس‌ها طراحی شود. این معماری SOA این امکان را فراهم می‌کرد که بتوانند مولفه‌های نرم‌افزاری را به صورت مستقل توسعه دهند.

در برخی از مطالب، درباره ساختار معماری وب سرویس آمازون (AWS) صحبت شده است. AWS یکی از برجسته‌ترین و پیشروترین‌های رایانش ابری است. آمازون در بیش از 190 کشور و با بیش از یک میلیون مشتری، از جمله نزدیک به 2000 سازمان دولتی، 5000 موسسه آموزشی و بیش از 17500 سازمان غیرانتفاعی مشتری دارد. همچنین بیش از یک سوم کاربران اینترنت از سایت یا برنامه‌ای بازدید می‌کنند که توسط AWS پشتیبانی می‌شود. AWS خدمات ابری را برای مدیریت ترافیک‌های بالا و داده‌های حجیم تولید شده ارائه می‌دهد. معماری آن نیز تضمین می‌کند که بهترین شیوه‌ها را برای توسعه و نگه‌داری در فضای ابری دنبال می‌کند.

معماری AWS شامل چهار مولفه استقرار ابر عمومی، ابر خصوصی، ابر community و ابر هیبرید است. هر یک از این 4 مولفه برای برخی از کارها مناسب هستند. مثلا سازمان‌هایی که تقاضای در حال رشد دارند از ابر عمومی استفاده می‌کنند. یا برای داشتن مقیاس پذیری، امنیت و انعطاف پذیری ابر هیبرید مناسب است. در شکل زیر معماری ساده‌ای برای AWSآمده است. همانطور مه در شکل زیر مشخص شده است، ابر خصوصی سفارشی برای ایمن‌سازی برنامه وب ایجاد می‌شود. در این ساختار ترافیک خارجی به سرورها توسط Elastic Load Balancer ارجاع داده می‌شود.

ساختار کلی معماری وب سرویس آمازون
ساختار کلی معماری وب سرویس آمازون

شکل فوق یک نمودار معماری ساده برای AWSاست که ساختار اصلی آن را مشخص کرده است. در ادامه به برخی از عناصر مهم معماری آمازون پرداخته خواهد شد. یکی از این عناصر load balancer است که منجر به بهبود کارایی سرورها می‌شود و اغلب به شکل سخت افزاری و به عنوان بخشی از شبکه در حالت سنتی استفاده می‌شود. اما با AWS Elastic Load Balancer، کنترل ظرفیت در شرایط مختلف ترافیک انجام می‌شود و حتی ترافیک خارجی را مدیریت می‌شود.

یکی دیگر از عناصر مهم، Cloud Front است. این مولفه اغلب برای تحویل محتوا به کار می‌رود. از طریق این مولفه، کاربران می‌توانند محتوا را به صورت خودکار و از نزدیک‌ترین محل درخواست کنند. این سبب می‌شود زمان تحویل محتوا کاهش پیدا کند و در نتیجه کارایی افزایش می‌یابد. مولفه‌های دیگری برای مدیریت امنیت (استفاده از EC2 که مشابه فایروال شبکه است)، Elastic Cache (برای افزایش مقیاس پذیری، قابلیت اطمینان و دسترسی سریع‌تر به اطلاعاتی که زیاد مورد استفاده قرار می‌گیرند) و Amazon RDS (پایگاه داده رابطه‌ای) هستند.

چارچوبی که توسط AWS ارائه شده، ویژگی‌های مهم و منحصر به فردی دارد که در ادامه به برخی از آنها پرداخته شده است. ویژگی اول، امنیت است. معماری AWS اطمینان می‌دهد که از داده‌ها و سیستم‌ها در برابر حملات و تهدیدات امنیتی با استفاده ار رمزنگاری، کنترل دسترسی، حفط محرمانگی و ... محافظت می‌کند.

ویژگی دوم، قابلیت اطمینان است. AWS عملکرد مداوم برنامه را با استفاده ار افزونگی، backup و ... تضمین می‌کند تا بتواند خدمات مورد نیاز سرویس گیرندگان را به طور مداوم در دسترس نگه دارد. همچنین AWS باید با سرعت بهینه امکان پاسخگویی را فراهم کند. برای این کار از قابلیت‌هایی مانند انتخاب منابع مناسب، مدیریت ذخیره‌سازی موثر داده‌ها و استفاده از CDN(برای دسترسی سریع) استفاده می‌کند.

منابع

https://medium.com/@kethan.pothula/amazon-system-design-and-architecture-d787a6572f35

http://highscalability.com/amazon-architecture

https://intellipaat.com/blog/what-is-aws-architecture/

https://www.tutorialspoint.com/amazon_web_services/amazon_web_services_basic_architecture.htm#:~:text=This%20is%20the%20basic%20structure,%2C%20various%20pricing%20options%2C%20etc


معماری TikTok

معماری نرم‌افزار TikTok برای پشتیبانی از پلتفرم رسانه‌های اجتماعی در مقیاس بزرگ با ویژگی‌هایی مانند اشتراک‌گذاری ویدیو، کشف محتوا، تعاملات کاربر، سیستم‌های توصیه و تجزیه و تحلیل داده‌ها طراحی شده است. این معماری بر اساس ترکیبی از میکروسرویس ها، زیرساخت های ابری، فناوری های پردازش داده ها و الگوریتم های یادگیری ماشین ساخته شده است. از ویژگی‌های مهم این نرم‌افزار تاخیر کم، مقیاس پذیری، در دسترس بودن بالا (حدود 99.999٪ یعنی متوسط زمان قطعی در سال 5.25 دقیقه) و ... است. در ادامه اجزای کلیدی معماری نرم افزار TikTok آمده است:

1. معماری میکروسرویس‌ها:

تیک تاک از معماری میکروسرویس برای تجزیه سیستم به سرویس‌های کوچک و مستقل استفاده می‌کند که عملکردهای خاصی مانند تایید هویت کاربر، آپلود ویدیو، توصیه محتوا (recommendation)، تعاملات اجتماعی و تجزیه و تحلیل را انجام می‌دهند.

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

2. زیرساخت رایانش ابری:

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

3. پردازش و تجزیه و تحلیل داده‌ها:

تیک تاک حجم زیادی از داده‌ها را برای تعاملات کاربر، توصیه‌های محتوا و ... پردازش می‌کند. این شامل پردازش real-time داده، پردازش دسته‌ای و الگوریتم‌های یادگیری ماشینی برای استخراج بینش و ارائه تجربیات شخصی برای کاربران است.

فناوری هایی مانند Apache Kafka، Apache Flink، Apache HBase و Elasticsearch برای indexing بلادرنگ، پردازش جریان داده ها و تجزیه و تحلیل استفاده می شوند. تیک تاک همچنین از چارچوب های پردازش داده خود برای تجزیه و تحلیل سفارشی و سیستم های توصیه استفاده می‌کند.

4. شبکه تحویل محتوا (CDN):

با توجه به حجم زیاد محتوای ویدیویی در تیک تاک، یک CDN برای ارائه محتوای ویدیویی به کاربران در سراسر جهان استفاده می شود. این امر زمان بارگذاری سریع و پخش بدون قطعی را برای کاربران بدون توجه به موقعیت مکانی آنها تضمین می کند.

5. بخش load balancer

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

6. استفاده از sharding

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

سه بخش CDN، load balancer و Sharding امکان مقیاس‌پذیری را برای این سیستم فراهم می‌کند.


یکی از بخش‌های مهم در این برنامه، سیستم توصیه‌گر آن است. در ادامه به توضیحات آن پرداخته شده است.

معماری سیستم توصیه گر تیک تاک
معماری سیستم توصیه گر تیک تاک

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

1. بخش فریم‌ورک Big Data

در تیک تاک، بیشتر داده‌ها از سمت تلفن همراه کاربران به سرورها ارسال می‌شود. همچنین اطلاعات دیگری مانند زمان مشاهده ویدئو، میزان فعالیت کاربران، تعداد لایک‌ها، اشتراک گذاری، نظرات و ... نیز وجود دارد. در شکل زیر معماری این بخش مشخص شده است:

جمع‌آوری داده‌ها از طریق Flume و Scribe است. سپس این داده‌ها به سمت Kafka هدایت شده و سپس توسط Hadoop پردازش می‌شوند. Apache Hadoop یک سیستم توزیع شده برای پردازش و ذخیره سازی داده‌ها است که کار Map Reduce را برای پردازش توزیع شده انجام می‌دهد. در ادامه YARN وجود دارد که چارچوبی برای زمانبندی کار و مدیریت منابع است.

در بخش Storage، اجزایی مانند HDFS (فایل سیستم توزیع شده)، HBase (پایگاه داده مقیاس‌پذیر و توزیع شده برای ذخیره سازی داده‌های ساختارمند در جداول بزرگ)، Hive (زیرساخت data warehouse)، Zookeeper (سرویس coordination با کارایی بالا) دارد. همچنین سیستم‌های پایگاه داده شامل MySQL، MongoDB و ... هستند.

از آنجایی که حجم داده‌ها به سرعت افزایش می‌یابد و فریم‌ورک پردازش داده باید به صورت بلادرنگ اینها را پردازش کند، از Apache Spark استفاده شده است. Spark با انجام پردازش در حافظه، کارایی MapReduce را افزایش می‌دهد. در چند سال گذشته، تیک تاک از چارچوب دیگری به نام Flink استفاده کرده است.

2. یادگیری ماشین

فریم‌ورک یادگیری عمیق و شبکه عصبی مانند TensorFlowبرای انجام بینایی کامپیوتر و پردازش زبان طبیعی (NLP) استفاده می‌شود. برخی از الگوریتم‌های یادگیری ماشین کلاسیک نیز مانند رگرسیون لجستیک استفاده می‌شوند. سایر الگوریتم‌ها شامل شبکه عصبی CNN و شبکه عصبی بازگشتی (RNN) نیز به کار رفتند. هکچنین برای سیستم توصیه گر مواردی مانند content based filtering و collaborative filtering نیز اعمال می‌شوند.

برای اینکه تیک تاک بتواند توصیه‌گر خوبی ارائه دهد، کارهای دیگری هم می‌کند:

الف) برای پیدا کردن توصیه‌گر خوب، مهندسان چندین الگوریتم یادگیری ماشین را با هم ترکیب می‌کنند و سپس با تست A/B بهترین روش را انتخاب می‌کنند.

ب) مدل‌های مورد استفاده گزارشات رایج کاربران مانند زمان دیدن ویدئو، لایک‌ها یا اشتراک‌گذاری و ... را برای پیدا کردن بهترین توصیه‌ها به کار می‌برند. علاوه بر این موارد نیز، ویژگی‌های دیگری هم به مرور به بردار ویژگی تصمیم‌گیری مدل‌ها اضافه می‌شود.

ج) مدل‌ها از کاربران بازخورد نیز دریافت می‌کنند. ایت تجربیات کاربران نیز بر روی تصمیمات تاثیر گذاشته و در نهایت خطاها را کاهش داده و توصیه‌ها را بهبود می‌دهد.

د) برای اولین بار در توصیه به کاربر جدید که اطلاعاتی از او وجود ندارد، چندین ویدئو بر اساس میزان محبوبیت و کیفیت به کاربر توصیه می‌شود.

3. میکروسرویس‌ها

تیک تاک از زیرساخت‌های ابری استفاده می‌کند. مؤلفه‌های توصیه‌ای مانند پروفایل کاربر، پیش‌بینی‌ها، فراخوانی و موتور بازخورد کاربر به عنوان API عمل می‌کنند. سرویس‌های آن (ایجاد پروفایل، پیش‌بینی، بازخورد کاربران و ...) با استفاده از API و در فضای ابری مانند Amazon AWS و Microsoft Azure میزبانی می‌شوند.

تیک تاک از کانتینری‌سازی با استفاده Kubernetes به عنوان یک orchestrator برای هماهنگی بین سرویس‌ها استفاده می‌کند. Service Mesh نیز ابزار دیگری برای مدیریت ارتباط سرویس‌هاست که وظیفه کنترل چگونگی تبادل و اشتراک داده بین بخش‌های مختلف را بر عهده دارد.

به خاطر ضرورت همزمانی بالا، سرویس‌ها با زبان Go (زبان اصلی توسعه در تیک تاک به دلیل پشتیبانی و شبکه داخلی قوی) و gRPC (چارچوب Remote Procedure Control برای ایجاد اتصال مناسب بین سرویس‌ها) توسعه داده می‌شوند.

یکی از دلایل موفقیت تیک تاک این است که آنها سعی بر ارائه بهترین تجربه کاربری دارند. به همین دلیل اغلب ابزارها را به صورت داخلی می‌سازند. برای مثال ByteMesh یک نسخه بهبود یافته از Service Mesh است یا KiteX یک فریم‌ورک Golang gRPC با کارایی بالا است.

منابع

https://www.youtube.com/watch?v=yaIYb8n8HnE

https://www.lavivienpost.com/how-tiktok-works-architecture-illustrated/

https://levelup.gitconnected.com/how-tik-toks-engineering-works-f746bb82645d

https://www.youtube.com/watch?v=oYY10fWtSr0

https://kindsonthegenius.com/system-design/system-design-design-tiktok-interview-question/


معماری Uber

معماری نرم افزار اوبر برای پشتیبانی از شبکه حمل و نقل در مقیاس بزرگ طراحی شده است که مسافران را به رانندگان متصل کرده و میلیون‌ها تراکنش و داده‌ها را به صورت بلادرنگ پردازش می‌کنند. شروع این معماری مانند بسیاری از نرم‌افزارهای دیگر با مونولیتیک، تعدادی از سرورها و یک پایگاه داده بود. بعدها در حدود سال 2014 معماری آن به سرویس‌گرا با 100 سرویس تبدیل شد.

1. معماری میکروسرویس:

اوبر از معماری میکروسرویس استفاده می‌کند تا سیستم خود را به سرویس‌های کوچک و مستقلی تقسیم کند که عملکردهای خاصی مانند matching سواری، پرداخت، ردیابی راننده، احراز هویت کاربر و ... را انجام می‌دهد.

2. پردازش بلادرنگ داده:

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

اولویت سرویس‌دهی در اوبر، تلفن همراه است. به این صورت که ابتدا تقاضاها و داده‌های تلفن همراه را پردازش می‌کند. اما مسئله چالش بر انگیز در پاسخگویی به تقاضا، تعداد متغیر رانندگان است. سیستم Dispatch در اوبر مانند یک پلتفرم بی‌درنگ برای مرتبط کردن مسافر با راننده عمل می‌کند.

بنابراین می‌توان گفت که به طور کلی دو سرویس دارد: 1) supply (تامین توسط راننده) و 2) demand (تقاضای مسافر)

  • سرویس supply خودروها را با استفاده از موقعیت جغرافیایی آنها ردیابی می‌کند. این ردیابی با توجه به برخی از ویژگی‌های خودرو مانند تعداد صندلی، نوع وسیله نقیله و ... است.
  • سرویس demand مسئول درخواست‌های مسافران است. وقتی درخواستی ثبت شود، این سرویس موقعیت GPS کاربر را ردیابی می‌کند. همچنین نوع درخواست را پردازش می‌کند و مسئولیت تطبیق نیازمندی‌های مشخص شده در درخواست با آنچه عرضه شده است را دارد.
  • مسئولیت تامین demand با supply بر عهده بخشی به نام DISCO است.

سرویس DISCO (Dispatch Optimization)

بخش اصلی نحوه کار این بخش با استفاده از GPS (موقعیت مکانی) است. پس باید نقشه‌ها و داده‌های مکانی مدل‌سازی شوند. زمین به شکل کرده است و تقریب مکان فقط با استفاده از طول و عرض جغرافیایی کار دشواری است. بنابراین اوبر با استفاده از کتابخانه Google S2، زمین را به سلول‌های کوچک تقسیم می‌کند و به هر سلول ID منحصر به فردی می‌دهد. اوبر از S2 استفاده می‌کند تا بتواند موقعیت‌های مکانی اطراف تا شعاع مشخصی را پیدا کند. برای مثال برای پوشش دایره‌ای با شعاع 1 کیلومتر از شهر لندن، S2 می‌تواند سلول‌های مورد نیاز را مشخص کند.

ویژگی منحصر به فرد کتابخانه S2 این است که برخلاف سیستم‌های جغرافیایی سنتی (نمایش مکان در دو بعد)، همه داده‌ها را در یک کره سه بعدی نشان می‌دهد. یکی از ویژگی‌های همه این کتابخانه، استفاده از کوئری کارآمد برای یافتن اشیا نزدیک، اندازه گیری فواصل و ... است. همچنین از آنجایی که روی مجموعه عظیم داده‌های جغرافیایی گوگل آزمایش شده، می‌توان گفت از دقت خوبی برخوردار است.

سرویس supply برای ارسال و ذخیره‌سازی پیام‌ها از Kafka استفاده می‌کند. راننده از APIهای Kafka برای ارسال مکان‌های دقیق به مرکز داده استفاده می‌کند. هنگامی که مکان‌های GPS در Kafka قرار می‌گیرند، به مرور زمان در حافظه اصلی هم ذخیره می‌شوند و هنگامی که سفر انجام می‌شود، در پایگاه داده ذخیره می‌شوند.

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

برای انجام عمل dispatch لازم است ابتدا از روی نقشه تمام موقعیت‌های رانندگان در یک شعاع خاص را پیدا کند و سپس ETA (زمان تخمینی برای رسیدن به مسافر) را محاسبه کند. سپس رانندگان را بر این اساس فیلتر کرده و به همه آنهایی که فیلتر شدند درخواست را ارسال می‌کنیم. اگر راننده درخواست را بپذیرد، این فرایند به پایان می‌رسد.

معماری سیستم

در ادامه به بررسی اجزای این معماری پرداخته شده است:

  • فایروال برنامه کاربردی وب (WAF): از این بخش برای بررسی‌های امنیتی استفاده می‌شود. برای مثال برخی از IPها را مسدود می‌کند یا بر اساس مکان‌هایی که اوبر از آنها پشتیبانی نمی‌کند، برخی از درخواست‌ها را فقط به load balancer ارسال می‌کند.
  • استفاده از Load Balancer: برای این بخش می‌توان از Load Balancer با تعداد لایه‌های مختلف مانند Layer 3 (مبتنی بر IP) ، Layer4 (مبتنی بر DNS) و Layer 7 (load balancing در سطح برنامه کاربردی) استفاده کرد.
  • استفاده از KAFKA REST API: از این API برای ارسال مکان هر 4 ثانیه یکبار توسط رانندگان ارسال می‌شود تا DISCO بتواند موقعیت را به صورت live رصد کند.

پایگاه‌های داده

اوبر قبلا از RDBMS برای ذخیره داده‌های مربوط به profile و اطلاعات مکانی و ... استفاده می‌کرد. اما این روش مقیاس پذیر نبود. به همین دلیل از پایگاه‌های داده NoSQL استفاده کردند. این پایگاه داده به صورت افقی مقیاس‌پذیر است. با توجه به حجم زیاد اطلاعات موقعیت مکان، خواندن و نوشتن در آن با کارایی بالاتری انجام می‌شود و همچنین دسترس‌پذیری مورد انتظار را برآورده می‌کند.

تجزیه و تحلیل

تجزیه و تحلیل داده‌ها امکان درک آنها را فراهم می‌کند. به همین دلیل لازم است که Uber بتواند داده‌های مرتبط با مشتریان و رانندگان تحلیل کند. تمام اطلاعات راننده و مسافر در پایگاه داده NoSQL یا RDBMS یا HDFS ذخیره می‌شوند. برای پردازش، داده‌ها از صف Kafka برداشته شده و سپس توسط Hadoop تجزیه و تحلیل می‌شوند.

نحوه مواجهه با failure

مشکل در دیتاسنترها به ندرت پیش می‌آید اما برای جلوگیری از ایجاد مشکل، اوبر دیتاسنتر پشتیبان دارد. اوبر در این دیتاسنتر داده‌های موجود در دیتاسنترهای دیگر را کپی نمی‌کند. در واقع اوبر از تلفن همراه رانندگان به عنوان منبعی برای داده‌های سفرها استفاده می‌کند تا با خرابی دیتاسنترها مقابله کند. وقتی که تلفن همراه راننده با سرویس Dispatch ارتباط برقرار می‌کند، این سیستم وضعیت رمزگذاری شده (برای پیگیری آخرین داده‌ها) را به تلفن همراه راننده ارسال ارسال می‌کند و در هر بار ارتباط این اطلاعات در برنامه راننده دریافت و ذخیره می‌شود. اگر برای دیتاسنتر مشکلی پیش بیاید، دیتاسنتر پشتیبانی اطلاعاتی درباره سفر ندارد، بنابراین خلاصه وضعیت را از برنامه راننده درخواست کرده و اطلاعات خود را بر اساس همین داده‌ها به روز می‌کند.

منابع

https://medium.com/@narengowda/uber-system-design-8b2bc95e2cfe

https://medium.com/nerd-for-tech/uber-architecture-and-system-design-e8ac26690dfc

https://interviewnoodle.com/uber-system-architecture-40201134aaea

https://www.geeksforgeeks.org/system-design-of-uber-app-uber-system-architecture/


معماری تلگرام

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

تلگرام با بیش از 700 میلیون کاربر فعال ماهانه تا سال 2023 به یک بستر ارتباطی محبوب در جهان تبدیل شده که علت اصلی محبوبیت آن، رعایت حریم خصوصی و ایجاد فضای امن برای تعاملات است. همچنین قابلیت سفارشی‌سازی را نیز دارد.

کلیت معماری

همانطور که اشاره شد، اصلی‌ترین ویژگی کیفی تلگرام امنیت و قابلیت اطمینان است. برای دستیابی به این هدف از ترکیبی از مدل‌های کلاینت-سرور، شبکه‌های P2P (peer to peer) و فضای ذخیره‌سازی مبتنی بر فضای ابری استفاده می‌کند.

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

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

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

ویژگی‌های امنیتی تلگرام

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

علاوه بر رمز کردن پیام‌ها، تلگرام این امکان را می‌دهد که پیام‌هایی که ارسال شدند پس از یک زمان مشخص حذف شوند. این ویژگی تضمین می‌کند که پیام‌های حساس یا محرمانه برای مدت زمان طولانی در سمت گیرنده وجود نداشته باشند. یکی دیگر از قابلیت‌هایی که منجر به حفط حریم شخصی می‌شود، secrete chatها هستند. در چت‌های secret، از ارسال پیام‌ها به شخص دیگری جلوگیری می‌کنند و همچنین قابلیت حذف پیام‌ها بعد اززمان مشخصی را می‌دهند. این چت‌ها فقط در همان دستگاهی که مکالمه در آنها آغاز شده وجود دارند و در سرورهای تلگرام ذخیره نمی‌شوند. همچنین برای ایجاد امنیت بیشتر، از احراز هویت دو مرحله‌ای (Two-Factor Authentication) هم استفاده می‌کند که از دسترسی غیر مجاز به حساب کاربری جلوگیری می‌کند.

بخش APIهای تلگرام

تلگرام دو API مختلف برای توسعه‌دهندگان ارائه داده تا با آن در ارتباط باشند. یکی از این APIها، مربوط به ربات تلگرام است. این API امکان ایجاد chat bot را فراهم کرده است که می‌توانند با کاربران تلگرام در تعامل باشند و کارهایی مانند ارسال و دریافت پیام، مدیریت چت و پاسخ به برخی از سوالات کاربر و ... را انجام دهند. همچنین این API امکان ارتباط با سرویس‌های دیگر و حتی پلتفرم‌های دیگر را فراهم می‌کند. دومین API مربوط به TDLib است. پایگاه داده تلگرام (TDLib) یک کتابخانه برای ایجاد کاربران خاص تلگرام با ویژگی‌های پیشرفته است.

ارائه APIها توسط تلگرام به توسعه دهندگان اجازه می‌دهد تا برنامه‌های خود را با این پلتفرم یکپارچه کنند. در نتیجه می‌تواند قابلیت‌هایی فراتر از پیام‌رسانی را به کاربران بدهد. از نظر فنی و پیاده سازی API تلگرام مبتنی بر پروتکل MTProto است که برای برقراری ارتباط سریع و ایمن بین کاربر و سرور طراحی شده است. همچنین این API از زبان‌های برنامه نویسی مختلف مانند پایتون، جاوا و Node.js پشتیبانی می‌کند. علاوه بر این، API دسترسی به چندین ویژگی از جمله پیام‌رسانی، چت‌های گروهی، اشتراک‌گذاری فایل و موارد دیگر را فراهم می‌کند.

هوش مصنوعی

تلگرام از هوش مصنوعی و یادگیری ماشین برای بهبود تجربه کاربری استفاده می‌کند. یکی از نمونه های استفاده تلگرام از هوش مصنوعی، چت‌بات‌ها هستند که امکان پرسش و پاسخ را با استفاده از پردازش زبان طبیعی (NLP) ایجاد می‌کند و کاربران می‌توانند پاسخ سوالات مختلف خود را از آنها بپرسند. مثال دیگر تشخیص اسپم است.

ذخیره سازی در فضای ابری

ذخیره‌سازی در فضای ابری به کاربران این امکان را می‌دهد تا به اطلاعات و پیام‌های خود از هر جا و با هر دستگاهی دسترسی داشته باشند. همچنین این سیستم ذخیره‌سازی بسیار امن و کارآمد است و گزینه مناسبی برای کسانی است که به حریم خصوصی و راحتی اهمیت می‌دهند زیرا تمام اطلاعات در سرورهای تلگرام به صورت رمز شده ذخیره می‌شوند. این رویکرد مزایای زیادی دارد که در ادامه به برخی از آنها اشاره خواهد شد:

- ذخیره‌سازی در فضای ابری منجر به قابلیت دسترسی بالا شده و امکان دسترسی به پیام‌ها را از هر جایی می‌دهند.

- فضای ابری، رمزگذاری و اقدامات امنیتی پیشرفته را برای محافظت از داده‌های کاربر در برابر دسترسی غیرمجاز فراهم می‌کند.

- فضای ابری به نوعی به عنوان گزینه پشتیبان عمل کرده و امکان بازیابی را فراهم می‌کند. همچنین تضمین می‌کند که در صورت آسیب دیدن، گم شدن و ... دستگاه کاربر، اطلاعات از دست نمی‌رود.

- فضای ابری امکان مقیاس پذیری دارد و می‌تواند مقدار فضای ذخیره‌سازی مورد نیاز را با توجه به میزان استفاده افزایش یا کاهش دهد.

- از نظر هزینه نسبت به روش‌های ذخیره‌سازی سنتی، مقرون به صرفه است.

این فضای ذخیره‌سازی از مراکز داده متعدد در مناطق جغرافیایی مختلف استفاده می‌کند تا اطمینان حاصل کند که داده‌های کاربر همیشه در دسترس هستند. همچنین از یک سیستم فایل‌های توزیع‌شده ویژه تلگرام به نام TFS (Telegram File System) استفاده می‌کند که امکان ذخیره‌سازی و بازیابی داده‌ها را فراهم می‌کند.

طراحی رابط کاربری

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

در مقایسه با سایر برنامه‌های پیام‌رسان، طراحی رابط کاربری این پلتفرم استفاده را بسیار ساده کرده و به همین دلیل تلگرام را از سایر پلتفرم‌ها متمایز می‌کند. در واقع می‌توان گفت طراحی UI این پلتفرم باعث محبوبیت آن است. چیدمان المان‌های این برنامه تمیز و مرتب است و به راحتی می‌توان دکمه‌های مورد نظر را پیدا کرد.

نسخه وب تلگرام

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

منابع

https://interviewnoodle.com/telegram-system-architecture-ddf9f7d358de

https://intuji.com/how-does-telegram-work-telegram-tech-stack/

https://delftswa.gitbooks.io/desosa-2017/content/telegram-web/chapter.html


این مطلب، بخشی از تمرینهای درس معماری نرم‌افزار در دانشگاه شهیدبهشتی است.

شاید از این پست‌ها خوشتان بیاید