天天看点

springboot集成rabbitmq,异步发送邮件功能实现

作者:mortyc137

1.配置qq邮箱的账号、密码;配置rabbitmq的ip、用户名、密码

springboot集成rabbitmq,异步发送邮件功能实现

qq邮箱配置

springboot集成rabbitmq,异步发送邮件功能实现

rabbitmq配置

2.声明队列、交换机、让队列绑定交换机,并且携带路由key(用的是路由模式)

设置消息和交换机持久性,是为了防止消息丢失

springboot集成rabbitmq,异步发送邮件功能实现

队列交换机绑定

3.为了保证生产者不丢失消息,需要让生产者确认消息

消息有一个唯一的消息id,mq收到消息后,会返回一个结果给发送者,表示消息处理成功

返回的结果有两种方式

a.发送者确认:消息没有投递到交换机,则返回ack,反之则返回nack

b.发送者回执:消息到交换机了,但是没有路由到队列,则返回ack,以及路由失败的原因。

springboot集成rabbitmq,异步发送邮件功能实现

发送者确认和发送者回执

消息投递成功后,调用updateMailSendLogStatus方法,修改消息数据库消息表中等于msgId的记录的状态字段(status等于1代表消息发送成功)

springboot集成rabbitmq,异步发送邮件功能实现

调用发送者确认和发送者回执方法

springboot集成rabbitmq,异步发送邮件功能实现

消息表

4.录入用户信息后,生成唯一的msgId,并且将消息发送给消费者

springboot集成rabbitmq,异步发送邮件功能实现

消息发送代码

5.消费者接收消息,开启手动确认模式,返回消息给生产者

使用redis,查询redis缓存是否存在msgId,如果存在直接将该消息标记为已消费(先判断redis是否存在msgId是为了避免消息重复消费,保证了接口的幂等性。channel.basicAck(tag, false):标记该消息已经成功消费了),否则,发送邮件(发送邮件即消费消息)

springboot集成rabbitmq,异步发送邮件功能实现

使用redis,避免消息重复消费

6.redis不存在msgId,则消费该消息

如果redis不存在msgId,说明消息没有被消费过,则可以消费消息。发送完邮件后,将msgId存入到redis中,下次同样的消息来后,就不会被消费。

springboot集成rabbitmq,异步发送邮件功能实现

消费消息

7.消费失败重试机制

使用Quartz定时任务框架,定时扫描数据库消息表中,状态等于0的记录(状态等于0代表消息投递中,消息者还没有消费到消息),对这些记录进行遍历,并判断记录中重试次数:count是否大于3,小于等于3,则再次对消息发送;反之,重试次数大于3,则将数据库这条记录的状态直接设置为:消息投递失败。

springboot集成rabbitmq,异步发送邮件功能实现

消费失败重试

总结:

消息可靠性保证:

1.发送者确认和发送者回执

2.消息和队列持久化

3.消费者失败重置

继续阅读