轉:微服務框架之微軟Service Fabric

常見的微服務架構用到的軟件&組件:html

docker(成熟應用)java

spring boot % spring cloud(技術趨勢)node

Service Fabric(屬於後起之秀 背後是微軟雲的驅動)ios

四種經常使用的微服務架構方案,分別是ZeroC IceGrid、Spring Cloud、基於消息隊列與Docker Swarm。git

實際生產中多半是組合的模式運用例如最佳實踐spring cloud+docker。github

微服務特性——持續集成(Jenkins,Snap-CI),構建(Maven,Gradle),部署(Docker),持續交付(Jenkins),日誌聚合(ELK,Splunk),運維(監控警告Zabbix,Nagios) spring

 

微軟的 Azure Service Fabric 的官方博客在2017.3.24日發佈了一篇博客 Service Fabric .NET SDK goes open source ,介紹了社區呼聲最高的 Service Fabric 開源的狀況以及當前的狀況,當時開源了 Service Fabric的.NET SDK 部分,社區一直在期盼着 Service Fabric 的正式開源,通過了一年漫長的等待,2018年3月14日微軟終於開源了 Service Fabric ,並且是以 MIT 許可下開放源代碼,在官方博客宣佈 https://blogs.msdn.microsoft.com/azureservicefabric/2018/03/14/service-fabric-is-going-open-source。docker

    目前微軟在 Github 上的開源地址是 https://github.com/Microsoft/service-fabric,目前的代碼構建適用於 Linux 的 Service Fabric ,運行基本測試,有問題能夠在上面提交 issue 和 PR 了,Windows 構建環境以及完整的 CI 環境尚未遷移過來。Windows 內部爲 Service Fabric 開發了將近十年的內部服務,其中大部分時間都是微軟內部平臺,好比 Office365,Azure Stack 平臺等,這意味着咱們有近十年的內部微軟工具能夠在遷移以前完成遷移和流程細化,逐步所有開源,之後所有開發都在開源模式下進行開發工做。數據庫

 

Service Fabric基本概念: Node, Application, Service, Partition/Replicas

Azure Service Fabric 是一款分佈式系統平臺,可方便用戶輕鬆打包、部署和管理可縮放的可靠微服務和容器。 開發人員和管理員不需解決複雜的基礎結構問題,只需專一於實現苛刻的任務關鍵型工做負荷,即那些可縮放、可靠且易於管理的工做負荷。json

 

     本節將爲你們介紹Azure Service Fabric的基本概念及相關組件的工做機制, 包括Micro Service, Node type, Node等等。雖然名稱叫Azure Service Fabric但其可應用的平臺遠不止Azure平臺自己,咱們會在後續章節的使用場景中爲你們專門描述Service Fabric在各大平臺上的工做形式。

Microsoft Azure Service Fabric是微軟開發的一套支撐高可用高伸縮雲服務的框架,其核心部分是一個分佈式系統平臺,用於構建可擴展的可靠應用。在便於封裝可部署代碼的同時,支持建立無狀態和有狀態的微服務,經過雲平臺來伸縮他們,來應對高複雜度、低延遲、數據密集的狀況。開發者和系統管理員能夠免於處理複雜的基礎設施問題,將精力更多地投入到所構建應用程序的實現上。

 

 

微服務Microservice

在具體介紹Service Fabric以前,不得不先提一下微服務的思想。由於使用Service Fabric的開發過程就是微服務的設計開發過程。有了Service Fabric,您只須要考慮開發微服務的功能,而無需過多考慮部署後的伸縮性和可用性的問題,這些問題均可以交給Service Fabric來幫您實現。

