优化说明
代码中,每次发送短信记录后都会将数据将数据推送推送到mq供下游使用。
在原有代码中直接在代码中发送mq,但是这个代码的问题点在于,每次处理都是同步阻塞来处理,会影响处理的速度,而且此逻辑对整个业务逻辑的结果并不产生影响。
所以可以将此处理从单线程阻塞处理改为多线程处理。
代码实现
/**
* 2022-03-25
* 数据推送给大数据
* @author joe
*/
@Slf4j
@Component
public class SmsSendBigDataComponentService {
@Lazy
@Resource
private RocketMQProducer stagePostSmsInfoProducer;
private static ThreadPoolExecutor executor = null;
static{
executor = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors()*5,
Runtime.getRuntime().availableProcessors()*10,
60L, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(Runtime.getRuntime().availableProcessors()*10),
new ThreadFactory(){
//在多线程下要使用线程安全的计数方式
private AtomicLong count = new AtomicLong(0L);
@Override
public Thread newThread(Runnable r) {
//为了便于查找指定的线程,可指定线程名称,否则后续查找线程名称相同,不易查找。
Thread t = new Thread(r);
String threadName = "BigDataAsync" + this.count.addAndGet(1L);
t.setName(threadName);
return t;
}
}, new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
BigDataAsyncExecute bde = (BigDataAsyncExecute) r;
//丢弃,打日志
log.error("BigDataAsyncExecute_queue_full,ignore_data:{}", JSON.toJSONString(bde.getData()));
} catch (Throwable e) {
log.error("BigDataAsyncExecute_RejectedExecutionHandler_eror", e);
}
}
});
}
/**
* 短信插入表的数据推送给大数据:新增操作 推送MQ
*
* @param object
* @throws Exception
*/
public void mqSendAdd(final StationSmsToBigDataDto object) throws Exception {
executor.execute(new BigDataAsyncExecute("add", object));
}
/**
* 短信插入表的数据推送给大数据:更新操作 推送MQ
*
* @param object
* @throws Exception
*/
public void mqSendUpdate(final StationSmsToBigDataDto object) throws Exception {
executor.execute(new BigDataAsyncExecute("update", object));
}
class BigDataAsyncExecute implements Runnable{
private String tag;
private StationSmsToBigDataDto data;
public StationSmsToBigDataDto getData() {
return data;
}
private BigDataAsyncExecute(){
}
public BigDataAsyncExecute(String tag, StationSmsToBigDataDto data){
this.tag = tag;
this.data = data;
}
@Override
public void run() {
try {
Result<SendResult> result = stagePostSmsInfoProducer.publish(JSON.toJSONString(data), tag, data.getId(), RocketMQProducer.MessageDelayLevel.LEVEL_1_SECOND);
if(result!=null&&!result.isSuccess()){
log.error("send_bigData_fail,data:{}", JSON.toJSONString(data));
}
} catch (Exception e) {
log.error("send_bigData_error,data:{}", JSON.toJSONString(data),e);
}
}
}
}