JdonFramework 6.4(Disruptor)版发布

11-09-07 banq
2009年JdonFramework 6.2版本推出基于内存的异步领域事件版本,其关键点是Domain Model + In-memory + Domain Events.常驻内存In-memory的领域模型Domain Model通过领域事件Domain Events驱动技术实现各种功能,正如基因DNA是生命各种活动功能的核心一样,实现了以领域模型而不是数据表为核心的新的模型驱动开发架构MDD。

2011年Martin Fowler肯定了LMAX架构的领域模型in-memory事件架构.

JdonFramework原先Domain Events是使用JDK FutureTask实现的, 但是最快并发开源框架Disruptor的创建者LMAX团队测试发现JDK所谓带锁并发包性能不优异,他们也发现函数式语言的Actor模型是有瓶颈的,所以他们采取Disruptor这样配合多核CPU高速缓冲策略的新框架,破除了Java多核并发隐患了JVM伪共享

JdonFramework 6.4版本引入了Disruptor作为其Domain Events实现机制,如下图:



JF的领域事件是一种异步模式 + 生产者-消费者模式。分为主题topic和Queue队列两种。领域模型是生产者;JF的消费者有两种:
(1).@Send => @Consumer;可以实现1:N多个,内部机制使用号称最快的并发框架Disruptor实现。适合轻量;小任务;原子性;无状态。
(2).@Send => @Componet;只能1:1,直接使用普通组件类作为消费者,使用jdk future机制,适合大而繁重的任务,有状态,单例。

有关新的JF领域事件见该文档:JdonFramework模型驱动快速开发

JiveJdon 4.4版本是基于JdonFramework 6.4版本的Disruptor新版本,基本使用Disruptor的DomainEventHandler替代了原来的MessageListener。其最新测试结果如下,由于将数据库等操作使用异步事件实现,回帖和帖子修改等写入性操作都是基于内存领域对象实现,性能大大提高:



领域事件是一种CQRS架构,也是一种Event Sourcing模式,可扩展性极强,通过以事件函数为核心,与面向函数思维一致,符合蒯因的引用透明原则和懒惰加载特性。

JdonFramework 6.4(Disruptor)版下载地址:SourceForge code.google.com下载

English: http://www.jdon.org/
JdonFramework on GitHub: https://github.com/banq/jdonframework

11
banq
2011-09-09 17:01
使用JF可以轻松实现DCI架构。事件的生产者实际是DCI中的角色,JF运行时通过将角色注入到模型中实现其角色扮演功能。

DCI:数据Data, 场景Context, 交互Interactions是由MVC发明者Trygve Reenskaug发明的。 见 DCI架构是什么? DCI让我们的核心模型更加简单,只有数据和基本行为。业务逻辑等交互行为在角色模型中 在运行时的场景,将角色的交互行为注射到数据中。

JdonFramework的Domain Events是DCI的交互行为,在实现领域事件的同时也实现了DCI。为更清楚说明DCI,下面以JdonFramework案例说明。源码见: SimpleJdonFrameworkTest.rar

领域模型是DCI的Data,只有数据和基本行为,更简单,但注意不是只有setter/getter的贫血模型。如下:

@Model
public class User Model {

     private String userId;
     private String name;

     @Inject
     private ComputerRole computerRole;

<p class="indent">


Domain Events事件或消息的生产者也就是DCI中的角色Role,比如我们有一个专门进行计数计算的角色,实际上真正计算核心因为要使用关系数据库等底层技术架构,并不真正在此实现,而是依托消息消费者@Consumer实现,那么消息生产者可以看出是一个接口,消费者看成是接口的实现:

@Introduce("message")
public class ComputerRole {

     @Send("computeCount")
     public DomainMessage computeCount(User[author]Model[/author] user) {
          return new DomainMessage(user);
     }

     @Send("saveUser")
     public DomainMessage save(User[author]Model[/author] user) {
          return new DomainMessage(user);
     }

}
<p class="indent">



DCI第三个元素是场景上下文Context,在这个场景下,ComputeRole将被注入到模型UserModel中,实现计数计算的业务功能:

public class ComputeContext {

