دوستان عزیزی که توی گولنگ از grpc استفاده میکنید.
سمت کلاینت دیگه برای ساخت کانکشن از grpc.Dial استفاده نکنید منسوخ شده
- البته بگم دلیل اینکه برداشته نشد مربوط میشه به تکنیک دپرکشن (Deprecation)
پیشنهاد میشه حداقل تو کد های جدیدتون از grpc.NewClient بجاش استفاده کنید با اینکه شک دارم روزی بخوان پاکش کنن Dial رو ولی خب منسوخ شده استفاده نکنید.
این فانکشن دقیقا مثل dial هستش و ازتون یک استرینگ میگیره که سرور تارگت شما هستش (با پورت ترجیحا) و یک سری اپشن اختیاری و در خروجی فانکشن یک grpc.ClientConn با پوینترش بهتون میده و یک ارور
سمت کلاینت دیگه برای ساخت کانکشن از grpc.Dial استفاده نکنید منسوخ شده
- البته بگم دلیل اینکه برداشته نشد مربوط میشه به تکنیک دپرکشن (Deprecation)
پیشنهاد میشه حداقل تو کد های جدیدتون از grpc.NewClient بجاش استفاده کنید با اینکه شک دارم روزی بخوان پاکش کنن Dial رو ولی خب منسوخ شده استفاده نکنید.
این فانکشن دقیقا مثل dial هستش و ازتون یک استرینگ میگیره که سرور تارگت شما هستش (با پورت ترجیحا) و یک سری اپشن اختیاری و در خروجی فانکشن یک grpc.ClientConn با پوینترش بهتون میده و یک ارور
🔥3
برای کسایی که میکروسرویس کار میکنن مهم نیست به چه زبانی
یک معماری هست به اسم database per service که دقیقا اینطوریه هر سرویس برای خودش یک دیتابیس مخصوص داره.
مزایا:
امنیت بیشتر
سرعت بیشتر (در صورتی که دیتابیس به صورت لوکال در دسترس باشه)
درصورت هک شدن یک سرویس دیتابیس همون سرویس در خطره
معایب:
مدیریت سخت
درکل چیز باحالیه ولی خودشم حالت های مختلف داره مثلا میشه دیتابیس رو به صورت لوکال تو اون سرویس نگه داشت یا دیتابیس رو هم توی یک هاست جدا نگهداری کرد ولی خب بازم سخت تر میشه
یک معماری هست به اسم database per service که دقیقا اینطوریه هر سرویس برای خودش یک دیتابیس مخصوص داره.
مزایا:
امنیت بیشتر
سرعت بیشتر (در صورتی که دیتابیس به صورت لوکال در دسترس باشه)
درصورت هک شدن یک سرویس دیتابیس همون سرویس در خطره
معایب:
مدیریت سخت
درکل چیز باحالیه ولی خودشم حالت های مختلف داره مثلا میشه دیتابیس رو به صورت لوکال تو اون سرویس نگه داشت یا دیتابیس رو هم توی یک هاست جدا نگهداری کرد ولی خب بازم سخت تر میشه
وقت بخیر
ی پروژه خیلی کوچیک ولی شاید کاربردی زدم
داشتم روی میکروسرویس کار میکردم که به این نتیجه رسیدم نمیشه با ی لاین ارور ساده همچیو هندل کرد. یعنی:
کلاینت به پروکسی میگه یوزر بساز > پروکسی به سرور میگه یوزر بساز
سرور میتونه هر جوابی بده. مثلا:
این کاربر قبلا وجود دارد
مشکلی پیش امد
نام کاربری قبلا استفاده شده
وقتی سرور به کلاینت خودش (پروکسی) میگه پروکسی باید یک جواب در قابل رستفول به کلاینت بده. پس فقط نیاز به یک message ساده نداره
یک ساختار تقریبا اینطوری نیاز داره:
Status: Error
Message: "Username exists"
Code: "USERNAME_EXISTS"
Data: ( فعلا چون ارور داریم خالیه و وجود نداره فیلدش)
و خب اگر بخوام به صورت دستی اینا رو بنویسم و با gRPC بفرستم مقیاس پذیری کد میره پایین و درصد خطا خیلی زیاد میشه.
برای همین یک سری const اماده کردم با یک اسکریپته اماده که گذاشتم روی گیتهاب (اسکریپت bash)
اینطوریه که میاد این متغیر های اماده رو میگیره
شما کافیه پروژه رو فورک کنید اگر دوست داشتید ادیت بزنید و ادرس پروژه توی اسکریپت ور به پروژه خودتون تعقیر بدید.
حالا تو هر پاسخ کد مخصوص رو میفرستید
نیاز هم نیست توی هر سرویس جداگانه کد هارو تعریف کنید
این اسکریپت هربار که اجراش کنید اخرین نسخه const های تعریف شده رو از شما میگیره و جایگذین میکنه با نسخه قدیمی
اینطوری اگر متغیر جدیدی اضافه بکنید فقط کافیه یک اسکریپت برای هر سرویس ران کنید (یا یک اسکریپت اصلی بنویسین که همه رو باهم ران کنه)
برای همه سرویس ها این تعقیر اعمال میشه و میتونن با زبون خودشون صحبت کنن باهمدیگه.
github: https://github.com/amodemoli/response-codes
اگر دوست داشتید استار بدید اگرم خواستید استفاده کنید پیشنهاد میدم فورک کنید چون برای هر پروژه این متغیر ها شاید نیاز به تعقیر های کوچیکی داشته باشن
- پروژه فقط برای زبان گولنگ هستش.
ی پروژه خیلی کوچیک ولی شاید کاربردی زدم
داشتم روی میکروسرویس کار میکردم که به این نتیجه رسیدم نمیشه با ی لاین ارور ساده همچیو هندل کرد. یعنی:
کلاینت به پروکسی میگه یوزر بساز > پروکسی به سرور میگه یوزر بساز
سرور میتونه هر جوابی بده. مثلا:
این کاربر قبلا وجود دارد
مشکلی پیش امد
نام کاربری قبلا استفاده شده
وقتی سرور به کلاینت خودش (پروکسی) میگه پروکسی باید یک جواب در قابل رستفول به کلاینت بده. پس فقط نیاز به یک message ساده نداره
یک ساختار تقریبا اینطوری نیاز داره:
Status: Error
Message: "Username exists"
Code: "USERNAME_EXISTS"
Data: ( فعلا چون ارور داریم خالیه و وجود نداره فیلدش)
و خب اگر بخوام به صورت دستی اینا رو بنویسم و با gRPC بفرستم مقیاس پذیری کد میره پایین و درصد خطا خیلی زیاد میشه.
برای همین یک سری const اماده کردم با یک اسکریپته اماده که گذاشتم روی گیتهاب (اسکریپت bash)
اینطوریه که میاد این متغیر های اماده رو میگیره
شما کافیه پروژه رو فورک کنید اگر دوست داشتید ادیت بزنید و ادرس پروژه توی اسکریپت ور به پروژه خودتون تعقیر بدید.
حالا تو هر پاسخ کد مخصوص رو میفرستید
نیاز هم نیست توی هر سرویس جداگانه کد هارو تعریف کنید
این اسکریپت هربار که اجراش کنید اخرین نسخه const های تعریف شده رو از شما میگیره و جایگذین میکنه با نسخه قدیمی
اینطوری اگر متغیر جدیدی اضافه بکنید فقط کافیه یک اسکریپت برای هر سرویس ران کنید (یا یک اسکریپت اصلی بنویسین که همه رو باهم ران کنه)
برای همه سرویس ها این تعقیر اعمال میشه و میتونن با زبون خودشون صحبت کنن باهمدیگه.
github: https://github.com/amodemoli/response-codes
اگر دوست داشتید استار بدید اگرم خواستید استفاده کنید پیشنهاد میدم فورک کنید چون برای هر پروژه این متغیر ها شاید نیاز به تعقیر های کوچیکی داشته باشن
- پروژه فقط برای زبان گولنگ هستش.
GitHub
GitHub - amodemoli/response-codes: This is a pretty personal project. I've prepared ready-made response codes, status codes, and…
This is a pretty personal project. I've prepared ready-made response codes, status codes, and so on, so I can read and use the files in my projects. - amodemoli/response-codes
❤2
𝐀𝐦𝐢𝐫
Photo
توی ریت لیمیتینگ وقتی کسی لیمیت میشه بیشتر افراد میان و یک پاسخ ساده به کلاینت میدن و تمام، اما خب همین کار خودش یک نقطه ضعف بزرگ در برابر حملات دیداسه. ⚠️
چرا؟ هربار که درخواستی به سمت سرور میره ریت لیمیتینگ باید کلی کار انجام بده، از جمله سیو کردن درخواست کاربر و غیره... که این کارا نسبتا سنگین هستن، اگر هر بار که کسی لیمیت میشه بهش یک جواب ساده بدیم. اون فرد دوباره درخواست میفرسته و دوباره ریت لیمیت کل مراحل و طی میکنه. از گشتن دنبال کاربر و حساب کردن تعداد توکن هاش (اگر از الگوریتم Token Bucket یا از golang.org/x/time/rate استفاده میکنید)
🔄 کل این مراحل باید دوباری طی بشن.
اینجاست که باید قبل از هندل کردن لیمیتر یک سیستم برای بن کردن کاربر استفاده کنیم، وقتی کسی چند بار بعد از تموم شدن توکن هاش بازم درخواست میده لیمیتر اسم اونو میفرسته و اونو برای مثال برای ۵ دقیقه بن میکنه، توی بن هم از سیستم sync.Map استفاده میکنیم چون سناریو اغلب برای خوندنه این بهترین گذینه هستش. 🚫
حالا کاربر وقتی درخواست میده قبل از رفتن درخواستش به سمت هندلر اصلی لیمیتر از یک فیلتر ساده بن ها رد میشه.
🔴 معایب این معماری: اگر لیمیتر و بن سیستم با توجه به ip کاربر هست (یعنی تو مپ به عنوان key ایپی کاربر سیو میشه) و سرویسی که اراعه میدیم third party هست، شرکت هایی که از سیستم NAT استفاده میکنن تو استفاده از پلتفرم به مشکل میخورن. 🌐
✅ برای رفع و جلوگیری: برسی ها رو بر اساس Api Key یا حساب کاربری کنید و اندپوینت های عمومی رو با محدودیت زیاد در دسترس کنید و بعد لاگین محدودیت هارو کمتر کنید.
چرا؟ هربار که درخواستی به سمت سرور میره ریت لیمیتینگ باید کلی کار انجام بده، از جمله سیو کردن درخواست کاربر و غیره... که این کارا نسبتا سنگین هستن، اگر هر بار که کسی لیمیت میشه بهش یک جواب ساده بدیم. اون فرد دوباره درخواست میفرسته و دوباره ریت لیمیت کل مراحل و طی میکنه. از گشتن دنبال کاربر و حساب کردن تعداد توکن هاش (اگر از الگوریتم Token Bucket یا از golang.org/x/time/rate استفاده میکنید)
🔄 کل این مراحل باید دوباری طی بشن.
اینجاست که باید قبل از هندل کردن لیمیتر یک سیستم برای بن کردن کاربر استفاده کنیم، وقتی کسی چند بار بعد از تموم شدن توکن هاش بازم درخواست میده لیمیتر اسم اونو میفرسته و اونو برای مثال برای ۵ دقیقه بن میکنه، توی بن هم از سیستم sync.Map استفاده میکنیم چون سناریو اغلب برای خوندنه این بهترین گذینه هستش. 🚫
حالا کاربر وقتی درخواست میده قبل از رفتن درخواستش به سمت هندلر اصلی لیمیتر از یک فیلتر ساده بن ها رد میشه.
🔴 معایب این معماری: اگر لیمیتر و بن سیستم با توجه به ip کاربر هست (یعنی تو مپ به عنوان key ایپی کاربر سیو میشه) و سرویسی که اراعه میدیم third party هست، شرکت هایی که از سیستم NAT استفاده میکنن تو استفاده از پلتفرم به مشکل میخورن. 🌐
✅ برای رفع و جلوگیری: برسی ها رو بر اساس Api Key یا حساب کاربری کنید و اندپوینت های عمومی رو با محدودیت زیاد در دسترس کنید و بعد لاگین محدودیت هارو کمتر کنید.
pkg.go.dev
rate package - golang.org/x/time/rate - Go Packages
Package rate provides a rate limiter.
❤2