<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های مصطفی روغنیان</title><link>https://virgool.ir/feed/@mostafatech</link><description>برنامه نویس و مدیر پروژه های نرم افزاری</description><language>fa</language><pubDate>2026-11-12 12:36:11</pubDate><image><url>https://files.virgool.ir/upload/users/84742/avatar/avatar.png</url><title>مصطفی روغنیان</title><link>https://virgool.ir/@mostafatech</link></image><item><title>راه اندازی یک پروژه نمونه از میکروسرویسها در Asp.net Core و Docker - قسمت دوم</title><link>https://virgool.ir/@mostafatech/راه-اندازی-یک-پروژه-نمونه-از-میکروسرویسها-در-aspnet-core-و-docker-قسمت-دوم-wim2giy5xwzi</link><description>در قسمت قبلی سیستم آموزشگاه را با دو میکروسرویس بصورت مستقل روی داکر راه اندازی کردیم. اکنون میخواهیم سرویسها را پشت gateway قرار دهیم.دروازه یا Gateway چیست؟وقتی پروژه شما دارای بیش از یک سرویس بود و نیاز بود برای تمام سرویسها پورت یا SubDomain مجزا تعریف کنید مدیریت این آدرس ها مشکل خواهد شد. برای رفع این مشکل از یک سرویس واسطه بنام Gateway استفاده میشود که همه درخواستها به این سرویس ارسال شده و از طریق آن به دست سرویس های مقصد میرسند.مزایای استفاده از gateway:عدم نیاز به expose کردن همه سرویسها در محیط بیرونی.مجهز به load balancer برای تقسیم کردن بار بین instance های مختلف از یک سرویس.معایب استفاده از gateway:درصورت وجود load بالا و عدم وجود استراتژی مناسب برای load balancing تبدیل به bottleneck سیستم خواهد شد.درصورت fail شدن آن، همه سرویسها از دسترس خارج خواهند شد و این موضوع با اصل استقلال میکروسرویسها (هر سرویس مستقل از وضعیت سرویسهای حتی وابسته دیگر بتواند به کار خود ادامه دهد) تناقض دارد.تعریف پروژه gatewayپروژه جدیدی با نام MicroservicesOnDocker.ApiGateway از نوع Asp.net Core – Empty ایجاد میکنیم. در این نوع پروژه نیازی به اضافه کردن MVC و هیچ کنترلری به پروژه نمیباشد. پورت اجرایی این پروژه را روی 57800 تنظیم میکنیم.پکیج Ocelot را از Nuget به این پروژه اضافه میکنیم و در کلاس Startup پروژه خطوط زیر را اضافه میکنیم:public void ConfigureServices(IServiceCollection services) {&#xA;    ...&#xA;    services.AddOcelot();&#xA;    ...&#xA;}&#xA;public void Configure(IApplicationBuilder app, IHostingEnvironment env) {&#xA;    ...&#xA;    app.UseOcelot().Wait();&#xA;}حال تنظیمات ocelot را به پروژه اضافه میکنیم. فایلی با نام ocelot.json را به پروژه اضافه میکنیم و محتویات زیر را در آن وارد میکنیم:{&#xA;    &#34;ReRoutes&#34;: [{&#xA;        &#34;DownstreamPathTemplate&#34;: &#34;/{everything}&#34;,&#xA;        &#34;DownstreamScheme&#34;: &#34;http&#34;,&#xA;        &#34;DownstreamHostAndPorts&#34;: [{&#xA;            &#34;Host&#34;: &#34;school_service&#34;,&#xA;            &#34;Port&#34;: 80&#xA;        }],&#xA;        &#34;UpstreamPathTemplate&#34;: &#34;/school/{everything}&#34;,&#xA;        &#34;UpstreamHttpMethod&#34;: [ &#34;Get&#34;, &#34;Post&#34; ]&#xA;    }, {&#xA;        &#34;DownstreamPathTemplate&#34;: &#34;/{everything}&#34;,&#xA;        &#34;DownstreamScheme&#34;: &#34;http&#34;,&#xA;        &#34;DownstreamHostAndPorts&#34;: [{&#xA;            &#34;Host&#34;: &#34;income_service&#34;,&#xA;            &#34;Port&#34;: 80&#xA;        }],&#xA;        &#34;UpstreamPathTemplate&#34;: &#34;/income/{everything}&#34;,&#xA;        &#34;UpstreamHttpMethod&#34;: [ &#34;Get&#34;, &#34;Post&#34; ]&#xA;    }],&#xA;    &#34;GlobalConfiguration&#34;: {&#xA;        &#34;BaseUrl&#34;: &#34;http://localhost:57800&#34;&#xA;    }&#xA;}همونطور که مشاهده میکنید در قسمت ReRoutes آدرسهای هر دو سرویس ما در محیط داکر تعریف شده اند. از آنجایی که این re-routing ها فقط در مد production کار میکنند برای مد development فایل دیگری با نام ocelot.Development.json با همان محتویات بالا ولی با تفاوت های زیر اضافه میکنیم:برای سرویس اول:&#34;Host&#34;: &#34;school_service&#34; =&gt; &#34;Host&#34;: &#34;localhost&#34;,&#xA;&#34;Port&#34;: 80 =&gt; &#34;Port&#34;: 57801برای سرویس دوم:&#34;Host&#34;: &#34;income _service&#34; =&gt; &#34;Host&#34;: &#34;localhost&#34;,&#xA;&#34;Port&#34;: 80 =&gt; &#34;Port&#34;: 57802حال بررسی کنیم که در تنظیمات بالا چه چیزی گفته شده:{&#xA;    &#34;DownstreamPathTemplate&#34;: &#34;/{everything}&#34;,&#xA;    &#34;DownstreamScheme&#34;: &#34;http&#34;,&#xA;    &#34;DownstreamHostAndPorts&#34;: [{&#xA;        &#34;Host&#34;: &#34;school_service&#34;,&#xA;        &#34;Port&#34;: 80&#xA;    }],&#xA;    &#34;UpstreamPathTemplate&#34;: &#34;/school/{everything}&#34;,&#xA;    &#34;UpstreamHttpMethod&#34;: [ &#34;Get&#34;, &#34;Post&#34; ]&#xA;},معنی آبجکت بالا این است که به سرویس gateway هر درخواستی با فرمت UpstreamPathTemplate آمد تبدیل به درخواستی با فرمت DownstreamPathTemplate به هاست و پورتی که در DownstreamHostAndPorts تعریف شده ارسال شود. متدهایی که در UpstreamHttpMethod تعریف شده متدهای مجاز هستند و متدهای دیگر re-route نخواهند شد. و نکته دیگر اینکه به این دلیل ویژگی DownstreamHostAndPorts بصورت آرایه تعریف شده که instance های دیگری از سرویس مورد نظر قابل تعریف باشند و روی این لیست از instance ها load balancing انجام میشود.آخرین کار معرفی فایلهای تنظیمات ocelot به برنامه dotnet core میباشد که باید در کلاس Program انجام شود:public staticIWebHostBuilder CreateWebHostBuilder(string[] args) =&gt;&#xA;    WebHost.CreateDefaultBuilder(args)&#xA;        .ConfigureAppConfiguration((hostingContext, config) =&gt; {&#xA;            config&#xA;                .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)&#xA;                .AddJsonFile(&#34;appsettings.json&#34;, true, true)&#xA;                .AddJsonFile($&#34;appsettings{hostingContext.HostingEnvironment.EnvironmentName}.json&#34;, true, true)&#xA;                .AddJsonFile(&#34;ocelot.json&#34;)&#xA;                .AddJsonFile($&#34;ocelot.{hostingContext.HostingEnvironment.EnvironmentName}.json&#34;, true, true)&#xA;                .AddEnvironmentVariables();&#xA;        })&#xA;        .UseStartup&lt;Startup&gt;();تنظیمات gateway انجام شده و میتوانید در محیط توسعه خود آن را اجرا کنید. نحوه اجراش هم به این صورت است که باید بصورت Multiple startup projects سیستم رو اجرا کنید. مطابق تصویر زیر:پروژه را با تنظیمات پیشفرض در پوشه publish\api_gateway_\.. پابلیش کنید.برای داکر نیاز به تغییراتی در فایل docker-compose.yml داریم:version: &#39;3&#39;&#xA;services:&#xA;    api_gateway:&#xA;        image: mcr.microsoft.com/dotnet/core/aspnet:2.2&#xA;        volumes:&#xA;            - ./api_gateway:/app&#xA;        working_dir: /app&#xA;        command: dotnet &#34;MicroservicesOnDocker.ApiGateway.dll&#34;&#xA;        ports:&#xA;            - 5000:80&#xA;        depends_on:&#xA;            - school_service&#xA;            - income_service&#xA;    school_service:&#xA;        image: mcr.microsoft.com/dotnet/core/aspnet:2.2&#xA;        volumes:&#xA;            - ./school_service:/app&#xA;        working_dir: /app&#xA;        command: dotnet &#34;MicroservicesOnDocker.School.Api.dll&#34;&#xA;    income_service:&#xA;        image: mcr.microsoft.com/dotnet/core/aspnet:2.2&#xA;        volumes:&#xA;            - ./income_service:/app&#xA;        working_dir: /app&#xA;        command: dotnet &#34;MicroservicesOnDocker.Income.Api.dll&#34;تغییراتی که در فایل docker-compose.yml ایجاد شده:سرویسی برای gateway اضافه شده که از طریق پورت 5000 قابل دسترسی است.برای سرویسهای school_service و income_service مقدار ports حذف شده. به این دلیل که دیگر نیازی نداریم به این سرویسها بصورت مستقیم دسترسی داشته باشیم.مقدار depends_on مشخص میکند که هر سرویس به چه سرویسهای دیگری وابستگی دارد و تضمین میکند این سرویس حتما درصورت وجود سرویسهای ذکر شده اجرا شود.با استفاده از دستور docker-compose up --build سیستم را اجرا کنید. حال میتوانیم سرویسهارو از طریق gateway فراخوانی کنیم:Request =&gt; [GET] http://localhost:5000/school/api/students&#xA;Request =&gt; [GET] http://localhost:5000/income/api/paymentsو سیستم ما روی داکر جواب مناسب را به این درخواست ها ارسال خواهد کرد. همونطور که ملاحظه میکنید اتفاقی که افتاد این بود که دو میکروسرویس روی یک base address و فقط با یک پیشوند قابل دسترس شدند. برای ساده تر کردن آدرس ها میتونید پیشوند /api را از route کنترلرها حذف کنید.خسته نباشید!در این قسمت توانستیم یک gateway راه اندازی کنیم و میکروسرویسهای خود را پشت آن قرار دهیم تا نهایتا بتوانیم تمام سرویسها را بطور مثال روی یک subdomain به فرمت http://api.mydomain.com قرار دهیم. در قسمت بعدی از اجرای سرویسها روی داکر نه تنها برای مد production بلکه در زمان توسعه استفاده میکنیم و با مزیت های این روش آشنا میشیم.</description><category>مصطفی روغنیان</category><author>مصطفی روغنیان</author><pubDate>Fri, 28 Feb 2020 00:44:28 +0330</pubDate></item><item><title>راه اندازی یک پروژه نمونه از میکروسرویسها در Asp.net Core و Docker - قسمت اول</title><link>https://virgool.ir/@mostafatech/راه-اندازی-یک-پروژه-نمونه-از-میکروسرویسها-در-aspnet-core-و-docker-قسمت-اول-gfjqiqnazjxe</link><description>در این مقاله سعی داریم یک نرم افزار بسیار ساده بر پایه معماری میکروسرویس با Asp.net Core و روی بستر docker آماده و راه اندازی کنیم. سطح مطالب این مقاله مناسب توسعه دهندگان بوده و هدف این است که محصول تولیدی آنها برای deploy در محیطهای container ای مناسب باشد.مقدمهگاهی با پروژه هایی سروکار داریم که از قسمت هایی با مرزهای حدودا مشخص تشکیل شده است. این مرزبندی ها را اغلب اوقات میتوان در فرایندهای سازمان مشتری مشاهده کرد. به بخش های مختلفی که توسط این مرزبندی ها تشکیل میشوند اصطلاحا Bounded Context یا BC میگویند. در معماری میکروسرویس معمولا به ازای یک یا چند BC (بر اساس اندازه یا اهمیت) یک میکروسرویس ایجاد میشود.در این مقاله میخواهیم سیستم یک آموزشگاه را تعریف کرده و راه حلی (Solution) برای آن ایجاد کنیم. BC اصلی در این سیستم آموزشگاه (School) و BC دیگر مربوط به مالی یا درآمد (Income) میباشد. برای هرکدام از BC ها میکروسرویسی به همان نام وجود داشته و هر دو میکروسرویس به اطلاعات یکدیگر وابستگی دارند. در ابتدا این دو میکروسرویس را بصورت مستقل راه اندازی میکنیم و در مرحله بعدی میکروسرویسها را پشت یک دروازه (gateway) قرار میدهیم که توسط تنها یک آدرس قابل دسترس شوند.پیشنیاز هابرای شروع فرض بر این است که شما با برنامه نویسی در Asp.net Core، زبان C# و مفاهیم اولیه داکر آشنایی داشته و داکر را روی سیستم عامل خود یا یک ماشین دیگر نصب کرده باشید. درصورتی که با موارد یاد شده آشنایی ندارید این مقاله مناسب شما نخواهد بود و درصورتی که با مراحل نصب داکر آشنایی ندارید میتوانید ابتدا با جستجو در اینترنت نحوه نصب آن را فراگرفته و نصب کنید.کدهای مقالهتمامی کدهای نمونه این مقاله در آدرس زیر قرار دارد:https://github.com/MostafaTech/MicroservicesOnDocker/tree/part1_exposed-servicesبرنچ part1_exposed-services شامل کدهای قسمت اول مقاله و برنچ master شامل آخرین نسخه و کامل شده کدها در انتهای مقاله میباشد.مخزن کد در گیتهاب شامل یک پروژه UI با VueJS نیز هست که درخواست ها به سرویسها در درون اون ارسال میشن و نیازی به ارسال دستی درخواستها نیست.کدها و تنظیمات بصورتی نوشته شدن که بدون نیاز به هیچگونه تغییر، در مدهای development و production کار کنند.تعریف ساختار پروژه در ویژوال استودیوسیستم ما Solution ای با نام MicroservicesOnDocker و حاوی پروژه های زیر است:پروژه MicroservicesOnDocker از نوع Class Library برای تعریف domainپروژه MicroservicesOnDocker.Infrastructure از نوع Class Library برای لایه Infrastructure جهت تعریف ابزارهایی که بصورت مشترک در همه پروژه ها استفاده میکنیمپروژه MicroservicesOnDocker.School.Api از نوع Asp.net Core - Api برای میکروسرویس School تنظیم شده روی پورت 57801پروژه MicroservicesOnDocker.Income.Api از نوع Asp.net Core - Api برای میکروسرویس Income تنظیم شده روی پورت 57802در همین ابتدا CORS را در سرویسهای خود فعال کنید که درصورتی که از ajax برای ارسال درخواستها استفاده میکنید دچار مشکل نشوید. در کلاس Startup هر دو پروژه api:public void ConfigureServices(IServiceCollection services) {&#xA;    ...&#xA;    services.AddCors();&#xA;    ...&#xA;}public void Configure(IApplicationBuilder app, IHostingEnvironment env) {&#xA;    ...&#xA;    app.UseCors(c =&gt; c.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().Build());&#xA;    ...&#xA;}در پروژه MicroservicesOnDocker.School.Api یک api برای خواندن لیست دانشجویان قرار دارد که بصورت زیر عمل میکند:Request =&gt; [GET] http://localhost:57801/api/students&#xA;Response =&gt; [{&#34;id&#34;:1,&#34;name&#34;:&#34;Johnny Depp&#34;},{&#34;id&#34;:2,&#34;name&#34;:&#34;Brad Pitt&#34;},{&#34;id&#34;:3,&#34;name&#34;:&#34;Leonardo DiCaprio&#34;},{&#34;id&#34;:4,&#34;name&#34;:&#34;Michael Jackson&#34;},{&#34;id&#34;:5,&#34;name&#34;:&#34;Freddy Mercury&#34;}]و در پروژه MicroservicesOnDocker.Income.Api یک api برای خواندن لیست پرداختهای دانشجویان قرار دارد که بصورت زیر عمل میکند:Request: [GET] http://localhost:57802/api/payments&#xA;Response =&gt; [{&#34;studentId&#34;:1,&#34;studentName&#34;:&#34;Johnny Depp&#34;,&#34;courseId&#34;:1,&#34;courseName&#34;:&#34;Acting Course&#34;,&#34;payAmount&#34;:2000.0},{&#34;studentId&#34;:2,&#34;studentName&#34;:&#34;Brad Pitt&#34;,&#34;courseId&#34;:1,&#34;courseName&#34;:&#34;Acting Course&#34;,&#34;payAmount&#34;:2000.0},{&#34;studentId&#34;:4,&#34;studentName&#34;:&#34;Michael Jackson&#34;,&#34;courseId&#34;:2,&#34;courseName&#34;:&#34;Music Course&#34;,&#34;payAmount&#34;:3000.0}]تا اینجا میکروسرویسهای ما بصورت مستقل و کاملا جداگانه عمل میکنند. برای اینکه بتونیم این سرویسهارو روی داکر به اجرا در بیاریم از docker-compose استفاده میکنیم. به این صورت که در شاخه اصلی پروژه یک فایل با نام docker-compose.yml با محتویات زیر اضافه میکنیم:version: &#39;3&#39;&#xA;services:&#xA;    school_service:&#xA;        image: mcr.microsoft.com/dotnet/core/aspnet:2.2&#xA;        volumes:&#xA;            - ./school_service:/app&#xA;        working_dir: /app&#xA;        command: dotnet &#34;MicroservicesOnDocker.School.Api.dll&#34;&#xA;        ports:&#xA;            - 5001:80&#xA;    income_service:&#xA;        image: mcr.microsoft.com/dotnet/core/aspnet:2.2&#xA;        volumes:&#xA;            - ./income_service:/app&#xA;        working_dir: /app&#xA;        command: dotnet &#34;MicroservicesOnDocker.Income.Api.dll&#34;&#xA;        ports:&#xA;            - 5001:80نکاتی درباره محتویات فایل بالا:دو سرویس school_service و income_service تعریف شده که در هردو، فایلهای پابلیش شده پروژه ها در پوشه app کانتینر قرار میگیرد که فایل dll اصلی پروژه با دستور dotnet اجرا میشود.ایمیج mcr.microsoft.com/dotnet/core/aspnet:2.2 برای اجرای هر دو سرویس استفاده شده که شامل یک ماشین لینوکس که روی آن dotnet core runtime نصب شده است.برای سرویس school_service پورت 5001 و برای income_Service پورت 5002 درنظر گرفته شده. به این صورت که داکر پورت 80 که asp.net برای گوش دادن به درخواستهای سرویس روی container باز کرده رو به 5001 و 5002 در ماشینی که داکر روی اون اجرا هست تبدیل میکنه و در واقع شما با ارسال درخواست به ماشین حاوی داکر روی پورت 5001 دارید به پورت 80 container ای که حاوی سرویس school_service هست درخواست ارسال میکنید. امیدوارم که شفاف گفته باشم.دستور working_dir باعث میشه که نیازی نباشه در آدرس دهی ها، آدرس پوشه حاوی فایلهای پروژه رو همیشه وارد کنید که در اینجا قبل از نام dll سرویس هست ولی در بخش بعدی استفاده بهتری هم داره که بعدا اشاره میکنم.یک پوشه با نام publish_ ایجاد کنید و از دو پروژه api خود پابلیش بگیرید و در مسیرهای زیر فایلهای پابلیش شده رو قرار بدید:project MicroservicesOnDocker.School.Api =&gt; ..\_publish\school_service&#xA;project MicroservicesOnDocker.Income.Api =&gt; ..\_publish\income_serviceمیتونید ویژوال استودیو رو طوری تنظیم کنید که موقع پابلیش در مسیرهای بالا فایلهارو پابلیش کنه. ضمنا تنظیمات پابلیش رو هم بصورت پیشفرض نگه دارید که بصورت زیر هستن:Deployment Mode: Framework-Dependent&#xA;Target Runtime: Portableفایل docker-compose.yml را در شاخه اصلی پوشه publish_ کپی کنید و یک terminal یا cmd در پوشه مذکور باز کرده و با دستور زیر پروژه ها را راه اندازی کنید:~ docker-compose upنکته: اگر سیستم عامل شما ویندوز هست همین دستور اکتفا میکنه ولی اگر در لینوکس هستید کافیه قبل از دستور فوق sudo را نیز وارد کنید. اگر شما هم مثل من سیستم عامل ویندوز دارید ولی داکر رو روی ماشین مجازی لینوکسی نصب کردید میتونید با استفاده از پروتکل samba یک پوشه share ویندوزی روی سیستم عامل لینوکس خود راه بندازید که پابلیش هایی که میگیرید رو روی ماشین مجازی خود کپی کنید و در اون ماشین دستورات داکر رو اجرا کنید. فقط قبلش یادتون باشه ip ماشین رو بدونید که در browser بتونید سرویسهارو باز کنید.هر دو سرویس با موفقیت اجرا شدندحالا میتونید یک browser باز کرده و درخواست های زیر رو ارسال کنید:[GET] http://localhost:5001/api/students&#xA;[GET] http://localhost:5002/api/paymentsو پروژه شما روی داکر جواب مناسب رو ارسال خواهد کرد. برای خاموش کردن سرویسها میتونید از Ctrl+C استفاده کنید.ارتباط سرویسها با یکدیگریکی از مزیت های داکر این است که میتواند بین چند container یک شبکه مجازی ایجاد کرده که مجهز به DNS اختصاصی میباشد. در docker-compose تنظیمات این شبکه مجازی بطور اتوماتیک انجام میشود و در حالات ساده نیاز به هیچ تنظیم اضافه ای نداریم. روش کار به این صورت است که تمام سرویسهایی که در docker-compose تعریف میشوند مشابه ماشینهایی درون یک شبکه ایزوله قرار میگیرند که توسط نام هر سرویس توسط سرویسهای دیگر قابل دسترس میباشند. ارتباطات درونی کاربردهای زیادی از جمله ارتباط با سرویس database، سرویس cache، سرویس messaging و ... دارند. با استفاده از این امکان میخواهیم بین دو میکروسرویس خودمان ارتباطی ایجاد نماییم.ابتدا به پروژه MicroservicesOnDocker.Infrastructure پکیج نوگت RestSharp را اضافه میکنیم. پکیج RestSharp این امکان را به ما میدهد که برای یک آدرس خاص درخواست http ارسال کنیم و جواب آن را بصورت serialize شده تحویل بگیریم. سپس کلاس زیر را به آن پروژه اضافه میکنیم:public class ServiceHelpers {&#xA;#if DEBUG&#xA;    public const string SchoolService = &#34;localhost:57801&#34;&#xA;    public const string IncomeService = &#34;localhost:57802&#34;&#xA;#else&#xA;    public const string SchoolService = &#34;school_service&#34;&#xA;    public const string IncomeService = &#34;income_service&#34;&#xA;#endif&#xA;    public static async Task&lt;T&gt; GetServiceData&lt;T&gt;(string service, string action) {&#xA;        var restClient = new RestSharp.RestClient($&#34;http://{service}/api/&#34;);&#xA;        var restRequest = new RestSharp.RestRequest(action, RestSharp.Method.GET, RestSharp.DataFormat.Json);&#xA;        var restResponse = await restClient.ExecuteAsync&lt;T&gt;(restRequest);&#xA;        if (restResponse.IsSuccessful) {&#xA;            return restResponse.Data;&#xA;        }&#xA;        return default(T);&#xA;    }&#xA;}در ابتدا دو constant برای هر سرویس تعریف کردیم که در حالت های Debug (یعنی موقعی که در ویژوال استودیو کلید F5 را میزنیم) و Release (یعنی وقتی پابلیش میگیریم) مقادیر متفاوت خواهند داشت. در حالت دیباگ پورت هایی که برای سرویسهایمان در زمان توسعه اختصاص داده ایم در ثابتها قرار خواهند گرفت و در حالت release به نامی که برای هر سرویس در docker-compose تعیین کرده ایم و پورت 80 آنها در ثابتها قرار میگیرند. اگر به متنی که در docker-compose نوشته بودیم توجه کنید میبینید که هر سرویس درواقع روی یک کانتینر با نام آن سرویس و پورت 80 بالا می آید و ما برای دسترسی بیرونی پورت 80 هر کانتینر را به پورت های 5001 و 5002 در ماشینی که داکر روی آن اجرا شده تبدیل کرده ایم. به این عمل expose کردن سرویس میگویند. ولی وقتی که ما از درون سرویسهای داکر قصد ارتباط با دیگر سرویسها را داشته باشیم به پورتهای بیرونی نیازی نداریم و میتوانیم با کانتینری که سرویس مورد نظر را اجرا کرده بصورت مستقیم ارتباط برقرار کنیم. حتی اگر آن سرویس expose نشده باشد.حال میخواهیم سرویس school را به سرویس income متصل کنیم. برای همین api دریافت اطلاعات دانشجویان را به شکل زیر تغییر میدهیم:[HttpGet]&#xA;public asyncTask&lt;ActionResult&lt;IEnumerable&lt;Dtos.StudentDto&gt;&gt;&gt; Get() {&#xA;    var students = _ds.GetStudents();&#xA;    var payments = awaitInfrastructure.ServiceHelpers.GetServiceData&lt;List&lt;Dtos.StudentPaymentDto&gt;&gt;(Infrastructure.ServiceHelpers.IncomeService, &#34;payments&#34;);&#xA;    return students.Select(x =&gt; new Dtos.StudentDto {&#xA;        StudentId = x.Id,&#xA;        StudentName = x.Name,&#xA;        hasPaid = payments.Any(y =&gt; y.StudentId == x.Id)&#xA;    }).ToList();&#xA;}در خط زیر ما از طریق http به یک سرویس داخلی داکر متصل شدیم:var payments = awaitInfrastructure.ServiceHelpers.GetServiceData&lt;List&lt;Dtos.StudentPaymentDto&gt;&gt;(Infrastructure.ServiceHelpers.IncomeService, &#34;payments&#34;);نکته: روشی که در این مثال برای پر کردن لیست دانشجویان استفاده شده از نظر پرفورمنس کاملا اشتباهه و در برنامه واقعی از این روش استفاده نکنید!الان میتونیم دوباره از سرویسها پابلیش بگیریم و پروژه رو روی داکر اجرا کنیم. برای اجرا و ساختن مجدد image ها از دستور زیر استفاده کنید:~ docker-compose up --buildنکته: درصورتی که میخاهید هنگام اجرای پروژه از ترمینال همچنان استفاده کنید در جلوی دستور بالا از سوییچ d- و برای خاموش کردن پروژه از docker-compose stop استفاده کنید.تست api دانشجویان:Request =&gt; [GET] http://localhost:5001/api/students&#xA;Response =&gt; [{&#34;id&#34;:1,&#34;name&#34;:&#34;Johnny Depp&#34;,&#34;hasPaid&#34;:true},{&#34;id&#34;:2,&#34;name&#34;:&#34;Brad Pitt&#34;,&#34;hasPaid&#34;:true},{&#34;id&#34;:3,&#34;name&#34;:&#34;Leonardo DiCaprio&#34;,&#34;hasPaid&#34;:false},{&#34;id&#34;:4,&#34;name&#34;:&#34;Michael Jackson&#34;,&#34;hasPaid&#34;:true},{&#34;id&#34;:5,&#34;name&#34;:&#34;Freddy Mercury&#34;,&#34;hasPaid&#34;:false}]خسته نباشید!در این قسمت از مقاله یاد گرفتیم که مجموعه ای از سرویسها که با asp.net core در محیط ویژوال استودیو را روی داکر اجرا کنیم و ارتباطی بین آنها برقرار کنیم. در قسمت بعدی میخواهیم تمام میکروسرویسها رو پشت یک gateway قرار دهیم و از expose کردن تک تک سرویسها جلوگیری کنیم.</description><category>مصطفی روغنیان</category><author>مصطفی روغنیان</author><pubDate>Thu, 27 Feb 2020 16:04:30 +0330</pubDate></item></channel></rss>