下面的这个方法是发邮件的抽象出来的一个公用方法:
String[] to 表示收件人列表;
subject 邮件主题;
templateName 邮件末班,用velocity写的,
Map params 参数,用来填充velocity中的某些字段取值的
public void sendHtmlWithTemplate(String[] to, String subject, String templateName, Map<String, Object> params) {
final MimeMessage mimeMessage = mailSender.createMimeMessage();
try {
final MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
messageHelper.setFrom(simpleMailMessage.getFrom());
if (ENV_ONLINE.equals(environment)) {
messageHelper.setTo(to);
messageHelper.setSubject(subject);
} else {
messageHelper.setTo(adminEmail);
messageHelper.setSubject(subject + Arrays.asList(to));
}
messageHelper.setSentDate(new Date());
final String content = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, templateName, "UTF-8",
params);
final String[] logTo = to;
messageHelper.setText(content, true);
new Thread() {
@Override
public void run() {
mailSender.send(mimeMessage);
logger.error("Mailsentto: " + Arrays.asList(logTo) + "\nContent: " + content);
}
}.start();
} catch (Exception e) {
logger.error("emailServiceError error:" + e.getMessage(), e);
}
}
在上面的发邮件的代码中,使用了内部类如下:
new Thread() {
@Override
public void run() {
mailSender.send(mimeMessage);
logger.error("Mailsentto: " + Arrays.asList(logTo) + "\nContent: " + content);
}
}.start();
我觉得在这个地方做这个控制是很恰当的吧,为什么team leader让我删掉这个new Thread()的部分。
原话:“把new Thread全部删掉,这些邮件发送不了的bug都没有暴露出来; 邮件发送模块的代码采用异步发送方式,失去异常事务回滚的能力,new Thread要全部删除;” 不懂是什么意思啊?
问题:
1.为什么要去掉new Thread()?
2.在什么样的并发业务场景下,需要使用new Thread()这样的方式?有没有更好的解决方法?
3.在并发场景下,使用new Thread().start()的方式有什么弊端?每次new Thread新建对象性能会很差么?邮件服务也是当触发某个业务规则的时候,可能需要大量发送一下邮件,用线程池好不好呢?
@Youming님은 이미 익명 내부 클래스의 불편한 점을 언급하셨습니다. 귀하의 비즈니스를 기준으로 설명하겠습니다.
기존 코드 로직에 따르면 우리 이메일 서비스가 외부에 노출해야 하는
메소드. 이메일을 비동기적으로 보내는 스레드를 시작하세요. 왜냐하면 호출자에게는 이번에 이메일 전송이 성공했는지, 실패/예외가 발생했는지 알려줘야 하기 때문입니다. 실패의 이유였습니다. 기존 계획을 따르면 이메일이 성공적으로 전송되거나 실패하더라도 외부 세계가 이를 인식하지 못한다고 외부 세계에 느껴질 수 있습니다. 이는 이메일이 지속되지 않고 잠시 후 다시 시도된다는 의미입니다. . 따라서 비동기식으로 이메일을 보내는 것은 귀하의 방법이 아닌 호출자에게 맡겨야 합니다sendHtmlWithTemplate
메소드는mailSender.send
가 아닌sendHtmlWithTemplate
메소드여야 하므로 다시 노출할 필요가 없습니다. 우리가 외부에 공개하는익명 개체는 매우 편리하지만 제대로 사용하지 않으면 애플리케이션이 붕괴됩니다. 예를 들어 이메일 전송 매개변수를 제어하지 않는 경우, 예를 들어 전송 중에 시간 초과가 발생한 후에도 계속 기다리면 이 스레드를 찾을 수 없거나 닫을 수 없습니다. 그만둬라, 이것이 프로그래머가 해야 할 일인가?
당신 머리가 왜 이곳을 없애라고 했는지 묻는다면, 그 사람은 당신의 능력을 충분히 신뢰하지 않아서 감히 당신이 이 악마를 통제하도록 놔두지 않을 것이라고밖에 말할 수 없습니다.
어떤 시나리오에 적합하냐고 물으신다면 적합한 시나리오는 없고 능력 있는 사람만 가능하다고 말씀드릴 수 있습니다.
많은 양의 이메일을 보내고 싶다면 대기열을 만들 수 있습니다. 스레드가 너무 많으면 좋지 않을 수 있습니다.
죄송합니다. 이제 문제를 확인했습니다.
자세한 내용은 @iMouseWu 및 @유명 님의 답변을 참고하세요.
js를 작성한 적이 있다면 여기서
new Thread()
가 비동기 동작인ajax
요청과 동일하다는 것을 이해할 수 있습니다. 이는 스레드 작업이 완료되기 전에 메서드가 호출자에게 반환됩니다. no 이메일을 보내면 예외가 발생합니다) 리더님이 "이 이메일을 보낼 수 없는 버그는 노출되지 않았습니다"라고 말씀하셨습니다.동시성이 크다고 생각되면
redis
+kafka
(또는 기타 메시지 구성 요소)를 사용하여 이메일 서비스에 메시지 형식으로 이메일을 보내도록 알릴 수 있습니다.