利用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

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上面了。

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的服务了

eShop on Container的代码都已经是一份成型的.net core 2.0的代码,所以不需要重新编写服务。

1.通过nuget添加最新的Service Fabric最新的SDK。

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下面接受管理和编排了。

访问localhost:5100


原文地址:https://www.cnblogs.com/wing-ms/p/8243020.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322382.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

12-多对一添加操作(添加新客户及对应的新订单)

多对一添加操作 场景&#xff1a;现在想要添加一个新客户对应一个新订单&#xff0c;那么要怎么来添加呢&#xff1f; 分析&#xff1a;由于添加订单时&#xff0c;客户对订单是一对多的关系&#xff0c;所以添加订单的时候必须要指明一位客户。 要同时添加新客户以及一个新订…

.NET Core+MySql+Nginx 容器化部署

1. 引言上两节我们通过简单的demo学习了docker的基本操作。这一节我们来一个进阶学习&#xff0c;完成ASP.NET Core MySql Nginx的容器化部署。本文是基于CentOS 7.4环境进行演示&#xff0c;示例项目可以访问Docker.NetCore.MySql进行下载。2. Hello MySQL同样我们还是以循序…

HiveSQL常用优化方法全面总结

转载自 HiveSQL常用优化方法全面总结 Hive作为大数据领域常用的数据仓库组件&#xff0c;在平时设计和查询时要特别注意效率。影响Hive效率的几乎从不是数据量过大&#xff0c;而是数据倾斜、数据冗余、job或I/O过多、MapReduce分配不合理等等。对Hive的调优既包含对HiveQL语…

P3597-[POI2015]WYC【矩阵乘法,倍增】

前言 正题 题目链接:https://www.luogu.org/problemnew/show/P3597 题目大意 问第kkk长的路径长度(非简单路径) 解题思路 先考虑kkk比较小时的情况&#xff0c;我们可以求出长度为111的路径&#xff0c;长度为222的路径&#xff0c;然后以此类推找到第一个与前面的和到kkk就…

13-一对多左连接查询分步查询(查询所有客户及客户对应的订单)

查询所有客户以及对应的订单 目录 左连接查询&#xff08;不支持懒加载&#xff09;分步查询&#xff08;支持懒加载&#xff09;左连接查询&#xff08;不支持懒加载&#xff09; 场景&#xff1a;我们想要查询出所有的客户&#xff0c;并且把每个客户对应的订单也查出来。…

实战 | 利用Delta Lake使Spark SQL支持跨表CRUD操作

转载自 实战 | 利用Delta Lake使Spark SQL支持跨表CRUD操作 供稿 | eBay ADI-Carmel Team 作者 | 金澜涛 编辑 | 顾欣怡 本文7309字&#xff0c;预计阅读时间22分钟 导读 本文介绍eBay Carmel团队利用Delta Lake&#xff0c;使Spark SQL支持Teradata的Update/Delete语法。…

14-多对多关系建表

多对多关系建表 目录 多对多关系多对多关系建表原则domain多对多关系 一个老师可以教多个学生&#xff0c;一个学生可以被多个老师教。一个学生可以选择多门课程&#xff0c;一门课程可以被多个学生选择。一个用户可以选择多个角色&#xff0c;一个角色可以被多个用户选择。…

DevOps文档中心的技术实践演进

这应该算是《Git企业开发者教程》的篇外篇&#xff0c;介绍一下这个教程是怎样写出来的。相信每个技术人都有类似下面的文件夹&#xff0c;保存着你辛苦工作的成果。实际的感觉&#xff1a;看着闹心&#xff0c;弃之不舍。一份文档久经修改&#xff0c;不能定稿&#xff0c;循环…

MySQL UPDATE 语句一个“经典”的坑

转载自 MySQL UPDATE 语句一个“经典”的坑 来源&#xff1a;ju.outofmemory.cn/entry/336774 有问题的SQL语句 why? 倒回去再重试验一把 最近好几次有开发同学在钉钉上问我&#xff0c;比如下图&#xff1a; 问题归纳起来就是&#xff1a;在MySQL里面update一条记录&…

jzoj4803-[NOIP2016提高A组模拟9.28]求导【模拟】

