您的位置:首页 > 其它

领域事件与Netty结合的一个使用场景与设计

2014-10-16 17:55 120 查看
一个应用系统,分布有中心与区节点个环节,系统间由于中心与节点处理内外网关系,系统中要进行双向的通信需NAT穿透,简单选型使用了Soket通信,由节点主动上连中心,提供服务,并保存套接字。

Netty是一个事件驱动,多线程的,支持多种协议与支持NIO的一个JAVA编写的Socket框架,使用Netty可以省去了很多开发中遇到的问题。

系统应用架构上根据了DDD做为参考,领域层-中心的Server , 节点的Client, 定义为了两个聚合根,行为类型,动作起来需要组合不同的聚合跟实例进行相关业务逻辑操作。

应用服务一层位于领域层之上,用于负责领域事件注册,事务控制的一个Facade层。

项目中有这样的一个场景:

中心Server通过一定机制,发送信令到对应的节点Client,节点Client接收到的信令进行相关操作(操作数据库,WebService请求),这些操作都均耗时耗资源,我们第一直观感觉是使用多线程解决,从而不阻塞Netty的相应InboundHandler在管道中进行下一个节点进行操作,项目中也确实是这样用了。:^)

对于这个相关操作,关系到了数据库事务控制等这些问题,而节点在Client位于领域层,按照DDD的思路,这一类的操作应该交由应用服务的某个方法执行。但接入到信令的操作发生在领域层,而领域层并不能获取到上层应用服务接口,这促使了我在项目中选用了领域事件,进行事件发布。

由应用服务层注册事件Subscriber,进行订阅,获取到领域事件后,交由同一层(应用服务)的服务接口进行操作。解决了不同层次依赖问题。

大致的思路,用些精简的伪代码表示:

准备领域事件的几个类

DomainEventPublisher事件发布器

public class DomainEventPublisher
{
public void publish(DomainEvent event,ExecutorService execotor)
{
...
executor.execute(new Runnable(){
public void run()
{
for(DomainEventSubscribe subscribe : this.subscribes)
{
subscribe.handle(event);
}
}
);
}
public void subscribe(DomainEventSubscribe subscribe){...}
}
DomainEvent 领域事件接口

public interface DomainEvent{}
DomainEventSubscriber 事件订阅者接口

public interface DomainEventSubscribe
{
void handle(DomainEvent domainEvent);
}


定义领域层Client端

Client聚合根

public class Clent
{
private DomainEventPublisher publiser;

public void open()
{
// ...netty的api等

//加入一个自定义的handler
channel.pipeline().addLast( new AppHandler() );
}

public void close(){...}

public void subscribe(DomainEventSubscribe subscribe)
{
this.publiser.subscribe(subscribe);
}
}

AppHandler

public class AppHandler extends ChannelInboundHandler
{
private DomainEventPublisher publisher;
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
{
Signalling signalling = (Singalling) msg;
String data = signalling.data();
AppDomainEvent event = new AppDomainEvent(data);
publisher.publish(event,ctx.channel().eventLoop());
...
}
}
AppDomainEvent,我们实现的领域事件

public class AppDomainEvent implements DoaminEvent
{
public AppDomainEvent(String data){this.data = data}

public String data(){return data}
}


应用层

ClientApplicationService,创建Client的一些Facade接口

public class ClientApplicationService
{
public void newClient(String clientId)
{
Client client = new Client(clientId);
client.subscribe(  new AppDomainEventSubscriber() );
return client;
}
}
AppDoaminEventSubscriber订阅器

public class AppDomainEventSubscriber implements DomainEventSubscribe
{
public void handle(DomainEvent event)
{
if(event.class.equals( AppDomainEvent.class ) )
{
AppDoaminEvent e = (AppDomainEvent) event;
ApplicationRegister.otherApplicationService().do(e.data());
}
}
}

注:ApplicationRegister.otherApplicationService()的意思是获取改领域层的其他应用服务,来进行对领域事件中带回来的data进行业务操作。

以上便是偶在项目中的一个解决方案,希望有帮助

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