這兩天在研讀大衆點評所採用的分佈式任務調度系統,發現了許雪裏的許多值得我學習的代碼。其中讓我印象最深的就是調度中心向執行器分發任務的代碼,在執行器和調度中心之間的通信使用的是內置的jetty服務器(總感覺netty更好一點,畢竟是傳輸層)。
調度中心使用動態代理,在執行某服務的方法的過程中,通過反射的方式獲得要執行的方法名, 方法參數然後將其 封裝爲一個request 傳遞給執行器,執行器再對調度中心的request進行解析,通過反射來執行相應的任務。
在這裏簡單模擬了一下:
/**
*
* @author xiaosuda
* @date 2018/2/6
*/
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
*/
String walk(Integer steps);
執行結果:
嘰嘰喳喳
嘰嘰喳喳
嘰嘰喳喳
嘰嘰喳喳
嘰嘰喳喳
嘰嘰喳喳
遠程執行結果:{該小鳥鳴叫內容:嘰嘰喳喳,鳴叫次數:6}
行走一步
行走一步
行走一步
行走一步
行走一步
遠程執行結果:{該小鳥行走了5步}