如何一步一步用DDD设计一个电商网站(十三)—— 领域事件扩展

news/2024/5/9 19:02:19/文章来源:https://blog.csdn.net/weixin_33910434/article/details/86232389

本系列所有文章

如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念

如何一步一步用DDD设计一个电商网站(二)—— 项目架构

如何一步一步用DDD设计一个电商网站(三)—— 初涉核心域

如何一步一步用DDD设计一个电商网站(四)—— 把商品卖给用户

如何一步一步用DDD设计一个电商网站(五)—— 停下脚步,重新出发

如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文

如何一步一步用DDD设计一个电商网站(七)—— 实现售价上下文

如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成

如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑

如何一步一步用DDD设计一个电商网站(十)—— 一个完整的购物车

如何一步一步用DDD设计一个电商网站(十一)—— 最后的准备

如何一步一步用DDD设计一个电商网站(十二)—— 提交并生成订单

如何一步一步用DDD设计一个电商网站(十三)—— 领域事件扩展

 

 

阅读目录

  • 前言
  • 回顾
  • 本地的一致性
  • 领域事件发布出现异常
  • 订阅者处理出现异常
  • 结语

 

一、前言

  上篇中我们初步运用了领域事件,其中还有一些问题我们没有解决,所以实现是不健壮的,下面先来回顾一下。

 

二、回顾

  先贴一下上篇中的遗留的问题:

        public Result Create(OrderRequest orderRequest){if (!string.IsNullOrWhiteSpace(orderRequest.CouponId)){var couponResult = DomainRegistry.SellingPriceService().IsCouponCanUse(orderRequest.CouponId, orderRequest.OrderTime);if (!couponResult.IsSuccess)return Result.Fail(couponResult.Msg);}var orderId = DomainRegistry.OrderRepository().NextIdentity();var order = Domain.Order.Aggregate.Order.Create(orderId, orderRequest.UserId, orderRequest.Receiver,orderRequest.CountryId, orderRequest.CountryName, orderRequest.ProvinceId, orderRequest.ProvinceName,orderRequest.CityId, orderRequest.CityName, orderRequest.DistrictId, orderRequest.DistrictName,orderRequest.Address, orderRequest.Mobile, orderRequest.Phone, orderRequest.Email,orderRequest.PaymentMethodId, orderRequest.PaymentMethodName, orderRequest.ExpressId,orderRequest.ExpressName, orderRequest.Freight, orderRequest.CouponId, orderRequest.CouponName, orderRequest.CouponValue, orderRequest.OrderTime);foreach (var orderItemRequest in orderRequest.OrderItems){order.AddOrderItem(orderItemRequest.ProductId, orderItemRequest.Quantity, orderItemRequest.UnitPrice, orderItemRequest.JoinedMultiProductsPromotionId, orderItemRequest.ProductName);}DomainRegistry.OrderRepository().Save(order);DomainEventBus.Instance().Publish(new OrderCreated(order.ID, order.UserId, order.Receiver));return Result.Success();}

  不知道大家有没有发现这里代码上的一个问题,就是DomainEventBus.Instance().Publish()方法在聚合的Save操作之后进行,其实本身不是很符合DDD的概念,任何的领域事件都是基于一个领域对象的,没有领域对象何来领域事件,所以领域事件一般都是由领域对象内部产生,故这里应该要把DomainEventBus.Instance().Publish()方法搬到Order.Create中调用。如果发现这个问题的童鞋,恭喜你对于领域事件的理解已经又深入了一个层次了。好了上篇中这么写其实是为了凸显出本地数据修改提交和领域事件的发布是涉及到数据一致性的问题的,其中的问题是:

  1.如果领域事件发布出现异常了怎么办?

  2.如果订阅者处理出现异常了怎么办?

  本篇我们就来一个一个解决问题。

 

