Java mail Transport의 커넥션을 활용한 속도 차이(일반발송, 동보발송)
javax.mail 패키지를 활용해서 메일을 전송하는 경우 Transport 객체를 활용해서 커넥션을 직접 사용하는경우와 직접 사용하지 않는 경우에 따라서 속도차이가 많이 난다.
javax.mail 패키지는 maven에서 쉽게 받을 수 있다.
<!-- 자바 메일 -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
4명한테 같은 내용의 메일을 보내는 상황을 가정하여보자.
이에대해 일반적으로 메일을 전송하는 코드는 아래와 같다.
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class MailSendTest {
private Session session = null;
private Properties props = System.getProperties();
private static final String HOST_IP = "IP주소";
private static final int PORT = 465;
private static final String USER_ID = "접속아이디@test.com";
private static final String PASS_WORD = "비밀번호";
public static void main(String args[]){
MailSendTest mail = new MailSendTest();
String title = "제목";
String content = "내용";
List<String> address = Arrays.asList("aaa@aaa.com","bbb@bbb.com","ccc@ccc.com","ddd@ddd.com");
if(mail.setEnv()){
for(String to_client : address){
try {
mail.mailSendingOneByOne(title, content, to_client); //1건씩 전송
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private boolean setEnv(){ //설정 메소드
props.put("mail.smtp.host", HOST_IP);
props.put("mail.smtp.port", PORT);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.trust", HOST_IP);
session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
String un = USER_ID;
String pw = PASS_WORD;
protected javax.mail.PasswordAuthentication getPasswordAuthentication() {
return new javax.mail.PasswordAuthentication(un, pw);
}
});
return true;
}
private void mailSendingOneByOne(String title, String content, String to_client) throws Exception{
Message msg = new MimeMessage(session); //MimeMessage 생성
msg.setFrom(new InternetAddress(USER_ID)); //발신자 셋팅
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to_client));
msg.setSubject(title); //제목셋팅
msg.setContent(content, "text/plain; charset=UTF-8"); //두번째 파라미터를 "text/html; charset=UTF-8"로 바꾸면 html 테그 내용을 전달 할 수 있다.
Transport.send(msg);
}
}
맨 밑의 Transport.send 라는 static 메소드를 활용하면 알아서 커넥션을 연결하고 메일을 전송하여 준 다음에 커넥션을 종료한다. 개발자는 간단하게 Transport.send만 호출하면 메일이 전송되기 때문에 편리하지만 속도가 느리다는 단점이 있다.
1번 보낼 때 마다 커넥션이 열리고, 닫히고가 반복되다 보니 1개의 메일을 보내는 데 걸리는 속도가 일반적으로 4~5초정도 나온다.
4명에게 메일을 보내게 되면 4*(4~5) = 16~20초 정도가 걸리게 되는 것 이다.
그러면 10명, 20명만 되더라도 시간이 너무 오래걸리는 단점이 존재한다.
위 방식은 통상적으로 내용이 같지 않는 메일을 보내는 경우에 사용이 된다.
만약에 같은 내용의 메일을 여러명에게 보내는경우라면 아래처럼 수정하면 된다.
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class MailSendTest2 {
private Session session = null;
private Properties props = System.getProperties();
private static final String HOST_IP = "IP주소";
private static final int PORT = 465;
private static final String USER_ID = "접속아이디@test.com";
private static final String PASS_WORD = "비밀번호";
public static void main(String args[]){
MailSendTest2 mail = new MailSendTest2();
String title = "제목";
String content = "<div>내용</div>";
List<String> address = Arrays.asList("aaa@aaa.com","bbb@bbb.com","ccc@ccc.com","ddd@ddd.com");
String to_client = address.toString().substring(1, address.toString().length()-1).replaceAll(" ", "");
if(mail.setEnv()){
try {
mail.mailSending(title, content, to_client);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private boolean setEnv(){ //설정 메소드
props.put("mail.smtp.host", HOST_IP);
props.put("mail.smtp.port", PORT);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.trust", HOST_IP);
session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
String un = USER_ID;
String pw = PASS_WORD;
protected javax.mail.PasswordAuthentication getPasswordAuthentication() {
return new javax.mail.PasswordAuthentication(un, pw);
}
});
return true;
}
private void mailSending(String title, String content, String to_client) throws Exception{
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(USER_ID));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to_client));
msg.setSubject(title);
msg.setContent(content, "text/html; charset=UTF-8");
Transport trns =session.getTransport("smtp"); //smtp 접속정보를 가져와서
trns.connect(); //커넥션을 1번 연다.
try {
trns.sendMessage(msg, InternetAddress.parse(to_client)); //해당 커넥션에 대상자와 내용을 한번에 전달한다.
} catch (Exception e) {
e.printStackTrace();
} finally{
trns.close();
}
}
}
위 방식은 connection을 개발자가 직접 연 뒤에 보낼 내용을 한번에 전송하는 방식이다.
이런걸 통상적으로 동보발송 형태라고 한다.
통상적으로 커넥션 열리고 닫히는 시간 2~3초를 제외하고 왠만한 내용이 1초 이내로 전송이 된다.
4명한테 전송할 때 걸리는 속도는 대략적으로 4~5초정도 나온 것 같다.
10명한테 전송할 때 걸리는 속도도 4~5초였던것 같다.
물론 첨부파일이나 보내는 대상이 많아진 경우에는 더 걸릴수 있다.
주의해야 될 점으로는 동보형식으로 전송되는 메일은 대상자가 많아질수록 스팸처리 된다는 점 이다.
다른 내용을 각각의 인원에게 보내야하는 경우에는 첫번째 방식을 활용하면 편리하고,
같은 내용을 모든 인원에게 보내야하는 경우에는 두번째 방식을 사용하면 속도측면에서 효율적으로 사용 할 수 있다.