spring boot 异步发送邮件

需求

 我自己的手机验证登录,然后想的是当手机验证码发送失败的时候换成绑定的邮箱发送验证码。(主要是发送手机验证码要钱,自己的学习测试项目就不太想包套餐。然后想正好熟悉一下邮箱验证这些操作。实际开发中肯定不会这么玩,然后如果直接 手机发送验证码->失败->邮箱验证。这样的话非常耗时。大概需要1000+ms,所以我想这怎样优化这个操作。)。发送邮件由于是一个耗时的操作,有可能需要一个几十秒的操作,但是呢,接口是一个瞬间完成的,为了不影响接口的性能,所以需要对发送邮件的操作进行异步操作。

过程

  • 首先我们要引入发送邮件的测试模块
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
public interface EmailServer {

    void  sendemail(String  subject,String from ,String touserEmail,String text);
}
  • 实现这个接口
@Component
@Service
public class EmailServerImpl implements EmailServer {
    @Autowired
    private JavaMailSender javaMailSender;
    @Async("taskExecutor")
    @Override
    public void sendemail(String subject, String from, String touserEmail, String text) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setSubject(subject);
        message.setFrom(from);
        message.setTo(touserEmail);
        message.setSentDate(new Date());
        message.setText(text);
        javaMailSender.send(message);
    }
}
  • 注入controller
  @Autowired
    private EmailServer emailServerl;
  • springboot启动异步
@EnableAsync//在启动项添加注解
  • 异步任务的配置
@Configuration
public class TaskPoolConfig {
    @Bean("taskExecutor")
    public Executor taskExecutor () {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数10:线程池创建时候初始化的线程数
        executor.setCorePoolSize(10);
        // 最大线程数20:
        executor.setMaxPoolSize(15);
        // 缓冲队列200:
        executor.setQueueCapacity(200);
        // 允许线程的空闲时间60秒:
        executor.setKeepAliveSeconds(60);
        // 线程池名的前缀:
        executor.setThreadNamePrefix("taskExecutor-");
        /*
        线程池对拒绝任务的处理策略:这里采用了CallerRunsPolicy策略,
         */
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,
        executor.setAwaitTerminationSeconds(600);
        return executor;
    }
}

然后就可以进行异步发送邮件了。效率上大概提升到200+ms。其中主要大部分时间是手机短信验证码->是否失败这个阶段。后面异步发邮件其实已经到了8-10ms左右了。对于我这里应该就这样了。主要是因为我需要手机短信发送后的返回信息进行判断,然后才决定是否需要邮箱发送短信。如果是正经的项目的话,两中方式肯定不会这样设计。应该分属于两个不同的验证链。然后两个验证链都可以独立采用异步方式进行验证码发送。这样也就是说用户在前端提交一个请求,会马上接收的验证码发送成功的信息。然后后台这个时候同时正在异步发送验证码。我这里采用的是线程池的方式来进行异步处理的。其实也可以通过消息中间件来进行处理。

posted @ 2020-09-12 11:28  大嘤熊  阅读(585)  评论(0)    收藏  举报