三、本地的一致性

  在解决上面的2个问题之前,我们先需要考虑在修改多个聚合的场景下本地上下文内的一致性问题,这个职责在DDD中由工作单元(UnitOfWork)来负责,工作单元就是为了保证本地的事务一致性,在.Net里的实现一般就是对SqlTransaction的封装运用。关于工作单元的实现一般有2种方式:

  (1)完全依赖于SqlTransaction,在工作单元第一次运用的时候就开启数据库事务。

  (2)使用本地变量存储变动的聚合,然后在工作单元Commit()的时候开启数据库事务并写入。

  2个实现方案各有优缺点,需要在一致性和性能之间做出权衡。另外工作单元和领域事件发布的结合运用可以参考我之前写的2篇文章:DDD设计中的Unitwork与DomainEvent如何相容?和DDD中的Unitwork与DomainEvent如何相容?(续),注意的是我在这2篇中运用的是方式(2)的实现方式。秉着没有最好只有更好的精神,如何才能做到更好的一致性,这里需要引出几个架构层面的概念:ES、Saga、A+ES。这些内容有一篇蟋蟀兄的文章(传送门在此)讲的很好,推荐大家阅读一下,我就不展开讲这些内容了。里面每一种方案的运用都有成本,大家根据实际情况权衡再运用即可,切记:软件开发中没有银弹。

 

四、领域事件发布出现异常

  这个现象是否会出现需要根据领域事件发布的实现方式来决定,只要实现方式是“非本地”的方案,那么必然会出现一些异常的状况。假如领域事件是通过消息队列来实现,那么涉及到了网络传输必然会大大的增加出现异常的可能性。如何来解决此类问题,秉承着一图胜千言的思想我直接贴个思维导图,先看下一般的几种实现方案的特点,见图1:

DDD13(1)

                             【图1】

  根据这个图,我们发现鱼和熊掌不可兼得,每个方案都由各自的特点,我们应当根据不同的场景使用不同的实现方案去做,才是最好的选择,并且据我所知,目前支持事务的消息队列开源方案非常的少,所以我们需要通过一定的补偿机制来处理与消息队列通信出现问题的场景。另外在分布式系统中,服务端的接口设计尽量需要满足无状态和幂等性(不展开去讲了,大家自行百度或者google),这也是整个系统高可用的重要的一环。最后的最后,通过对账机制作为最后一道防线,确保重要的数据不产生差错。

  那么我们来看一下这2个实现方案对应我们的编码应该如何来做:

  1.通过消息机制的发布就是把我在Demo中运用DomainEventBus的内部实现由Dictionary替换为外部的消息队列即可,然后需要注册DistributeExceptionEvent来处理丢给消息队列进行分发时出现异常的问题,做补偿措施。

  2.通过DB的方案,大致的伪代码如下:

            var unitOfWork = new UnitOfWork();unitOfWork.RegisterSaved(order);var domainEvents = GetEventsFromBus();foreach(var domainEvent in domainEvents){var body = Serialize(domainEvent);unitOfWork.RegisterSaved(new Message{Body = body});}return unitOfWork.Commit();

  大家可以看到,这个方式首先带来的问题是让工作单元变得异常的臃肿,随之导致整个事务的总耗时增加。并且此时Message表中的现存数据可能还在同步进行消费/推送,那么产生资源竞争是必然会遇到的问题,导致的后果是整个工作单元的提交失败。

 

五、订阅者处理出现异常

  这个问题也是比较常见的,特别是处理业务复杂的接口和涉及过多RPC调用的接口出现的概率更大。所以每个应用每个接口都需要考虑好此类问题。一般的解决方案我也梳理了一个思维导图,如下图2:

DDD13(2)

                              【图2】

  其实很明显通过回滚的方式有很多局限性。所以说个人建议选择下面的方案,尽量做到内部消化,以提高接口对外的自治性。另外针对重试进行一些限制,一是为了减少一些无用功来占用系统资源,二是避免在系统本身达到瓶颈的情况下出现马太效应,让拥堵问题越发严重。

 

六、结语

  本篇没有增加太多代码,只是在Mall.Infrastructure中增加了几个工作单元(方式(2))相关的类,其中只包含了一些核心逻辑代码,具体的实现希望大家能够自己动手。多谢各位看官。

 

 

 

本文完整的源码地址:https://github.com/ZacharyFan/DDDDemo/tree/Demo13。

 

