commandbus

记近一年线上项目经验及架构变更记录

馋奶兔 提交于 2020-08-17 02:19:42
简介 M 项目, 是一个电子社保业务系统,2019.8 月团队接手了这个项目的开发工作,到 2020.7 月客户的业务量翻了4倍,工作日同时在线员工数量40人,以下记录总结 2019.8-至今项目的架构变化,以及项目中积累的一些经验。 [2019.8] 项目接手后的初始架构 物理架构 M 项目的原始物理架构非常的简单,属于最简单的单机单体系统,大部分服务都寄宿在一台双核,8G 内存的虚拟机中(包含 MySQL 数据库服务和文件存储服务),只有邮件发送服务使用的是第三方服务 SendGrid 。相对于客户最多 10 人同时在线的需求,日均 300 张发票的业务场景,此虚拟机的配置和物理架构足够支撑客户的业务。 逻辑架构 项目初期的逻辑架构也非常简单,有 2 个可用站点,分别是业务系统站点 Gateway 和项目宣传站点 Portal 。所有的业务都封装在 Gateway API 中。数据持久化使用了单机版的 MySQL 实例。 其中 Gateway API 是项目的核心部分,程序的所有业务代码都集中于此,小到发送邮件,创建 PDF, 大到提交发票,社保索赔,支付订单都放置与此。这种设计方式很适合初期堆功能,虽然后期客户发展,这种设计造成了很大的问题,但是在项目初期,我觉着这种方式还是非常适合帮助客户快速拓展业务的。 在逻辑架构上,我觉着唯一存在问题就是 Gateway API

eShopOnContainers 知多少[11]:服务间通信之gRPC

删除回忆录丶 提交于 2020-08-15 11:32:04
引言 最近翻看最新3.0 eShopOncontainers源码,发现其在架构选型中补充了 gRPC 进行服务间通信。那就索性也写一篇,作为系列的补充。 gRPC 老规矩,先来理一下gRPC的基本概念。gRPC是Google开源的RPC框架,比肩dubbo、thrift、brpc。其优势在于: 1. 基于proto buffer:二进制协议,具有高性能的序列化机制。相较于JSON(文本协议)而言,首先从数据包上就有60%-80%的减小,其次其解包速度仅需要简单的数学运算完成,无需复杂的词法语法分析,具有8倍以上的性能提升。 2. 支持数据流。 3. 基于proto 文件:可以更方便的在客户端和服务端之间进行交互。 4. gRPC语言无关性: 所有服务都是使用原型文件定义的。这些文件基于protobuffer语言,并定义服务的接口。基于原型文件,可以为每种语言生成用于创建服务端和客户端的代码。其中protoc编译工具就支持将其生成C #代码。从.NET Core 3 中,gRPC在工具和框架中深度集成,开发者会有更好的开发体验。 gRPC 在 eShopOncontainers 的应用 首先来理一下eShopOncontainers 中服务间同步通信的技术选型,主要还是是基于HTTP/REST,gRPC作为补充。 在eShopOncontainers中Ordering API

架构简洁之道:从阿里开源应用架构COLA说起

时间秒杀一切 提交于 2020-08-11 17:09:51
导读: COLA 的主要目的是为应用架构提供一套简单的可以复制、可以理解、可以落地、可以控制复杂性的”指导和约束"。在实践中作者发现 COLA 在简洁性上仍有不足,因此给 COLA 做了一次“升级”,在这次升级中,没有增加任何新的功能,而是尽量多删减了一些概念和功能,让 COLA 更简洁有效。 最近,同事告诉我,COLA 作为应用架构,已经被选入阿里云的 Java 应用初始化的应用架构选项之一。 This is really something,于是,在这个里程碑节点上,我开始回过头来,重新审视 COLA 一路走来的得与失。 COLA 作为一种架构思想无疑是成功的。但是作为框架,个人感觉有点鸡肋之嫌。特别是在简洁性上做的不好,感觉做了不少画蛇添足的事情。 试想一下,有些功能我作为作者都很少去使用,我实在想不到,它为什么还有存在的理由。 基于上面的思考,我做了这一次 COLA 2.0 到 COLA 3.0 的升级。在本次升级中,我没有增加任何新的功能,而是尽量多删减了一些概念和功能。让 COLA 可以更加纯粹的 focus 在应用架构上,而不是框架支持和架构约束上。 支持我做这些决策的背后原因只有一个——奥卡姆剃刀原理。 奥卡姆剃刀原理 奥卡姆剃刀原理,是指如无必要,勿增实体(Entities should not be multiplied unnecessarily),即

