利用Service Fabric承載eShop On Containers的實現方法

利用Service Fabric承載eShop On Containers的實現方法

從Pet Shop 到eShop on Container都是Microsoft在技術演進的路徑上給開發者展示.Net的開發能力和架構能力的Sample工程,Petshop的時候更多的是展現應用的分層架構,設計的抽象與模組間的通訊。到了eShop on Container更多的關注在架構設計與微服務化的,下面我們先來看看eshop on Container的架構圖

在上圖,我們可以看到後端服務分成了

1 Identity microservice(驗證服務)

2 Catalog microservice(商品分類服務)

3 Ordering microservice(訂單服務)

4 Basket microservice(購物車服務)

5 Marketing microservice(市場營銷服務)

6 Locations microservice(地理位置資訊服務)

在以前的分層架構中,通常這些服務都是以某一模組來體現的,為什麼現在要將他們拆分成了各個服務呢?當我們從業務場景上面來看這些服務時,我們會發現每個服務的訪問峰值時間區間、容量規劃都是不一樣的,甚至實現這些服務最方便最簡單的技術棧都有可能是不一樣的(當然強大的.net core無所不能,但是公司內不同業務線上的技術儲備不一樣,就有可能選擇不同的技術實現)。這是因為如果我們都將這些模組整合到了一個程式或者服務中的時候,就會碰到在不同時間內服務高峰期擴充套件系統容量困難,要不就是資源不足,要不就是資源過剩。譬如搶購業務開始前大家提前個半小時登入了系統,這時候系統最忙的是登入模組,到了開始搶購時間,系統最忙的是訂單模組。不採用微服務架構的話,半小時前準備給登入模組使用的資源不一定能夠及時的釋放出來給訂單模組。如果兩個模組都使用單一程式架構的話,很可能出現的情況就是搶購的業務把所有資源都佔滿了了,連其他正常訪問系統的使用者資源都被佔用掉,導致系統崩潰。在講究Dev/Ops的今天,開發人員和架構師需要更多的考慮硬體架構層面對程式應用帶來的影響。

用Service Fabric來承載eShop on Container微服務的方法一,通過Service Fabric直接管理Docker

首先我們先到Azure上申請一個Container Registry來承載eShop各個微服務程式的映象(image).建立Azure Docker Registry可以參考官方文件:https://docs.microsoft.com/zh-cn/azure/container-registry/

現在最新版本Service Fabric已經可以直接管理編排Docker了。

1.建立一個型別為Container的Service

image

2.在servicemanifest.xml中描述清楚image所在路徑


<CodePackage Name="Code" Version="1.0.0">
<!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers -->
<EntryPoint>
<ContainerHost>
<ImageName>eshopsample.azurecr.io/catalog:latest</ImageName>  
</ContainerHost>  
</EntryPoint>
<!-- Pass environment variables to your container: --> 
<EnvironmentVariables>
<EnvironmentVariable Name="HttpGatewayPort" Value=""/>
</EnvironmentVariables>
</CodePackage>

這裡非常簡單,指定了image所在位置就好了,如果本身Docker Image裡需要很多配置資訊譬如:資料庫連結串、其他服務的地址等等都可以在EnvironmentVariables裡面去配置。

3.配置Registry的訪問賬號密碼,需要在ApplicationManifest.xml上面來配置


<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="CatalogService_Pkg" ServiceManifestVersion="1.0.1" />  
<Policies>
<ContainerHostPolicies CodePackageRef="Code" Isolation="hyperv">
<RepositoryCredentials AccountName="youraccount" Password="xxxxxxxxxxxxx" PasswordEncrypted="false"/>
<PortBinding ContainerPort="80" EndpointRef="CatalogServieEndpoint"/>
</ContainerHostPolicies>
</Policies>
</ServiceManifestImport>

整個過程不會太複雜,只要配置好了Catalog microserivce的ServiceManifest.xm和ApplicationManifest.xml檔案之後,我們可以用同樣的方法將其他服務一一配置完成,然後我們就可以將Service Fabric的配置Publish到Cluster上面了。

image

Service Fabric會自動根據配置在Cluster上面Pull Image和將Docker執行起來。非常簡單

用Service Fabric承載eShop on Container微服務的方法二:用Service Fabric的Runtime執行eShop on Container的微服務

Service Fabric本身就是個微服務的開發框架,現在已經直接支援了.net Core 2.0了所以,我們更新了Service Fabric的SDK之後就可以直接建立.net core的服務了

imageimage

eShop on Container的程式碼都已經是一份成型的.net core 2.0的程式碼,所以不需要重新編寫服務。

1.通過nuget新增最新的Service Fabric最新的SDK。

image

2.修改programe.cs,啟動ServiceFabric Runtime而不是直接啟動Asp.net WebHost


public static void Main(string[] args)
{
try
{
// ServiceManifest.XML 檔案定義一個或多個服務型別名稱。
// 註冊服務會將服務型別名稱對映到 .NET 型別。
// 在 Service Fabric 建立此服務型別的例項時,
// 會在此主機程序中建立類的例項。
ServiceRuntime.RegisterServiceAsync("Catalog.API",
context => new CatalogAPI(context)).GetAwaiter().GetResult();
ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(CatalogAPI).Name);
// 防止此主機程序終止,以使服務保持執行。 
Thread.Sleep(Timeout.Infinite);
}
catch (Exception e)
{
ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString());
throw;
}
}

3.編寫

CatalogAPI 類用於啟動WebHost


internal sealed class CatalogAPI : StatelessService
{
public CatalogAPI(StatelessServiceContext context)
: base(context)
{ }
/// <summary>
/// Optional override to create listeners (like tcp, http) for this service instance.
/// </summary>
/// <returns>The collection of listeners.</returns>
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new KestrelCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting WebListener on {url}");
return new WebHostBuilder()
.UseKestrel()
.ConfigureServices(
services => services
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((builderContext, config) =>
{
IHostingEnvironment env = builderContext.HostingEnvironment;
config.AddJsonFile("settings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.UseWebRoot("Pics")
.Build();     
}))
};
}
}

4.編寫serviceManifest.xml描述服務埠等資訊


<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="Catalog.APIPkg"
Version="1.0.3"
xmlns="http://schemas.microsoft.com/2011/01/fabric"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ServiceTypes>
<StatelessServiceType ServiceTypeName="Catalog.API" />
</ServiceTypes>
<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.0.3">
<EntryPoint>
<ExeHost>
<Program>Catalog.API.exe</Program>
<WorkingFolder>CodePackage</WorkingFolder>
</ExeHost>
</EntryPoint>
<EnvironmentVariables>
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="Development"/>
</EnvironmentVariables>
</CodePackage>
<ConfigPackage Name="Config" Version="1.0.1" />
<Resources>
<Endpoints> 
<Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input" Port="5101" />
</Endpoints>
</Resources>
</ServiceManifest>

5.修改AppcationManifest.xml增加幾個服務的描述資訊

新增ServiceImport節


<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="Catalog.APIPkg" ServiceManifestVersion="1.0.3" />
<ConfigOverrides />
</ServiceManifestImport>

在DefaultService中描述Service


<Service Name="Catalog.API" ServiceDnsName="catalog.fabric.api">
<StatelessService ServiceTypeName="Catalog.API" InstanceCount="[Catalog.API_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>

這樣我們就可以將Catalog這個服務改造成可以通過Service Fabric來管理的微服務了。通過Publish,我們可看到幾個服務都已經在Service Fabric下面接受管理和編排了。

image

訪問localhost:5100

image

以上這篇利用Service Fabric承載eShop On Containers的實現方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援指令碼之家。