作者:Zachary_Fan
出处:http://www.cnblogs.com/Zachary-Fan/p/DDD_13.html

 

 

▶关于作者:张帆(Zachary,个人微信号:Zachary-ZF)。坚持用心打磨每一篇高质量原创。欢迎扫描右侧的二维码~。

定期发表原创内容:架构设计丨分布式系统丨产品丨运营丨一些思考。

 

如果你是初级程序员,想提升但不知道如何下手。又或者做程序员多年,陷入了一些瓶颈想拓宽一下视野。欢迎关注我的公众号「跨界架构师」,回复「技术」,送你一份我长期收集和整理的思维导图。

如果你是运营,面对不断变化的市场束手无策。又或者想了解主流的运营策略,以丰富自己的“仓库”。欢迎关注我的公众号「跨界架构师」,回复「运营」,送你一份我长期收集和整理的思维导图。

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

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

相关文章

安全分析的几个好的工具网站的使用

最近在工作中还是遇到了一些攻击者追查等等事情,结合自己过去做过一年的安全分析师的经验,对几款比较好的追踪溯源网站的使用做一个简介。 一、关联神器passivetotal 1、网址:https://community.riskiq.com/ 2、简介:常用来搜索IP…

java 在线编辑模版 代码编辑器 兼容手机平板PC freemaker 静态引擎 网站源码

java 企业网站源码 前后台都有 静态模版引擎, 代码生成器大大提高开发效率前台: 支持三套模版, 可以在后台切换官网 http://www.fhadmin.org/系统介绍:1.网站后台采用主流的 SSM 框架 jsp JSTL,网站后台采用freemaker静…

我用阿里云部署的个人网站并帮兄弟表白

我叫田程,是四川理工学院一名大二的学生,主修通信工程专业。因为个人的兴趣爱好,目前在用ECS云服务器部署网站和挂机。 我的初衷只是想做一个类似广告联盟的产品,后来发现对我来说兴趣是大于功利的,就放弃了盈利的想法…

SEO优化-robots.txt解读

一、什么是robots.txt robots.txt 文件由一条或多条规则组成。每条规则可禁止(或允许)特定抓取工具抓取相应网站中的指定文件路径。 通俗一点的说法就是:告诉爬虫,我这个网站,你哪些能看,哪些不能看的一个协…

net java开发网站性能_TechEmpower Web 框架性能第19轮测试结果正式发布,ASP.NET Core在主流框架中拔得头筹...

TechEmpower 第19轮编程语言框架性能排行榜2020年5月28日正式发布,详见官方博客:https://www.techempower.com/blog/2020/05/28/framework-benchmarks-round-19/,TechEmpower基准测试有许多场景(也称为测试类型),此次评测多了一个综合评分选项…

网站域名空间服务器,网站 域名 空间 服务器

网站 域名 空间 服务器 内容精选换一换本节介绍使用华为云DDoS高防保障业务连续性,且网站域名解析至中国大陆节点服务器的备案场景。如图1所示。① 配置网站域名(www.example.com),接入华为云DDoS高防,把域名解析指向高防IP。② 用户通过网站…

注册网站域名多少钱_新手如何注册域名—建立网站,从域名注册开始

