(1)从zookeer中获取一台主机,然后用这台主机器加载所有的任务,然后分发到每一个server服务中
(2)每一台server,循环遍历每一个任务,计算出下一次要执行的时间
(3)将所有的任务加入到队列中,按照时间从小到大进行排序
(4)同时启动一个死循环,从队列中获取任务进行执行,拿当时时间与队列头部第一个元素比对是否小于当前时间,如果小于表示要执行。如果需要执行,那么需要落一个任务实例,表示定时调度了,然后将任务实例放到实例执行队列中
package scheduler;
import akka.actor.UntypedActor;
import org.joda.time.DateTime;
import java.util.Comparator;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
public class TimeSchedulerActor extends UntypedActor {
private Queue<TimePlanEntry> timeQueue=new PriorityBlockingQueue<>(100, new Comparator<TimePlanEntry>() {
@Override
public int compare(TimePlanEntry o1, TimePlanEntry o2) {
int timeCompare=o1.getScheduleTime().compareTo(o2.getScheduleTime());
return timeCompare==0?o2.getPriority()-o1.getPriority():timeCompare;
}
});
private FireQueue fireQueue= BlockingFireQueue.getInstance();
@Override
public void onReceive(Object o) throws Throwable {
//加入任务
TimePlanEntry timePlanEntry=new TimePlanEntry();
timeQueue.add(timePlanEntry);
//如果是加入任务实例
JobInstance jobInstance=new JobInstance();
fireQueue.put(jobInstance);
}
class TimeScanThread extends Thread{
public TimeScanThread(String name){
super(name);
}
@Override
public void run() {
while (true){
try{
DateTime now=DateTime.now();
while (!timeQueue.isEmpty()){
TimePlanEntry entry=timeQueue.peek();
if(entry!=null&& !entry.getScheduleTime().isAfter(now)){
timeQueue.remove();
//执行任务
//使用http 或者 rpc进行调度
}else {
break;
}
}
}catch (Exception e){
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
package scheduler;
import org.joda.time.DateTime;
public class TimePlanEntry {
private DateTime scheduleTime;
private int priority;
public DateTime getScheduleTime() {
return scheduleTime;
}
public void setScheduleTime(DateTime scheduleTime) {
this.scheduleTime = scheduleTime;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
}
(5)启动任务线程执行每一个任务实例
package scheduler;
public class Dispatcher extends Thread {
private FireQueue fireQueue=BlockingFireQueue.getInstance();
@Override
public void run() {
while (true){
try {
JobInstance jobInstance=fireQueue.get();
//根据任务类型进行任务的执行
//http 或者 rpc 的任务执行
}catch (Exception e){
}
}
}
}
额外增加一个 http请求使用
package scheduler;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.nio.client.HttpAsyncClient;
import org.apache.http.nio.conn.NoopIOSessionStrategy;
import org.apache.http.nio.conn.SchemeIOSessionStrategy;
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
import org.apache.http.nio.reactor.ConnectingIOReactor;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import javax.net.ssl.SSLContext;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class HttpDispatcher {
//线程安全多线程共享
public static CloseableHttpAsyncClient httpAsyncClient=null;
//线程池
public static PoolingNHttpClientConnectionManager connectionManager;
private static final int SOCKET_TIMEOUT=10;
private static final int CONNECT_TIME=4;
private static final int POOL_CONNECT_TIME=5;
private static final int IO_THREADS=32;
private boolean enableSec=false;
public void init() throws Exception {
if(httpAsyncClient==null){
//配置IO线程
IOReactorConfig ioReactorConfig=IOReactorConfig.custom().setIoThreadCount(IO_THREADS).setSoKeepAlive(true).build();
ConnectingIOReactor ioReactor=new DefaultConnectingIOReactor(ioReactorConfig);
//https
connectionManager=new PoolingNHttpClientConnectionManager(ioReactor, getSSlRegistryAsync());
connectionManager.setDefaultMaxPerRoute(40);
connectionManager.setMaxTotal(300);
HttpAsyncClientBuilder builder= HttpAsyncClients.custom();
builder.setConnectionManager(connectionManager);
builder.setSSLContext(getSSLContext());
httpAsyncClient=builder.build();
httpAsyncClient.start();
}
}
public void execute(JobInstance jobInstance){
try {
}catch (Exception e){
}
}
public Registry<SchemeIOSessionStrategy> getSSlRegistryAsync() throws Exception{
return RegistryBuilder.create().
register("http", NoopIOSessionStrategy.INSTANCE).
register("https",new SSLIOSessionStrategy(getSSLContext(),new String[]{"SSLv2Hello","SSLv3","TLSv1"},null,NoopHostnameVerifier.INSTANCE)).build();
}
public SSLContext getSSLContext() throws Exception{
TrustStrategy acceptingTrustStrategy=new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
};
final SSLContext sslContext= SSLContexts.custom().loadTrustMaterial(null,acceptingTrustStrategy).build();
sslContext.getServerSessionContext().setSessionCacheSize(1000);
return sslContext;
}
}