<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های ساسان پرویز</title><link>https://virgool.ir/feed/@sasanparviz</link><description>مهندس نرم افزار و سرور</description><language>fa</language><pubDate>2026-11-12 05:19:19</pubDate><image><url>https://files.virgool.ir/upload/users/528413/avatar/CQatu8.jpeg</url><title>ساسان پرویز</title><link>https://virgool.ir/@sasanparviz</link></image><item><title>استفاده از ردیس برای کش پست‌های هر تگ.</title><link>https://virgool.ir/@sasanparviz/استفاده-از-ردیس-برای-کش-پست-های-هر-تگ-vpiizwju09lc</link><description>یکی از چالش هایی که جدیدا بهش  برخوردیم این بود که براساس تگ هایی که یک سری پست دارن اون ها رو نشون  ندیم، بولد (Bold) نشون بدیم و ... برای این کار یک دیتابیس داریم که لیست  تگ‌ها رو توی خودش نگه میداره و یک دیتابیس دیگه که با Many-to-many رابطه  بین پست و تگ ها رو ذخیره میکنه. تا اینجای قضیه سادست. اما از اونجایی که  درخواست های زیادی سمت وبسایتمون میاد باید حتما یک کش داشته باشیم که  دیتابیسمون به رحمت خدا نره و نماز میت بر ما واجب نشه.چرا از ردیس استفاده میکنیم؟برای  کش کردن کلی راه حل مثل Redis, memcached و... هست. اما تفاوتی که ردیس  داره اینه که دیتاتایپ هایی به ما میده که بتونیم طبق نیازی که داریم ازشون  استفاده کنیم.حالا  که معلوم شد چرا از ردیس استفاده میکنیم بیاید با هم مشکلمون رو بررسی  کنیم و براساس ابزار هایی که ردیس بهمون میده چند تا راه حل پیدا کنیم و با  بنچ مارک گرفتن بهینه ترینشون رو انتخاب کنیم.مسئله  ما اینه که یک لیست از پست آی‌دی داریم (۱۰۰ تا پست) و میخوایم چک کنیم  برای تک تک اون آی‌دی ها که ۴ تا تگ مشخص رو دارن یا نه.راه حل های ابتدایی و بدرد نخوربدرد  نخور لفظ خوبی نیست! اما خب برای این همه بار اضافه ایی که این راه حل ها  میارن حرف خوبیه. هر دیتاتایپ ایی جای خودش به کار میاد. قرار نیست همه چیز  با یک ارایه خشک و خالی حل شه.راه حل ابتدایی اولیه اینه  که کل آی‌دی های پست های هر تگ رو توی یک آرایه بریزیم و برای هر بار چک  کردن هم از اول تا آخر ارایه بریم که پیچیدگی زمانی N داره و به درد این  کار نمیخوره.راه حل ابتدایی دوم اینه  ارایه ایی که آی دی ها ریخته میشه توش رو Sort کنیم که پیچیدگی زمانی  دریافت لگاریتمی میشه. اما خب چه کاریه اینقدر پیچیدش کنیم!ساده‌ترین راه حل،‌ ترکیب شناسه‌ پست با تگ در Key ردیس.احتمالا  ساده‌ترین راه حلی که به ذهن همه میاد اینه که یک ترکیب مثل postid:tagid  توی ردیس ذخیره کنن. حالا هر بار نیاز بود چک کنن پست X آیا تگ Y رو داره  یا نه، باید چک کنن که کلید x:y وجود داره توی ردیس ما یا نه. قبل از هر  تصمیمی بهتره یک بنچ‌مارک ازش بگیریم. من یک اسکریپت نوشتم که برای ۱۰۰  تا تگ و ۴۰۰ هزار تا پست دیتا تولید میکنه. ( در مجموع میشه ۴۰ میلیون داده  توی ردیس ). همچنین یک اسکریپت دیگه هم داریم که برای ۱۰۰ تا پست چک کنه  که ۴ تا تگ رو دارن یا نه.اجرای اسکریپت افزودن دیتا یک دقیقه و ۳۸ ثانیه طول کشید.حجم مموری ردیس بعد از افزودن دیتای: ۳.۱۳گیگاجرای اسکریپت دریافت ۴ تگ برای ۱۰۰ تا پست: ۱.۲۴ میلی‌ثانیه.چون حالت دیگه ایی نداریم که مقایسه کنیم عددا یکم برامون گنگ هستن. ۳ گیگ خوبه یا نه؟ بهتر راه حل های دیگه رو هم چک کنیم.استفاده از هش ردیسحالا  چطور ازش استفاده میکنیم؟ یک کلید میسازیم برای هر تگ و به اون هشمون  تک تک پست هایی که اون تگ رو دارن با مقدار 1 اضافه میکنیم. مثلا اگه تگ  free داشته باشیم با پست های 5,12 و 21 دستور ردیسمون اینطور میشه:HMSET tag:free 12 1 5 1 21 1توی دستور بالا میگیم یک هش به اسم tag:free بساز که به ترتیب 12,5,21 مقدارشون یک باشه.ما  برای این کار دو تا راه حل داشتیم، کلید ما تگ باشه و هش ما پست ها، یا  کلید پست باشه و هش ما لیست تگ های اون پست. چرا راه اول رو انتخاب کردیم؟برای  اینکه علت رو دقیق تر متوجه بشیم باید صورت مسئله رو یک بار دیگه بخونیم.  یک لیست ۱۰۰ تایی داریم و میخوایم برای هر تگ چک کنیم که آیا تک تک این پست  ها فلان تگ رو دارن یا نه. همچنین باید در نظر داشته باشیم برای دریافت  اطلاعات از هش ما نمیخوایم یکی یکی چک کنیم که تگ فلان پست فلان رو داره یا  نه. ما میخوایم همزمان بگیم که یک پست اون ۴ تا تگ رو داره یا یک تگ اون  ۱۰۰ تا پست رو داره یا نه؟ حالا اگه کلید ما پست آی دی باشه و هش ما تگ  های ما، باید ۱۰۰ تا چک برای ۴ تا تگ داشته باشیم در حالی که الان با این  روش ۴ تا چک برای ۱۰۰ تا پست رو داریم.حالا که متوجه کلیت این روش شدیم بهتره بریم سراغ بنچ مارک گرفتن.اسکریپت افزودن دیتاها ۴۰ ثانیه طول کشید.حجم مموری گرفته شده ۲.۱ گیگ بود.اسکریپت دریافت اطلاعات از کش ۸۵۰ میکروثانیه یعنی کمتر از یک میلی‌ثانیه طول کشید.این روش خیلی سریع تر بود. اما مشکلی که هست اینه میخوایم سعی کنیم اگر امکانش هست حافظه کمتر از ۲ گیگ باشه.یک  دیتاتایپ ایی که هنوز در موردش صحبت نکردیم ست ها (Sets) هستند. اگه درس  ساختمان داده رو خونده باشید میدونید ست ها از هش توی خودشون استفاده  میکنن. اما برعکس هش‌ایی که توی ردیس داشتیم قرار نیست دیگه دیتای اضافی  ایی که به هر آیتم بدیم. توی ست میتونیم چک کنیم که آیا یک آیتم عضو ست هست  یا نه.استفاده از ست‌های ردیسکاری  که میخوایم انجام بدیم تقریبا شبیه مپ هست. به ازای هر تگ یک ست داریم که  حاوی آی‌دی پست هایی هست که اون تگ رو دارن. فرقش با هش اینه دیگه نمیگیم  هر عضو مقدار true (یا یک) رو داره. چون هر عضو قرار نیست دیتایی رو توی  خودش ذخیره کنه. صرفا با کامند های ردیس میتونیم چک کنیم که آیا فلان عضو  توی فلان ست هست یا نه. براساس این موضوع میشه پیشبینی کرد که حافظه رم ما  کمتر میشه و احتمالا به زیر ۲ گیگ برسیم. بهتره بنچ‌مارک بگیریم:اسکریپت افزودن دیتا ها فقط ۳۰ ثانیه طول کشید.حجم مموری گرفته شده ۱.۷ گیگ بود ( هورااا‌ )اسکریپت دریافت اطلاعات از ردیس ( ؟؟؟‌)خب،  به یک مشکل خوردیم! بذارید مسئله رو دوباره بگم. ما یک کلید داریم که نشون  دهنده یک تگ هست که حاوی یک ست از آی‌دی پست هاست. ما میخوایم ۱۰۰ تا پست  رو توی اون ست چک کنیم. اما کامندی که ردیس برای چک کردن عضو درون ست به ما  میده single هست. یعنی فقط یک عضو رو میتونیم تست کنیم. چطور ۱۰۰ تا رو با  هم چک کنیم؟ از pipeline استفاده میکنیم (با استفاده از پایپ‌لاین ها یک  مجموعه دستور برای ردیس با هم می فرستیم که پشت سر هم اجرا بشن.) اما برعکس  هش یا get دستوری نیست که همه رو با هم بگیره و مطمئن باشیم بهینه سازی  های ردیس روش انجام میشه.۳. اسکریپت دریافت اطلاعات از ردیس: ۱.۴ میلی‌ثانیهجمع بندیست  ها میتونست جواب بهتری باشه ولی مجبوریم ۴۰۰ مگ رو با stability معاوضه  کنیم. البته سرعت دریافت از هش تا دو برابر سریع تر از ست بود که کنار  استیبل بودن هش ها باعث شد این گزینه رو انتخاب کنیم.</description><category>ساسان پرویز</category><author>ساسان پرویز</author><pubDate>Wed, 06 Aug 2025 13:18:24 +0330</pubDate></item><item><title>مقدمه‌ای بر Nest.js برای توسعه‌دهندگان Angular</title><link>https://virgool.ir/@sasanparviz/مقدمه-ای-بر-nestjs-برای-توسعه-دهندگان-angular-pg2r4pni7zj3-pg2r4pni7zj3</link><description>فریمورک Nest.js یک فریموریک پروگرسیو نودجی‌اس، نوشته شده با Typescript است. این ابزار به صورت متن باز ارائه می‌شود. دلیلی که در این مطلب صحبت از توسعه‌دهندگان Angular شده، این است که Nest.js ویژگی‌های زیادی را از Anguar به ارث برده، همچنین این نکته بسیار مهمی است که بدانیم، انگولار و Nest.js هر دو با تایپ‌اسکریپت نوشته شده‌اند.فریمورک Nest.js برای بک-اند است، با استفاده از این فریمورک شما می‌توانید اپلیکیشن‌های بهینه، مطمئن و مقیاس‌پذیری را برای سازمان‌ها بنویسید. این ابزار توسط توسعه‌دهنده Kamil Mysliwiec نوشته شده است.ویژگی‌های کلی Nest.js:گسترش‌پذیری: از آنجایی که Nest یک فریمورک ماژولار است به شما این قابلیت را می‌دهد تا کتابخانه‌های مختلف را برای خود بسازید.معماری: ساختار پروژه‌های Nest به صورتی است که به شما این قابلیت را می‌دهد تا بدون زحمت زیاد، از پروژه‌های‌تان تست بگیرید و آن‌ها را پایدار نگه دارید. همچنین قابلیت مقیاس‌پذیری بالا یکی دیگر از ویژگی‌های مهم آن است.انعطاف‌: Nest فریمورکی است که قابلیت ساخت هرگونه اپلیکیشن Server-Side را به شما می‌دهد.جریان پیشرفت: Nest همواره سعی دارد تا خود را با آخرین‌ نسخه‌های Javascript و Typescript سازگار کند، به همین دلیل جریان پیشرفت مناسبی را برای شما بوجود می‌آورد.از آنجایی که این فریمورک با استفاده از تایپ‌اسکریپت نوشته شده، (همان زبانی که انگولار نیز با آن نوشته شده) توسعه‌دهندگان Angular به سرعت می‌توانند آن را یاد گرفته و برای پروژه‌های خود بک-اند بنویسند. بنابراین دیگر نیازی نیست سراغ فریمورک‌های بک-اند دیگر بروند.البته Nest به صورت کامل مستقل نوشته نشده و در آن از ابزارهای کاملی چون Express و Mongoose نیز استفاده می‌شود. Express فریمورک مینیمال نودجی‌اس است که بسیاری از قابلیت‌های مورد نظر برای مدیریت درخواست‌های http را فراهم می‌کند، از طرفی دیگر Mongoose نیز یک ODM بی نظیر برای مدیریت کارهای مربوط به بانک اطلاعاتی برای زبان تایپ‌اسکریپت است. شما می‌توانید از طریق این ابزار با بانک اطلاعاتی MongoDB ارتباط برقرار کنید.پیش‌نیازهابرای شروع کار با Nest.js شما به یکسری پیش‌نیاز نیاز دارید. با در نظر گرفتن این موضوع که شما یک توسعه‌دهنده انگولار هستید، انتظار می‌رود موارد زیر را داشته باشید:نودجی‌اس و NPM: اگر این موارد را در اختیار ندارید می‌توانید به وبسایت رسمی نودجی‌اس رفته و آن را نصب کنید.انتظار می‌رود که آشنایی کاملی با نسخه‌های مختلف اکمااسکریپت و تایپ‌اسکریپت داشته باشید. اگر با انگولار کار کرده باشید مطمئنا این دو مورد را می‌دانید.نصب nestjs/cliابزار Nest CLI یک رابط کاربری مبتنی بر خط فرمان است که شما اجازه می‌دهد تا به سرعت پروژه مورد نظر و فایل‌های مورد نیاز برای پروژه را بسازید. شما می‌توانید از طریق این ابزار کامپوننت‌ها و ماژول‌های مختلف را مدیریت کنید، پروژه را اجرا نمایید و اپلیکیشن نهایی را بسازید. Nest CLI براساس Angular Devkit نوشته شده و از Nodemon برای مشاهده تغییرات فایل‌ها استفاده می‌کند.برای نصب کردن این ابزار کافی‌ست از طریق npm به صورت زیر عمل کنید:npm install -g @nestjs/cliایجاد اولین پروژه Nestبعد از نصب Nest CLI حال بیایید اولین پروژه Nest را پیاده‌سازی کنیم. برای اینکار کافی‌ست دستور زیر را اجرا نماییم:nest new firstnestprojectبعد از اینکار، CLI از شما اطلاعاتی در ارتباط با پروژه را درخواست می‌کند. اطلاعاتی در رابطه با توضیحات، نسخه و نویسنده پروژه؛ البته می‌توانید همه آن‌ها را خالی گذاشته و بعدا تکمیل کنید.ابزار CLI بعد از انجام این کارها، دسته‌ای از فایل‌ها و فولدرها را برای شما ایجاد می‌کند و بعد از آن از شما می‌خواهد تا پکیج منیجری که می‌خواهید در پروژه استفاده کنید را انتخاب نمایید: دو گزینه npm و yarn در اختیار شماست که ما پروژه این آموزش را با npm جلو خواهیم برد.بعد از انجام تمام این کارها، حال می‌توانید به ریشه اصلی پروژه رفته و برای اجرای آن دستور زیر را وارد کنید:npm run start:devحال می‌توانید با رفتن به آدرس http://127.0.0.1:3000 پروژه‌تان را مشاهده کنید. در صفحه بارگذاری شده باید یک رشته Hello World! را مشاهده کنید.ساختار پروژه‌های Nestپروژه‌های Nest یک ساختار فایلی از پیش تعیین شده دارند، این ساختار به نحوی ایجاد شده که بتواند بیشترین تست‌پذیری، مقیاس‌پذیری و پایداری را داشته باشند.پروژه یک دایرکتوری node_modules و یک فایل package.json در خود دارد که برای هر پروژه مبتنی بر node.js ضروری است. همچنین فایل‌های مهم زیر را می‌توانید در این پروژه مشاهده بکنید:فایل tsconfig.json برای پیکربندی تایپ‌اسکریپت.فایل nodemon.json برای پیکربندی nodemon.فایل tslint.json برای لینتینگ تایپ‌اسکریپت.فایل nest-cli.json برای پیکربندی CLI.دایرکتوری src جایی برای قرارگیری کدهای واقعی پروژه.دایرکتوری test جایی برای قرارگیری تست‌ها.ایجاد یک ماژولفریمورک Nest.js از معماری ماژولاری برخوردار است. در Nest.js شما می‌توانید از طریق کلاس‌های Typescript که روی آن‌ها یک دکوراتور @Module() قرار گرفته، ماژول مورد نظرتان را ایجاد کنید. یک شکل رسمی از ساختار ماژولار اپلیکیشن‌های Nest.js به صورت زیر است:هر پروژه Nest حداقل یک ماژول به صورت ماژول ریشه دارد.برای ایجاد یک ماژول در Nest به محیط ترمینال برگشته و دستور زیر را وارد کنید:nest generate module exampleاین کار باعث می‌شود که در آدرس src/example فایل example.module.ts ایجاد شده و فایل src/app.module.ts نیز بروزرسانی شود. این بروزرسانی بعد از هر بار افزودن یک ماژول انجام می‌شود.اگر ما فایل ماژول را باز کنیم محتوای زیر را مشاهده خواهیم کرد:import { Module } from &#39;@nestjs/common&#39;;&#xA;&#xA;@Module({})&#xA;export class ExampleModule {}این یک کلاس ساده تایپ‌اسکریپت است که در زیر یک دکوراتور Module قرار گرفته است.حال اگر ماژول اصلی اپلیکیشن را در src/app.module.ts مشاهده بکنید، می‌توانید ماژول ساخته شده را به صورت یک دستور import ببینید:import { Module } from &#39;@nestjs/common&#39;;&#xA;import { AppController } from &#39;./app.controller&#39;;&#xA;import { AppService } from &#39;./app.service&#39;;&#xA;import { ExampleModule } from &#39;./example/example.module&#39;;&#xA;&#xA;@Module({&#xA;  imports: [ExampleModule],&#xA;  controllers: [AppController],&#xA;  providers: [AppService],&#xA;})&#xA;export class AppModule {}که ExampleModule از آدرس example/example.module اضافه شده است.ایجاد یک کنترلر Nestدر Nest از کنترلرها برای مدیریت درخواست‌های ورودی HTTP و برگشت یک پاسخ استفاده می‌شود. این کنترلرها براساس routeهایی که تعیین می‌کنید اجرا می‌شوند. شما می‌توانید یک کنترلر را با استفاده از یک کلاس تایپ اسکریپت و دکوراتور @Controller ایجاد کنید.برای ساخت یک کنترلر دستور زیر را در محیط ترمینال وارد کنید:nest generate controller example/exampleحال اگر فایل src/example/example/example.controller.ts را باز کنید کدهای زیر را مشاهده خواهید کرد:import { Controller } from &#39;@nestjs/common&#39;;&#xA;&#xA;@Controller(&#39;example&#39;)&#xA;export class ExampleController {}اگر فایل ماژولی را که ساختیم نیز باز کنید: src/example/example.module.ts با خروجی زیر مواجه خواهید شد:import { Module } from &#39;@nestjs/common&#39;;&#xA;import { ExampleController } from &#39;./example/example.controller&#39;;&#xA; &#xA;@Module({&#xA;  imports: [ExampleModule],&#xA;  controllers: [ExampleController]&#xA;})&#xA;export class ExampleModule {}حال بیایید فایل کنترلر را یک بار دیگر باز کنیم و یک مسیر یا route را ایجاد نماییم. ابتدا در فایل example.controller.ts کدهای زیر را اضافه کنید:import { Get, Post, Body } from  &#39;@nestjs/common&#39;;حال متد index() را به صورت زیر اضافه کنید:   @Get()    index() {      return &#34;Example Controller!&#34;    }حال اگر در مرورگر آدرس localhost:3000/example را اجرا کنید، می‌توانید یک صفحه خالی همراه با یک متن Example Controller را مشاهده نمایید.در مثال بالا ما از یک دکوراتور @Get استفاده کردیم، به این معنا که درخواست را به صورت Get قبول کرده و یک پاسخ ارسال می‌کند. حال اگر بخواهیم با POST کار بکنیم کافی‌ست دکوراتور را به صورت زیر بکار ببریم:    @Post(&#39;echo&#39;)&#xA;    echo(@Body() data): any {&#xA;        return data;&#xA;    }  در بالا ما یک مسیر جدید را در example/echo ایجاد کردیم که یک فایل json را برگشت می‌دهد. دکوراتور @Body نیز کمک می‌کند تا بتوانیم جواب مربوطه را استخراج کنیم. در واقع حال ما یک Rest API ساختیم که می‌شود با فرستادن درخواست به localhost:3000/example/echo به داده‌های آن دسترسی داشت:در پایاندر این مقاله ما سعی داشتیم تا فریمورک Nest.js را به توسعه‌دهندگان انگولار معرفی کنیم. ما ابزار Nest CLI را نصب کردیم و یک پروژه بسیار کوچک را ایجاد کردیم. اگر قصد دارید تا اطلاعات بیشتری را راجع به Nest.js بدست بیاورید به سراغ مستندات رسمی آن بروید.</description><category>ساسان پرویز</category><author>ساسان پرویز</author><pubDate>Wed, 06 Aug 2025 13:18:00 +0330</pubDate></item></channel></rss>