1、邮件发送阻塞问题
1.1、问题描述
在调用邮件功能的时候,会出现阻塞的情况,导致请求时间过长甚至抛异常的情况
1.2、解决方案
分析:断点查看发现主要延迟项还是在邮件调用的上,外部接口服务并不是很稳定,导致前端会一直停留在等待状态,最长可以到60s。
目前是选择进行异步进行调用(开线程池进行调用),先给前端返回发送中的状态,之后再进行调用发送接口。
最后通过socket进行回调,更新发送情况。
1.3、代码范例(仅供参考)
@Async("asyncServiceExecutor")
public void eSend(String to, String html, SendRecord record) throws Exception {
MultiValueMap<String, Object> body = new LinkedMultiValueMap<String, Object>(7);
body.add("from", from);
body.add("to", to);
body.add("subject", subject);
body.add("html", html);
body.add("apiUser", API_USER);
body.add("apiKey", API_KEY);
body.add("respEmailId", "true");
ResponseEntity entity = RestUtils.post(SEND_CLOUD_API, null, body);
LOGGER.info("【发送给{}邮件信息接口返回:{}】", to, JSONObject.toJSONString(entity));
JSONObject bodyJson = (JSONObject)entity.getBody();
String statusCode = bodyJson.getString("statusCode");
//1成功 2失败
int sendState = "200".equalsIgnoreCase(statusCode) ? 1 : 2;
JSONObject info = bodyJson.getJSONObject("info");
if(info != null){
JSONArray emailIdList = info.getJSONArray("emailIdList");
if(emailIdList != null){
record.setEmailId(emailIdList.subList(0, 1).get(0).toString());
record.setState(sendState);
}
}
sendRecordService.updateById(record);
esService.updateOrInsertSendRecord(record);
SocketIOClient socketIOClient = SocketIoEventHandler.getSocketRelationMap().get(record.getCreateUserType() + "_" + record.getCreateUserId());
JSONObject json = new JSONObject();
json.put("type", sendState == 1 ? "success" : "error");
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH时mm分ss秒") ;
Date parse = sdf1.parse(record.getCreateTime());
json.put("msg", String.format(notifyMsg, sdf2.format(parse), record.getEmail(), EmailStateConstants.stateMap.getOrDefault(statusCode, "状态有误")));
if(socketIOClient != null){
socketIOClient.sendEvent("fmsg", json);
}
}