DDD/CQRS模式,微服务,容器
DDD/CQRS模式,微服务,容器
https://docs.microsoft.com/zh-cn/previous-versions/msp-n-p/ee658109(v=pandp.10)
Web架构分层指南
一.概述
本章Web架构分层指南,参考了“Microsoft应用程序体系结构指南”(该书是在2009年出版的,当时出版是为了帮助开发人员和架构师更快速,更低风险地使用Microsoft平台和.NET Framework设计和构建有效,高质量的应用程序)。虽然已过去十年了,技术架构已更新(如流行的DDD/CQRS模式,微服务,容器),但web分层思想还是一样可取,下面是一个“传统N分层设计”架构图,该架构在2010年左右是最流行的,包括了表现层presentation,服务层services,业务层business,数据访问层data,横切关注点cross,如下所示:
对比传统多层或三层.net web架构,下图是当前流行的.net web微服务架构,在web程序分层之上还包含了容器,web api网关,各服务对应的数据存储(sqlserver,redis,mongoDB),web程序有web api并结合应用了DDD\CQRS分层模式,以及系统各种中间件。
下图是一个订单微服务站点,包含了简化的cqrs分层,蓝色长方格是表示cqrs分层的职责,包括了查询 Queries viewModels和命令Command Domain-Model以及上层的应用服务层Application,如下所示
1.1 逻辑分层设计架构类型
(1) 最传统的分层是经典三层设计,包括表现层,业务层,数据层.
(2) 基于服务的解决方案SOA,公开应用程序业务功能的服务层,服务层在业务层之上。
(3) 基于领域驱动设计的DDD\CQRS分层模式
(4) 微服务架构。
这4种web分层架构是不断的演化改变 ,每一种分层架构并不是独立的思想,它包含了演化之前的架构分层思想。从以前三层架构到现在的微服务架构,是适应每个时代互联网业务实现的需求。
功能 |
SOA |
微服务 |
组件大小 |
大块业务逻辑 |
单独任务或小块业务逻辑 |
耦合 |
通常松耦合 |
总是松耦合 |
公司架构 |
任何类型 |
小型、专注于功能交叉团队 |
管理 |
着重中央管理 |
着重分散管理 |
目标 |
确保应用能够交互操作 |
执行新功能、快速拓展开发团队 |
二.Web分层设计步骤
1.分层策略
(1)分层粒度是确定分层策略的关键第一步.
(2)在逻辑分层中, 多层是在同一进程中运行,这可以利用更高性能的通信机制。例如通过组件接口直接调用。必须小心保持层之间的封装和松散耦合。
(3)在物理分层中,确定合适的通信机制,该机制考虑到通信延迟并保持之间的松散耦合。
(4)多层中,考虑它们之间如何相互影响,将确保性能和灵活性之间的良好平衡。
2.确定需要层
最常用的方法是将表现层,服务层,业务层和数据访问层功能分离到单独的层中。某些应用程序还引入了各种组件像缓存、日志、消息队列等。
3.决定如何分发各层和组件
对于web体系架构,一般都是在一个物理层,只有在必要时,才应在不同的物理层上分布层和组件。这是实现分布式部署的常见原因包括安全策略,物理约束,共享业务逻辑和可伸缩性。
4.确定是否需要折叠层
一般规则是您应始终将功能分组到层中。在某些情况下,一个层可以充当代理或传递层,提供封装和松散耦合,而不提供大量功能。但是,通过分离该功能,您可以稍后对其进行扩展,而对设计中的其他层几乎没有影响,如:应用服务层。
5.确定层之间引用的规则
在分层策略时,您必须定义层如何相互交互的规则(交互是指:各层引用的关系)。指定交互规则的主要原因是最小化依赖性并消除循环引用。因此应该遵循以下方法之一:
(1)自上而下的交互
较高级别的层可以与下面的层交互,但是较低级别的层不应该与上面的层交互。此规则将帮助您避免层之间的循环依赖关系,以及要降低层之间的依赖性。
(2)严格的互动
每个层必须仅与下面的层进行交互。此规则将强制严格分离关注点,其中每个层仅知道下面的层。此规则的好处是对层界面的修改只会影响上面的层。如果您正在设计一个将随着时间的推移进行修改以引入新功能并且您希望最大限度地减少这些更改的影响的应用程序,或者您正在设计可能分布在不同物理层上的应用程序,请考虑使用此方法。
(3)松散的互动
较高级别的层可以绕过层直接与较低级别的层交互。这可以提高性能,但也会增加依赖性。换句话说,对较低级别层的修改可以影响上面的多个层。
下图是一个示例:该web架构示例是使用了 cqrs 模式,涉及到了事件源es, 事件源实现本因该分离到命令域和查询域, 而项目中应用服务层直接引用了底层数据访问层Dapper(绕过了领域层), 这样底层Dapper接口方法的修改或换成EF将影响顶层应用服务层,这属于第三种"松散的互动"。 应该推荐使用第一种自上而下的交互。
6.确定跨领域问题
定义层后,必须标识跨越层的功能。此功能通常被描述为横切关注点,包括日志记录,缓存,验证,身份验证和异常管理。确定应用程序中的每个横切关注点非常重要,并设计单独的组件以尽可能地管理这些问题。此方法可帮助您实现更好的可重用性和可维护性。
如下图所示:NLog与Redis是具体实现组件,实现了Common层中的日志和缓存接口,Common层就是横切组件,是跨层可重用的。像Ioc也是横切组件。 下图层的名称没有标识跨越层的功能,如果是GFNetCore.Infra.CrossCutting.IoC 这样命名会更好。
7.定义层之间的接口
为层定义接口时,主要目标是强制层之间的松散耦合。这意味着层不应暴露另一层可能依赖的内部细节。相反,层的接口应设计为通过提供隐藏层内组件细节的公共接口来最小化依赖性。这种隐藏称为抽象,有许多不同的方法来实现它。以下设计方法可用于定义层的接口:
(1)抽象接口
通过定义抽象基类或接口类来实现,该类充当具体类的类型定义。该类型定义了一个公共接口,该层的所有使用者都使用该接口与该层进行交互。这是一种面向接口编程,例如:表现层调用应用服务层的接口。表现层在CustomerController控制器中如下所示(通过依赖注入后,构造方法来实例):
//表现层调用应用服务层ApplicationService
private readonly ICustomerAppService _customerAppService; public CustomerController(ICustomerAppService customerAppService,
INotificationHandler<DomainNotification> notifications) : base(notifications)
{
_customerAppService = customerAppService;
}
但在项目中,为了简化开发量,表现层调用应用服务层的实现类(违反了面向接口编程)。表现层在CustomerController控制器中如下所示:
//调用应用服务层ApplicationService
private readonly CustomerAppService _customerAppService = null; //日志对象
public readonly ILoggerEX _logger; public CustomerController(INotificationHandler<DomainNotification> notifications,
ILoggerEX logger,
CustomerAppService customerAppService)
: base(notifications)
{
_customerAppService = customerAppService;
_logger = logger;
}
(2)依赖倒置
这是一种编程风格,是面向接口编程的实现,依赖倒置的应用如:DDD\CQRS, 层依赖于层接口,而不是层依赖于另一个层的实现。依赖注入模式是依赖性反转的常见实现。依赖性反转方法提供了灵活性,可以帮助实现可插入设计,因为依赖性是通过配置而不是代码组成的。它还可以最大化可测试性,因为您可以轻松地将具体测试类注入到设计的不同层中。
依赖性是通过配置的,如下代码所示,由CommandRepository类来实现ICommandRepository接口:
services.AddScoped<ICommandRepository<CommandModels.Customer>, CommandRepository<CommandModels.Customer>>();
services.AddScoped<IQueryRepository<QueryModels.Customer>, QueryRepository<QueryModels.Customer>>();
(3) 基于消息
可以使用基于消息的通信来实现接口并提供层之间的交互,.net技术如:wcf, web services, msmq它们支持跨物理和进程边界的交互(以xml的soap格式传输),但这是对于09年流行的web架构。现在基于消息多数用web api技术,是面向微服务开发(以json的rest api)。
asp.net core系列篇
asp.net core系列 73 Exceptionless+Nlog以及Apollo介绍
posted @ 2019-09-24 19:57 花阴偷移 阅读 (344) | 评论 (0)编辑
asp.net core系列 72 Exceptionless使用介绍
posted @ 2019-09-07 16:46 花阴偷移 阅读 (478) | 评论 (0)编辑
asp.net core系列 71 Web架构分层指南
posted @ 2019-08-23 09:32 花阴偷移 阅读 (1292) | 评论 (6)编辑
asp.net core系列 70 即时通迅-WebSocket+Redis发布订阅
posted @ 2019-08-09 09:33 花阴偷移 阅读 (1175) | 评论 (2)编辑
asp.net core系列 69 Amazon S3 资源文件上传示例
posted @ 2019-08-08 20:04 花阴偷移 阅读 (346) | 评论 (0)编辑
asp.net core系列 68 Filter管道过滤器
posted @ 2019-07-16 09:37 花阴偷移 阅读 (608) | 评论 (5)编辑
asp.net core系列 67 Web压力测试工具WCAT
posted @ 2019-07-11 12:34 花阴偷移 阅读 (660) | 评论 (3)编辑
asp.net core系列 66 Dapper介绍--Micro-ORM
posted @ 2019-06-29 14:27 花阴偷移 阅读 (928) | 评论 (0)编辑
asp.net core系列 65 正反案例介绍SOLID原则
posted @ 2019-05-24 09:43 花阴偷移 阅读 (519) | 评论 (1)编辑
asp.net core系列 64 结合eShopOnWeb全面认识领域模型架构
posted @ 2019-05-16 11:12 花阴偷移 阅读 (1011) | 评论 (5)编辑
asp.net core系列 63 领域模型架构 eShopOnWeb项目分析 上
posted @ 2019-05-13 13:45 花阴偷移 阅读 (1097) | 评论 (1)编辑
asp.net core系列 62 CQRS架构下Equinox开源项目分析
posted @ 2019-05-07 11:09 花阴偷移 阅读 (2196) | 评论 (23)编辑
asp.net core系列 61 Ocelot 构建服务发现简单示例
posted @ 2019-04-28 16:31 花阴偷移 阅读 (566) | 评论 (2)编辑
asp.net core系列 60 Ocelot 构建服务认证示例
posted @ 2019-04-25 15:06 花阴偷移 阅读 (529) | 评论 (0)编辑
asp.net core系列 59 Ocelot 构建基础项目示例
posted @ 2019-04-23 14:55 花阴偷移 阅读 (738) | 评论 (5)编辑
asp.net core系列 58 IS4 基于浏览器的JavaScript客户端应用程序
posted @ 2019-04-19 14:17 花阴偷移 阅读 (527) | 评论 (3)编辑
asp.net core系列 57 IS4 使用混合流(OIDC+OAuth2.0)添加API访问
posted @ 2019-04-18 14:49 花阴偷移 阅读 (495) | 评论 (0)编辑
asp.net core系列 56 IS4使用OpenID Connect添加用户认证
posted @ 2019-04-17 14:53 花阴偷移 阅读 (453) | 评论 (0)编辑
asp.net core系列 55 IS4使用Identity密码保护API
posted @ 2019-04-15 10:25 花阴偷移 阅读 (510) | 评论 (3)编辑
asp.net core系列 54 IS4用客户端凭据保护API
posted @ 2019-04-12 09:22 花阴偷移 阅读 (636) | 评论 (5)编辑
asp.net core系列 53 IdentityServer4 (IS4)介绍
posted @ 2019-04-11 09:05 花阴偷移 阅读 (722) | 评论 (1)编辑
asp.net core系列 52 Identity 其它关注点
posted @ 2019-04-10 09:58 花阴偷移 阅读 (252) | 评论 (0)编辑
asp.net core系列 51 Identity 授权(下)
posted @ 2019-04-09 12:03 花阴偷移 阅读 (562) | 评论 (5)编辑
asp.net core系列 50 Identity 授权(中)
posted @ 2019-04-08 10:42 花阴偷移 阅读 (719) | 评论 (1)编辑
asp.net core系列 49 Identity 授权(上)
posted @ 2019-04-03 11:44 花阴偷移 阅读 (732) | 评论 (1)编辑
asp.net core系列 48 Identity 身份模型自定义
posted @ 2019-03-25 15:51 花阴偷移 阅读 (893) | 评论 (1)编辑
asp.net core系列 47 Identity 自定义用户数据
posted @ 2019-03-22 16:24 花阴偷移 阅读 (881) | 评论 (0)编辑
asp.net core系列 46 Identity介绍
posted @ 2019-03-21 17:00 花阴偷移 阅读 (1075) | 评论 (0)编辑
asp.net core系列 45 Web应用 模型绑定和验证
posted @ 2019-03-20 10:43 花阴偷移 阅读 (542) | 评论 (0)编辑
asp.net core系列 44 Web应用 布局
posted @ 2019-03-19 09:05 花阴偷移 阅读 (667) | 评论 (0)编辑
asp.net core系列 43 Web应用 Session分布式存储(in memory与Redis)
posted @ 2019-03-18 09:43 花阴偷移 阅读 (741) | 评论 (3)编辑
asp.net core系列 42 Web 应用 分部视图
posted @ 2019-03-14 10:35 花阴偷移 阅读 (520) | 评论 (1)编辑
asp.net core系列 41 Web 应用 MVC视图
posted @ 2019-03-13 11:56 花阴偷移 阅读 (467) | 评论 (0)编辑
asp.net core系列 40 Web 应用MVC 介绍与详细示例
posted @ 2019-03-11 14:56 花阴偷移 阅读 (771) | 评论 (0)编辑
asp.net core系列 39 Web 应用Razor 介绍与详细示例
posted @ 2019-03-08 10:17 花阴偷移 阅读 (379) | 评论 (0)编辑
asp.net core系列 38 WebAPI 返回类型与响应格式--必备
posted @ 2019-03-06 11:59 花阴偷移 阅读 (1232) | 评论 (0)编辑
asp.net core系列 37 WebAPI 使用OpenAPI (swagger)中间件
posted @ 2019-03-05 11:24 花阴偷移 阅读 (849) | 评论 (0)编辑
asp.net core系列 36 WebAPI 搭建详细示例
posted @ 2019-03-04 11:47 花阴偷移 阅读 (1695) | 评论 (0)编辑
asp.net core系列 35 EF保存数据(2) -- EF系列结束
posted @ 2019-03-01 11:54 花阴偷移 阅读 (597) | 评论 (0)编辑
asp.net core系列 34 EF保存数据(1)
posted @ 2019-02-28 16:00 花阴偷移 阅读 (630) | 评论 (0)编辑
asp.net core系列 33 EF查询数据 (2)
posted @ 2019-02-27 16:09 花阴偷移 阅读 (507) | 评论 (2)编辑
asp.net core系列 32 EF查询数据 必备知识(1)
posted @ 2019-02-26 16:22 花阴偷移 阅读 (923) | 评论 (3)编辑
asp.net core系列 31 EF管理数据库架构--必备知识 反向工程
posted @ 2019-02-25 13:57 花阴偷移 阅读 (824) | 评论 (1)编辑
asp.net core系列 30 EF管理数据库架构--必备知识 迁移
posted @ 2019-02-22 16:19 花阴偷移 阅读 (739) | 评论 (2)编辑
asp.net core系列 29 EF模型配置(查询类型,关系数据库建模)
posted @ 2019-02-21 17:39 花阴偷移 阅读 (573) | 评论 (2)编辑
asp.net core系列 28 EF模型配置(字段,构造函数,拥有实体类型)
posted @ 2019-02-20 17:47 花阴偷移 阅读 (599) | 评论 (2)编辑
asp.net core系列 27 EF模型配置(索引,备用键,继承)
posted @ 2019-02-19 12:29 花阴偷移 阅读 (534) | 评论 (0)编辑
asp.net core系列 26 EF模型配置(实体关系)
posted @ 2019-02-18 15:18 花阴偷移 阅读 (603) | 评论 (0)编辑
asp.net core系列 25 EF模型配置(隐藏属性)
posted @ 2019-02-17 11:19 花阴偷移 阅读 (441) | 评论 (0)编辑
asp.net core系列 24 EF模型配置(主键,生成值,最大长度,并发标记)
posted @ 2019-02-16 09:49 花阴偷移 阅读 (623) | 评论 (0)编辑
asp.net core系列 23 EF模型配置(概述, 类型和属性的包含与排除)
posted @ 2019-02-15 09:25 花阴偷移 阅读 (559) | 评论 (0)编辑
asp.net core 系列 22 EF(连接字符串,连接复原,DbContext)
posted @ 2019-02-14 09:47 花阴偷移 阅读 (1739) | 评论 (0)编辑
asp.net core 系列 21 EF现有数据库进行反向工程
posted @ 2019-02-13 09:32 花阴偷移 阅读 (860) | 评论 (0)编辑
asp.net core 系列 20 EF基于数据模型创建数据库
posted @ 2019-02-12 09:43 花阴偷移 阅读 (1112) | 评论 (3)编辑
asp.net core 系列 19 EFCore介绍
posted @ 2019-01-30 09:42 花阴偷移 阅读 (1056) | 评论 (1)编辑
asp.net core 系列 18 web服务器实现
posted @ 2019-01-29 09:17 花阴偷移 阅读 (1515) | 评论 (2)编辑
asp.net core 系列 17 通用主机 IHostBuilder
posted @ 2019-01-28 09:13 花阴偷移 阅读 (1070) | 评论 (0)编辑
asp.net core 系列 16 Web主机 IWebHostBuilder
posted @ 2019-01-25 11:06 花阴偷移 阅读 (1175) | 评论 (2)编辑
asp.net core 系列 15 中间件
posted @ 2019-01-24 10:26 花阴偷移 阅读 (981) | 评论 (0)编辑
asp.net core 系列 14 错误处理
posted @ 2019-01-23 09:17 花阴偷移 阅读 (722) | 评论 (0)编辑
asp.net core 系列 13 日志
posted @ 2019-01-22 09:44 花阴偷移 阅读 (940) | 评论 (2)编辑
asp.net core 系列 12 选项 TOptions
posted @ 2019-01-21 11:47 花阴偷移 阅读 (832) | 评论 (1)编辑
asp.net core 系列 11 配置configuration (下)
posted @ 2019-01-18 14:06 花阴偷移 阅读 (804) | 评论 (0)编辑
asp.net core 系列 10 配置configuration (上)
posted @ 2019-01-17 17:39 花阴偷移 阅读 (1143) | 评论 (0)编辑
asp.net core 系列 9 三种运行环境和IIS发布
posted @ 2019-01-16 15:00 花阴偷移 阅读 (1064) | 评论 (6)编辑
asp.net core 系列 8 Razor框架路由(下)
posted @ 2019-01-15 16:47 花阴偷移 阅读 (838) | 评论 (0)编辑
asp.net core 系列 7 Razor框架路由(上)
posted @ 2019-01-14 11:13 花阴偷移 阅读 (1213) | 评论 (0)编辑
asp.net core 系列 6 MVC框架路由(下)
posted @ 2019-01-11 10:11 花阴偷移 阅读 (1092) | 评论 (7)编辑
asp.net core 系列 5 MVC框架路由(上)
posted @ 2019-01-09 17:25 花阴偷移 阅读 (1575) | 评论 (4)编辑
asp.net core 系列 4 注入服务的生存期
posted @ 2019-01-08 10:47 花阴偷移 阅读 (1527) | 评论 (6)编辑
asp.net core 系列 3 依赖注入服务
posted @ 2019-01-06 11:36 花阴偷移 阅读 (1705) | 评论 (2)编辑
asp.net core 系列 2 启动Startup类介绍
posted @ 2019-01-05 13:57 花阴偷移 阅读 (2310) | 评论 (1)编辑
asp.net core 系列 1 概述
posted @ 2019-01-02 13:49 花阴偷移 阅读 (2623) | 评论 (5)编辑
DDD/CQRS模式,微服务,容器的更多相关文章
- WeText项目:一个基于.NET实现的DDD、CQRS与微服务架构的演示案例
最近出于工作需要,了解了一下微服务架构(Microservice Architecture,MSA).我经过两周业余时间的努力,凭着自己对微服务架构的理解,从无到有,基于.NET打造了一个演示微服务架 ...
- NET实现的DDD、CQRS与微服务架构
WeText项目:一个基于.NET实现的DDD.CQRS与微服务架构的演示案例 最近出于工作需要,了解了一下微服务架构(Microservice Architecture,MSA).我经过两周业余时间 ...
- .NET Core/.NET5/.NET6 开源项目汇总6:框架与架构设计(DDD、云原生/微服务/容器/DevOps/CICD等)项目
系列目录 [已更新最新开发文章,点击查看详细] 开源项目是众多组织与个人分享的组件或项目,作者付出的心血我们是无法体会的,所以首先大家要心存感激.尊重.请严格遵守每个项目的开源协议后再使用.尊 ...
- 基于容器微服务的PaaS云平台设计(二)通过kubernetes实现微服务容器管理
版权声明:本文为博主原创文章,欢迎转载,转载请注明作者.原文超链接 ,博主地址:http://www.cnblogs.com/SuperXJ/ 上一章描述了基于spring cloud的微服务实例(实 ...
- .NET微服务 容器化.NET应用架构指南(支持.NET Core2)
介绍 企业通过使用容器,日益实现成本节约.解决部署问题并改进 DevOps 和生产操作. 通过创建 Azure 容器服务.Azure Service Fabric 等产品,同时与 Docker.Mes ...
- Docker+Kubernetes(k8s)微服务容器化实践
第1章 初识微服务微服务的入门,我们从传统的单体架构入手,看看在什么样的环境和需求下一步步走到微服务的,然后再具体了解一下什么才是微服务,让大家对微服务的概念有深入的理解.然后我们一起画一个微服务的架 ...
- .Net Core 微服务容器系列基础目录篇
1.开场白 HI,各位老铁,大家端午好,之前写了些关于.net core商城系列的文章,有点乱,今天心血来潮想着整理一下(今天只是先把目录列出来,后面的每篇文章这两天会进行重新修改的,目前先将就看下) ...
- DDD之1微服务设计为什么选择DDD
背景 名词解释 如果你的团队目前正是构建微服务架构风格的软件系统,问自己两个问题? 软件架构演进 软件架构大致经历了从单机架构,集中式架构,分布式微服架构,程序的层次图如下所示. 单机架构 特点如下: ...
- 【DDD/CQRS/微服务架构案例】在Ubuntu 14.04.4 LTS中运行WeText项目的服务端
在<WeText项目:一个基于.NET实现的DDD.CQRS与微服务架构的演示案例>文章中,我介绍了自己用Visual Studio 2015(C# 6.0 with .NET Frame ...
随机推荐
- idea中隐藏.iml文件
在创建父子工程或者聚合工程时产生的大量 .iml 文件,有时会对我们的操作产生干扰,所以,一般情况下,我们都将其隐藏掉,步骤如下: File——>settings——>Editor——&g ...
- 项目(二) esp32-cam 网页图像人脸
https://randomnerdtutorials.com/esp32-cam-video-streaming-face-recognition-arduino-ide/ ESP32-CAM Pi ...
- UFUN函数 UF_ATTR函数(UF_ATTR_read_value 函数用法)
//此函数的功能是输入tag值,返回与属性标题对应的属性值 static string read_attr(tag_t object_tag) { UF_initialize(); ]="零 ...
- 【LG3582】[POI2015]KIN
[LG3582][POI2015]KIN 题面 洛谷 题解 这题维护区间的信息有点像最大子段和,我们往最大子段和上面靠. 对于一个颜色,我们有一个直观的想法就是将它一次出现的权值设为正,二次出现就设为 ...
- 设置Git--在Git中设置您的用户名--创建一个回购--Fork A Repo--社会化
设置Git GitHub的核心是名为Git的开源版本控制系统(VCS).Git负责计算机上本地发生的所有GitHub相关的事情. 要在命令上使用Git,您需要在计算机上下载,安装和配置Git. 如果要 ...
- Internet地址结构
IP地址结构及分类寻址 IP地址 = <网络号> + <主机号> ------------IPv4(32bit)点分四组表示法: 192.168.31.1 ...
- java.lang.IllegalArgumentException: host parameter is null
即 URL 应为 http://www.baidu.com 但是实际配置成了 www.baidu.com 所以出现此错误
- lastlogon
function Get-ADUserLastLogon($userName) { $dcs = Get-ADDomainController -Filter {Name -like "*& ...
- API调试工具--------Postman
Postman一款非常流行的API调试工具.其实,开发人员用的更多.因为测试人员做接口测试会有更多选择,例如Jmeter.soapUI等.不过,对于开发过程中去调试接口,Postman确实足够的简单方 ...
- coroutine闲谈
coroutine居然能被吹到这种地步