ENode 2.0 – 全体架构介绍澳门美高梅手机网站

前言

今凡是只满面春风之生活,又是星期,可以轻松的勾勒写篇了。二零一八年,我勾勒了ENode
1.0版本,这时自己耶描绘了一个浅析序列。经过了多年的年月,我对第一个本子做了无数架构上的创新,最根本之就是给ENode实现了分布式,通过新增一个分布式音信队列EQueue来实现。之所以要规划一个分布式的信息队列是以以enode
1.0版中,某个特定的消息队列只可以为某特定的消费者花。这样即便会面导致一个题目,就是固然消费者挂了,这这么些消费者对应的信息队列就无法自动被别消费者花了。这多少个问题会合直接导致系统不可用。而ENode
2.0饱受,就不会合生之题目了,因为音信队列被设计也罢单独的,被消费者所共享的;一个音队列可以叫多单顾客集群消费或播报消费,假诺一个主顾挂了,这其他的买主会晤自行到上。这里具体的细节,我会在后详细介绍。

       
在出以及项目运维中,对数据库的操作大家眼前犹是运客户端工具举行操作,例如MySQL的客户端工具navicat,Oracle的客户端工具

ENode框架简介

  1. 框架名称:ENode
  2. 框架特色:DDD+CQRS + EDA + 伊芙nt Sourcing + In Memory
  3. 筹目的:让程序员只关心工作代码、高性能、分布式、可水平扩张
  4. 开源地址:https://github.com/tangxuehua/enode
  5. 基于enode实现的一个成功案例,一个论坛:https://github.com/tangxuehua/forum
  6. nuget包Id:ENode
  7. 一个独立的分布式音讯队列EQueue,可以吗ENode提供Command,Domain
    伊夫nt的发表暨订阅:https://github.com/tangxuehua/equeue

PL/SQL Developer,
MSSQL的客户端工具查询分析器等。方今大家利用的大都是C/S单机版的客户端工具,要连数据库的电脑都使设置客户端工具,

ENode架构图

澳门美高梅手机网站 1

熟练CQRS架构的人头张这图应该就是还熟识不过了,enode实现之是一个CQRS架构。基本的定义就不多介绍了,要是我们对达图备受的片段定义还未极端知道,可以看一下自家的博客里的别样有关随笔,我应当都发出描绘到。下面要介绍一下enode
2.0于落实CQRS架构时的部分未一致的地点(由于篇幅的限制,先说其三触及吧):

navicat还于好安装,而Oracle客户端工具安装就相比累了。

Command Handler一涂鸦独自处理一个Command

固然您莫可知以command
handler中一样破修改多单聚合根,我觉得就应该是enode对开发人员的最好老封锁,可能吧是最好受开发人士觉得难受的地点。但我觉着这不是约,而是对数据强一致性和结尾一致性的一个正确认识。在自身套了ddd+cqrs+event
sourcing这三单东西下,我认识及,聚合内要保证强一致性,聚合间最后一致性。传统三交汇开发,我们由此unit
of work情势(简称uow,比如nhibernate的session, entity
framework的dbcontext)可以擅自实现五只目的修改的赛一致性事务;确实当人情三重合格局开发被,这种以uow的道来实现抢先集的大一致性事务之措施大实用,开发起来挺有利,开发人员可以不要担心会油可是生数未均等的问题了,因为拥有修改总是以一个事务内保留。

可是enode的宏图目标不是为补助传统三叠开发,而是面向ddd+cqrs+eda+event
sourcing架构的框架。曾经自己为想吃command
handler扶助修改多独聚合根,但诸如此类做得使面临一个生讨厌的题材:command在殡葬至command
queue时,无法依据聚合根ID来程由于了。因为一个command会修改多独聚合根,也就是说一个command不会合暨一个聚合根一一对诺了。这意味着跟一个聚合根没道总是被路由于到与一个command
queue里,这样便造成同ID的聚合根可能相会以片令服务器被同时修改,这就谋面造成全体系或者会师反复的起并发更新冲突。很多command就会不断的重试,整个系统的性质就会师稳中有降。而enode设计之初就是为了胜性能,所以即刻点吃我看异常麻烦接受。

