package org.example.design.notifier;
import org.demo.schedule.SpringContextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.task.TaskExecutor;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.FutureTask;
public class MQNotifier {
private final Logger LOG = LoggerFactory.getLogger(MQNotifier.class);
private volatile boolean consumerFail;
private List<FutureTask<Boolean>> futureList = new ArrayList<>();
public static interface INotifier {
void doNotify() throws Exception;
}
public static MQNotifier newInstance() {
return new MQNotifier();
}
public MQNotifier addNotify(INotifier notifier) {
futureList.add(new FutureTask(() -> {
try {
notifier.doNotify();
} catch (Exception e) {
LOG.error("推送结果异常:", e);
return Boolean.FALSE;
}
return Boolean.TRUE;
}));
return this;
}
public boolean executeAll() {
TaskExecutor taskExecutor = (TaskExecutor) SpringContextUtils.getBean("taskExecutor");
try {
for (FutureTask<Boolean> task : futureList) {
taskExecutor.execute(task);
}
for (FutureTask<Boolean> task : futureList) {
Boolean taskResult = task.get();
if (!taskResult) {
return Boolean.FALSE;
}
}
return Boolean.TRUE;
} catch (Exception e) {
LOG.error("推送结果异常:", e);
return Boolean.FALSE;
}
}
}
package org.example.design.notifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
public class AsyncScheduledTaskConfig {
@Value("${spring.task.execution.pool.core-size}")
private int corePoolSize;
@Value("${spring.task.execution.pool.max-size}")
private int maxPoolSize;
@Value("${spring.task.execution.pool.queue-capacity}")
private int queueCapacity;
@Value("${spring.task.execution.thread-name-prefix}")
private String namePrefix;
@Value("${spring.task.execution.pool.keep-alive}")
private int keepAliveSeconds;
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//最大线程数
executor.setMaxPoolSize(maxPoolSize);
//核心线程数
executor.setCorePoolSize(corePoolSize);
//任务队列的大小
executor.setQueueCapacity(queueCapacity);
//线程前缀名
executor.setThreadNamePrefix(namePrefix);
//线程存活时间
executor.setKeepAliveSeconds(keepAliveSeconds);
/**
* 拒绝处理策略
* CallerRunsPolicy():交由调用方线程运行,比如 main 线程。
* AbortPolicy():直接抛出异常。
* DiscardPolicy():直接丢弃。
* DiscardOldestPolicy():丢弃队列中最老的任务。
*/
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
//线程初始化
executor.initialize();
return executor;
}
}
应用:
/**
* 处理MQ消息
*/
@Slf4j
@Component("demo")
public class Demo implements ConsumerBusinessExecutor {
@Resource
private AdvertiserReportManager advertiserReportManager;
@Override
public ConsumerBussnessExecuteResult execute(MessageReq messageReq) {
log.info("接收到MQ消息,key->[{}],body->[{}]", messageReq.getKey(), messageReq.getBody());
JSONObject jsonObject = JSONObject.parseObject(messageReq.getBody());
boolean isAllSuccess = MQNotifier.newInstance()
.addNotify(() -> advertiserReportManager.report(EventType.MONEY_SAVING_CARD, jsonObject))
.executeAll();
if (!isAllSuccess) {
return ConsumerBussnessExecuteResult.FAIL;
} else {
return ConsumerBussnessExecuteResult.SUCCESS;
}
}
}