微服務的思想就是將複雜單體式應用程序解耦成多個各個獨立的服務,在功能不變的狀況下,被分解出來的多個可管理的服務能夠經過約定的接口相互通訊。這種方法爲採用單體式編碼很難實現的功能提供了模塊化的解決方案。由於,單個服務能夠更易於開發、維護。這種架構方式使每一個單個服務均可以有專門的團隊來開發,每一個團隊能夠各自選擇本身擅長的開發技術,經過約定接口來實現相互通訊。每一個服務能夠獨立實現、測試、部署和升級,開發者再也不須要擔憂其餘服務部署對本服務的影響。AB測試加快了部署的速度,從而實現持續集成持續部署。全部微服務做爲一個總體爲用戶提供服務,同時各個微服務能夠根據自身對資源的需求獨立擴展,從而最大化服務器的資源利用率。

回到Service Fabric, 一個Service Fabric開發的應用程序由數個服務組成,每一個服務能夠做爲個體獨自修改、擴展和管理,同時能夠按照一個完整的應用程序來管理。Service fabric的設計目的就是用微服務的方式來簡化構建複雜應用的過程。

 

集羣Cluster

集羣是一組經過網絡鏈接的虛擬或者物理主機,您的微服務就部署在集羣中,集羣的大小能夠擴展到上千臺主機。

 

節點Node

集羣中的一臺機器或者VM稱爲Node, 每一個Node會被分配一個名稱(string字符串)。Node還有其餘一些屬性,好比位置屬性placement properties。能夠經過每臺機器或者VM都有一個自啓動Windows系統服務FabricHost.exe,它隨系統啓動後會執行另外兩個程序:Fabric.exe 和 FabricGateway.exe, 這兩個程序就組成了一個完整的Node。出於測試目的,有時單臺機器上也能夠經過運行多個Fabric.exe 和 FabricGateway.exe的實例來擁有多個Node。

一個集羣中的全部Node相互之間平等且能夠直接互相通訊。Node除了宿主在物理主機或VM中,還能夠宿主在基於Windows的Docker容器中、本地部署的服務器中、其餘公有云和私有云中,咱們會在後續Service Fabric的使用場景中爲你們詳細介紹這一內容。

 

 

應用程序Application:Application Type和Service Type

Service Fabric應用程序(Application)是一組服務(service)的集合,其中一個service是爲Application提供指定功能的單元。您將經過定義一個Application Type和對應的幾個Service Type來構建一個Service Fabric的Application. 當Application被部署到Service Fabric Cluster裏面時,這些類型會被相應地初始化成application實例和service實例。這裏相似咱們OO地思想。

Application Type和Named Application: Application Type包含一組Service Type的集合,對應上文中的Service Fabric應用程序(Application)是一組服務(service)的集合。 Application Type的name和version定義在ApplicationManifest.xml文件中。在部署的時候,ApplicationManifest.xml會被拷貝到Service Fabric的image store中。經過在Cluster中建立Named Application來初始化Application的實例。Named Application經過"fabric:/MyNamedApp"的形式來命名。

Service Type和Named Service: Service Type的name和version定義在ServiceManifest.xml文件中。當建立好一個Named Application後,就能夠建立Named service. 例如您在 "MyNamedApp" Named Application中建立一個 "MyDatabase" Named Service, Name Service被命名爲 "fabric:/MyNamedApp/MyDatabase".

 

 

 

分區Partitions和複製replicas

一個service能夠包含多個分區Partition,Service Fabric經過使用分區做爲擴展的機制來將工做分佈到不一樣的service實例上。

一個分區Partition能夠包含一個或者多個複製replicas。Service Fabric經過使用複製來實現可用性。一個分區能夠有一個主複製和多個從複製,多個複製之間的狀態能夠自動同步。當主複製出現錯誤時,其中一個從複製被自動提高爲主複製,以保證系統的可用性。而後將從複製的個數恢復到正常水平,保證足夠的從複製冗餘。

 

 

使用Visual Studio+Service Fabric運行Spring Boot微服務

 

Service Fabric是微軟提供的微服務管理框架,通過了微軟Cosmos DB等多個產品的驗證。

