Spring-Dumpling,一个另外的开源小软件详细说明

除了分身做beetl(http://beetl.sourceforge.net/) 外,实际上还做了一个Spring相关的,技术含量不高,但还是很有用。所以推荐给大家

 

一、 概述

Spring-Dumpling(简称 SD)  是在基于 Spring 框架下的提供协作服务,正如 Spring 自带的  @Service,SD 提供 @CooperationService  以及如下注解:

@Publish / @Subscribe

@ClusterSync       

@RemotePublish / @RemoteSubscriber 

@RemoteNotify / @RemoteWait

@Process / @Task

来完成业务方法的协作。

二、 安装:

1 https://sourceforge.net/projects/spring-dumpling/ 下载最新版本spring-dumpling.0.1.jar 或者下载工程自个打包

放入 classpath

spring 做如下配置即可

<!--  springdumpling  配置 -->

< bean   id = "spring-dumpling"   class = "com.bee.spring.dumpling.SpringBowl" >

 

< property   name = "psProvider"   ref = "defaultPublisScribeProvider"   />

<!--  

<property name="nwProvider"  ref ="jmsNotifyWaitProvider" />

<property name="remotePSProvider"  ref ="jmsRemotePSProvider" />

<property name="clusterSyncProvider"  ref ="zkClusterSyncProvider" />

-->

</ bean >  

< bean   id = "defaultPublisScribeProvider"   class = "com.bee.spring.dumpling.DefaultPSProviderImpl" />

< bean   id = "zkClusterSyncProvider"   class = "com.bee.spring.dumpling.ZkClusterSyncProvider" >

< property   name = "zkConf"   ref = "zkConf"   />

</ bean >

< bean   id = "jmsNotifyWaitProvider"   class = "com.bee.spring.dumpling.jms.activemq.JMSNotifyWaitProvider" >

< property   name = "jmsConf"   ref = "jmsConf"   />

</ bean >  

< bean   id = "jmsRemotePSProvider"   class = "com.bee.spring.dumpling.jms.activemq.JMSRemotePSProvider" >

< property   name = "jmsConf"   ref = "jmsConf"   />

</ bean >  

   <!--  zk 配置 -->

< bean   id = "zkConf"   class = "com.bee.spring.dumpling.clustersync.zk.ZKConf" >

< property   name = "server"   value = "127.0.0.1:2181" />

<!-- <property name="useACL" value="1"/> -->

</ bean >

<!-- JMS消息配置 -->

< bean   id = "jmsConf"   class = "com.bee.spring.dumpling.jms.activemq.JmsConfig" >

< property   name = "url"   value = "failover://(tcp://127.0.0.1:61616,tcp://127.0.0.1:61617)?randomize=false" />

</ bean >

<!-- enable  aop  -->

< aop:aspectj-autoproxy />

<!-- <bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />  -->

     < context:component-scan   base-package = "com.netease" />

<!--  springdumpling  配置结束 -->

 

 

 

目前采用ZK 作为 ClusterSync  的协调服务提供者, ActivityMQ 作为 RemotePublish  RemoteNotify 的服务提供者

 

三、 使用

 

1.  @CooperationService

需要实现协调服务的类,必须在类上申明@CooperationService ,如下例子

 

@CooperationService

@Service

public   class  UserServiceImpl  implements  UserService ,ApplicationContextAware

{

 

2.  @Publish / @Subscribe

@Publish,有如下属性

  path: 一个逻辑路径,必须要

  ruleExp: 根据输入值,输出值的表达式判断是否需要 Publish, 否则,总是通知其他机器 如规则 rule="returnValue==true" ,默认是发送

  argExp:一个参数表达式列表,如果没有,则按照输入参数和输出参数作为参数列表,传递个 sub 。参数格式如: argExp="args[0].orderId,args[1],returnValue;

@Transactional

@Publish (path =  "/user/ login " , ruleExp =  "returnValue!=null" , argExp =  "args[0],returnValue" )

public  UserVo updateLoginTime(String userName)

{

System. out .println( "update login userName for "  + userName);

userDao .updateLoginTime(userName);

return   userDao .login(userName);

}

 

 

 

@Subscribe 

  path: 一个逻辑路径,必须要

  runPolicy: 运行时机,有俩个值,一个是 sameTransacion, 表示于 publish 方法在同一事物里,另外一个是 afterCommint, 这是默认值,表示当事物成功提交后异步执行,如果 Publish 没有在事物上下文里,则 @publish 方法执行完毕后立刻执行

 

@Subscribe (path =  "/user/ login " ,runPolicy= Subscribe . AFTER_COMMIT )

@Transactional

public   void  auditLogin(String name, UserVo vo)

{

//do nothing,just log 

System. out .println( "user "  + vo.getName() +  "last login time:"  + vo.getLastLoginTime()

" in subscribe UserCreditServiceImpl.auditLogin" );

userCreditDao .addLoginTimes(name);

// throw new UnsupportedOperationException("just test,no roll back");

}

 

 

 

3.  @ClusterSync 

path:一个逻辑路径,一旦机器( JVM )获取锁,将永久占有锁,机器宕机或者失去连接,将导致其他机器中的某一个占用

allowAcessAsFistTime: false或者 true ,默认 false 。如果为 true ,则允许第一次调用忽略锁

 

@ClusterSync(path="/testsys/job/xxxjob")

Public void doit(){

 

4.  @RemotePublish / @RemoteSubscriber 

@RemotePublish,同 Publish ,但是发布到远程

  path 一个路径

  ruleEx: 根据输入值,输出值判断是否需要 Notify ,默认是 returnValue!=null  ,否则,总是通知其他机器 . 如规则 rule="returnValue==true"

  argExp:一个参数表达式列表,如果没有,则按照输入参数和输出参数作为参数列表,传递个 sub 。参数格式如: argExp="arg0=input[0].orderId;arg1=input[0].cash;arg2=returnValue;"

p ersisit :是否持久化消息

 

@RemotePublish (path =  "/user/age12" , argExp =  "args[0],args[1]" )

public   void  updateAge(String userName,  int  age)

{

System. out .println( "update age"  + userName +  ","  + age);

}

 

 @RemoteSubscriber

  path:一个路径。

@RemoteSubscribe (path =  "/user/age12" )

public   void  addAge(String userName,  int  age)

{

System. out .println( "add age "  + userName +  ","  + age);

}

 

5.  @RemoteNotify / @RemoteWait

 @RemoteNotify,远程只能有一个被执行

  path 一个路径

  rule: 根据输入值,输出值的表达式判断是否需要 Notify ,否则,总是通知其他机器 如规则 rule="returnValue==true" ,默认是发送

  argExp:一个参数表达式列表,如果没有,则按照输入参数和输出参数作为参数列表,传递个 sub 。参数格式如: argExp="arg0=input[0].orderId;arg1=input[0].cash;arg2=returnValue;"

p ersisit :是否持久化消息

 

@ RemoteNotify(path= "/test/mq2" ,persisit= true )

public   void  sendMsg(String str){

sendList.add(str);

}

 

  @RemoteWait 

  path:一个路径。 

@RemoteWait (path= "/test/mq2" )

public   void  receiveMsg(String str){

receiverList .add(str);

}

 

 

四、 协作服务安装

 

每组annotation 可以有自己的协作服务提供者,或者共用一种协作服务提供者(如果服务提供者都支持)。

协作服务提供时机应该是系统启动成功后(也包括系统各个组件初始化成功后)

Remote的协作服务实现可以通过 JMS ZK, 甚至数据库表共享来实现。推荐使用 ZK ,但 ZK  RemotePublish  支持并不好。不适合线上业务,只适合一些数据同步和管理功能。

@Publish,@Process是基于 Local 的,则不需一个第三方协作服务提供者。

 

@ClusterSync   使用了Zookeeper, 只需要安装 Zookeeper ,并在配置文件中指定 server IP 地址即可

@RemotePublis @RemoteNotify使用了 ActivyMQ ,同样只需要安装好 MQ ,并设定 URL 的值即可

 

五 应用场景说明

 

多台机器上只有一台能执行某个 job ,则使用 @RemoteSynronized 

主业务调用后会调用一些次要业务,不希望次要业务影响主业务的性能和牺牲可维护性 主业务使用 @Publish, 多个次业务使用 @Subscribe

数据需要同步到多台机器上,使用 @RemotePublish 和  @RemoteSubscriber 标签

数据需要交给远程的任一台机器处理,使用 @RemoteNotify 然后结合 @RemoteWait  标签一起用

主业务和次要业务处理后,还要求交给远端一个机器处理 可以在使用 @Publish,@Subscrbie 后,可以结合 @RemoteNotify @RemoteWait  来处理

 

 

 

欢迎使用和建议

猜你喜欢

转载自javamonkey.iteye.com/blog/1601688