package com.zy.asrs.service;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.zy.asrs.domain.NotifyDto;
|
import com.zy.asrs.domain.NotifySendResult;
|
import com.zy.asrs.entity.HttpRequestLog;
|
import com.zy.common.utils.HttpHandler;
|
import com.zy.common.utils.RedisUtil;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.stereotype.Service;
|
|
import java.util.Date;
|
|
/**
|
* 异步通知服务
|
* 用于异步发送HTTP通知请求,避免阻塞定时器线程
|
*/
|
@Service
|
@Slf4j
|
public class NotifyAsyncService {
|
|
@Autowired
|
private RedisUtil redisUtil;
|
@Autowired
|
private HttpRequestLogService httpRequestLogService;
|
|
/**
|
* 异步发送通知
|
*
|
* @param notifyUri 通知URI
|
* @param notifyUriPath 通知路径
|
* @param key Redis键
|
* @param notifyDto 通知数据
|
*/
|
@Async
|
public void sendNotifyAsync(String notifyUri, String notifyUriPath, String key, NotifyDto notifyDto) {
|
sendNotifyNow(notifyUri, notifyUriPath, key, notifyDto, true, true);
|
}
|
|
public NotifySendResult sendNotifyNow(String notifyUri, String notifyUriPath, String key, NotifyDto notifyDto,
|
boolean deleteOnSuccess, boolean updateRetryState) {
|
HttpRequestLog httpRequestLog = new HttpRequestLog();
|
httpRequestLog.setName(notifyUri + notifyUriPath);
|
httpRequestLog.setRequest(JSON.toJSONString(notifyDto));
|
httpRequestLog.setCreateTime(new Date());
|
|
NotifySendResult result = new NotifySendResult();
|
result.setSuccess(false);
|
try {
|
String response = new HttpHandler.Builder()
|
.setUri(notifyUri)
|
.setPath(notifyUriPath)
|
.setJson(JSON.toJSONString(notifyDto))
|
.build()
|
.doPost();
|
result.setResponse(response);
|
httpRequestLog.setResponse(response);
|
|
JSONObject jsonObject = JSON.parseObject(response);
|
Integer code = jsonObject == null ? null : jsonObject.getInteger("code");
|
if (code != null && code == 200) {
|
if (deleteOnSuccess && key != null) {
|
redisUtil.del(key);
|
}
|
result.setSuccess(true);
|
result.setMessage("通知成功");
|
} else {
|
result.setMessage("通知接口返回失败");
|
}
|
} catch (Exception e) {
|
log.error("异步通知失败, key={}", key, e);
|
result.setMessage("通知异常: " + e.getMessage());
|
} finally {
|
httpRequestLog.setResult(result.isSuccess() ? 1 : 0);
|
httpRequestLogService.insert(httpRequestLog);
|
}
|
|
if (!result.isSuccess() && updateRetryState && key != null) {
|
handleNotifyFailure(key, notifyDto);
|
}
|
return result;
|
}
|
|
/**
|
* 处理通知失败的情况
|
*/
|
private void handleNotifyFailure(String key, NotifyDto notifyDto) {
|
try {
|
int times = notifyDto.getRetryTimes() + 1;
|
if (times >= notifyDto.getFailTimes()) {
|
// 超过次数
|
redisUtil.del(key);
|
return;
|
}
|
|
notifyDto.setLastRetryTime(System.currentTimeMillis());
|
notifyDto.setRetryTimes(times);
|
redisUtil.set(key, notifyDto);
|
} catch (Exception e) {
|
log.error("处理通知失败逻辑异常, key={}", key, e);
|
}
|
}
|
}
|