下面的这个方法是发邮件的抽象出来的一个公用方法:
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新建对象性能会很差么?邮件服务也是当触发某个业务规则的时候,可能需要大量发送一下邮件,用线程池好不好呢?
伊谢尔伦2017-04-18 09:21:21
@Youming님은 이미 익명 내부 클래스의 불편한 점을 언급하셨습니다. 귀하의 비즈니스를 기준으로 설명하겠습니다.
기존 코드 로직에 따르면 우리 이메일 서비스가 외부에 노출해야 하는 sendHtmlWithTemplate
메소드는 mailSender.send
가 아닌 sendHtmlWithTemplate
메소드여야 하므로 다시 노출할 필요가 없습니다. 우리가 외부에 공개하는
高洛峰2017-04-18 09:21:21
익명 개체는 매우 편리하지만 제대로 사용하지 않으면 애플리케이션이 붕괴됩니다. 예를 들어 이메일 전송 매개변수를 제어하지 않는 경우, 예를 들어 전송 중에 시간 초과가 발생한 후에도 계속 기다리면 이 스레드를 찾을 수 없거나 닫을 수 없습니다. 그만둬라, 이것이 프로그래머가 해야 할 일인가?
당신 머리가 왜 이곳을 없애라고 했는지 묻는다면, 그 사람은 당신의 능력을 충분히 신뢰하지 않아서 감히 당신이 이 악마를 통제하도록 놔두지 않을 것이라고밖에 말할 수 없습니다.
어떤 시나리오에 적합하냐고 물으신다면 적합한 시나리오는 없고 능력 있는 사람만 가능하다고 말씀드릴 수 있습니다.
天蓬老师2017-04-18 09:21:21
죄송합니다. 이제 문제를 확인했습니다.
자세한 내용은 @iMouseWu 및 @유명 님의 답변을 참고하세요.
js를 작성한 적이 있다면 여기서 new Thread()
가 비동기 동작인 ajax
요청과 동일하다는 것을 이해할 수 있습니다. 이는 스레드 작업이 완료되기 전에 메서드가 호출자에게 반환됩니다. no 이메일을 보내면 예외가 발생합니다) 리더님이 "이 이메일을 보낼 수 없는 버그는 노출되지 않았습니다"라고 말씀하셨습니다.
동시성이 크다고 생각되면 redis
+kafka
(또는 기타 메시지 구성 요소)를 사용하여 이메일 서비스에 메시지 형식으로 이메일을 보내도록 알릴 수 있습니다.