Go Casts 🚀
Part I - Single-Node Patterns عموما وقتی از distributed system ها صحبت میشه، منظور اجرای سرویس های مختلف بر روی ماشین های مجزا از هم هست، اما خیلی اوقات پیش میاد که ما میتونیم یک application رو به سرویس های مجزا روی یک single-node machine تقسیم کنیم. اینکه…
The Sidecar Pattern
یکی از الگوهای معروف single-node الگوی sidecar هست
در این الگو هر ماشین یا صحیح تر بگیم، هر pod از دو container تشکیل شده، یکی container اصلی هست که لاجیک اصلی برنامه رو اجرا میکنه و دومین container یک کانتینر جانبی هست که مسئولیتش بهبود دادن و تقویت کردن کانتینر اصلی ست.
https://www.oreilly.com/library/view/designing-distributed-systems/9781491983638/ch02.html
@gocasts
#designing_distributed_systems_brendan_burns
یکی از الگوهای معروف single-node الگوی sidecar هست
در این الگو هر ماشین یا صحیح تر بگیم، هر pod از دو container تشکیل شده، یکی container اصلی هست که لاجیک اصلی برنامه رو اجرا میکنه و دومین container یک کانتینر جانبی هست که مسئولیتش بهبود دادن و تقویت کردن کانتینر اصلی ست.
https://www.oreilly.com/library/view/designing-distributed-systems/9781491983638/ch02.html
@gocasts
#designing_distributed_systems_brendan_burns
👍2
Go Casts 🚀
The Sidecar Pattern یکی از الگوهای معروف single-node الگوی sidecar هست در این الگو هر ماشین یا صحیح تر بگیم، هر pod از دو container تشکیل شده، یکی container اصلی هست که لاجیک اصلی برنامه رو اجرا میکنه و دومین container یک کانتینر جانبی هست که مسئولیتش بهبود…
به عنوان مثال تصور کنید یه legacy application دارید که سال ها پیش توسعه اون تموم شده و همچنان داره کار میکنه، اما فقط http رو پشتیبانی میکنه، و حالا شرکت تصمیم گرفته که به دلایل امنیتی همه سرویس هاشو بصورت https ارائه بده
برای برطرف کردن این موضوع دو تا راه حل داریم
یک اینکه تیم توسعه این نرم افزار قدیمی رو دوباره پیدا کنیم و محیط توسعه قدیمی رو مجددا راه اندازی کنیم و یه build جدید بگیریم که پشتیبانی https رو هم داره
راه دوم اینه که یه کانتینر جانبی اضافه کنیم که بصورت proxy همه درخواست های کاربر رو بصورت https بگیره و پاسخ اپلیکیشن رو بهشون پس بده!!
مثلا میتونیم از nginx به عنوان sidecar استفاده کنیم
@gocasts
#designing_distributed_systems_brendan_burns
برای برطرف کردن این موضوع دو تا راه حل داریم
یک اینکه تیم توسعه این نرم افزار قدیمی رو دوباره پیدا کنیم و محیط توسعه قدیمی رو مجددا راه اندازی کنیم و یه build جدید بگیریم که پشتیبانی https رو هم داره
راه دوم اینه که یه کانتینر جانبی اضافه کنیم که بصورت proxy همه درخواست های کاربر رو بصورت https بگیره و پاسخ اپلیکیشن رو بهشون پس بده!!
مثلا میتونیم از nginx به عنوان sidecar استفاده کنیم
@gocasts
#designing_distributed_systems_brendan_burns
👍2
Go Casts 🚀
به عنوان مثال تصور کنید یه legacy application دارید که سال ها پیش توسعه اون تموم شده و همچنان داره کار میکنه، اما فقط http رو پشتیبانی میکنه، و حالا شرکت تصمیم گرفته که به دلایل امنیتی همه سرویس هاشو بصورت https ارائه بده برای برطرف کردن این موضوع دو تا راه…
Modular Applicatoin Containers
الگوی sidecar به ما این اجازه رو میده که بتونیم یک سری modular container داشته باشیم که در سرویس های مختلف ازشون استفاده کنیم.
مثلا تصور کنید که شما میخواید برای همه سرویس های زیرساخت تون عملکرد پروسه هارو مانیتور کنید و مصرف منابع رو مشاهده کنید.
یک راهش اینه که همه سرویس هایی که ممکنه به زبان های مختلفی هم توسعه داده شده رو آپدیت کنید و برای همه اون ها یک مسیر /topz اضافه کنید که با فراخوانیش میشه منابع اون پروسه رو مانیتور کرد. که خب این راه حل نیاز داره همه سرویس ها بروزرسانی بشن که خیلی کار سختیه و همچنین اساسا خیلی از زبان ها محدودیت دارن در بدست آوردن چنین اطلاعاتی و خروجی همه اون سرویس ها یکسان نمیشه.
الگوی sidecar این ایده رو میده که ما یه sidecar container داشته باشیم که از PID namespace یکسانی با container اصلی برخوردار هست و تمامی اطلاعات پروسه های container اصلی رو میتونه ببینه، اینطوری ما با فقط نوشتن یک کانتینر ساده میتونیم بصورت ماژولار همه سرویس هامون رو ارتقا بدیم و از مانیتورینگ منابعشون لذت ببریم.
حتی modularity این امکان رو میده که ما دیگه نیاز نداشته باشیم توسعه بدیم و از community و دنیای open-source کمک بگیریم. مثلا در مورد همین /topz میشه از این ایمیج استفاده کرد..
docker run --pidcontainer:${APP_ID} -p 8080:8080 brendanburns/topz:db0fa58 /server --address=0.0.0.0:8080
@gocasts
#designing_distributed_systems_brendan_burns
الگوی sidecar به ما این اجازه رو میده که بتونیم یک سری modular container داشته باشیم که در سرویس های مختلف ازشون استفاده کنیم.
مثلا تصور کنید که شما میخواید برای همه سرویس های زیرساخت تون عملکرد پروسه هارو مانیتور کنید و مصرف منابع رو مشاهده کنید.
یک راهش اینه که همه سرویس هایی که ممکنه به زبان های مختلفی هم توسعه داده شده رو آپدیت کنید و برای همه اون ها یک مسیر /topz اضافه کنید که با فراخوانیش میشه منابع اون پروسه رو مانیتور کرد. که خب این راه حل نیاز داره همه سرویس ها بروزرسانی بشن که خیلی کار سختیه و همچنین اساسا خیلی از زبان ها محدودیت دارن در بدست آوردن چنین اطلاعاتی و خروجی همه اون سرویس ها یکسان نمیشه.
الگوی sidecar این ایده رو میده که ما یه sidecar container داشته باشیم که از PID namespace یکسانی با container اصلی برخوردار هست و تمامی اطلاعات پروسه های container اصلی رو میتونه ببینه، اینطوری ما با فقط نوشتن یک کانتینر ساده میتونیم بصورت ماژولار همه سرویس هامون رو ارتقا بدیم و از مانیتورینگ منابعشون لذت ببریم.
حتی modularity این امکان رو میده که ما دیگه نیاز نداشته باشیم توسعه بدیم و از community و دنیای open-source کمک بگیریم. مثلا در مورد همین /topz میشه از این ایمیج استفاده کرد..
docker run --pidcontainer:${APP_ID} -p 8080:8080 brendanburns/topz:db0fa58 /server --address=0.0.0.0:8080
@gocasts
#designing_distributed_systems_brendan_burns
👍1
Go Casts 🚀
Modular Applicatoin Containers الگوی sidecar به ما این اجازه رو میده که بتونیم یک سری modular container داشته باشیم که در سرویس های مختلف ازشون استفاده کنیم. مثلا تصور کنید که شما میخواید برای همه سرویس های زیرساخت تون عملکرد پروسه هارو مانیتور کنید و مصرف…
Designing Sidecars fo Modularity and Reusability
مبحث آخری که در مورد الگوی sidecar در کتاب مطرح میشه بحث طراحی sidecar container هست که باید بگونه ای باشه که قابلیت modularity و reusability داشته باشه
برای طراحی چنین container ی باید موارد زیر رو رعایت کنیم:
- Parameterizing your containers
این موضوع خیلی مهمه، چون اگه نشه کانتینر جانبی رو کانفیگ کرد نمیشه اونو در کنار سرویس های مختلف استفاده کرد، تصور کنید یه nginx رو که فقط به یه دامنه خاص گوش میده.. و آدرس این دامنه hardcode شده باشه داخل sidecar container...، خب طبیعیه که نمیشه این کانتینر رو در کنار سرویس های مختلف استفاده کرد
برای این قضیه هم میشه از command line arguments ها کمک گرفت هم از environment variable ها که استفاده از متغیرهای محیطی راه حل بهتریه عموما
- Creating the API surface of your container
برای کانتیتر جانبی باید یک API ثابت و پایدار تعریف کرد که در طول زمان دچار تغییرات ناسازگار نشه، زیرا وقتی یه کانتینر جانبی در کنار سرویس های مختلف استفاده میشه، ایجاد broken change در کانتینر جانبی عملکرد همه اون سرویس هارو تحت تاثیر قرار میده
به عنوان مثال برای همان nginx container تصور کنید اسم پارامتری که دامنه رو از env میخونه از ADDRESS به DOMAIN تغییر کنه، با همین تغییر کوچیک، در صورت بروزرسانی sidecar خیلی از سرویس ها دیگه مختل میشه کارشون
- Documenting the operation of your container
نکته آخر هم بحث مستندات هست که اگه قرار یه کانتینر جانبی بصورت گسترده استفاده بشه باید حتما مستندات خوبی داشته باشه که برای همه قابل فهم و استفاده باشه، مثلا یکی از راه های مستند کردن نوشتن کامنت های توضیحی در فایل Dockerfile مربوط به کانتینر هست
@gocasts
#designing_distributed_systems_brendan_burns
مبحث آخری که در مورد الگوی sidecar در کتاب مطرح میشه بحث طراحی sidecar container هست که باید بگونه ای باشه که قابلیت modularity و reusability داشته باشه
برای طراحی چنین container ی باید موارد زیر رو رعایت کنیم:
- Parameterizing your containers
این موضوع خیلی مهمه، چون اگه نشه کانتینر جانبی رو کانفیگ کرد نمیشه اونو در کنار سرویس های مختلف استفاده کرد، تصور کنید یه nginx رو که فقط به یه دامنه خاص گوش میده.. و آدرس این دامنه hardcode شده باشه داخل sidecar container...، خب طبیعیه که نمیشه این کانتینر رو در کنار سرویس های مختلف استفاده کرد
برای این قضیه هم میشه از command line arguments ها کمک گرفت هم از environment variable ها که استفاده از متغیرهای محیطی راه حل بهتریه عموما
- Creating the API surface of your container
برای کانتیتر جانبی باید یک API ثابت و پایدار تعریف کرد که در طول زمان دچار تغییرات ناسازگار نشه، زیرا وقتی یه کانتینر جانبی در کنار سرویس های مختلف استفاده میشه، ایجاد broken change در کانتینر جانبی عملکرد همه اون سرویس هارو تحت تاثیر قرار میده
به عنوان مثال برای همان nginx container تصور کنید اسم پارامتری که دامنه رو از env میخونه از ADDRESS به DOMAIN تغییر کنه، با همین تغییر کوچیک، در صورت بروزرسانی sidecar خیلی از سرویس ها دیگه مختل میشه کارشون
- Documenting the operation of your container
نکته آخر هم بحث مستندات هست که اگه قرار یه کانتینر جانبی بصورت گسترده استفاده بشه باید حتما مستندات خوبی داشته باشه که برای همه قابل فهم و استفاده باشه، مثلا یکی از راه های مستند کردن نوشتن کامنت های توضیحی در فایل Dockerfile مربوط به کانتینر هست
@gocasts
#designing_distributed_systems_brendan_burns
ضمنا من یه توضیحی بدم که چرا سیستم های توزیع شده و دونستن الگوهاشون مهمه؟ به این دلیل که عموما اکثر محیط های توسعه ای که در چند سال اخیر ما باهاشون سر و کار داشتیم بصورت توزیع شده بوده و هستن، و گاهی خودمون حتی متوجه این موضوع نیستیم، خیلی وقت ها فکر میکنیم چون برنامه ای که نوشتیم بصورت یکپارچه (monolith) هست پس الگوهای توزیع شده دیگه کاربردی ندارن در حالیکه از این موضوع غافل هستیم که در لحظه داریم به انواع مختلف از الگوهای سرویس های توزیع شده استفاده میکنیم و خودمون خبر نداریم. دونستن این الگوها خیلی کمک میکنه سیستم های بهتری طراحی و پیاده سازی کنیم. بنابراین من با کتاب عالی Designing Distributed Systems شروع کردم که فوق العاده کتاب مختصر و مفیدیه
@gocasts
https://www.amazon.co.uk/Designing-Distributed-Systems-Brendan-Burns/dp/1491983647
#distributedsystems #bookreading
#designing_distributed_systems_brendan_burns
@gocasts
https://www.amazon.co.uk/Designing-Distributed-Systems-Brendan-Burns/dp/1491983647
#distributedsystems #bookreading
#designing_distributed_systems_brendan_burns
Amazon
Designing Distributed Systems: Patterns and Paradigms for Scalable, Reliable Services
Designing Distributed Systems: Patterns and Paradigms for Scalable, Reliable Services
👍2
Go Casts 🚀
The Sidecar Pattern یکی از الگوهای معروف single-node الگوی sidecar هست در این الگو هر ماشین یا صحیح تر بگیم، هر pod از دو container تشکیل شده، یکی container اصلی هست که لاجیک اصلی برنامه رو اجرا میکنه و دومین container یک کانتینر جانبی هست که مسئولیتش بهبود…
یه نکته ای که تو الگوی sidecar باید بهش توجه بشه اینه که این دو تا container اصطلاحا tightly coupled هستن، یعنی یه سری shared resource دارن، مثلا در مثال nginx proxy دو تا container باید یه network داشته باشن
یا مثلا وقتی از fluentd برای log aggregate کردن استفاده میشه به عنوان sidecar باید یه shared mounted volume وجود داشته باشه که application container داخل اون لاگ هاشو میریزه و fluentd container اون لاگ هارو از فایل میخونه و consume میکنه
اصلاحا به container هایی که تو یه گروه هستن، با هم schedule میشن و shared resource دارن pod گفته میشه
تو الگوی sidecar همیشه کانتینر داخل pod مربوط به application قرار میگیره
#designing_distributed_systems_brendan_burns
@gocasts
یا مثلا وقتی از fluentd برای log aggregate کردن استفاده میشه به عنوان sidecar باید یه shared mounted volume وجود داشته باشه که application container داخل اون لاگ هاشو میریزه و fluentd container اون لاگ هارو از فایل میخونه و consume میکنه
اصلاحا به container هایی که تو یه گروه هستن، با هم schedule میشن و shared resource دارن pod گفته میشه
تو الگوی sidecar همیشه کانتینر داخل pod مربوط به application قرار میگیره
#designing_distributed_systems_brendan_burns
@gocasts
👍1
Go Casts 🚀
یه نکته ای که تو الگوی sidecar باید بهش توجه بشه اینه که این دو تا container اصطلاحا tightly coupled هستن، یعنی یه سری shared resource دارن، مثلا در مثال nginx proxy دو تا container باید یه network داشته باشن یا مثلا وقتی از fluentd برای log aggregate کردن…
The Ambassadors pattern
الگوی ambassadors یکی دیگه از single-node pattern هاست که جلوی app container میشینه و ارتباط app رو با دنیای بیرون مدیریت میکنه.
بر خلاف sidecar pattern که عموما یک functionality به app اضافه میکرد الگوی ambassadors عموما در خروجی app مداخله میکنه و تعامل با دنیای بیرون app از طریق ambassador container صورت میگیره
https://www.oreilly.com/library/view/designing-distributed-systems/9781491983638/ch03.html
#designing_distributed_systems_brendan_burns
@gocasts
الگوی ambassadors یکی دیگه از single-node pattern هاست که جلوی app container میشینه و ارتباط app رو با دنیای بیرون مدیریت میکنه.
بر خلاف sidecar pattern که عموما یک functionality به app اضافه میکرد الگوی ambassadors عموما در خروجی app مداخله میکنه و تعامل با دنیای بیرون app از طریق ambassador container صورت میگیره
https://www.oreilly.com/library/view/designing-distributed-systems/9781491983638/ch03.html
#designing_distributed_systems_brendan_burns
@gocasts
Go Casts 🚀
The Ambassadors pattern الگوی ambassadors یکی دیگه از single-node pattern هاست که جلوی app container میشینه و ارتباط app رو با دنیای بیرون مدیریت میکنه. بر خلاف sidecar pattern که عموما یک functionality به app اضافه میکرد الگوی ambassadors عموما در خروجی…
using an Ambassador to Shard a Service
خیلی از اوقات در scale بالا مدیریت حجم زیادی از داده ها در یک single machine ممکن نیست و به اجبار داده ها باید بین چندین instance مختلف shard بشن
این موضوع نباید تغییری در application برای ارتباط با storage layer ایجاد کنه
#designing_distributed_systems_brendan_burns
@gocasts
خیلی از اوقات در scale بالا مدیریت حجم زیادی از داده ها در یک single machine ممکن نیست و به اجبار داده ها باید بین چندین instance مختلف shard بشن
این موضوع نباید تغییری در application برای ارتباط با storage layer ایجاد کنه
#designing_distributed_systems_brendan_burns
@gocasts
Go Casts 🚀
using an Ambassador to Shard a Service خیلی از اوقات در scale بالا مدیریت حجم زیادی از داده ها در یک single machine ممکن نیست و به اجبار داده ها باید بین چندین instance مختلف shard بشن این موضوع نباید تغییری در application برای ارتباط با storage layer ایجاد…
شاید ایده اولیه ای که به ذهن میرسه این باشه که خود application این موضوع رو مدیریت کنه و با دونستن اینکه چه تعداد shard وجود داره، هر بار بر اساس الگوریتم و داده مورد نظر انتخاب کنه که کوئری رو به کدوم instance بفرسته
اما این راه حل پیچیدگی زیادی به لاجیک اضافه میکنه و مشکلات زیادی داره، از جمله اینکه سیستم باید از سلامت shard instance ها با خبر باشه
راه حل بهتر اینه که یک ambassador service در هر pod مربوط به application باشه که با توجه به کوئری ورودی تعیین کنه درخواست رو به کدوم shard instance بفرسته، مزیت اصلی این الگو اینه که application نیاز نیست تغییری ایجاد کنه و مثل معمول صرفا به یک local database service درخواست هاشو میفرسته، و این ambassador service هست که تمامی پیچیدگی های sharding رو مدیریت میکنه.
مزیت دوم این الگو modularity هست، زیرا میتوان به راحتی این ambassador container رو برای طیف زیادی از application های مختلف استفاده کرد بدون اینکه نیاز باشه در لاجیک اون application ها تغییری ایجاد بشه
به عنوان مثال اگه شما میخواید redis رو بصورت shard شده استفاده کنید میتونید از کد زیر برای پیاده سازی چنین معماری ای در kubernetes استفاده کنید:
https://github.com/brendandburns/designing-distributed-systems/blob/master/ambassadors/redis-shards.yaml
#designing_distributed_systems_brendan_burns
@gocasts
اما این راه حل پیچیدگی زیادی به لاجیک اضافه میکنه و مشکلات زیادی داره، از جمله اینکه سیستم باید از سلامت shard instance ها با خبر باشه
راه حل بهتر اینه که یک ambassador service در هر pod مربوط به application باشه که با توجه به کوئری ورودی تعیین کنه درخواست رو به کدوم shard instance بفرسته، مزیت اصلی این الگو اینه که application نیاز نیست تغییری ایجاد کنه و مثل معمول صرفا به یک local database service درخواست هاشو میفرسته، و این ambassador service هست که تمامی پیچیدگی های sharding رو مدیریت میکنه.
مزیت دوم این الگو modularity هست، زیرا میتوان به راحتی این ambassador container رو برای طیف زیادی از application های مختلف استفاده کرد بدون اینکه نیاز باشه در لاجیک اون application ها تغییری ایجاد بشه
به عنوان مثال اگه شما میخواید redis رو بصورت shard شده استفاده کنید میتونید از کد زیر برای پیاده سازی چنین معماری ای در kubernetes استفاده کنید:
https://github.com/brendandburns/designing-distributed-systems/blob/master/ambassadors/redis-shards.yaml
#designing_distributed_systems_brendan_burns
@gocasts
GitHub
designing-distributed-systems/ambassadors/redis-shards.yaml at master · brendandburns/designing-distributed-systems
Sample code and configuration files from the Designing Distributed Systems book. - brendandburns/designing-distributed-systems
👍1
Go Casts 🚀
شاید ایده اولیه ای که به ذهن میرسه این باشه که خود application این موضوع رو مدیریت کنه و با دونستن اینکه چه تعداد shard وجود داره، هر بار بر اساس الگوریتم و داده مورد نظر انتخاب کنه که کوئری رو به کدوم instance بفرسته اما این راه حل پیچیدگی زیادی به لاجیک…
Using an Ambassador for Service Brokering
یکی از ملزومات portable کردن application برای استفاده در محیط های مختلف بحث service discovery هست.
تصور کنید که application شما در محیط production باید به یه public cloud متصل بشه مثل AWS RDS و برای محیط staging به یک physical datacenter یا private cloud متصل بشه
مدیریت کردن این موضوع لاجیک application رو پیچیده میکنه، زیرا بر اساس محیطی که در اون قرار داره باید بحث service discovery رو مدیریت کنه.
بهتر اینه که یک service broker بصورت ambassador container داشته باشیم، که مسئولیت این موضوع رو قبول کنه، و application طبق معمول صرفا به یه local database متصل بشه
#designing_distributed_systems_brendan_burns
@gocasts
یکی از ملزومات portable کردن application برای استفاده در محیط های مختلف بحث service discovery هست.
تصور کنید که application شما در محیط production باید به یه public cloud متصل بشه مثل AWS RDS و برای محیط staging به یک physical datacenter یا private cloud متصل بشه
مدیریت کردن این موضوع لاجیک application رو پیچیده میکنه، زیرا بر اساس محیطی که در اون قرار داره باید بحث service discovery رو مدیریت کنه.
بهتر اینه که یک service broker بصورت ambassador container داشته باشیم، که مسئولیت این موضوع رو قبول کنه، و application طبق معمول صرفا به یه local database متصل بشه
#designing_distributed_systems_brendan_burns
@gocasts
🔥1
Go Casts 🚀
Using an Ambassador for Service Brokering یکی از ملزومات portable کردن application برای استفاده در محیط های مختلف بحث service discovery هست. تصور کنید که application شما در محیط production باید به یه public cloud متصل بشه مثل AWS RDS و برای محیط staging به…
Using an Ambassador to Do Experimentation or Request Splitting
فرض کنید نسخه بتای جدید application شما آماده شده و حالا میخواید قبل از اینکه نسخه جدید رو لانچ کنید از عملکرد اون مطمئن بشید. یکی از راه کارهایی که وجود داره اینه که بخشی از درخواست های production رو به نسخه beta محول میکنن برای پاسخگویی، اینطوری میتونن متوجه بشن که نسخه جدید چقدر در انجام کار خودش موفقه
پیاده سازی این روش بدون داشتن ambassador container لازمه اش اینه که لاجیک برنامه پیچیده تر بشه و خود application این موضوع رو handle کنه که خب کار خوبی نیست...
برای پیاده سازی این موضوع در kubernetes می توان چنین کدی نوشت
https://github.com/brendandburns/designing-distributed-systems/blob/master/ambassadors/web-experiment.yaml
#designing_distributed_systems_brendan_burns
@gocasts
فرض کنید نسخه بتای جدید application شما آماده شده و حالا میخواید قبل از اینکه نسخه جدید رو لانچ کنید از عملکرد اون مطمئن بشید. یکی از راه کارهایی که وجود داره اینه که بخشی از درخواست های production رو به نسخه beta محول میکنن برای پاسخگویی، اینطوری میتونن متوجه بشن که نسخه جدید چقدر در انجام کار خودش موفقه
پیاده سازی این روش بدون داشتن ambassador container لازمه اش اینه که لاجیک برنامه پیچیده تر بشه و خود application این موضوع رو handle کنه که خب کار خوبی نیست...
برای پیاده سازی این موضوع در kubernetes می توان چنین کدی نوشت
https://github.com/brendandburns/designing-distributed-systems/blob/master/ambassadors/web-experiment.yaml
#designing_distributed_systems_brendan_burns
@gocasts
🔥1
Go Casts 🚀
Using an Ambassador to Do Experimentation or Request Splitting فرض کنید نسخه بتای جدید application شما آماده شده و حالا میخواید قبل از اینکه نسخه جدید رو لانچ کنید از عملکرد اون مطمئن بشید. یکی از راه کارهایی که وجود داره اینه که بخشی از درخواست های production…
Adapters
الگوی آخری که از دسته single-node pattern ها بررسی میکنید adapter هست.
الگوی adapter وقتی استفاده میشه که بخوایم interface یک container رو تغییر بدیم. منظور از interface میتونه apiی باشه که ارائه میده، cliی باشه که داره و چیزای دیگه.
https://www.oreilly.com/library/view/designing-distributed-systems/9781491983638/ch04.html
#designing_distributed_systems_brendan_burns
#gocasts
الگوی آخری که از دسته single-node pattern ها بررسی میکنید adapter هست.
الگوی adapter وقتی استفاده میشه که بخوایم interface یک container رو تغییر بدیم. منظور از interface میتونه apiی باشه که ارائه میده، cliی باشه که داره و چیزای دیگه.
https://www.oreilly.com/library/view/designing-distributed-systems/9781491983638/ch04.html
#designing_distributed_systems_brendan_burns
#gocasts
Go Casts 🚀
Adapters الگوی آخری که از دسته single-node pattern ها بررسی میکنید adapter هست. الگوی adapter وقتی استفاده میشه که بخوایم interface یک container رو تغییر بدیم. منظور از interface میتونه apiی باشه که ارائه میده، cliی باشه که داره و چیزای دیگه. https://…
مثلا شما فرض کنید که میخواید یه سرویس Prometheus بالا بیارید روی زیرساختتون، و همه application های داخل زیرساخت رو مانیتور کنید.
سرویس prometheus انتظار داره همه سرویس ها یک مسیر در api خودشون داشته باشن مثلا /metrics که سرویس مورد نظر طبق ساختاری که Prometheus انتظار داره دیتا رو اونجا serve میکنه
با اینکار Prometheus هر چند وقت یکبار اون api رو فراخوانی میکنه و دیتای metric های جدید رو از سرویس دریافت میکنه و دیتابیس خودش رو بروز میکنه.
حالا تصور کنید که شما در زیرساخت خودتون چندین اپلیکیشن دارید که هر کدوم هم ممکنه با یه زبان یا فریمورک خاصی نوشته شده باشه، خب طبیعتا خیلی سخته که بخواید برای همه اون سرویس ها این api رو توسعه بدید.
علاوه بر سخت بودن توسعه چنین چیزی، باید در نظر بگیرید که همه سرویس های موجود در زیرساخت شما توسط تیم شما توسعه داده نشده، مثلا فرض کنید که شما از یک کلاستر redis استفاده میکنید و میخواید که redis رو هم به سرویس هایی که توسط prometheus مانیتور میشن اضافه کنید، شما نمیتونید چنین apiی برای redis توسعه بدید.
#designing_distributed_systems_brendan_burns
@gocasts
سرویس prometheus انتظار داره همه سرویس ها یک مسیر در api خودشون داشته باشن مثلا /metrics که سرویس مورد نظر طبق ساختاری که Prometheus انتظار داره دیتا رو اونجا serve میکنه
با اینکار Prometheus هر چند وقت یکبار اون api رو فراخوانی میکنه و دیتای metric های جدید رو از سرویس دریافت میکنه و دیتابیس خودش رو بروز میکنه.
حالا تصور کنید که شما در زیرساخت خودتون چندین اپلیکیشن دارید که هر کدوم هم ممکنه با یه زبان یا فریمورک خاصی نوشته شده باشه، خب طبیعتا خیلی سخته که بخواید برای همه اون سرویس ها این api رو توسعه بدید.
علاوه بر سخت بودن توسعه چنین چیزی، باید در نظر بگیرید که همه سرویس های موجود در زیرساخت شما توسط تیم شما توسعه داده نشده، مثلا فرض کنید که شما از یک کلاستر redis استفاده میکنید و میخواید که redis رو هم به سرویس هایی که توسط prometheus مانیتور میشن اضافه کنید، شما نمیتونید چنین apiی برای redis توسعه بدید.
#designing_distributed_systems_brendan_burns
@gocasts
👍1
Go Casts 🚀
مثلا شما فرض کنید که میخواید یه سرویس Prometheus بالا بیارید روی زیرساختتون، و همه application های داخل زیرساخت رو مانیتور کنید. سرویس prometheus انتظار داره همه سرویس ها یک مسیر در api خودشون داشته باشن مثلا /metrics که سرویس مورد نظر طبق ساختاری که Prometheus…
اینجاست که داشتن یه adapter container به کمک میاد
اساسا مفهوم adapter در برنامه نویسی یعنی اینکه شما قراره یک interface رو تبدیل به یک interface جدید کنی تا مطابق باشه با چیزی که سرویس های دیگه انتظار دارن
مثلا سرویس redis با interface خاص خودش دیتا رو برای مانیتور کردن ارائه میده و این دیتا به کار prometheus نمیاد، ما باید این وسط یه سرویس واسط داشته باشیم که کارش این باشه که دیتا رو با interface مربوط به redis بخونه و به صورت interfaceی که مد نظر prometheus هست ارائه بده.
برای این کار شما میتونید از exporter های prometheus استفاده کنید که یک سری adapter هستن برای انجام همین کار
مثلا برای مثال موجود میتونید از redis_export استفاده کنید
https://github.com/brendandburns/designing-distributed-systems/blob/master/adapters/prometheus-redis.yaml
#designing_distributed_systems_brendan_burns
@gocasts
اساسا مفهوم adapter در برنامه نویسی یعنی اینکه شما قراره یک interface رو تبدیل به یک interface جدید کنی تا مطابق باشه با چیزی که سرویس های دیگه انتظار دارن
مثلا سرویس redis با interface خاص خودش دیتا رو برای مانیتور کردن ارائه میده و این دیتا به کار prometheus نمیاد، ما باید این وسط یه سرویس واسط داشته باشیم که کارش این باشه که دیتا رو با interface مربوط به redis بخونه و به صورت interfaceی که مد نظر prometheus هست ارائه بده.
برای این کار شما میتونید از exporter های prometheus استفاده کنید که یک سری adapter هستن برای انجام همین کار
مثلا برای مثال موجود میتونید از redis_export استفاده کنید
https://github.com/brendandburns/designing-distributed-systems/blob/master/adapters/prometheus-redis.yaml
#designing_distributed_systems_brendan_burns
@gocasts
GitHub
designing-distributed-systems/adapters/prometheus-redis.yaml at master · brendandburns/designing-distributed-systems
Sample code and configuration files from the Designing Distributed Systems book. - brendandburns/designing-distributed-systems
Go Casts 🚀
اینجاست که داشتن یه adapter container به کمک میاد اساسا مفهوم adapter در برنامه نویسی یعنی اینکه شما قراره یک interface رو تبدیل به یک interface جدید کنی تا مطابق باشه با چیزی که سرویس های دیگه انتظار دارن مثلا سرویس redis با interface خاص خودش دیتا رو برای…
به جز مثال مذکور برای کاربردهای adapter نمونه های مختلف دیگه ای وجود داره
یکی از این نمونه ها بحث log کردن هست. سرویس های مختلف به فرمت های مختلف دیتا رو لاگ میکنن، اما اگه شما بخواید توسط یک log aggregator با یک فرمت و ساختار ثابت دیتای سرویس های مختلف رو جمع آوری کنید نیاز دارید که برای هر سرویس یک log adapter استفاده کنید که وظیفه اش تبدیل کردن دیتای لاگ از فرمت مبدا به فرمت مورد نظر سرویس logging agnet هست.
مثلا یکی از agent های معروف برای لاگ کردن دیتا fluentd هست که مشابه با exporter های prometheus یک سری plugin داره که اجازه میده لاگ های موجود با فرمت های مختلف رو به صورت فرمت استاندارد درآورده و ذخیره کنید.
لازمه این کار اینه که برای هر سرویس یک adapter container وجود داشته باشه که با application container یک shared volume داشته باشه و خروجی لاگ های application رو به صورت فرمت استاندارد مورد نظر fluentd دربیاره.
#designing_distributed_systems_brendan_burns
@gocasts
یکی از این نمونه ها بحث log کردن هست. سرویس های مختلف به فرمت های مختلف دیتا رو لاگ میکنن، اما اگه شما بخواید توسط یک log aggregator با یک فرمت و ساختار ثابت دیتای سرویس های مختلف رو جمع آوری کنید نیاز دارید که برای هر سرویس یک log adapter استفاده کنید که وظیفه اش تبدیل کردن دیتای لاگ از فرمت مبدا به فرمت مورد نظر سرویس logging agnet هست.
مثلا یکی از agent های معروف برای لاگ کردن دیتا fluentd هست که مشابه با exporter های prometheus یک سری plugin داره که اجازه میده لاگ های موجود با فرمت های مختلف رو به صورت فرمت استاندارد درآورده و ذخیره کنید.
لازمه این کار اینه که برای هر سرویس یک adapter container وجود داشته باشه که با application container یک shared volume داشته باشه و خروجی لاگ های application رو به صورت فرمت استاندارد مورد نظر fluentd دربیاره.
#designing_distributed_systems_brendan_burns
@gocasts
👍1
Go Casts 🚀
به جز مثال مذکور برای کاربردهای adapter نمونه های مختلف دیگه ای وجود داره یکی از این نمونه ها بحث log کردن هست. سرویس های مختلف به فرمت های مختلف دیتا رو لاگ میکنن، اما اگه شما بخواید توسط یک log aggregator با یک فرمت و ساختار ثابت دیتای سرویس های مختلف رو…
دوستان یه نکته ای از تجربه شخصی خودم بگم شاید بهتون کمک کنه که چه اینجا و چه جاهای دیگه مطالب رو عمقی تر به خاطر بسپرید.
سعی کنید در مورد هر الگو یا best-practice خاصی که مطالعه میکنید تو ذهنتون به این فکر کنید که در گذشته و یا حال، چه پروژه هایی بوده که اگه چنین الگویی براش لحاظ میشد، خروجی کار بهتر میشد.
لزومی نداره که حتما این روش هارو پیاده کنید و باهاشون تمرین داشته باشید.
همین که یه تمرین ذهنی داشته باشید از اینکه «فکر کنید این الگو کجای معماری سیستم شما میتونست قرار بگیره»، این خودش کافیه برای اینکه مطالب رو عمقی تر به ذهن بسپارید و در ادامه اگه لازم شد بتونید ازش بهره ببرید.
@gocasts
سعی کنید در مورد هر الگو یا best-practice خاصی که مطالعه میکنید تو ذهنتون به این فکر کنید که در گذشته و یا حال، چه پروژه هایی بوده که اگه چنین الگویی براش لحاظ میشد، خروجی کار بهتر میشد.
لزومی نداره که حتما این روش هارو پیاده کنید و باهاشون تمرین داشته باشید.
همین که یه تمرین ذهنی داشته باشید از اینکه «فکر کنید این الگو کجای معماری سیستم شما میتونست قرار بگیره»، این خودش کافیه برای اینکه مطالب رو عمقی تر به ذهن بسپارید و در ادامه اگه لازم شد بتونید ازش بهره ببرید.
@gocasts
👍1
و نکته دیگه اینکه قطعا دوست ندارم کانال یک طرفه باشه، قطعا در جمع عزیزان کانال هستند کسانی که تجربیات خیلی خوبی داشتند، اگه در کامنت ها مطلب مفیدی نوشته بشه بنده حتما با ارجاع به شخص مورد نظر، مطلب رو در کانال منتشر میکنم که بقیه دوستان هم بهره مند بشن.
دوستان سلام، در مورد تست نویسی در golang یه سری مقاله خیلی خوب بهتون معرفی میکنم، با خوندن این سری مقاله، عملا هر آنچه که در مورد تست نویسی در گولنگ باید بدونید رو یاد میگیرد، بقیه ش دیگه میشه تمرین و تجربه در کار...
Testing in Go: First Principles
https://ieftimov.com/post/testing-in-go-first-principles/
Testing in Go: Failing Tests
https://ieftimov.com/post/testing-in-go-failing-tests/
Testing in Go: Writing Practical Failure Messages
https://ieftimov.com/post/testing-in-go-writing-practical-failure-messages/
Testing in Go: go test
https://ieftimov.com/post/testing-in-go-go-test/
Testing in Go: Table-Driven Tests
https://ieftimov.com/post/testing-in-go-table-driven-tests/
Testing in Go: Subtests
https://ieftimov.com/post/testing-in-go-subtests/
Testing in Go: Fixtures
https://ieftimov.com/post/testing-in-go-fixtures/
Testing in Go: Dependency Injection
https://ieftimov.com/post/testing-in-go-dependency-injection/
Testing in Go: Test Doubles by Example
https://ieftimov.com/post/testing-in-go-test-doubles-by-example/
Testing in Go: Golden Files
https://ieftimov.com/post/testing-in-go-golden-files/
Testing in Go: Clean Tests Using t.Cleanup
https://ieftimov.com/post/testing-in-go-clean-tests-using-t-cleanup/
Testing in Go: HTTP Servers
https://ieftimov.com/post/testing-in-go-testing-http-servers/
Testing in Go: WebSockets
https://ieftimov.com/post/testing-in-go-websockets/
Testing in Go: Stop Leaking Files
https://ieftimov.com/post/testing-in-go-stop-leaking-files/
#golang #test #unit_test #integration_test #tdd
@gocasts
Testing in Go: First Principles
https://ieftimov.com/post/testing-in-go-first-principles/
Testing in Go: Failing Tests
https://ieftimov.com/post/testing-in-go-failing-tests/
Testing in Go: Writing Practical Failure Messages
https://ieftimov.com/post/testing-in-go-writing-practical-failure-messages/
Testing in Go: go test
https://ieftimov.com/post/testing-in-go-go-test/
Testing in Go: Table-Driven Tests
https://ieftimov.com/post/testing-in-go-table-driven-tests/
Testing in Go: Subtests
https://ieftimov.com/post/testing-in-go-subtests/
Testing in Go: Fixtures
https://ieftimov.com/post/testing-in-go-fixtures/
Testing in Go: Dependency Injection
https://ieftimov.com/post/testing-in-go-dependency-injection/
Testing in Go: Test Doubles by Example
https://ieftimov.com/post/testing-in-go-test-doubles-by-example/
Testing in Go: Golden Files
https://ieftimov.com/post/testing-in-go-golden-files/
Testing in Go: Clean Tests Using t.Cleanup
https://ieftimov.com/post/testing-in-go-clean-tests-using-t-cleanup/
Testing in Go: HTTP Servers
https://ieftimov.com/post/testing-in-go-testing-http-servers/
Testing in Go: WebSockets
https://ieftimov.com/post/testing-in-go-websockets/
Testing in Go: Stop Leaking Files
https://ieftimov.com/post/testing-in-go-stop-leaking-files/
#golang #test #unit_test #integration_test #tdd
@gocasts
Ilija Eftimov 👨🚀
Testing in Go: First Principles
If you have any programming experience, whether that’s as a student or a professional, there’s a good chance you have heard about testing.
👍1
Go Casts 🚀
دوستان سلام، در مورد تست نویسی در golang یه سری مقاله خیلی خوب بهتون معرفی میکنم، با خوندن این سری مقاله، عملا هر آنچه که در مورد تست نویسی در گولنگ باید بدونید رو یاد میگیرد، بقیه ش دیگه میشه تمرین و تجربه در کار... Testing in Go: First Principles https…
اساسا تست نویسی مقوله ای بسیار ساده، بسیار لذت بخش و در عین حال بسیار کارآمد هست.
دقت کنید وقتی صحبت از تست نویسی میشه منظور tdd نیست، tdd صرفا یک approach هست برای تست نوشتن، شما میتونید این روش رو استفاده کنید و یا نکنید
تست نویسی انواع مختلفی داره:
unit test
integration test
end to end test
که هر کدوم ارزش و جایگاه خودشونو دارن
تست نویسی واسه وقتایی که حوصله development ندارید مثل کافئین میمونه 😃
و وقتی ارزش خودشو نشون میده که لازم باشه یه چیزی رو refactor کنید، مخصوصا اگه refactor بزرگ باشه خیلی ریسک انجامش بالا میره، اگه از قبل تست های قابل اطمینان و جامعی براش نوشته باشید دیگه خیالتون میتونه تا حدود خیلی زیادی بابت refactor کردن راحت باشه
#golang #test #unit_test #integration_test #tdd
@gocasts
دقت کنید وقتی صحبت از تست نویسی میشه منظور tdd نیست، tdd صرفا یک approach هست برای تست نوشتن، شما میتونید این روش رو استفاده کنید و یا نکنید
تست نویسی انواع مختلفی داره:
unit test
integration test
end to end test
که هر کدوم ارزش و جایگاه خودشونو دارن
تست نویسی واسه وقتایی که حوصله development ندارید مثل کافئین میمونه 😃
و وقتی ارزش خودشو نشون میده که لازم باشه یه چیزی رو refactor کنید، مخصوصا اگه refactor بزرگ باشه خیلی ریسک انجامش بالا میره، اگه از قبل تست های قابل اطمینان و جامعی براش نوشته باشید دیگه خیالتون میتونه تا حدود خیلی زیادی بابت refactor کردن راحت باشه
#golang #test #unit_test #integration_test #tdd
@gocasts
Go Casts 🚀
به جز مثال مذکور برای کاربردهای adapter نمونه های مختلف دیگه ای وجود داره یکی از این نمونه ها بحث log کردن هست. سرویس های مختلف به فرمت های مختلف دیتا رو لاگ میکنن، اما اگه شما بخواید توسط یک log aggregator با یک فرمت و ساختار ثابت دیتای سرویس های مختلف رو…
حالا که بحث adapter رو کردیم، شاید بد نباشه یه نگاهی به تفاوت الگوی adapter و wrapper بندازیم، این دو الگو خیلی به هم شبیه هستن و گاهی با هم اشتباه گرفته میشن
پیشنهاد میکنم که حتما اصل مقاله رو هم مطالعه کنید
The Difference Between An Adapter And A Wrapper
Being cognizant of what problem you are trying to solve and what pattern you are using to solve that problem will help you to keep your code clean and focused on a singular purpose.
Use wrappers to simplify code, encapsulate third-party dependencies, and eliminate repetition.
Use the adapter pattern to allow yourself to swap out third-party dependencies at will by interacting with your own interface, and then making adapters that map from your own interface to the third party code.
تفاوت wrapper با adapter در این نکته است که هدف اصلی wrapper اینه که interface موجود نسبت به یک کتابخانه خارجی رو ساده سازی میکنه و به یک interface ساده تر تبدیلش میکنه، اما adapter شکاف بین دو interface موجود رو جبران میکنه و مثل یک پل (bridge) بین این دو عمل میکنه. با کمک adapter ما یک مساله ناسازگاری (incompatibility) رو حل میکنیم، اما به کمک wrapper نیاز ساده سازی کردن یک interface موجود رو حل می کنیم.
مثال
مثلا تصور کنید که برنامه شما نیاز داره که یک سری اطلاعات کاربر رو از شبکه اجتماعی بگیره. کلاس FacebookConnector میتونه یک wrapper برای Facebook SDK باشه که اتصال شما به facebook رو راحت میکنه. به جای اینکه از sdk استفاده کنی که برای usecase های مختلف interface رو در معرض نمایش (expose)میذاره، از یک کلاس wrapper استفاده میشه که فقط برای usecase های شما یک interface ارائه میده.
حالا مثلا دیگه اینه که تصور کنید که اپلیکیشن شما یک سری داده از شبکه های اجتماعی میخواد در مورد کاربر، اما براش مهم نیست این داده ها از کدوم شبکه اجتماعی هستن. تو این حالت میشه یه interface داشت مثلا به اسم ISocialIntegrator که usecase های برنامه رو پیاده میکنه اما هیچ وابستگی ای به هیچ شبکه اجتماعی خاصی نداره.
بعد از اینکه تصمیم گرفتید از کدوم شبکه اجتماعی استفاده کنید، شما میتونید یک adapter بین ISocialIntegrator و کتابخونه شبکه اجتماعی مورد نظر خودتون بنویسید. مثلا FacebookAdapter یا LinkedInAdapter که خلا بین اینترفیس SocialIntegrator و api واقعی شبکه اجتماعی مورد نظر رو پر میکنه.
با استفاده از wrapper میشه وابستگی های شخص ثالث رو ساده سازی کرده، کپسوله کرد.
با استفاده از adapter میشه براحتی وابستگی های شخص ثالث رو تغییر داد به کمک داشتن یک interface اختصاصی برای برنامه و نوشتن یک سری adapter که interface برنامه رو به کد وابستگی شخص ثالث نگاشت میکنن.
https://www.thecodedself.com/The-Difference-Between-an-Adapter-and-a-Wrapper/
#design_pattern
#adapter
#wrapper
@gocasts
پیشنهاد میکنم که حتما اصل مقاله رو هم مطالعه کنید
The Difference Between An Adapter And A Wrapper
Being cognizant of what problem you are trying to solve and what pattern you are using to solve that problem will help you to keep your code clean and focused on a singular purpose.
Use wrappers to simplify code, encapsulate third-party dependencies, and eliminate repetition.
Use the adapter pattern to allow yourself to swap out third-party dependencies at will by interacting with your own interface, and then making adapters that map from your own interface to the third party code.
تفاوت wrapper با adapter در این نکته است که هدف اصلی wrapper اینه که interface موجود نسبت به یک کتابخانه خارجی رو ساده سازی میکنه و به یک interface ساده تر تبدیلش میکنه، اما adapter شکاف بین دو interface موجود رو جبران میکنه و مثل یک پل (bridge) بین این دو عمل میکنه. با کمک adapter ما یک مساله ناسازگاری (incompatibility) رو حل میکنیم، اما به کمک wrapper نیاز ساده سازی کردن یک interface موجود رو حل می کنیم.
مثال
مثلا تصور کنید که برنامه شما نیاز داره که یک سری اطلاعات کاربر رو از شبکه اجتماعی بگیره. کلاس FacebookConnector میتونه یک wrapper برای Facebook SDK باشه که اتصال شما به facebook رو راحت میکنه. به جای اینکه از sdk استفاده کنی که برای usecase های مختلف interface رو در معرض نمایش (expose)میذاره، از یک کلاس wrapper استفاده میشه که فقط برای usecase های شما یک interface ارائه میده.
حالا مثلا دیگه اینه که تصور کنید که اپلیکیشن شما یک سری داده از شبکه های اجتماعی میخواد در مورد کاربر، اما براش مهم نیست این داده ها از کدوم شبکه اجتماعی هستن. تو این حالت میشه یه interface داشت مثلا به اسم ISocialIntegrator که usecase های برنامه رو پیاده میکنه اما هیچ وابستگی ای به هیچ شبکه اجتماعی خاصی نداره.
بعد از اینکه تصمیم گرفتید از کدوم شبکه اجتماعی استفاده کنید، شما میتونید یک adapter بین ISocialIntegrator و کتابخونه شبکه اجتماعی مورد نظر خودتون بنویسید. مثلا FacebookAdapter یا LinkedInAdapter که خلا بین اینترفیس SocialIntegrator و api واقعی شبکه اجتماعی مورد نظر رو پر میکنه.
با استفاده از wrapper میشه وابستگی های شخص ثالث رو ساده سازی کرده، کپسوله کرد.
با استفاده از adapter میشه براحتی وابستگی های شخص ثالث رو تغییر داد به کمک داشتن یک interface اختصاصی برای برنامه و نوشتن یک سری adapter که interface برنامه رو به کد وابستگی شخص ثالث نگاشت میکنن.
https://www.thecodedself.com/The-Difference-Between-an-Adapter-and-a-Wrapper/
#design_pattern
#adapter
#wrapper
@gocasts
The Coded Self
The Difference Between An Adapter And A Wrapper
The adapter pattern and wrappers each solve common but distinct problems. Their common usage and similarities in implementation, however, can lead to confusion. Both terms seem to be used interchangeably when in fact there are a few key differences. The adapter…
Forwarded from Maestro
Media is too big
VIEW IN TELEGRAM
بخش اول unit test در golang
موضوعاتی که پوشش داده شده
unit test (simple functions without any dependency)
table driven test
subtests
#golang #unit_test #test
@gocasts
موضوعاتی که پوشش داده شده
unit test (simple functions without any dependency)
table driven test
subtests
#golang #unit_test #test
@gocasts