相反,尽管一个command总是独自会创或者改动一个聚合根,这大家的command就会按照聚合根ID来程由于至一定的信队列,同一个聚合根ID总是会叫路由于至与一个queue,而一个queue的买主服务器(command
handler所在的服务器)同一时刻连续独自发一个,这我们不怕能确保一个聚合根的修改不会师暴发出现问题。当然就这样还不够,在此command消费者服务器里,enode框架会因而内存级别之queue对同一个聚合根的所有command再一次展开排队(如若需要排队的说话),之所以要这样是以有时对一个聚合根的起修改command可能1s外发送了众恢复,所以command
handler肯定来不及在1s内任何甩卖掉这个command,所以需要在内存里再一次排队(Taobao双十一底上,应用服务器内部也会暴发接近的对同一个聚合根设计一个对应的外存queue来防止对同一个聚合根的修改的现身争辩的题材)。通过如此的筹划,大家得以就绝大部分状下,不会合再一次闹起争辩之题材,也不怕是command不碰面重新现身重试的情。这样结尾之效率固然是:不同ID的聚合根的拍卖可以并行,同一个ID的聚合根的处理是串行,通过个别层排队实现。前边说到,这样只可以成功绝大部分气象下非会面发出出现争持,那么什么时要会生出现争辩呢?就是于增产command消费者服务器的早晚,比如我们发现以来网繁忙,我们期待扩展command消费者服务器来加速command的拍卖,这在增产服务器后,原来修改某聚合根的command可能会合给路由于到新的服务器,可是这聚合根的有点command可能还在原本的服务器上还没有执行完毕,此时尽管会合冒出与一个聚合根在个别台服务器上为同时修改的或了;这这怎么化解吗?我本之想法是框架层面不必解决了,我们才待以系统最空的下(比如凌晨4点)的下,扩大服务器即可,因为卓殊时段音讯队列里的信息是最少之,也不怕是不太可能会发生为增command
handler服务器假设致使出现争辨之题材,这样大家便可极其酷限度的免可能带来的面世争执。

      
当对长途服务器的数据库举行访问管理时,特别是Linux服务器,都如被对应端口,这样吧增了服务器的安全隐患,增添了工作量。

让Domain生活在In Memory中

相比一般的CQRS架构,enode每一趟在拍卖一个command,在获取聚合根时,不是由eventstore获取,而是打缓存获取。从点的架构图能够看来,enode架构中生一个domain
memory
cache,如今所以redis实现。这样做的便宜是,将有着的聚合根都休息存在redis缓存中,这样尽管会增进聚合根的读取时间;有一个问题需考虑,redis缓存服务器宕机了怎么惩罚?宕机后缓存数据就从未了,这哪恢复生机这个缓存数据呢?这也是自身选redis的一个要理由,因为redis襄助持久化,我们得以运用redis的aof或快照形式的持久化效率,来持久化缓存数据。从而可以当redis挂了后能最好抢之速度苏醒缓存,重启redis服务器即可。这又开从前和重启的进程中,因为不可能从redis获取聚合根了,这只可以于eventstore通过event
sourcing的道去取得,这样的话性能肯定会相比差,这怎么收拾为?答案是经过定时为聚合根创立快照,这吗是使event
sourcing架构的一个补。我们好定时对某些聚合跟成立快照(注意,我觉着只需要考虑这一个对性要求相当高的模块所关联到的聚合根创设快照即可),这怎么开创为?可以初叶一个单身的过程,监听domain
event,对急需创造快照的domain
event做出判断,按照某种快照创造策略举行判定,假若看用创立快照,则于event
store拿出拖欠聚合根的连带事件,通过event
sourcing还原抱有版本的聚合根,这样虽然收获了某个聚合根的某版本的快照了。然后持久化起来即可。然后,enode辅助在自event
store获取聚合根前,先反省是否发快照,假若发生快照,则会优先加载快照,再管快照之后的domain
event从event store获取,再将这几个快照之后的domain
event一个个apply到如今聚合根,从而获取时状态的聚合根。那一个历程较得到该聚合根的享有世界事件在一个个透过event
sourcing还原博聚合根要赶紧之多;尤其是于一个聚合根的domain
event相比较多的情事下便更有意义。由此,通过缓存的引入,我们可增长command
handler的处理速度。

      
假如生按照web的数据库客户端工具,就足以立异和缓解者的一些题材。经过多少个月之不懈努力,这款基于web的客户端工具终于出现了。