架构简洁之道:从阿里开源应用架构 COLA 说起

让人想犯罪 __ 提交于 2020-08-09 13:04:50
导读 :COLA 的主要目的是为应用架构提供一套简单的可以复制、可以理解、可以落地、可以控制复杂性的”指导和约束"。在实践中作者发现 COLA 在简洁性上仍有不足,因此给 COLA 做了一次“升级”,在这次升级中,没有增加任何新的功能,而是尽量多删减了一些概念和功能,让 COLA 更简洁有效。 最近,同事告诉我,COLA 作为应用架构,已经被选入阿里云的 Java 应用初始化的应用架构选项之一。 This is really something,于是,在这个里程碑节点上,我开始回过头来,重新审视 COLA 一路走来的得与失。 COLA 作为一种架构思想无疑是成功的。但是作为框架,个人感觉有点鸡肋之嫌。特别是在简洁性上做的不好,感觉做了不少画蛇添足的事情。 试想一下,有些功能我作为作者都很少去使用,我实在想不到,它为什么还有存在的理由。 基于上面的思考,我做了这一次 COLA 2.0 到 COLA 3.0 的升级。在本次升级中,我没有增加任何新的功能,而是尽量多删减了一些概念和功能。让 COLA 可以更加纯粹的 focus 在应用架构上,而不是框架支持和架构约束上。 支持我做这些决策的背后原因只有一个——奥卡姆剃刀原理。 奥卡姆剃刀原理 奥卡姆剃刀原理,是指如无必要,勿增实体(Entities should not be multiplied unnecessarily),即

CQRS之旅——旅程3(订单和注册限界上下文)

北战南征 提交于 2020-04-27 21:18:56
旅程3:订单和注册限界上下文 CQRS之旅的第一站 “寓言家和鳄鱼是一样的,只是名字不同” --约翰·劳森 描述: 订单和注册上下文有一部分职责在会议预订的过程中,在此上下文中,一个人(注册者)可以购买特定会议的座位。还可以为已购买的座位分配与会者的名称(这在第5章“ 准备发布V1版本 ”中进行了描述)。 这是我们CQRS旅程的第一站,因此团队决定实现一个核心的、但自包含的系统部分——订单和注册。对与会者来说,注册过程必须尽可能地轻松。该流程必须确保业务客户能够预订到尽可能多的座位,并为他们提供灵活的,在会议上为不同类型的座位设置价格的功能。 因为这是团队处理的第一个限界上下文,所以我们还实现了系统的一些基础设施来支持领域域的功能。包括命令和事件消息总线以及聚合的持久化机制。 备注:本章描述的Contoso会议管理系统并不是该系统的最终版本。本此旅程描述的是一个过程,因此一些设计决策和实现细节在过程的后期会发生变化。这些变化将在后面的章节中描述。 在将来的某个旅程中,对这个限界上下文的改进计划包括支持等待列表(如果没有足够的座位可用,对座位的请求将放在等待列表中),以及允许业务客户为座位类型设置各种类型的折扣。 备注:在这个版本中没有实现等待列表,但是社区成员正在开发这个特性和其他特性。任何带外发布和更新都将在“ CQRS之旅 ”网站上公布。 本章的工作术语定义:

CQRS之旅——旅程8(后记:经验教训)