Service Fabric官方文檔只提供了Visual Studio + .net + C#的開發部署方案和Linux + Eclipse + Java的部署方案,但沒有Visual Studio+Eclipse+Java的部署方法,經過摸索和文檔,發現微軟提供了這樣的途徑,微軟真是比之前開放多了。

1. 首先在Visual Studio中建立Service Fabric工程,

2. 選擇來賓可執行文件,輸入第一個微服務的名稱,選擇可執行的jar包所在文件目錄,Work Folder選爲CodeBase,

3. 在VS項目樹中,選擇Jar包,同時將java運行環境包複製/粘貼到code目錄中,

4.  打開"ServiceManifest.xml", 更改如下參數,

  1. Program: This should point to java.exe file in JRE folder that was copied.
  2. Arguments: This should contain the -jar and path of the JAR filename relative to java.exe. They are arguments passed to java.exe when it starts.
  3. WorkingFolder: This should be CodeBase.
  4. Endpoint: Name a endpoint and provide protocol as HTTP and port no (8080) along with type(input)

 

5. 點擊Start按鈕,就能夠將此微服務部署搭配本地Service Fabric Cluster上了。

 

【案例深度講解】利用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

 

 

學習Azure Service Fabric的總結:

  • Azure Service Fabric其實分爲兩塊:Azure和Service Fabric。
  • Service Fabric只是一套軟件分佈式系統,理論上它可使用在非Azure環境。也就是說:非Azure環境的機器集羣,進行合理配置,也可使用Service Fabric 構建分佈式系統。
  • 當咱們在Azure門戶上建立Azure Service Fabric時,會自動建立Azure Load Balancer, Azure Virtual Machine Scale Set, Azure Virtual Machine。這是由於這些組件都是在Azure環境中將Service Fabric接入公網必須的組件和平臺。可是理論上若是從此有其餘的產品,經過合理的負載均衡和配置邏輯,只要可讓服務器集羣面向外部網絡提供服務,Service Fabric均可以適用。
  • Service Fabric自行構建了一整套虛擬概念,包括後面會說起的Micro Service, Node type, Node等等。這些概念都是僅在Service Fabric範圍內適用。例如Micro Service,能夠用C#構建,也能夠用Java實現。Node type能夠是Azure VMSS, 也但是是硬件物理服務器。
  • Service Fabric幫助架構師將分佈式系統和硬件進行脫耦。理想程度下,全部職責以下:
    • 軟件開發者只須要關係分佈式微服務功能邏輯實現,微服務之間如何調用經過統一接口完成
    • 應用部署者只須要關心如何將微服務部署至各個node,以及考慮應用的升級維護
    • 硬件架構師只須要關心維護虛擬機和網絡之間的部署關係,而且在虛擬機性能產生問題是增長虛擬機來分擔壓力

【參考資料】

一、大話微服務架構之微服務框架微軟ServiceFabric正式開源(三) http://baijiahao.baidu.com/s?id=1595179278058800506

二、Service Fabric https://azure.microsoft.com/zh-cn/documentation/learning-paths/service-fabric/

三、DevOps 工具集成 | Microsoft Azure https://azure.microsoft.com/zh-cn/products/devops-tool-integrations/

四、【圖文】微服務架構設計_https://wenku.baidu.com/view/eb6467d10408763231126edb6f1aff00bed570a3.html

五、微服務架構與實踐摘要-電子發燒友網觸屏版 http://m.elecfans.com/article/631884.html

六、微服務架構設計 - PetterLiu - 博客園 https://www.cnblogs.com/wintersun/p/6219259.html

七、微服務實踐:從單體式架構遷移到微服務架構 https://blog.csdn.net/gaowenhui2008/article/details/70239716

八、微服務架構 - 老_張 - 博客園 https://www.cnblogs.com/imyalost/p/6792724.html

本文轉自:https://blog.csdn.net/enweitech/article/details/80696225

相關文章
相關標籤/搜索