Event Store的设计

       目前支撑之数据库包括MySQL,Oracle,PostgreSQL,MSSQL。

至于重复的command的幂等处理与聚合根可能是的出现争辨的判定

此外一些相当重大之凡,因为我们的command是碰头发送至分布式信息队列,然后队列中的command音信会于拿走下执行;我们精晓,大家很麻烦保证一个信不谋面被再度执行,也就是说,一个command可能会合更执行。因而,大家的下要帮助针对command的密等处理。而对此用enode框架的使用,因为所有command
side的数额持久化就是持久化domain event,程序员不必关心domain
event的持久化过程。所以enode很有必要能放扶助对command的重复处理的判定。那么咋样做为?我当太依赖谱的做法是,在持久化domain
event的当儿便可知相对靠谱的检测出有command是否让还执行了。这要命自然就悟出用吃持久化的domain
event和有他的附和command关联起来。所以我计划了如下的结构,用来代表一个command在操作聚合根后所发出的园地事件的信息。

/// <summary>The commandId which generate this event stream.
/// </summary>
public string CommitId { get; private set; }
/// <summary>The aggregate root id.
/// </summary>
public string AggregateRootId { get; private set; }
/// <summary>The aggregate root type code.
/// </summary>
public int AggregateRootTypeCode { get; private set; }
/// <summary>The version of the event stream.
/// </summary>
public int Version { get; private set; }
/// <summary>The occurred time of the event stream.
/// </summary>
public DateTime Timestamp { get; private set; }
/// <summary>The domain events of the event stream.
/// </summary>
public IEnumerable<IDomainEvent> Events { get; private set; }
  • CommitId:就是时的CommandId;
  • AggregateRootId:当前深受操作的聚合根的全局唯一ID;
  • AggregateRootTypeCode:表示聚合根的种的一个code,通过该code我们得清楚当前记录是孰品种的聚合根的;
  • Version:一个版本号,表示聚合根发生领域事件后底初本子号,是发生事件前的版号+1;也就是说,聚合根的版是历次被修改一不成,这Version就加1;
  • 提姆(Tim)estamp:一个时空穿,用于记录出domain event时的年月;
  • 伊夫nts:表示手上command操作聚合根后所生的圈子事件,一破操作可以有多单领域事件;

对于地点的结构体,咱们得兑现六只举足轻重之意义:1)为AggregateRootId和Version这一点儿个字段建立唯一索引,这样我们尽管可以实现判断有聚合根是否让起修改,因为即使生出现修改导致出现争辨,这保存至eventstore时,它们的Version肯定是相同的;2)为AggregateRootId和CommitId五只字段建立唯一索引,这样咱们便会判定有command是否为再一次执行,因为一个command被实例化出来后,它所假如改的聚合根ID就非容许再次修改了,所以要该command被再执行,这最终来的世界事件(下边是结构体)最终吃持久化到eventstore时尽管会师违反这一个唯一索引,从而框架就可知分晓是不是有command被重复执行了;

除此以外,上边这个结构体被保存到eventstore时,是盖同等漫长记下之法门叫保留,伊夫(Eve)nts集合会被列化为一段落二进制;所以,假使大家因而干项目数据库来保存,这就是然而发一致长达insert语句即可,这样就贯彻了一个聚合根的如出一辙不良修改的政工持久化。然后为上少单目录的存在,我们即便能于保留时判断是否有出现顶牛要command是否受再一次执行。

      下边为我们介绍一下立马款基于JAVA
WEB开发之TreeDMS数据库管理系列,类似phpmyadmin的软件。
 