自作多情 提交于 2020-04-26 15:36:17
旅程8:后记:经验教训 我们的地图有多好?我们走了多远?我们学到了什么?我们迷路了吗? “这片土地可能对那些愿意冒险的人有益。”亨利.哈德逊 这一章总结了我们旅程中的发现。它强调了我们在这个过程中所学到的最重要的经验教训,提出了如果我们用新知识开始这段旅程,我们将以不同的方式做的一些事情,并指出了Contoso会议管理系统的一些未来道路。 你应该记住,这个总结反映的是我们的具体旅程,并非所有这些发现都适用于你自己的CQRS旅行。例如,我们的目标之一是探索如何在部署到Microsoft Azure并在利用云的可伸缩性和可靠性的应用程序中实现CQRS模式。对于我们的项目,这意味着使用消息传递来支持多个角色类型和实例之间的通信。您的项目可能不需要多个角色实例,或者没有部署到云中,因此可能不需要如此广泛地(或者根本不需要)使用消息传递。 我们希望这些发现能够被证明是有用的,特别是当您刚刚开始使用CQRS和事件源时。 我们学到了什么 本节描述了我们学到的主要经验教训。它们没有以任何特定的顺序呈现。 性能问题 在我们的旅程开始时,我们对CQRS模式的一个概念是,通过分离应用程序的读和写方面,我们可以优化每个方面的性能。CQRS社区的许多人都认同这一观点,例如: “CQRS告诉我,我可以分别优化读和写,而且我不必总是手动的反规范化到平面表中。” Kelly Sommers - CQRS顾问

微服务实战(七):落地微服务架构到直销系统(实现命令与命令处理器)

浪子不回头ぞ 提交于 2020-04-22 02:53:40
我们先来看看CQRS架构,你对下图的架构还有印象吗?每个组件的功能都还清楚吗?如果有疑问,请查考文章《 微服务实战(五):落地微服务架构到直销系统(构建高性能大并发系统) 》。 前一篇文章已经实现了Event Store的基础功能部分,本篇文章我们通过C端的标准方式,实现一个下单的高并发命令端,来看看需要实现的具体流程: 1.前端用户调用一个下单Command WebApi,传递下单命令;下单Command WebApi接受到下单命令后,将下单命令数据投递到一个命令队列中,向前端用户返回一个信息。 2.下单Command Handler WebApi侦听命令队列中的下单命令,然后调用领域对象逻辑,将执行的结果也就是Order对象的当前状态持久化到Event Store中。 3.下单Command Handler WebApi将下单相关信息通过事件的方式发布到一个事件队列中。(用户事件处理器最终将订单信息更新到业务库中) 下面通过代码简单体现下过程: 1.定义创建订单命令: public class CreateOrderCommand:BaseEvent { public OrderDTO orderdto { get ; set ; } public CreateOrderCommand() { } public CreateOrderCommand(OrderDTO

如何将 .NetFramework WebApi 按业务拆分成多个模块

谁说我不能喝 提交于 2020-04-13 21:09:52
【今日推荐】:为什么一到面试就懵逼!>>> 如何将 .NetFramework WebApi 按业务拆分成多个模块 在 .NetFramework 中使用 WebApi ,在不讨论 微服务 的模式下,大部分都是以层来拆分库的 : 基础设施 数据存储层 服务层 WeApi 层 一些其它的功能库 项目结构可能会像下面这样子 有些人可能会将其中的 数据存储层、服务层 按业务功能进行垂直拆分, 但是到了 WebApi 这层,就不得不把所向所有业务功能的 Controller 都堆在这儿了。 随着业务的堆积,WebApi 这层的代码量越来越大,耦合性也越来越强,越来越难维护。 … …… ……… ………… 这时候,微服务 就出现了。 可是,微服务 给系统所带来的复杂程度是极高的, 在某些场景下,转 微服务 可以很好的解决这些问题,但是又会带来更多的新问题, 所以我们希望有一种模式,即能像 微服务 那样对代码进行垂直切分,又能保持简单易维护的 单体应用程序 模式。 打算在 单体应用程序 中解决这种趋于 臃肿 问题,我们可以借鉴 微服务 那种 按业务垂直拆分 的思想。 但是与 微服务 不同是,它依然是单启动程序,这个启动程序能够组织出散落在各个模块中的所有 WebApi 并暴露给外部。 换个角度思考,其实就是将业务 模块化 。 微软维护的 Ochard 框架很好的实现了这些功能,但是使用