正题 题目大意 求一个标准多项式的求导 解题思路 暴力模拟即可&#xff0c;注意细节即可 一下是贴心的坑爹细节样例 (233x)−>(1)而不是(1)(233x)->(1)而不是(1)(233x)−>(1)而不是(1) (1)−>(0)而不是()(1)->(0)而不是()(1)−>(0)而不是() codecodecode …

g4e基础篇#1 为什么要使用版本控制系统

本篇是Git企业开发者教程基础篇的第一篇1. 基础篇&#xff1a;为什么要使用版本控制系统Git 分布式版本控制系统的优势Git 安装和设置初始化Git存储库(Repo)起步 1 – 创建分支和保存代码起步 2 – 了解Git历史记录起步 3 – 拉取请求 Pull Request 工作机制Git是一种版本控制系…

15-多对多做左连接查询(查询老师,并且把关联的学生也查出来)

多对多左连接查询 目录 左连接查询老师对学生是多对多的关系&#xff0c;把中心放在老师上&#xff0c;一个老师可以教多个学生&#xff0c;实际上老师对学生也可以理解为一对多的关系。 左连接查询 场景&#xff1a;查询老师&#xff0c;并且把关联的学生也查出来。 Teac…

.Net 如何模拟会话级别的信号量,对http接口调用频率进行限制(有demo)

现在&#xff0c;因为种种因素&#xff0c;你必须对一个请求或者方法进行频率上的访问限制。 比如&#xff0c; 你对外提供了一个API接口&#xff0c;注册用户每秒钟最多可以调用100次&#xff0c;非注册用户每秒钟最多可以调用10次。比如&#xff0c; 有一个非常吃服务器资源的…

1.数据湖deltalake初识

转载自 1.数据湖deltalake初识 1.delta特性简介 Delta Lake是Spark计算框架和存储系统之间带有Schema信息数据的存储中间层。它给Spark带来了三个最主要的功能&#xff1a; 第一&#xff0c;Delta Lake使得Spark能支持数据更新和删除功能&#xff1b; 第二&#xff0c;Del…

Quartz.NET 3.0 正式发布

Quartz.NET是一个强大、开源、轻量的作业调度框架&#xff0c;你能够用它来为执行一个作业而创建简单的或复杂的作业调度。它有很多特征&#xff0c;如&#xff1a;数据库支持&#xff0c;集群&#xff0c;插件&#xff0c;支持cron-like表达式等等。在2017年的最后一天Quartz.…

(九)IDEA便捷配置MyBatis.xml文件

在使用IDEA新建mybatis.xml经常需要手动复制粘贴之前的xml配置。这样也比较麻烦。我们可以IDEA进行关于xml的配置 1.创建MyBatis Config的模版 1.打开新增2.查看编辑页面查看编辑页面 我们看到Name&#xff1a;为我们新增模版的文件名称。Extension&#xff1a;为我们新增文件…

用 Identity Server 4 (JWKS 端点和 RS256 算法) 来保护 Python web api

目前正在使用asp.net core 2.0 (主要是web api)做一个项目, 其中一部分功能需要使用js客户端调用python的pandas, 所以需要建立一个python 的 rest api, 我暂时选用了hug, 官网在这: http://www.hug.rest/.目前项目使用的是identity server 4, 还有一些web api和js client.项目…

MySQL死锁如何处理

转载自 MySQL死锁如何处理 前提 笔者负责的一个系统最近有新功能上线后突然在预警模块不定时报出MySQL死锁导致事务回滚。幸亏&#xff0c;上游系统采用了异步推送和同步查询结合的方式&#xff0c;感知到推送失败及时进行了补偿。于是&#xff0c;笔者争取了一点时间详细分析…

(十)IDEA添加mybatis-mapp.xml文件

1.点击file–Settings–Editor–file and Code Templates 2.配置mybatis-mapper.xml的网址,点击file–Settings–ages& Frameworks–Schmas and DTDs 3.创建mapper.xml文件

g4e基础篇#2 Git分布式版本控制系统的优势

1. 基础篇&#xff1a;为什么要使用版本控制系统Git 分布式版本控制系统的优势Git 安装和设置初始化Git存储库(Repo)起步 1 – 创建分支和保存代码起步 2 – 了解Git历史记录起步 3 – 拉取请求 Pull Request 工作机制Git是当前最棒的版本控制系统&#xff0c;已经迅速成为了事…