单线程service服务
1.@Service修饰类名,同时类继承Thread类
@Service
public class MasterSchedulerService extends Thread {
/**
* logger of MasterSchedulerService
*/
private static final Logger logger = LoggerFactory.getLogger(MasterSchedulerService.class);
@Autowired
private ServerConfig serverConfig;
/**
* dolphinscheduler database interface
*/
@Autowired
private ProcessService processService;
/**
* zookeeper master client
*/
@Autowired
private ZKClient zkClient;
/**
* master exec service
*/
private ThreadPoolExecutor masterExecService;
@Autowired
private FamaVmMapper vmMapper;
/**
* constructor of MasterSchedulerService
*/
@PostConstruct
public void init(){
this.masterExecService = (ThreadPoolExecutor) ThreadUtils.newDaemonFixedThreadExecutor("Server-Thread"
, serverConfig.getMasterExecThreads());
}
@Override
public synchronized void start(){
super.setName("MasterSchedulerService");
super.start();
}
public void close() {
masterExecService.shutdown();
boolean terminated = false;
try {
terminated = masterExecService.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException ignore) {
Thread.currentThread().interrupt();
}
if(!terminated){
logger.warn("masterExecService shutdown without terminated, increase await time");
}
logger.info("master schedule service stopped...");
}
/**
* run of MasterSchedulerService
*/
@Override
public void run() {
logger.info("master scheduler started");
while (Stopper.isRunning()){
try {
if (zkClient.getZkClient().getState() == CuratorFrameworkState.STARTED) {
scheduleProcess();
}
} catch (Exception e) {
logger.error("master scheduler thread error", e);
}
}
}
private void scheduleProcess() throws Exception {
InterProcessMutex mutex = null;
try {
mutex = zkClient.blockAcquireMutex();
// make sure to scan and delete command table in one transaction
Command command = processService.findOneCommand();
if (command != null) {
logger.info("find one command: {}", JsonUtils.toJSONString(command));
try {
String address = getLocalAddress();
ResourceInstance processInstance = processService.handleCommand(address,command);
logger.info("processInstance: {}", JsonUtils.toJSONString(processInstance));
if (processInstance != null) {
MapperContext context = new MapperContext();
context.vmMapper = vmMapper;
MasterExecThread execThread = new MasterExecThread(
processInstance
, processService
, serverConfig
, context);
masterExecService.execute(execThread);
}
} catch (Exception e) {
logger.error("Command consumer error ", e);
// processService.moveToErrorCommand(command, e.toString());
}
} else {
//indicate that no command ,sleep for 1s
Thread.sleep(Constants.SLEEP_TIME_MILLIS);
}
} finally {
zkClient.releaseMutex(mutex);
}
}
private String getLocalAddress() {
return NetUtils.getAddr(serverConfig.getListenPort());
}
}
2.执行时,直接执行start方法
@ComponentScan(value = {"fama.cost"})
public class FamaServerApplication implements IStoppable {
private static final Logger logger = LoggerFactory.getLogger(FamaServerApplication.class);
@Autowired
private MasterSchedulerService schedulerService;
@Autowired
private SpringApplicationContext springApplicationContext;
@Autowired
private BeanContext beanContext;
@Autowired
private ZKClient zkClient;
public static void main(String[] args) {
Thread.currentThread().setName("Schedule-Server");
new SpringApplicationBuilder(FamaServerApplication.class).web(WebApplicationType.NONE).run(args);
int currentProcessPid = getProcessID();
logger.info("Current Process Pid : {}",currentProcessPid);
}
@PostConstruct
public void run() {
this.zkClient.start(this);
this.schedulerService.start();
try {
logger.info("start Quartz server...");
QuartzExecutors.getInstance().start();
} catch (Exception e) {
try {
QuartzExecutors.getInstance().shutdown();
} catch (SchedulerException e1) {
logger.error("QuartzExecutors shutdown failed : " + e1.getMessage(), e1);
}
logger.error("start Quartz failed", e);
}
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
if (Stopper.isRunning()) {
close("shutdownHook");
}
}
}));
}
public void close(String cause) {
try {
//execute only once
if (Stopper.isStopped()) {
return;
}
logger.info("master server is stopping ..., cause : {}", cause);
// set stop signal is true
Stopper.stop();
try {
//thread sleep 3 seconds for thread quietly stop
Thread.sleep(3000L);
} catch (Exception e) {
logger.warn("thread sleep exception ", e);
}
//close
this.schedulerService.close();
this.zkClient.close();
//close quartz
try {
QuartzExecutors.getInstance().shutdown();
logger.info("Quartz service stopped");
} catch (Exception e) {
logger.warn("Quartz service stopped exception:{}", e.getMessage());
}
} catch (Exception e) {
logger.error("master server stop exception ", e);
} finally {
// System.exit(-1);
}
}
@Override
public void stop(String cause) {
close(cause);
}
public static final int getProcessID() {
try {
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
return Integer.valueOf(runtimeMXBean.getName().split("@")[0]).intValue();
}catch (Exception ex){
logger.error(ex.getMessage(),ex);
return 0;
}
}
}
原创:做时间的朋友
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示