XXL-JOB原理--執行器註冊(二)
阿新 • • 發佈:2018-12-15
1、xxl-job新增執行器到任務排程中心有兩種方式
(1)客戶端執行器自動將名稱和機器地址註冊到任務排程中心
(2)可以在任務排程中心手動錄入執行器名稱和相關的機器地址(多個機器地址用逗號隔開)
2、自動註冊流程
(1)在執行器客戶端配置執行器名稱和任務排程中心地址:
### xxl-job admin address list, such as "http://address" or "http://address01,http://address02" ##任務排程中心地址 xxl.job.admin.addresses=http://127.0.0.1:8080 ### xxl-job executor address ##任務排程器名稱和機器資訊 xxl.job.executor.appname=xxl-job-executor-sample xxl.job.executor.ip=127.0.0.1 xxl.job.executor.port=9998
(2)相關注冊執行程式碼:
在執行器啟動時會讀取配置,當存在任務排程中心地址會依次向任務排程中心註冊其地址
XxlJobExecutor類在進行初始化時會進行如下操作。
//當存在多個任務排程中心時,建立代理類並註冊,在NetComClientProxy private static void initAdminBizList(String adminAddresses, String accessToken) throws Exception { if (adminAddresses!=null && adminAddresses.trim().length()>0) { for (String address: adminAddresses.trim().split(",")) { if (address!=null && address.trim().length()>0) { String addressUrl = address.concat(AdminBiz.MAPPING); AdminBiz adminBiz = (AdminBiz) new NetComClientProxy(AdminBiz.class, addressUrl, accessToken).getObject(); if (adminBizList == null) { adminBizList = new ArrayList<AdminBiz>(); } adminBizList.add(adminBiz); } } } }
在XxlJobExecutor被呼叫時執行getObject方法,完成向任務排程中心傳送請求進行服務註冊操作。
@Override public Object getObject() throws Exception { return Proxy.newProxyInstance(Thread.currentThread() .getContextClassLoader(), new Class[] { iface }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // filter method like "Object.toString()" if (Object.class.getName().equals(method.getDeclaringClass().getName())) { logger.error(">>>>>>>>>>> xxl-rpc proxy class-method not support [{}.{}]", method.getDeclaringClass().getName(), method.getName()); throw new RuntimeException("xxl-rpc proxy class-method not support"); } // request RpcRequest request = new RpcRequest(); request.setServerAddress(serverAddress); request.setCreateMillisTime(System.currentTimeMillis()); request.setAccessToken(accessToken); request.setClassName(method.getDeclaringClass().getName()); request.setMethodName(method.getName()); request.setParameterTypes(method.getParameterTypes()); request.setParameters(args); // send //向任務排程中心傳送請求進行服務註冊 RpcResponse response = client.send(request); // valid response if (response == null) { throw new Exception("Network request fail, response not found."); } if (response.isError()) { throw new RuntimeException(response.getError()); } else { return response.getResult(); } } });
在JettyClient中呼叫send方法完成服務註冊操作
public RpcResponse send(RpcRequest request) throws Exception {
try {
// serialize request
byte[] requestBytes = HessianSerializer.serialize(request);
// reqURL
String reqURL = request.getServerAddress();
if (reqURL!=null && reqURL.toLowerCase().indexOf("http")==-1) {
reqURL = "http://" + request.getServerAddress() + "/"; // IP:PORT, need parse to url
}
//傳送post請求進行服務註冊,簡單註冊一下IP和埠資訊等
// remote invoke
byte[] responseBytes = HttpClientUtil.postRequest(reqURL, requestBytes);
if (responseBytes == null || responseBytes.length==0) {
RpcResponse rpcResponse = new RpcResponse();
rpcResponse.setError("Network request fail, RpcResponse byte[] is null");
return rpcResponse;
}
// deserialize response
RpcResponse rpcResponse = (RpcResponse) HessianSerializer.deserialize(responseBytes, RpcResponse.class);
return rpcResponse;
} catch (Exception e) {
logger.error(e.getMessage(), e);
RpcResponse rpcResponse = new RpcResponse();
rpcResponse.setError("Network request error: " + e.getMessage());
return rpcResponse;
}
}
相關注冊資訊如下:
總結:其實執行器註冊到任務排程的資訊非常簡單,可以就簡單的認為為應用的一些基本資訊,IP、埠和應用名稱等等,並不用將具體的任務類等資訊註冊到任務排程中心,所以任務排程中心無法感知執行器一些具體資訊,只能需要靠運維和技術人員在任務排程中心進行選擇配置,否則可能會無法正常執行任務。