这两天在研读大众点评所采用的分布式任务调度系统,发现了许雪里的许多值得我学习的代码。其中让我印象最深的就是调度中心向执行器分发任务的代码,在执行器和调度中心之间的通信使用的是内置的jetty服务器(总感觉netty更好一点,毕竟是传输层)。

调度中心使用动态代理,在执行某服务的方法的过程中,通过反射的方式获得要执行的方法名, 方法参数然后将其 封装为一个request 传递给执行器,执行器再对调度中心的request进行解析,通过反射来执行相应的任务。

在这里简单模拟了一下:

/**
*
* @author xiaosuda
* @date
public class MastNode

public static void main(String [] args){
MastNode mastNode = new MastNode();
ProxyFactory proxyFactory = mastNode.new ProxyFactory(new BirdServiceImpl(), BirdService.class);
BirdService proxy = (BirdService) proxyFactory.getProxy();
System.out.println(proxy.say("叽叽喳喳", 6));
System.out.println(proxy.walk(5));

}

class ProxyFactory {
private Object obj;
private Class< ? extends Object> cla;

public ProxyFactory(Object obj, Class< ? extends Object> cla){
this.obj = obj;
this.cla = cla;
}

public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] { cla }, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
RpcRequest rpcRequest = new RpcRequest();
rpcRequest.setServiceBean(obj);
rpcRequest.setMethodName(method.getName());
rpcRequest.setParameterTypes(method.getParameterTypes());
rpcRequest.setParameters(args);

WorkNode workNode = new WorkNode();
return workNode.executeRpcMethod(rpcRequest);
}
});
}
}
}


class WorkNode {
public Object executeRpcMethod(RpcRequest request) throws InvocationTargetException {
String methodName = request.getMethodName();
Class<?>[] parameterTypes = request.getParameterTypes();
Object[] parameters = request.getParameters();
Object serviceBean = request.getServiceBean();
FastClass serviceFastClass = FastClass.create(serviceBean.getClass());
FastMethod serviceFastClassMethod = serviceFastClass.getMethod(methodName, parameterTypes);
Object result = serviceFastClassMethod.invoke(serviceBean, parameters);
return "远程执行结果:{" + result + "}";

}
}

class RpcRequest {
private Object serviceBean;
private String methodName;
private Class<?>[] parameterTypes;
private Object[] parameters;

public void setServiceBean(Object serviceBean) {
this.serviceBean = serviceBean;
}

public Object getServiceBean() {
return serviceBean;
}

public String getMethodName() {
return methodName;
}

public void setMethodName(String methodName) {
this.methodName = methodName;
}

public Class<?>[] getParameterTypes() {
return parameterTypes;
}

public void setParameterTypes(Class<?>[] parameterTypes) {
this.parameterTypes = parameterTypes;
}

public Object[] getParameters() {
return parameters;
}

public void setParameters(Object[] parameters) {
this.parameters = parameters;
}
}

class BirdServiceImpl implements BirdService{
@Override
public String say(String content, Integer times) {

for (int i = 0; i < times; i++) {
System.out.println(content + " ");
}

StringBuilder sb = new StringBuilder();
sb.append("该小鸟鸣叫内容:").append(content).append(",鸣叫次数:").append(times);
return sb.toString();
}

@Override
public String walk(Integer steps) {
for (int i = 0; i < steps; i++) {
System.out.println("行走一步");
}

StringBuilder sb = new StringBuilder();
sb.append("该小鸟行走了").append(steps).append("步");
return sb.toString();
}
}

interface BirdService {
/**
*
* @param content
* @param times
* @return
String say(String content, Integer times);

/**
*
* @param steps
* @return

执行结果:

叽叽喳喳 
叽叽喳喳
叽叽喳喳
叽叽喳喳
叽叽喳喳
叽叽喳喳
远程执行结果:{该小鸟鸣叫内容:叽叽喳喳,鸣叫次数:6}
行走一步
行走一步
行走一步
行走一步
行走一步
远程执行结果:{该小鸟行走了5步}