注册域名的一般流程是什么?个人申请域名流程需要知道哪些?一、域名注册流程、方法:1.在网站上注册一个用户名。(http://www.11977.net/reg/ 点击注册 这里我们列举恒派互联)点击注册会员账号2. 登陆会员号。3. 查询你要注册的域名是否被人注册…

服务器建立down文件夹不能,学习笔记五、windows iis网站搭建和ftp服务器配置

安装IIS服务选中文件服务,顺便把ftp文件也装上直接下一步下一步安装完成网站虚拟目录个人理解就是目录建站建立虚拟目录映射对应的具体目录之后,访问采用域名虚拟目录别名/ip虚拟目录别名1、不同端口搭建网站2、不同域名搭建网站(相同ip相同端口&#xf…

网站的客户端和服务器地址,主站和从站与服务器客户端

主站和从站与服务器客户端 内容精选换一换华为云帮助中心,为用户提供产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题、视频帮助等技术文档,帮助您快速上手使用华为云服务。用户可以在公有云MRS集群以外的节点上使用客户端&#x…

云服务器上传php网站,php代码上传云服务器

php代码上传云服务器 内容精选换一换登录Windows弹性云服务器如图1所示。(可选)使用密钥文件解析密码。对于密钥方式鉴权的弹性云服务器,需先通过管理控制台提供的获取密码功能,将创建弹性云服务器时使用的密钥文件解析为密码。具体操作,请参…

看看来自日本的扫描,做网站需要注意的

2019独角兽企业重金招聘Python工程师标准>>> 今天研究网站日志发现的,一个来自日本IP的网站扫描,总结: 1. 尽量不要用常见的主流CMS,即便用,目录名也要改得面目全非,外加服务器限制直接访问 2. …

wordpress js 运行短代码_WordPress网站速度优化攻略

WordPress网站在内容逐渐增多时,会出现网站速度慢的问题。WordPress网站速度优化也成为了网站优化的重要事项之一。47%的用户只有两秒的耐心等待网站加载。不仅如此,网站还会受到搜索引擎对长时间加载的排名惩罚。为什么WordPress网站速度快不起来网站速…

语音增强 理论与实践 pdf_pdf转换器在线转换可以用哪个免费网站?

今天我将介绍一个在线转换pdf文件的实用网站,它可以帮助大家把pdf转为word、ppt、excel、jpg等文件哦,同时也支持反向转换。有需要的伙伴可收藏网页,这样遇到文档转换的问题就不必花时间找转换工具啦。网站介绍迅捷PDF在线转换器网站功能多样…

部署Nginx网站服务实现访问状态统计以及访问控制功能

Nginx专为性能优化而开发,最知名的优点是它的稳定性和低系统资源消耗,以及对HTTP并发连接的高处理能力,单个物理服务器可支持30000-50000个并发请求。 Nginx的安装文件可以从官方网站http://www.nginx.org/下载,下面以Nginx1.12版本为例&…

可以免费自学编程的12个网站

编程学习本文来自简书,原文地址:http://www.jianshu.com/p/9f094ce31075 很多人包括一些企业家,和市场营销人员都认为学习编程对一个人走向成功十分有帮助。在过去的一年里,我一直在学习编程。它有助我成为一个更好的创业者,我甚至…

PHP如何打造一个高可用高性能的网站呢?

https://blog.csdn.net/jwq101666/article/details/80162245 1. 说到高可用的话要提一下redis,用过的都知道redis是一个具备数据库特征的nosql,正好弥补了PHP的瓶颈,个人认为PHP的 瓶颈在于数据库,像Apache和Nginx的高级web服务器…

怎么修复网站漏洞之metinfo远程SQL注入漏洞修补

2019独角兽企业重金招聘Python工程师标准>>> 2018年11月23日SINE网站安全检测平台,检测到MetInfo最新版本爆出高危漏洞,危害性较大,影响目前MetInfo 5.3版本到最新的 MetInfo 6.1.3版本,该网站漏洞产生的主要原因是Met…

IIS配置和发布网站

一、安装配置IIS 控制面板-》程序和功能-》启用或关闭Windows功能选中“Internet Information Services”,勾选Web管理工具子项,万维网服务子项(万维网中有极少数不用勾选,不做细致描述全部勾选了)。勾选完成后&#x…

资源帖-优秀博客、iOS开发技术文、学习网站

图片发自简书App 一些博客 王巍 Objc中国发起人、Line工程师ibireme YYKit作者bang JSPatch作者唐巧 《iOS开发进阶》作者、猿题库工程师孙源 前百度工程师,现滴滴工程师玉令天下xuyafei张不坏NSHipster中文版glow刚刚在线里脊串Jamin阿毛的蛋疼地zeeyangTian Wei…

关于初创型公司对公司网站的开发与管理内容

WebSite 一、理论和原理二、软件、类库、中间件三、技术相关四、案例分析对于一个网站而言需要知道公司的需求,想要给别人展示的是什么,重点放在哪里,让观众了解或者注重自己的关键点在哪里,方便观众更快更好的了解公司是干什么的…