【SEDA异步框架】【三】异步框架技术选型

基于SEDA的异步框架设计与实现

三、异步框架技术选型

       在这次实现的SEDA异步框架中,采用的基础架构原型如下:

        采用了spring+quartz+fastjson+rabbitmq来实现。和传统SEDA架构区别比较大的地方在于:

        1、采用分布式mq(使用了rabbitmq)而不是blockingqueue。如此既可以支持以后可能进行的分布式化扩展,也可以使得框架具有高可用性,在大数据处理的时候仍可具有较为客观的性能。同时,消息的传递过程中,采用了高性能的fastjson进行数据序列化和反序列化。使得数据在stage之间的传递速度更快。

        2、除了分布式mq之外,还提供了本地动态线程池所需要的队列。避免了consumer由于长时间处理导致数据在队列中积压。

       3、stage利用quartz来提供定时功能,使得stage中的work可以选择定时/实时进行数据处理。从而迎合更多不同类型的需求。(比如定时报警,定时分析监控数据)

1、spring

       spring无需再赘述,使用其IOC、AOP等功能,并同时使用spring的其他组件比如spring-rabbit、spring-quartz等。保证spring各包兼容即可。

2、quartz

       quartz 的介绍文档网上很多,quartz作为一款优秀的定时器框架可以和spring无缝结合,同时还具有java自带的定时器timer所不具备的定时启动的 功能。其类crontab风格的定时任务声明也更符合我们企业级应用过程中的书写风格。之前文章中介绍过使用quartz过程中需要关注的几个点,复述如 下:   1)Job不能为内部类,否则无法初始化   2)保证spring升级到新版本。如果使用老版本比如3.0.5,则会出现如下异常:

 java.lang.IncompatibleClassChangeError: Found interface org.quartz.JobExecutionContext, but class was expected  

   该case在http://code.google.com/p/wisematches/issues/detail?id=156上有记录。

  3)引入spring-context-support包来使用quartz相关内容,并保证与其他包的兼容性。   4)其定时语法和crontab有些许差别。语法见: http://www.blogjava.net/javainthink/archive/2006/10/19/76077.html

       在异步框架中的使用场景:辅助实现定时功能,从而使得异步框架可以更加灵活的支持各种需求。

3、fastjson        fastjson官网:http://code.alibabatech.com/wiki/display/FastJSON/Home-zh。如其描 述,"fastjson是最快的json库。特别在parser方面,fastjson的性能令人惊奇,甚至超越了二进制协议的protobuf"。虽然 只是fastjson一家之辞,但是从protobuf官网上对各种序列化/反序列化工具进行的性能测试中,也可以看出fastjson优异的性能已经将 传统的jackson工具抛在身后。

  除了速度这一最大优势之外,其还具有如下优势:         1)遵循http://json.org标准,为其官方网站收录的参考实现之一。   2)功能强大,支持JDK的各种类型,包括基本的JavaBean、Collection、Map、Date、Enum、泛型。   3)无依赖,不需要例外额外的jar,能够直接跑在JDK上。        4)开源,使用Apache License 2.0协议开源              在异步框架中的使用场景:辅助stage到stage之间的数据通信,负责数据在通信过程中的序列化和反序列化过程。

4、rabbitmq

       stage与stage之间需要依靠事件队列来进行通信,如果依赖于SEDA官网推荐的BlockingQueue,则无法满足未来的分布式部署。所以决定采用分布式mq来实现。以下比较几个主流的消息中间件:

       1) activemq:

       被称为消息中间件中的瑞士军刀。支持JMS,性能不错。开源社区活跃。能与java很好结合。Spring有相应lib。其功能较为完备,可支持P2P和代理,但性能逊于rabbitmq。从性能角度出发来考虑,决定不使用activemq。

       2)zeromq

       性能比其他中间件优异得多。但无法持久化,不能保证数据的可靠性。由于数据的可靠性不能被保证,所以暂时也不考虑。

       3)redis       可以当作轻量级的中间件。当传输数据大小少于10k时入队性能优异,数据较大时性能急剧下降。而其出队性能不论数据量大小都十分优秀。考虑到项目实现过程 中可能出现的大于10K的请求响应事件数据(比如推荐关键词、比如与后端服务交互返回的数据),所以不采用redis。

       4)kafka 

       除此之外,kafka也是一款值得注目的,性能优异的分布式消息中间件,通过producer的push和consumer的poll来实现数据的交互。 kafka自带负载均衡、并有高可用、高吞吐等特性。但是考虑到实际项目的适用情况,暂时还不需要zookeeper集群,broker集群来进行如此大 规模的数据处理。加上其依赖于scala环境,所以要部署和运维显得不那么方便。所以暂时不考虑。

       5)rabbitmq

       支持AMQP,性能优于activemq。能与java很好结合。Spring有相应lib。环境部署起来不如activemq便捷,需要erlang环境。

        在http://www.aqee.net/message-queue-shootout/一文中对activemq和rabbitmq进行的性能比较显示出rabbitmq更佳的性能。如下图所示:

       综上所述,考虑到该次项目所应用的场景和处理数据量的规模,且需要较为优秀的性能,较为便捷的部署方式,能保证消息可靠性以及可持久化,并且对java友好。最终权衡之下,选择了基于AMPQ的rabbitmq消息中间件。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券