1、安装及登录系统
 访问http://www.treesoft.cn/dms.html,
下载treeDMS,window中一向解压,运行就足以为此了,程序中既连了JAVA运行条件,Linux中使事先安装JAVA环境,将先后直接复制过去,运行即可。下图为报到后的主页面:
澳门美高梅手机网站 2

至于Domain 伊夫nt大数据量的考虑

以统筹event store时,我设想了累累。最终当event
store要缓解的卓殊酷的少单问题是持久化性能与而水平扩大性。首先,因为每一次command
handler在拍卖完一个聚合根后,都碰面拿来的世界事件持久化到event
store,没持久化完成则免可知当该command已处理终结,所以持久化的性质对拍卖command的吞吐量至关首要。其余一些纵是可是水平扩大性,因为event
store里保存的且是domain
event,而enode又是为了促成强性能为对象的,所以event
store里的数码一定会丰盛多,比如1s备受使持久化1K单domain
event,这同样龙就相会出8600W长长的记下要记录,一天便真么多,这1年即使再多矣,所以用单点存储所有的domain
event突显不靠谱了。所以我们的event
store必须要匡助水平扩大。比如我们可设计100个分区,这每个分区一天只待保留86W长达记下,一年为只需要保留3亿差不多少长度长的记下即可。此前我可怜追求单个存储节点的胜性能,所以已经想了假若用leveldb,stsdb,甚至redis那种高性能的依照key,value的nosql存储。但后来意识这种nosql存储虽然性能非凡高,但以光是key,value的仓储结构,所以无办法补助二级索引,这样便一贯不道落实者第一沾着干的command的幂等处理与聚合根并发争辨之检测。另一个根本的来头是,event
store中之数码我们有时候是若吃询问的。比如现在某个command碰着的起顶牛,这框架需要活动重试,不过重试以前用先更新redis缓存,就是拿eventstore里的摩登的聚合根更新到redis缓存里,这样command在重试时才会用到新型版本的聚合根,这样重试才会打响。这哪自eventstore里拿最新的聚合根呢?只好冲聚合根ID从eventstore里查询。而聚合根ID又不是key,value
nosql的key,自然就是从未有过道落实此要求了;所以,我当理所当然的点子应该是故干项目数据库来促成eventstore。有人说干项目数据库的属性大。我以为如提到项目数据库补助水平扩充,也即使是用domain
event sharding(分片)到不同之分库分表中,这平均到每个库里的domain
event的数据就未慌了;这样合eventstore的持久化性能就得就分库的数之加码而线性扩充;比如自己前天单个db
insert domain event的性是1K
tps(mysql配合ssd硬盘完全无压力,呵呵),这10只仓库底tps就会落得1W
tps了。因为大家分库会因聚合根ID的hash
code来平均散列,这样能保证每个库中之聚合根的domain
event数量是中央相同的;从而就可知促成普event
store的持久化性能就分库的增而线性扩张。所以,有矣分库的优势,大数据量和性都无是题材了。且以涉嫌项目数据库帮忙二级索引和唯一索引,这查询domain
event也非是问题了。

2、系统主页
      登录成功后,举办系统主页面, 首糟糕下的用户
请点击左侧上之“参数配置”按钮,举办数据库地址、用户等信息之部署,以便连接到用户数据库。
    
系统主页包括:右侧为数据库表展示区,中间也SQL编辑和数码显示区,左边为查询附助区。功效直观,操作便捷。 
澳门美高梅手机网站 3

ENode物理部署结构图

澳门美高梅手机网站 4

高达图是enode在事实上项目遭到自手上认为的一个物理部署协会图。

第一客户端浏览器通过网络最终访问到我们的web服务器集群,当然web服务器前面肯定还有网关和负载均衡器,我这边为突出重点就无写出来了。然后每个web服务器接受到httprequest后会见生成command,然后通过enode框架发送至分布式新闻队列服务器(message
queue
server),方今出于本人开的equeue实现。然后信息队列服务器上之信息会受推送到command
process servers,command process server就是行command
handler、完成domain logic,持久化domain event,以及publish domain
event的服务器。command process server处理完后,domain
event会由enode框架自动发送到message queue server,然后会为event process
server处理,event process server就是订阅domain event,然后因domain
event更新query db。对于查询,web server可以直接通过sql查询query db即可。

