七、测试服务
启动 SpringBoot 服务之后,用 postman 模拟请求接口。
查看控制台信息。
查询接受者邮件信息。
邮件发送成功!
八、消息发送失败处理
虽然,上面案例可以成功的实现消息的发送,但是上面的流程很脆弱,例如:rabbitMQ 突然蹦了、邮件发送失败了、重启 rabbitMQ 服务器出现消息重复消费,应该怎处理呢?
很显然,我们需要对原有的逻辑进行升级改造,因此我们需要引入数据库来记录消息的发送情况。
8.1、创建消息投递日志表
CREATE TABLE `msg_log` ( `msg_id` varchar(255) NOT NULL DEFAULT '' COMMENT '消息唯一标识', `msg` text COMMENT '消息体, json格式化', `exchange` varchar(255) NOT NULL DEFAULT '' COMMENT '交换机', `routing_key` varchar(255) NOT NULL DEFAULT '' COMMENT '路由键', `status` int(11) NOT NULL DEFAULT '0' COMMENT '状态: 0投递中 1投递成功 2投递失败 3已消费', `try_count` int(11) NOT NULL DEFAULT '0' COMMENT '重试次数', `next_try_time` datetime DEFAULT NULL COMMENT '下一次重试时间', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`msg_id`), UNIQUE KEY `unq_msg_id` (`msg_id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='消息投递日志';
8.2、编写 MsgLog 相关服务类
public interface MsgLogService { /** * 插入消息日志 * @param msgLog */ void insert(MsgLog msgLog); /** * 更新消息状态 * @param msgId * @param status */ void updateStatus(String msgId, Integer status); /** * 查询消息 * @param msgId * @return */ MsgLog selectByMsgId(String msgId); }
8.3、改写服务逻辑
在生产服务类中,新增数据写入。
同时,在RabbitConfig
服务配置,当消息发送成功之后,新增更新消息状态逻辑。
改造消费者ConsumerMailService
,每次消费的时候,从数据库中查询,如果消息已经被消费,不用再重复发送数据!
这样即可保证,如果 rabbitMQ 服务器,即使重启之后重新推送消息,通过数据库判断,也不会重复消费进而发生业务异常!
8.4、利用定数任务对消息投递失败进行补偿
当 rabbitMQ 服务器突然挂掉之后,生成者就无法正常进行投递数据,此时因为消息已经被记录到数据库,因此我们可以利用定数任务查询出没有投递成功的消息,进行补偿投递。
利用定数任务,对投递失败的消息进行补偿投递,基本可以保证消息 100% 消费成功!
九、总结
本文主要是通过发送邮件这个业务案例,来讲解 Springboot 与 rabbitMQ 技术的整合和使用!
当然解决这个业务需求的技术方案还有很多,例如 Springboot 与 rocketMQ 也可以实现这个需求,这个会在后期的文章讲解!
同时,Springboot + rabbitMQ 这种架构方案更适合于集群应用,如果是单体应用,直接通过服务类操作即可实现邮件推送!
本篇主要是Springboot 与 rabbitMQ整合和基本使用教程,希望小伙伴能有所收获!