본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Java(자바)

Java mail Transport의 커넥션을 활용한 속도 차이(일반발송, 동보발송)

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2019. 7. 18.

 

 

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초였던것 같다.

물론 첨부파일이나 보내는 대상이 많아진 경우에는 더 걸릴수 있다.

 

주의해야 될 점으로는 동보형식으로 전송되는 메일은 대상자가 많아질수록 스팸처리 된다는 점 이다.

 

다른 내용을 각각의 인원에게 보내야하는 경우에는 첫번째 방식을 활용하면 편리하고,

같은 내용을 모든 인원에게 보내야하는 경우에는 두번째 방식을 사용하면 속도측면에서 효율적으로 사용 할 수 있다.

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글