各类服务器的集群:

  • web server:无状态,可以任意扩大服务器;
  • command process
    server:就是拍卖事务逻辑的服务器,也是无论状态,可以轻易扩大服务器;但服务器的数最为好和command所对应的topic下的queue的数目保持一致,这一点持续在形容分布式音讯队列equeue的著作时在详细谈吧;
  • redis
    server:就是缓存聚合根的服务器,属于缓存服务器;可以按需仓储的容量来规划需要起首多少台redis
    server;目前本身看最好好之redis动态扩容方法就是是pre sharding;
  • event db server:就是储存domain
    event的服务器,按照上的分析,我们运用的是关联项目数据库,比如用mysql;mysql的分库分表技术一度杀熟,后续著作我们还详尽座谈什么分库及怎么着做多少迁移;
  • event process server:就是订阅domain event,依照domain
    event更新query db的服务器;可以因需要来布局多少令,和command
    process server类似;这里暴发好几须使事先领一下,就是以更新query
    db时,因为每趟换代都是本着某个domain event来更新query db的,而domain
    event只象征一个聚合根的改动,所以每便我们改进query
    db时,也仅仅更新该聚合根所在范围之阐明;大家绝不要去改进领先该聚合根范围的阐发,否则就是会见爆发并发争执,导致event
    handler执行破产;这样虽然会晤是的cqrs的query
    db同步数据变的慌缓慢。对于query side,如果我们当直接由query
    db查询数据极其慢,可以设想规划查询缓存,也尽管是匪走query
    db来询问数据,而是走缓存。这种缓存就与我们日常底缓存设计类了;利用domain
    event,大家自然就暴发优势足吃缓存非常及时的翻新,呵呵。因为若闹domain
    event过来,大家便会便捷翻新我们的query side缓存,而query
    db就可异步更新即可。这样尽管可以缓解query side同步革新数据慢的题材。
  • message queue
    server:就是信息队列服务器,近来equeue还非援助集群,只协理单机;那些以后爆发时光会考虑实现master-slave情势,类似于Tmall的rocketmq一样。

好了,就形容这个吧,后续的再度累小说被补充及,呵呵。

3、SQL在线编辑执行
    
在SQL编辑区可一向编辑语句,对数据库举办操作维护。援助多告诉句批量实践,襄助拔取执行,辅助至关重要字高亮指示,扶助多结果显示。
澳门美高梅手机网站 5

4、表数据在线编维护
    
采纳左边库表后,将直查询表数据,并展现出。可透过新增、编辑、删除按钮对表数据举办维护。也可从来对击行,举办数量编辑,操作非凡方便。
澳门美高梅手机网站 6

5、表结构在线编维护
    
通过点击“设计”按钮,将切换至表明结构设计页,您得方便的增多、修改、删除表字段,调整字段顺序,设置主键,设置非空等操作。
澳门美高梅手机网站 7

6、SQL查询语句之保存
     
当您编了多SQL语句后,可点击”SQL保存”按钮,保存自己之劳动成果,通过左边“我的SQL”列表,可查询及保存记录。    
  澳门美高梅手机网站 8

7、SQL语法的鼎力相助
    
系统整合了部分常用的SQL语法匡助信息,可以采纳并查六柱预测应的言语,选拔后语法音讯将显示在编辑区。
  澳门美高梅手机网站 9

8、皮肤配色的挑三拣四
   
系统内置14套UI皮肤,45套代码编辑区UI方案,可自由设置组成,深色的屏幕有助爱慕视力。上面的截图就是采纳了不同的肌肤。
 澳门美高梅手机网站 10

小结,希望就款软件叫我们工作牵动帮助,同时想国产软件能引领行业技术立异!

一经您觉得看本文对而发出匡助,请点一下“推荐”按钮,您的“推荐”将是本身尽要命的研发重力!欢迎各位下载。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注