微服务框架之微软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