ASP.NET الأساسية في الخدمات الموثوقة لنسيج خدمة Azure
ASP.NET Core هو إطار مفتوح المصدر ومتعدد المنصات. صُمم هذا الإطار لإنشاء تطبيقات قائمة على السحابة ومتصلة بالإنترنت، مثل تطبيقات الويب وتطبيقات إنترنت الأشياء والنهايات الخلفية للجوال.
هذه المقالة هي دليل متعمق لاستضافة ASP.NET الخدمات الأساسية في Service Fabric Reliable Services باستخدام Microsoft.ServiceFabric.AspNetCore. مجموعة من حزم NuGet.
للحصول على برنامج تعليمي تمهيدي حول ASP.NET Core في Service Fabric وإرشادات حول إعداد بيئة التطوير الخاصة بك، راجع البرنامج التعليمي: إنشاء تطبيق ونشره باستخدام خدمة واجهة برمجة تطبيقات الويب الأساسية ASP.NET وخدمة خلفية ذات حالة.
تفترض بقية هذه المقالة أنك تعرف ASP.NET Core فعلاً. إذا لم يكن الأمر كما هو، فالرجاء قراءة أساسيات ASP.NET Core.
ASP.NET الأساسية في بيئة نسيج الخدمة
يمكن تشغيل كل من تطبيقات ASP.NET Core ونسيج الخدمة على .NET Core أو .NET Framework الكامل. يمكنك استخدام ASP.NET Core بطريقتين مختلفتين في نسيج الخدمة:
- مستضاف كضيف قابل للتنفيذ. تُستخدم هذه الطريقة بشكل أساسي لتشغيل تطبيقات ASP.NET Core الموجودة على نسيج الخدمة دون أي تغييرات في التعليمات البرمجية.
- تشغيل داخل خدمة موثوق بها. تتيح هذه الطريقة تكاملاً أفضل مع وقت تشغيل نسيج الخدمة وتسمح بخدمات ASP.NET الأساسية الرائعة.
تُبين بقية هذه المقالة كيفية استخدام ASP.NET Core داخل خدمة موثوقة، من خلال مكونات تكامل Core ASP.NET التي تُشحن مع Service Fabric SDK.
استضافة خدمة نسيج الخدمة
في Service Fabric، يتم تشغيل مثيل واحد أو أكثر و/أو نسخ متماثلة من الخدمة في عملية مضيف خدمة: ملف قابل للتنفيذ يقوم بتشغيل التعليمات البرمجية للخدمة. بصفتك مؤلف خدمة، تمتلك عملية مضيف الخدمة، ويقوم نسيج الخدمة بتنشيطها ومراقبتها نيابة عنك.
يقترن ASP.NET التقليدي (حتى MVC 5) بإحكام ب IIS من خلال System.Web.dll. يوفر ASP.NET Core فصلاً بين خادم الويب وتطبيق الويب خاصتك. يسمح هذا الفصل لتطبيقات الويب بأن تكون محمولة بين خوادم الويب المختلفة. كما يسمح باستضافة خوادم الويب ذاتيا. هذا يعني أنه يمكنك بدء تشغيل خادم ويب في العملية خاصتك، بدلاً من العملية التي يملكها برنامج خادم ويب مخصص، مثل IIS.
للجمع بين خدمة Service Fabric ASP.NET، إما كضيف قابل للتنفيذ أو في خدمة موثوقة، يجب أن تكون قادرًا على بدء ASP.NET داخل عملية مضيف الخدمة. تتيح لك ASP.NET Core الاستضافة الذاتية للقيام بذلك.
Hosting ASP.NET الأساسية في خدمة موثوقة
عادة ما تقوم تطبيقات ASP.NET Core المستضافة ذاتيا بإنشاء WebHost في نقطة إدخال التطبيق، مثل static void Main()
الأسلوب في Program.cs
. في هذه الحالة، ترتبط دورة حياة WebHost بدورة حياة العملية.
لكن نقطة إدخال التطبيق ليست المكان المناسب لإنشاء WebHost في خدمة موثوقة. وذلك لأن نقطة إدخال التطبيق تُستخدم فقط لتسجيل نوع خدمة مع وقت تشغيل نسيج الخدمة، بحيث يمكنها إنشاء مثيلات من نوع الخدمة هذه. يجب إنشاء WebHost في خدمة موثوقة نفسها. ضمن عملية مضيف الخدمة، يمكن أن تمر مثيلات الخدمة و/أو النسخ المتماثلة بدورات حياة متعددة.
يتم تمثيل مثيل خدمة موثوق بها بواسطة فئة الخدمة المشتقة من StatelessService
أو StatefulService
. يتم تضمين مكدس الاتصال لخدمة في ICommunicationListener
تنفيذ في فئة الخدمة الخاصة بك. Microsoft.ServiceFabric.AspNetCore.*
تحتوي حزم NuGet على تطبيقات ICommunicationListener
لبدء وإدارة ASP.NET Core WebHost إما ل Kestrel أو HTTP.sys في خدمة موثوق بها.
ASP.NET Core ICommunicationListeners
تطبيقات ICommunicationListener
Kestrel و HTTP.sys في Microsoft.ServiceFabric.AspNetCore.*
حزم NuGet لها أنماط استخدام مماثلة. لكنهم يقومون بإجراءات مختلفة قليلاً خاصة بكل خادم ويب.
يوفر كل من مستمعي الاتصال منشئًا يأخذ الوسيطات التالية:
ServiceContext serviceContext
: هذا هو الكائن الذيServiceContext
يحتوي على معلومات حول الخدمة قيد التشغيل.string endpointName
: هذا هو اسمEndpoint
التكوين في ServiceManifest.xml. إنه في المقام الأول المكان الذي يختلف فيه اثنان من مستمعو التواصل. يتطلب HTTP.sys تكويناEndpoint
، بينما لا يتطلب Kestrel ذلك.Func<string, AspNetCoreCommunicationListener, IWebHost> build
: هذا lambda الذي تقوم بتنفيذه، حيث تقوم بإنشاء وإرجاعIWebHost
. يسمح لك بتكوينIWebHost
الطريقة التي تفعلها عادة في تطبيق ASP.NET Core. يوفر lambda عنوان URL الذي تم إنشاؤه لك، اعتمادا على خيارات تكامل Service Fabric التي تستخدمها والتكوين الذيEndpoint
توفره. يمكنك بعد ذلك تعديل عنوان URL هذا أو استخدامه لبدء تشغيل خادم الويب.
تكامل نسيج الخدمة الوسيطة
Microsoft.ServiceFabric.AspNetCore
تتضمن حزمة NuGet أسلوب الامتداد UseServiceFabricIntegration
على IWebHostBuilder
الذي يضيف البرنامج الوسيط المدرك ل Service Fabric. يقوم هذا البرنامج الوسيط بتكوين Kestrel أو HTTP.sys ICommunicationListener
لتسجيل عنوان URL خدمة فريد مع خدمة تسمية Service Fabric. ثم يتحقق من صحة طلبات العملاء لضمان اتصال العملاء بالخدمة الصحيحة.
هذه الخطوة ضرورية لمنع العملاء من الاتصال عن طريق الخطأ بالخدمة الخطأ. ويرجع ذلك إلى أنه في بيئة مضيف مشترك مثل نسيج الخدمة، يمكن تشغيل تطبيقات ويب متعددة على نفس الجهاز الفعلي أو الظاهري ولكنها لا تستخدم أسماء مضيفين فريدة. يُوصف هذا السيناريو بمزيد من التفصيل في القسم التالي.
حالة من الهوية الخطأ
تستمع النسخ المتماثلة للخدمة، بغض النظر عن البروتوكول، إلى مجموعة IP:port فريدة. بمجرد أن تبدأ نسخة متماثلة من الخدمة في الاستماع إلى نقطة نهاية IP:port، فإنها تُبلغ عن عنوان نقطة النهاية هذا إلى خدمة تسمية نسيج الخدمة. هناك، يمكن للعملاء أو الخدمات الأخرى اكتشافه. إذا كانت الخدمات تستخدم منافذ تطبيق معينة ديناميكيًا، فقد تستخدم نسخة متماثلة من الخدمة نفس نقطة نهاية IP:port لخدمة أخرى كانت موجودة مسبقًا على نفس الجهاز الفعلي أو الظاهري. يمكن أن يتسبب ذلك في اتصال العميل بالخدمة الخطأ عن طريق الخطأ. يمكن أن ينتج هذا السيناريو في حالة حدوث تسلسل الأحداث التالي:
- تستمع الخدمة A على 10.0.0.1:30000 عبر HTTP.
- يحل العميل الخدمة A ويحصل على العنوان 10.0.0.1:30000.
- تنتقل الخدمة A إلى عقدة مختلفة.
- تُوضع الخدمة B على 10.0.0.1 وتستخدم بالصدفة نفس المنفذ 30000.
- يحاول العميل الاتصال بالخدمة A باستخدام العنوان المخزن مؤقتًا 10.0.0.1:30000.
- يتم الآن توصيل العميل بنجاح بالخدمة B، دون إدراك أنه متصل بالخدمة الخطأ.
هذا يمكن أن يسبب أخطاء في أوقات عشوائية يمكن أن يكون من الصعب تشخيصها.
استخدام عناوين URL الفريدة للخدمة
لمنع هذه الأخطاء، يمكن للخدمات نشر نقطة نهاية إلى "خدمة التسمية" باستخدام معرف فريد، ثم التحقق من صحة هذا المعرف الفريد في أثناء طلبات العميل. هذا عمل تعاوني بين الخدمات في بيئة موثوقة غير معادية للمستأجر. لا يوفر مصادقة خدمة آمنة في بيئة مستأجرة معادية.
في بيئة موثوق بها، يقوم البرنامج الوسيط الذي تمت إضافته بواسطة UseServiceFabricIntegration
الأسلوب تلقائيا بإلحاق معرف فريد بالعنوان المنشور في خدمة التسمية. ويتحقق من صحة هذا المعرف في كل طلب. إذا لم يتطابق المعرف، فسيقوم البرنامج الوسيط على الفور بإرجاع استجابة HTTP 410 Gone.
يجب أن تستفيد الخدمات التي تستخدم منفذًا معينًا ديناميكيًا من هذه البرامج الوسيطة.
لا تواجه الخدمات التي تستخدم منفذًا فريدًا ثابتًا هذه المشكلة في بيئة تعاونية. عادةً ما يتم استخدام منفذ فريد ثابت للخدمات التي تواجه خارجيًا والتي تحتاج إلى منفذ معروف لتطبيقات العميل للاتصال بها. على سبيل المثال، ستستخدم معظم تطبيقات الويب التي تواجه الإنترنت المنفذ 80 أو 443 لاتصالات مستعرض الويب. في هذه الحالة، لا ينبغي تمكين المعرف الفريد.
يُبين الرسم التخطيطي التالي تدفق الطلب مع تمكين البرامج الوسيطة:
تستخدم كل من تطبيقات Kestrel و HTTP.sys ICommunicationListener
هذه الآلية بنفس الطريقة بالضبط. على الرغم من أن HTTP.sys يمكن أن يميز الطلبات داخليا استنادا إلى مسارات URL الفريدة باستخدام ميزة مشاركة منفذ HTTP.sys الأساسية، إلا أن تنفيذ HTTP.sys ICommunicationListener
لا يستخدم هذه الوظيفة. هذا لأنه ينتج عنه رموز حالة خطأ HTTP 503 وHTTP 404 في السيناريو الموضح سابقًا. وهذا بدوره يجعل من الصعب على العملاء تحديد الهدف من الخطأ، حيث يتم استخدام HTTP 503 وHTTP 404 بشكل شائع للإشارة إلى الأخطاء الأخرى.
وبالتالي، فإن كلا من Kestrel وتطبيقات HTTP.sys ICommunicationListener
تتوحد على البرامج الوسيطة التي يوفرها أسلوب الامتداد UseServiceFabricIntegration
. لذلك، يحتاج العملاء فقط إلى تنفيذ إجراء إعادة حل نقطة نهاية الخدمة على استجابات HTTP 410.
HTTP.sys في خدمات موثوقة
يمكنك استخدام HTTP.sys في خدمات موثوقة عن طريق استيراد حزمة Microsoft.ServiceFabric.AspNetCore.HttpSys NuGet. تحتوي هذه الحزمة على HttpSysCommunicationListener
، وتنفيذ .ICommunicationListener
HttpSysCommunicationListener
يسمح لك بإنشاء ASP.NET Core WebHost داخل خدمة موثوق بها باستخدام HTTP.sys كخادم ويب.
تم إنشاء HTTP.sys على واجهة برمجة تطبيقات Windows HTTP Server. تستخدم واجهة برمجة التطبيقات هذه برنامج تشغيل kernel HTTP.sys لمعالجة طلبات HTTP وتوجيهها إلى العمليات التي تقوم بتشغيل تطبيقات الويب. يسمح ذلك لعمليات متعددة على نفس الجهاز الفعلي أو الظاهري باستضافة تطبيقات الويب على نفس المنفذ، مع إزالة الغموض إما عن طريق مسار عنوان URL فريد أو اسم مضيف. هذه الميزات مفيدة في نسيج الخدمة لاستضافة مواقع ويب متعددة في نفس المجموعة.
إشعار
HTTP.sys التنفيذ يعمل فقط على نظام Windows.
يوضح الرسم التخطيطي التالي كيفية استخدام HTTP.sys برنامج تشغيل HTTP.sys kernel على Windows لمشاركة المنفذ:
HTTP.sys في خدمة غير متماثلة
للاستخدام HttpSys
في خدمة عديمة الحالة، قم بتجاوز CreateServiceInstanceListeners
الأسلوب وإرجاع مثيل HttpSysCommunicationListener
:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new HttpSysCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
new WebHostBuilder()
.UseHttpSys()
.ConfigureServices(
services => services
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseStartup<Startup>()
.UseUrls(url)
.Build()))
};
}
HTTP.sys في خدمة راقية
HttpSysCommunicationListener
غير مصمم حاليا للاستخدام في الخدمات ذات الحالة بسبب المضاعفات مع ميزة مشاركة المنفذ HTTP.sys الأساسية. لمزيد من المعلومات، راجع القسم التالي حول تخصيص المنفذ الديناميكي باستخدام HTTP.sys. بالنسبة إلى الخدمات المتميزة، فإن Kestrel هو خادم الويب المقترح.
تكوين نقطة النهاية
Endpoint
التكوين مطلوب لخوادم الويب التي تستخدم واجهة برمجة تطبيقات Windows HTTP Server، بما في ذلك HTTP.sys. يجب أن تحتفظ خوادم الويب التي تستخدم واجهة برمجة تطبيقات Windows HTTP Server أولا بعنوان URL الخاص بها مع HTTP.sys (يتم إنجاز ذلك عادة باستخدام أداة netsh ).
يتطلب هذا الإجراء امتيازات مرتفعة لا تتمتع بها خدماتك افتراضيًا. يتم استخدام خيارات "http" أو "https" لخاصية Protocol
Endpoint
التكوين في ServiceManifest.xml خصيصا لإرشاد وقت تشغيل Service Fabric لتسجيل عنوان URL مع HTTP.sys نيابة عنك. يقوم بذلك باستخدام بادئة URL لأحرف البدل القوية.
على سبيل المثال، للحجز http://+:80
لخدمة، استخدم التكوين التالي في ServiceManifest.xml:
<ServiceManifest ... >
...
<Resources>
<Endpoints>
<Endpoint Name="ServiceEndpoint" Protocol="http" Port="80" />
</Endpoints>
</Resources>
</ServiceManifest>
ويجب تمرير اسم نقطة النهاية إلى الدالة HttpSysCommunicationListener
الإنشائية:
new HttpSysCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
return new WebHostBuilder()
.UseHttpSys()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
})
استخدام HTTP.sys مع منفذ ثابت
لاستخدام منفذ ثابت مع HTTP.sys، قم بتوفير رقم المنفذ في Endpoint
التكوين:
<Resources>
<Endpoints>
<Endpoint Protocol="http" Name="ServiceEndpoint" Port="80" />
</Endpoints>
</Resources>
استخدام HTTP.sys مع منفذ ديناميكي
لاستخدام منفذ معين ديناميكيا مع HTTP.sys، احذف الخاصية Port
في Endpoint
التكوين:
<Resources>
<Endpoints>
<Endpoint Protocol="http" Name="ServiceEndpoint" />
</Endpoints>
</Resources>
يوفر المنفذ الديناميكي المخصص بواسطة التكوين منفذا Endpoint
واحدا فقط لكل عملية مضيف. يسمح نموذج استضافة نسيج الخدمة الحالي باستضافة مثيلات خدمة متعددة و/أو نُسخ متماثلة في نفس العملية. وهذا يعني أن كل واحد سيشارك نفس المنفذ عند تخصيصه من خلال Endpoint
التكوين. يمكن لمثيلات HTTP.sys المتعددة مشاركة منفذ باستخدام ميزة مشاركة منفذ HTTP.sys الأساسية. ولكنه غير مدعوم من قبل HttpSysCommunicationListener
بسبب المضاعفات التي يقدمها لطلبات العميل. لاستخدام المنفذ الديناميكي، Kestrel هو خادم الويب المقترح.
Kestrel في خدمات موثوقة
يمكنك استخدام Kestrel في Reliable Services عن طريق استيراد حزمة Microsoft.ServiceFabric.AspNetCore.Kestrel NuGet. تحتوي هذه الحزمة على KestrelCommunicationListener
، وتنفيذ .ICommunicationListener
KestrelCommunicationListener
يسمح لك بإنشاء ASP.NET Core WebHost داخل خدمة موثوق بها باستخدام Kestrel كخادم ويب.
Kestrel هو خادم ويب عبر الأنظمة الأساسية ل ASP.NET Core. على عكس HTTP.sys، لا يستخدم Kestrel مدير نقطة نهاية مركزي. أيضًا على عكس HTTP.sys، لا يدعم Kestrel مشاركة المنفذ بين عمليات متعددة. يجب أن يستخدم كل مثيل من Kestrel منفذًا فريدًا. لمزيد من المعلومات حول Kestrel، راجع تفاصيل التنفيذ.
Kestrel في خدمة غير متماثلة
للاستخدام Kestrel
في خدمة عديمة الحالة، قم بتجاوز CreateServiceInstanceListeners
الأسلوب وإرجاع مثيل KestrelCommunicationListener
:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
new WebHostBuilder()
.UseKestrel()
.ConfigureServices(
services => services
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.UseUniqueServiceUrl)
.UseStartup<Startup>()
.UseUrls(url)
.Build();
))
};
}
Kestrel في خدمة رائعة
للاستخدام Kestrel
في خدمة ذات حالة، قم بتجاوز CreateServiceReplicaListeners
الأسلوب وإرجاع مثيل KestrelCommunicationListener
:
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
return new ServiceReplicaListener[]
{
new ServiceReplicaListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, (url, listener) =>
new WebHostBuilder()
.UseKestrel()
.ConfigureServices(
services => services
.AddSingleton<StatefulServiceContext>(serviceContext)
.AddSingleton<IReliableStateManager>(this.StateManager))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.UseUniqueServiceUrl)
.UseStartup<Startup>()
.UseUrls(url)
.Build();
))
};
}
في هذا المثال، يتم توفير مثيل مفرد من IReliableStateManager
إلى حاوية حقن تبعية WebHost. هذا ليس ضروريا تماما، ولكنه يسمح لك باستخدام IReliableStateManager
مجموعات موثوقة في أساليب إجراء وحدة تحكم MVC.
Endpoint
لا يتم توفير اسم تكوين في KestrelCommunicationListener
خدمة ذات حالة. يُشرح ذلك بمزيد من التفصيل في القسم التالي.
تكوين Kestrel لاستخدام HTTPS
عند تمكين HTTPS باستخدام Kestrel في خدمتك، ستحتاج إلى تعيين العديد من خيارات الاستماع. ServiceInstanceListener
قم بتحديث لاستخدام نقطة نهايةHttps والاستماع إلى منفذ معين (مثل المنفذ 443). عند تكوين مضيف الويب لاستخدام خادم الويب Kestrel، يجب عليك تكوين Kestrel للاستماع إلى عناوين IPv6 على جميع واجهات الشبكة:
new ServiceInstanceListener(
serviceContext =>
new KestrelCommunicationListener(
serviceContext,
"EndpointHttps",
(url, listener) =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");
return new WebHostBuilder()
.UseKestrel(opt =>
{
int port = serviceContext.CodePackageActivationContext.GetEndpoint("EndpointHttps").Port;
opt.Listen(IPAddress.IPv6Any, port, listenOptions =>
{
listenOptions.UseHttps(GetCertificateFromStore());
listenOptions.NoDelay = true;
});
})
.ConfigureAppConfiguration((builderContext, config) =>
{
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
})
.ConfigureServices(
services => services
.AddSingleton<HttpClient>(new HttpClient())
.AddSingleton<FabricClient>(new FabricClient())
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
}))
للحصول على مثال كامل في برنامج تعليمي، راجع تكوين Kestrel لاستخدام HTTPS.
تكوين نقطة النهاية
Endpoint
التكوين غير مطلوب لاستخدام Kestrel.
Kestrel هو خادم ويب مستقل بسيط. على عكس HTTP.sys (أو HttpListener)، لا يحتاج إلى Endpoint
تكوين في ServiceManifest.xml لأنه لا يتطلب تسجيل عنوان URL قبل البدء.
استخدام Kestrel مع منفذ ثابت
يمكنك تكوين منفذ ثابت في Endpoint
تكوين ServiceManifest.xml للاستخدام مع Kestrel. على الرغم من أن هذا ليس ضروريًا للغاية، فإنه يوفر فائدتين محتملتين:
- إذا لم يقع المنفذ في نطاق منفذ التطبيق، فإنه مفتوح من خلال جدار حماية نظام التشغيل بواسطة نسيج الخدمة.
- سيستخدم عنوان URL المقدم لك من خلال
KestrelCommunicationListener
هذا المنفذ.
<Resources>
<Endpoints>
<Endpoint Protocol="http" Name="ServiceEndpoint" Port="80" />
</Endpoints>
</Resources>
Endpoint
إذا تم تكوين، يجب تمرير اسمه إلى الدالة KestrelCommunicationListener
الإنشائية:
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) => ...
إذا لم يستخدم ServiceManifest.xml تكوينا Endpoint
، فاحذف الاسم في الدالة KestrelCommunicationListener
الإنشائية. في هذه الحالة، سيستخدم منفذًا ديناميكيًا. راجع القسم التالي للحصول على مزيد من المعلومات حول هذا.
استخدام Kestrel مع منفذ ديناميكي
لا يمكن ل Kestrel استخدام تعيين المنفذ التلقائي من Endpoint
التكوين في ServiceManifest.xml. وذلك لأن تعيين المنفذ التلقائي من Endpoint
تكوين يعين منفذا فريدا لكل عملية مضيف، ويمكن أن تحتوي عملية مضيف واحد على مثيلات Kestrel متعددة. هذا لا يعمل مع Kestrel لأنه لا يدعم مشاركة المنفذ. لذلك، يجب فتح كل مثيل Kestrel على منفذ فريد.
لاستخدام تعيين المنفذ الديناميكي مع Kestrel، احذف Endpoint
التكوين في ServiceManifest.xml بالكامل، ولا تمرر اسم نقطة نهاية إلى الدالة KestrelCommunicationListener
الإنشائية، كما يلي:
new KestrelCommunicationListener(serviceContext, (url, listener) => ...
في هذا التكوين، KestrelCommunicationListener
سيتم تحديد منفذ غير مستخدم تلقائيا من نطاق منفذ التطبيق.
بالنسبة إلى HTTPS، يجب أن تحتوي على نقطة النهاية التي كُونت باستخدام بروتوكول HTTPS بدون منفذ محدد في ServiceManifest.xml وتمرير اسم نقطة النهاية إلى منشئ KestrelCommunicationListener.
تكامل IHost ونموذج الحد الأدنى من الاستضافة
بالإضافة إلى IWebHost/IWebHostBuilder، يدعم KestrelCommunicationListener
وHttpSysCommunicationListener
بناء خدمات ASP.NET Core باستخدام IHost/IHostBuilder.
يتوفر هذا بدءًا من الإصدار 5.2.1363 من Microsoft.ServiceFabric.AspNetCore.Kestrel
والحزم Microsoft.ServiceFabric.AspNetCore.HttpSys
.
// Stateless Service
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
return Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseKestrel()
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseUrls(url);
})
.ConfigureServices(services => services.AddSingleton<StatelessServiceContext>(serviceContext))
.Build();
}))
};
}
// Stateful Service
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
return new ServiceReplicaListener[]
{
new ServiceReplicaListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
return Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseKestrel()
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.UseUniqueServiceUrl)
.UseContentRoot(Directory.GetCurrentDirectory())
.UseUrls(url);
})
.ConfigureServices(services =>
{
services.AddSingleton<StatefulServiceContext>(serviceContext);
services.AddSingleton<IReliableStateManager>(this.StateManager);
})
.Build();
}))
};
}
إشعار
نظرًا لأن KestrelCommunicationListener وHttpSysCommunicationListener مخصصان لخدمات الويب، فمن المطلوب تسجيل/تكوين خادم ويب (باستخدام أسلوب ConfigureWebHostDefaults أو ConfigureWebHost) عبر IHost
قدم ASP.NET 6 نموذج الحد الأدنى من الاستضافة وهو طريقة أكثر تبسيطًا لإنشاء تطبيقات الويب. يمكن أيضًا استخدام نموذج الحد الأدنى من الاستضافة مع KestrelCommunicationListener وHttpSysCommunicationListener.
// Stateless Service
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
var builder = WebApplication.CreateBuilder();
builder.Services.AddSingleton<StatelessServiceContext>(serviceContext);
builder.WebHost
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url);
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
return app;
}))
};
}
// Stateful Service
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
return new ServiceReplicaListener[]
{
new ServiceReplicaListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
var builder = WebApplication.CreateBuilder();
builder.Services
.AddSingleton<StatefulServiceContext>(serviceContext)
.AddSingleton<IReliableStateManager>(this.StateManager);
builder.WebHost
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.UseUniqueServiceUrl)
.UseUrls(url);
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
return app;
}))
};
}
مزود تكوين نسيج الخدمة
يعتمد تكوين التطبيق في ASP.NET Core على أزواج القيم الرئيسية التي أنشأها موفر التكوين. اقرأ التكوين في ASP.NET Core لفهم المزيد حول دعم تكوين ASP.NET Core العام.
يصف هذا القسم كيفية تكامل موفر تكوين Service Fabric مع تكوين ASP.NET Core عن طريق استيراد حزمة Microsoft.ServiceFabric.AspNetCore.Configuration
NuGet.
ملحقات بدء تشغيل AddServiceFabricConfiguration
بعد استيراد حزمة Microsoft.ServiceFabric.AspNetCore.Configuration
NuGet، تحتاج إلى تسجيل مصدر تكوين Service Fabric باستخدام واجهة برمجة تطبيقات تكوين ASP.NET Core. يمكنك القيام بذلك عن طريق التحقق من ملحقات AddServiceFabricConfiguration في Microsoft.ServiceFabric.AspNetCore.Configuration
مساحة الاسم مقابل IConfigurationBuilder
.
using Microsoft.ServiceFabric.AspNetCore.Configuration;
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddServiceFabricConfiguration() // Add Service Fabric configuration settings.
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
الآن يمكن لخدمة ASP.NET Core الوصول إلى إعدادات تكوين نسيج الخدمة، تمامًا مثل أي إعدادات تطبيق أخرى. على سبيل المثال، يمكنك استخدام نمط الخيارات لتحميل الإعدادات إلى كائنات مكتوبة بقوة.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MyOptions>(Configuration); // Strongly typed configuration object.
services.AddMvc();
}
تعيين المفتاح الافتراضي
افتراضيًا، يتضمن موفر تكوين نسيج الخدمة اسم الحزمة واسم القسم واسم العقار. تُشكل هذه معًا مفتاح تكوين ASP.NET Core، كما يلي:
$"{this.PackageName}{ConfigurationPath.KeyDelimiter}{section.Name}{ConfigurationPath.KeyDelimiter}{property.Name}"
على سبيل المثال، إذا كان لديك حزمة تكوين تسمى MyConfigPackage
بالمحتوى التالي، فستتوفر قيمة التكوين على ASP.NET Core IConfiguration
من خلال MyConfigPackage:MyConfigSection:MyParameter.
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Section Name="MyConfigSection">
<Parameter Name="MyParameter" Value="Value1" />
</Section>
</Settings>
خيارات تكوين نسيج الخدمة
يدعم ServiceFabricConfigurationOptions
موفر تكوين Service Fabric أيضا تغيير السلوك الافتراضي لتعيين المفتاح.
الإعدادات المُشَفرة
يدعم نسيج الخدمة الإعدادات المشفرة، وكذلك موفر تكوين نسيج الخدمة. لا يتم فك تشفير الإعدادات المشفرة إلى ASP.NET Core IConfiguration
بشكل افتراضي. تُخَزن القيم المشفرة هناك بدلاً من ذلك. ولكن إذا كنت ترغب في فك تشفير القيمة لتخزينها في ASP.NET Core IConfiguration، يمكنك تعيين علامة DecryptValue إلى false في AddServiceFabricConfiguration
الملحق، كما يلي:
public Startup()
{
ICodePackageActivationContext activationContext = FabricRuntime.GetActivationContext();
var builder = new ConfigurationBuilder()
.AddServiceFabricConfiguration(activationContext, (options) => options.DecryptValue = false); // set flag to decrypt the value
Configuration = builder.Build();
}
حزم تكوين متعددة
يدعم نسيج الخدمة حزم تكوين متعددة. افتراضيًا، يتم تضمين اسم الحزمة في مفتاح التكوين. ولكن يمكنك تعيين العلامة IncludePackageName
إلى خطأ، كما يلي:
public Startup()
{
ICodePackageActivationContext activationContext = FabricRuntime.GetActivationContext();
var builder = new ConfigurationBuilder()
// exclude package name from key.
.AddServiceFabricConfiguration(activationContext, (options) => options.IncludePackageName = false);
Configuration = builder.Build();
}
تعيين المفاتيح المخصصة واستخراج القيمة ومجموعة البيانات
يدعم موفر تكوين Service Fabric أيضا سيناريوهات أكثر تقدما لتخصيص تعيين المفتاح باستخدام ExtractKeyFunc
القيم واستخراجها مخصصا باستخدام ExtractValueFunc
. يمكنك حتى تغيير عملية ملء البيانات بالكامل من تكوين Service Fabric إلى تكوين ASP.NET Core باستخدام ConfigAction
.
توضح الأمثلة التالية كيفية استخدام ConfigAction
لتخصيص محتوى البيانات:
public Startup()
{
ICodePackageActivationContext activationContext = FabricRuntime.GetActivationContext();
this.valueCount = 0;
this.sectionCount = 0;
var builder = new ConfigurationBuilder();
builder.AddServiceFabricConfiguration(activationContext, (options) =>
{
options.ConfigAction = (package, configData) =>
{
ILogger logger = new ConsoleLogger("Test", null, false);
logger.LogInformation($"Config Update for package {package.Path} started");
foreach (var section in package.Settings.Sections)
{
this.sectionCount++;
foreach (var param in section.Parameters)
{
configData[options.ExtractKeyFunc(section, param)] = options.ExtractValueFunc(section, param);
this.valueCount++;
}
}
logger.LogInformation($"Config Update for package {package.Path} finished");
};
});
Configuration = builder.Build();
}
تحديثات التكوين
يدعم موفر تكوين نسيج الخدمة أيضًا تحديثات التكوين. يمكنك استخدام ASP.NET Core IOptionsMonitor
لتلقي إعلامات التغيير، ثم استخدام IOptionsSnapshot
لإعادة تحميل بيانات التكوين. لمزيد من المعلومات، راجع ASP.NET خيارات Core.
يتم دعم هذه الخيارات افتراضيًا. ليست هناك حاجة إلى مزيد من الترميز لتمكين تحديثات التكوين.
السيناريوهات والتكوينات
يوفر هذا القسم مجموعة من خادم الويب وتكوين المنفذ وخيارات تكامل نسيج الخدمة والإعدادات المتنوعة التي نوصي بها لاستكشاف السيناريوهات التالية وإصلاحها:
- ASP.NET الأساسية غير المتماثلة المعروضة خارجيًا
- خدمات ASP.NET الأساسية غير المتماثلة الداخلية فقط
- الخدمات الداخلية ASP.NET الأساسية فقط
الخدمة المكشوفة خارجيا هي التي تعرض نقطة نهاية يتم استدعاؤها من خارج نظام المجموعة، عادة من خلال موازن تحميل.
الخدمة الداخلية فقط هي خدمة يتم استدعاء نقطة النهاية الخاصة بها فقط من داخل نظام المجموعة.
إشعار
لا ينبغي أن تتعرض نقاط نهاية الخدمة الرائعة بشكل عام للإنترنت. لن تتمكن المجموعات الموجودة خلف موازنات التحميل غير المدركة لدقة خدمة نسيج الخدمة، مثل Azure Load Balancer، من عرض الخدمات ذات الحالة. وذلك لأن موازن التحميل لن يتمكن من تحديد موقع حركة المرور وتوجيهها إلى النسخة المتماثلة المناسبة من الخدمة.
ASP.NET الأساسية غير المتماثلة المعروضة خارجيًا
Kestrel هو خادم الويب المقترح لخدمات الواجهة الأمامية التي تعرض نقاط نهاية HTTP الخارجية التي تواجه الإنترنت. على Windows، يمكن أن يوفر HTTP.sys إمكانية مشاركة المنفذ، ما يسمح لك باستضافة خدمات ويب متعددة على نفس المجموعة من العقد باستخدام نفس المنفذ. في هذا السيناريو، يتم تمييز خدمات ويب حسب اسم المضيف أو المسار، دون الاعتماد على وكيل الواجهة الأمامية أو بوابة لتوفير توجيه HTTP.
عند التعرض للإنترنت، يجب أن تستخدم خدمة غير متماثلة نقطة نهاية معروفة ومستقرة يمكن الوصول إليها من خلال موازن التحميل. ستوفر عنوان URL هذا لمستخدمي تطبيقك. نوصي بإجراء التكوين التالي:
نوع | التوصية | ملاحظات |
---|---|---|
خادم الويب | Kestrel | Kestrel هو خادم الويب المفضل، حيث يُدعم عبر نظامي التشغيل Windows وLinux. |
تكوين المنفذ | ثابت | يجب تكوين منفذ ثابت معروف في Endpoints تكوين ServiceManifest.xml، مثل 80 ل HTTP أو 443 ل HTTPS. |
خيارات تكامل نسيج الخدمة | بلا | ServiceFabricIntegrationOptions.None استخدم الخيار عند تكوين البرنامج الوسيط لتكامل Service Fabric، بحيث لا تحاول الخدمة التحقق من صحة الطلبات الواردة لمعرف فريد. لن يعرف المستخدمون الخارجيون لتطبيقك معلومات التعريف الفريدة التي تستخدمها البرامج الوسيطة. |
عدد المثيلات | -1 | في حالات الاستخدام النموذجية، يجب تعيين إعداد عدد المثيلات إلى -1. يتم ذلك بحيث يتوفر مثيل على جميع العقد التي تتلقى حركة المرور من موازن التحميل. |
إذا كانت هناك عدة خدمات معروضة خارجيًا تشترك في نفس مجموعة العقد، فإنه يمكنك استخدام HTTP.sys مع مسار عنوان URL فريد ولكنه مستقر. يمكنك تحقيق ذلك عن طريق تعديل عنوان URL المقدم عند تكوين IWebHost. لاحظ أن هذا ينطبق على HTTP.sys فقط.
new HttpSysCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
url += "/MyUniqueServicePath";
return new WebHostBuilder()
.UseHttpSys()
...
.UseUrls(url)
.Build();
})
الخدمة الأساسية ASP.NET الداخلية فقط غير المتماثلة
يجب أن تستخدم الخدمات غير المتماثلة التي تُستدعى فقط من داخل المجموعة عناوين URL فريدة ومنافذ معينة ديناميكيًا لضمان التعاون بين خدمات متعددة. نوصي بإجراء التكوين التالي:
نوع | التوصية | ملاحظات |
---|---|---|
خادم الويب | Kestrel | على الرغم من أنه يمكنك استخدام HTTP.sys للخدمات الداخلية غير المتماثلة، فإن Kestrel هو أفضل خادم يسمح لمثيلات خدمة متعددة بمشاركة مضيف. |
تكوين المنفذ | تعيين ديناميكي | قد تشترك النسخ المتماثلة المتعددة لخدمة ذات حالة في عملية مضيف أو نظام تشغيل مضيف، وبالتالي ستحتاج إلى منافذ فريدة. |
خيارات تكامل نسيج الخدمة | UseUniqueServiceUrl | باستخدام تعيين المنفذ الديناميكي، يمنع هذا الإعداد مشكلة الهوية الخاطئة الموضحة سابقًا. |
عدد المثيل | أي | يمكن تعيين إعداد عدد المثيلات إلى أي قيمة ضرورية لتشغيل الخدمة. |
الخدمة الأساسية ASP.NET الداخلية فقط
وينبغي أن تستخدم الخدمات الحكومية التي لا تُستدعى إلا من داخل المجموعة المخصصة ديناميكيًا لضمان التعاون بين خدمات متعددة. نوصي بإجراء التكوين التالي:
نوع | التوصية | ملاحظات |
---|---|---|
خادم الويب | Kestrel | HttpSysCommunicationListener لم يتم تصميم للاستخدام من قبل الخدمات ذات الحالة التي تشترك فيها النسخ المتماثلة في عملية مضيف. |
تكوين المنفذ | تعيين ديناميكي | قد تشترك النسخ المتماثلة المتعددة لخدمة ذات حالة في عملية مضيف أو نظام تشغيل مضيف، وبالتالي ستحتاج إلى منافذ فريدة. |
خيارات تكامل نسيج الخدمة | UseUniqueServiceUrl | باستخدام تعيين المنفذ الديناميكي، يمنع هذا الإعداد مشكلة الهوية الخاطئة الموضحة سابقًا. |