반응형

Go smtp SendMail 기능 구현

 

사용한 메일 서버

- gmail 서버

 

사용한 라이브러리

- "net/smtp"

 

구현할 때 주의할 점

- 메일 여러개를(현재 테스트 해봤을 때는 10개까지) 보냈을 때 gmail 서버에서 스팸으로 인식해서 걸러버리기 때문에 발송하는 메세지 부분에서 특정 값들을 넣어 스팸으로 인식하지 못하도록 해야합니다.

 

 

구현

import (
	"net/smtp"
)

func SendMail() {
    auth := smtp.PlainAuth("", "", "", "smtp.gmail.com")
    from := ""
    to := []string{""}

    // 메시지 작성
    headerSubject := "Subject: [제목] 메일 테스트 발송입니다\r\n"
    headerBlank := "\r\n"
    body := "[본문] 메일 테스트 발송"
    msg := []byte(headerSubject + headerBlank + body)

    // 메일 보내기
    err := smtp.SendMail("smtp.gmail.com:587", auth, from, to, msg)
    if err != nil {
        log.Fatalf("Failed to send the email: %v", err)
    }
    
    return
}

 

기본 구현의 문제점

- 여러 메일을 한 번에 보내도록 for문을 작성하여 구현하면 스팸으로 인식하는 문제와 처리 속도가 느려진다는 문제가 있습니다. 1개의 메일을 처리하고 return 하는데 2초 이상이 걸립니다. 만약 10개 이상이면 20초가 아닌 더 오래 걸립니다.

 

 

개선

func SendMail() {
	auth := smtp.PlainAuth("", sms.GetEmailInfo(), sms.GetEmailPasswordInfo(), sms.GetEmailHostInfo())
	from := sms.GetEmailInfo()
	to := []string{sms.GetEmailInfo()} // 아직 따로 DB에서 데이터를 가져올 것이 없어 개발자 메일을 가져왔습니다.

	// 메시지 작성
	headerSubject := "Subject: [제목] 메일 테스트 발송입니다\r\n"
	headerBlank := "\r\n"
	body := "[본문] 메일 테스트 발송"
	//msg := []byte(headerSubject + headerBlank + body)

	// 메일 보내기
	var wg sync.WaitGroup
	for _, t := range to {
		wg.Add(1)
		go func(t string) {
			defer wg.Done()
			go smtp.SendMail("smtp.gmail.com:587", auth, from, to, []byte(fmt.Sprintf(headerSubject+headerBlank+body, t)))
		}(t)
	}

	wg.Wait()
}

 

개선 사항

- go의 장점인 go routine을 사용하여 비동기 방식으로 코드를 짜서 smtp.SendMail() 함수가 끝날 때까지 매번 기달리지 않고 for문을 돌고 SendMail() 함수를 끝냅니다. 기존에 걸리던 2초를 밀리세컨드로 줄였고, 대량으로 메일을 보내도 함수 실행에서 종료까지의 속도는 밀리세컨드로 유지됩니다.

반응형

'Golang > Let's Go' 카테고리의 다른 글

Go 에러로 인한 서버 다운 막는 방법  (0) 2023.08.28
Golang 속도 측정 방법  (0) 2023.08.28
Zero allocation  (0) 2023.08.10
Go 패키지 외부 공개 여부  (0) 2023.08.09
go work 실행 함수  (0) 2023.08.09

+ Recent posts