    private DomainMessage ageAsyncResult;

     public void preloadData(User[author]Model[/author] user) {
          if (ageAsyncResult == null)
               ageAsyncResult = user.getUserDomainEvents().computeCount(user);
     }

     public int loadCountNow(User[author]Model[/author] user) {
          preloadData(user);
          return (Integer) ageAsyncResult.getEventResult();
     }

     public int loadCountByAsync(User[author]Model[/author] user) {
          if (ageAsyncResult == null)
               ageAsyncResult = user.getUserDomainEvents().computeCount(user);
          else if (ageAsyncResult != null)
               return (Integer) ageAsyncResult.getEventResult();
          return -1;

     }
}
<p class="indent">



DCI应用源码下载:SimpleJdonFrameworkTest.rar

开发文档:JdonFramework模型驱动快速开发
更多文档:http://www.jdon.com/jdonframework/manual.htm

关于领域事件和DCI纠结讨论见:

DCI,领域模型,领域事件的一些想法,该文讨论场景和事件到底应该如何结合?怎么结合?

DCI并不反对继承 一文认为DCI目前最大的不确定性或者说问题是何时以及如何定义一个Context上下文场景?我个人认为通过领域事件实际上巧妙回避了这个问题,因为事件隐含了场景。

[该贴被banq于2011-09-10 17:09修改过]

[该贴被banq于2011-09-13 12:14修改过]

flyzb
2011-09-11 13:54
感谢banq的不懈努力。
  对于DCI,banq的提供思路在大多数场景下没问题。不过在我遇到的实际应用发现,在更复杂的场景中,领域对象的事件响应可能还会因场景不同而不同。这也就是说,大多数情况下主要由场景触发不同的领域对象事件,但领域对象的事件响应还可能进一步细分为不同的场景。
  所以领域对象事件和场景可能是相互交织的。不知道banq有没有更好的思路。

xuyifeng
2011-09-12 01:06
不知道jdon还记得我不,很久以前发你一个邮件,现在我也在java的领域中遨游了!最近的几篇主题LMAX和disrutor,让我非常刚兴趣。貌似我在多线程并发领域总是很有兴趣。
废话不多说。我看了disruptor的主题文章,如果真如文章所说,这个是目前最快的并非处理,那么在我一直在想,这个技术是否可以用到我们公司的系统中去。因为我们公司目前的系统虽然完整,但是咋性能上没有下很多时间,因为需要追求稳定。(插播下广告:我在职的公司是深圳的安捷信联,深圳的手机深圳通就是我们的产品)。而我们公司的系统驱动就是使用open mq的队列消息。我对disruptor的唯一担心是,他稳定吗?可以在并发情况下,保证数据的完整性等一系列问题(问题提的不好,见谅!)。
希望可以有更多的相关的文章,我很希望能够学习下这个技术。

banq
2011-09-12 07:41
2011年09月12日 01:06 "@flyzb "的内容
领域对象事件和场景可能是相互交织的。不知道banq有没有更好的思路。 ...


目前我也比较纠结..这个问题需要详细讨论才可能有好的思路,如果说场景或上下文是一个“面”,那么事件是“面”里那个点。场景在技术还要实现混合Assigned注入等作用。

2011年09月12日 01:06 "@xuyifeng "的内容

我对disruptor的唯一担心是,他稳定吗?可以在并发情况下,保证数据的完整性等一系列问题(问题提的不好,见谅!)。


这个问题Martin Fowler的LMAX架构已经回答了,LMAX团队在2010的Qcon大会汇报了他们这个技术,直至2011年老马写这篇文章,至少已经已经稳定运行一年,LMAX他们有专门的博客http://blogs.lmax.com/

banq
2011-09-29 15:01
Jdon Framework 6.5beta发布

完整演示从软件分析设计到代码实现的全过程,涉及DDD DCI和Domain Events:

http://www.jdon.com/jdonframework/dci.html


2012年3月9日:Jdon Framework 6.5.1发布

[该贴被banq于2012-03-09 12:47修改过]

superallen
2011-11-20 12:13
想学习一下源码,可是弄了半天下载不下来,下载的时候提示 没有权限,用putty key generator生成了一个key还是不行,banq知道一下吧。
这个工具有点复杂,为什么不直接用SVN呢。

banq
2011-11-20 13:58
2011年11月20日 12:13 "@superallen"的内容
想学习一下源码,可是弄了半天下载不下来 ...


下载页面中直接下载:

http://www.jdon.com/jdonframework/download.html, GitHub是比较麻烦,我也是跌跌撞撞,你下载打包好的zip即可。

index002
2011-12-08 14:35

index002
2011-12-08 14:36
不错

sorra
2012-01-12 18:19
对"场景, 角色"我理解得不是很好.
http://www.jdon.com/jivejdon/thread/37976 看了这个帖子后, 我理解为把Context放在了角色之中?

看到DCI的定义, 我首先想到的是自己曾尝试过的一种做法: 通过Context的改变, 来改变Interaction的语义. (语义中可能有不变性和可变性, 这里改变其可变性)

以Strategy模式为例: 对算法的调用是不变的, 而通过替换封装了算法的对象, 可以替换所使用的算法实现. Context就隐式存在于这个封装了算法的对象中. 把Context替换了, 同样的Interaction就会有不一样的具体行为.

[该贴被sorra于2012-03-03 11:34修改过]

abel1978
2012-04-17 09:39
楼主您好,最近我一直在研究Disruptor。有些地方还是不太明白,想请教一下楼主:
1、首先是ringbuffer。虽然我们可以以异步的方式,先将事件放入ringbuffer,可是最终还是要写入到数据库的。当多个handler同时操作数据库时,不是一样还是存在性能的问题吗?
2、您说到:
“JiveJdon 4.4版本是基于Jdonframework 6.4版本的Disruptor新版本,基本使用Disruptor的DomainEventHandler替代了原来的MessageListener。其最新测试结果如下,由于将数据库等操作使用异步事件实现,回帖和帖子修改等写入性操作都是基于内存领域对象实现,性能大大提高”
想知道,您是如何实现将内存中的对象最终写入数据库的?另外,对于服务器发生意外,内存数据丢失的问题您又是如何解决的?
谢谢!

[该贴被abel1978于2012-04-17 09:41修改过]

banq
2012-04-17 09:55
2012-04-17 09:39 "@abel1978"的内容
有些地方还是不太明白,想请教一下楼主 ...


这涉及全新的架构,不是一两句说清楚的,异步=并发,也就是两个线程以上同时做事:
第一个线程是处理内存中的数据。
handler操作数据库是在第二个线程。

这两个线程互相不影响。

其它问题参考这个文章:LMAX架构

beethoven
2012-07-26 04:22
banq老师你好,
对于异步处理,我有一个疑问。
看论坛里的讨论,似乎jdon即使是很小的操作,也采用异步方式去做的。
但并不是对什么都做异步就会始速度更快。因为那会造成额外的线程上下文切换。

msdn上也指出了过度并行化的缺陷
《数据并行和任务并行中的潜在缺陷》

http://msdn.microsoft.com/zh-cn/library/dd997392.aspx

所以为,异步只是在某些特定情况下是适用并且确实能提升网站吞吐量的。但异步不是主要,它只是一个辅助。

[该贴被beethoven于2012-07-26 04:26修改过]

[该贴被beethoven于2012-07-26 04:27修改过]

banq
2012-07-26 09:30
2012-07-26 04:22 "@beethoven"的内容
异步不是主要,它只是一个辅助 ...


那篇文章看了,是标题党,主要还是谈如何使用并行,关键是从业务设计上区分可变和不变性出来。见:不变性设计,我们采取异步并发,主要是为了回避堵塞,见无堵塞的并发编程,另开线程的开销比锁堵塞等开销要小于得多。

另外异步也能够从设计上松耦合系统,能够实现灵活扩展等等,这个话题可见异步编程模型这个主题标签的讨论。

猜你喜欢
2Go 1 2 下一页