Getting started
该章节将会初步介绍Reactor是什么,以及如何快速的在项目中实施
reactor是基于模块化的思想构建和实现的。通过reactor可以将一系列业务整合到一个模块(module)里面,而各个业务的实现形成一次交互(interaction),各个模块和interaction是相互独立的,所以可以达到项目的解耦以及提高各个业务实现的重用性。下图是整个reactor的架构图:
上图可以看到整个reactor是遵循分层的架构,位于中间层,其中interaction reactor
是上次解码层和reactor内部的入口。通过它的pipeline
下发到某个处理具体请求的interaction module
,其中logger
,以及authentication
也是一个module,这些module均挂载在pipeline
中。上面说了,module中包含具体的业务实现(interaction
),如果一个请求落到某个module之后,那么将会在该module中路由到某个业务实现(interaction
)上。
一、引入Maven依赖
1、引入reactor的所有模块
<dependency>
<groupId>com.pinganfu.mobile</groupId>
<artifactId>reactor-all</artifactId>
<version>${reactor.version}</version>
</dependency>
2、分模块引入
<!--reactor核心模块-->
<dependency>
<groupId>com.pinganfu.mobile.reactor</groupId>
<artifactId>reactor-frm</artifactId>
<version>${reactor.version}</version>
</dependency>
<!--reactor mtp基础公共模块,包含校验和日志-->
<dependency>
<groupId>com.pinganfu.mobile.reactor</groupId>
<artifactId>reactor-comm</artifactId>
<version>${reactor.version}</version>
</dependency>
<!--reactor 监控模块-->
<dependency>
<groupId>com.pinganfu.mobile.reactor.monitor</groupId>
<artifactId>collector</artifactId>
<version>${reactor.version}</version>
</dependency>
二、在spring的xml配置文件中引入reactor的namespace
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:reactor="http://mobile.pinganfu.com/schema/reactor"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://mobile.pinganfu.com/schema/reactor http://mobile.pinganfu.com/schema/reactor/reactor.xsd">
</beans>
三、开启reactor
<reactor:reactor id="demo-reactor" systemName="hello" asynchronous="true" acceptorThreads="1" serviceThreads="100"/>
往你的spring的xml配置文件中添加上面一段配置
配置属性说明:
systemName
:表示当前应用的名称,比如MTP
asynchronous
:表示开启异步模式,所有经过reactor来处理的请求,均是采用异步方式处理
acceptorThreads
:接受请求的线程数量
serviceThreads
:所有处理业务的线程数量
四、配置你第一个交互(interaction)
<reactor:javaInteraction operationPath="first_module/first" minVer="3.2.2" maxVer="3.3.3" clientType="android" checkLoginState="false" id="firstInteraction" class="com.pinganfu.mobile.reactor.FirstInteraction">
</reactor:javaInteraction>
上面内容添加到spring的xml中
配置属性说明:
operationPath
:当前交互能够处理请求的绝对路径
minVer/maxVer
:当前交互能够处理的最小版本和最大版本区间,默认是,表示处理所有版本
clientType
:能够处理的客户端类型,默认是,表示所有客户端类型
checkLoginState
:当前交互是否需要校验登录态,默认是true
id
:一个交互的唯一标识
class
:交互实现类的全路径
业务交互实现:
package com.pinganfu.mobile.reactor;
import com.pinganfu.mobile.reactor.frm.export.ClientType;
import com.pinganfu.mobile.reactor.frm.export.action.Action;
import com.pinganfu.mobile.reactor.frm.export.action.ActionAdapter;
import com.pinganfu.mobile.reactor.frm.export.action.AsyAction;
import com.pinganfu.mobile.reactor.frm.export.action.AsyActionCallBack;
import com.pinganfu.mobile.reactor.frm.future.Future;
import com.pinganfu.mobile.reactor.frm.future.FutureListener;
import com.pinganfu.mobile.reactor.frm.pipeline.Context;
import com.pinganfu.mobile.reactor.frm.pipeline.Event;
/**
* Created by bieber on 2015/10/16.
*/
public class FirstInteraction extends ActionAdapter<FirstRequest, FirstResponse> {
@Override
public FirstResponse action(FirstRequest request) {
FirstResponse firstResponse= new FirstResponse();
firstResponse.setHello("hello world,"+request.getName()+"!");
return firstResponse;
}
}
请求实体:
package com.pinganfu.mobile.reactor;
import com.pinganfu.mobile.reactor.frm.export.InteractiveBaseRequest;
/**
* Created by bieber on 2015/10/16.
*/
public class FirstRequest extends InteractiveBaseRequest {
private String name;
public FirstRequest(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
响应实体:
package com.pinganfu.mobile.reactor;
import com.pinganfu.mobile.reactor.frm.export.InteractiveBaseResponse;
/**
* Created by bieber on 2015/10/16.
*/
public class FirstResponse extends InteractiveBaseResponse {
private String hello;
public FirstResponse() {
}
public String getHello() {
return hello;
}
public void setHello(String hello) {
this.hello = hello;
}
}
五、把你的交互添加到你的module中
<reactor:module queueSize="10000" operationPath="/first_module" id="firstModule" weight="10">
<reactor:interactions>
<reactor:ref bean="firstInteraction"/>
</reactor:interactions>
</reactor:module>
把上面的内容添加到spring的xml配置中
配置属性说明:
operationPath
:当前模块的操作路径
queueSize
:当前模块的能够处理队列大小,默认是0,表示使用同步队列,异步模式有效
weight
:当前模块的权重,权重越大,获取的线程池大小越大(异步模式有效)
通过上面边完成了将reactor嵌入到你的项目中,下面贴出完整的xml配置:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:reactor="http://mobile.pinganfu.com/schema/reactor"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://mobile.pinganfu.com/schema/reactor http://mobile.pinganfu.com/schema/reactor/reactor.xsd">
<reactor:reactor id="demo-reactor" systemName="hello" asynchronous="true" acceptorThreads="1" serviceThreads="100"/>
<reactor:javaInteraction operationPath="first_module/first" minVer="3.2.2" maxVer="3.3.3" clientType="android" checkLoginState="false" id="firstInteraction" class="com.pinganfu.mobile.reactor.FirstInteraction">
</reactor:javaInteraction>
<reactor:module queueSize="10000" operationPath="/first_module" maxVer="*" minVer="*" id="firstModule" weight="10">
<reactor:interactions>
<reactor:ref bean="firstInteraction"/>
</reactor:interactions>
</reactor:module>
</beans>
通过上面的配置,只需要启动的时候加载上面的xml即可!
package com.pinganfu.mobile;
import com.alibaba.fastjson.JSON;
import com.dianping.cat.Cat;
import com.dianping.cat.message.Event;
import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;
import com.pinganfu.mobile.reactor.FirstRequest;
import com.pinganfu.mobile.reactor.FirstResponse;
import com.pinganfu.mobile.reactor.HelloRequest;
import com.pinganfu.mobile.reactor.HelloResposne;
import com.pinganfu.mobile.reactor.frm.ReactorAcceptor;
import com.pinganfu.mobile.reactor.frm.export.Acceptor;
import com.pinganfu.mobile.reactor.frm.export.ClientType;
import com.pinganfu.mobile.reactor.frm.export.InteractiveBaseResponse;
import com.pinganfu.mobile.reactor.frm.future.Future;
import com.pinganfu.mobile.reactor.frm.future.FutureListener;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
/**
* Created by bieber on 2015/10/16.
*/
public class ReactorDemo {
public static void main(String[] args) throws InterruptedException {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:/spring/reactor.xml", "classpath*:/spring/applicationContext.xml", "classpath*:/spring/applicationContext-monitor.xml");
final Acceptor reactorAcceptor = applicationContext.getBean(Acceptor.class);
final FirstRequest request = new FirstRequest("bieber");
request.setOperation("first_module/first");
request.setClientVer("3.2.2");
request.setClientType(ClientType.ANDROID);
Future<FirstResponse> responseFuture = reactorAcceptor.fireMessageReceivedEvt(request,FirstResponse.class,null);
//阻塞模式
FirstResponse response = responseFuture.get();
System.out.println(response.getHello());
//非阻塞模式
responseFuture.addListener(new FutureListener<FirstResponse>() {
@Override
public void operationComplete(Future<FirstResponse> future, Object attachment) {
try {
FirstResponse response = future.get();
System.out.println(response.getHello());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
运行上段程序会得到下面的结果:
hello world,bieber!
hello world,bieber!