Spring Cloud整合RabbitMQ
文章目录
1、下载
- erlang
- rabbitMQ
- RabbitMQ_Management
1.1 安装erlang
- 安装依赖
yum -y install ncurses-devel yum search libtool yum search libtool-ltdl-devel yum install libtool yum install libtool-ltdl-devel yum install gcc-c++ yum install erlang-doc yum install erlang-jinterface
- 安装依赖完成解压缩包
tar -zxvf otp_src_19.3.tar.gz #解压完成放到指定目录 mv otp_src_19.3 /usr/local/erlang #进入otp_src_19.3包下进行编译 ./configure --prefix=/usr/local/erlang
- 安装erlang
make make install
- 配置环境变量
vi /etc/profile ERLANG_HOME=/usr/local/erlang export PATH=$PATH:$ERLANG_HOME/bin #重启环境变量 source /etc/profile
1.2 安装rabbitMQ
- 解压
tar -zxvf rabbitmq-server-generic-unix-3.7.5.tar #移动到指定目录 mv rabbitmq-server-generic-unix-3.7.5 /usr/local/rabbitmq
- 配置环境变量
vi /etc/profile export PATH=$PATH:/usr/local/rabbitmq/sbin #重启环境变量 source /etc/profile
- 开启rabbitmq服务
#开启mq服务 rabbitmq-server -detached #开启mq rabbitmqctl start_app #开启管理面板 rabbitmq-plugins enable rabbitmq_management
- 用户管理
#查询所有用户 rabbitmqctl list_users #添加一个用户 rabbitmqctl add_user liyao 123456 #配置权限 rabbitmqctl set_permissions -p "/" liyao ".*" ".*" ".*" #查看用户权限 rabbitmqctl list_user_permissions liyao #设置tag rabbitmqctl set_user_tags zhaobl administrator #删除用户(安全起见,删除默认用户) rabbitmqctl delete_user guest
1.4 使用RabbitMQ_Management
- 打开本地管理界面 http://localhost:15672/#/
- 点击该按钮
- 添加队列
2、整合
2.1 添加依赖
<!-- 消息队列-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2.2 配置RabbitMq
- 配置文件
spring: rabbitmq: host: localhost username: guest password: guest port: 5672 virtual-host: vhost listener: simple: #开启手动确认消息 acknowledge-mode: manual concurrency: 3 #消费者最小数量 max-concurrency: 10 # 消费者最大数量 retry: #开启消费重试 enabled: true #重试三次 max-attempts: 3 #间隔五秒 initial-interval: 5000
- 配置JavaBean
@Configuration public class RabbitMqConfig { //配置消息的序列化器 @Bean public MessageConverter jsonMessageConverter(){ return new Jackson2JsonMessageConverter(); } /** * 配置队列 * @return */ @Bean public Queue syncWaiterInfoQueue(){ return new Queue(RabbitConstant.sysWaiterInfoQueue,true); } /** * 配置交换机 * @return */ @Bean DirectExchange syncWaiterInfoExchange() { return new DirectExchange(RabbitConstant.sysWaiterInfoExchange,true,false); } //将队列和交换机绑定, 并设置用于匹配键 @Bean Binding bindingSyncWaiterInfo() { return BindingBuilder.bind(syncWaiterInfoQueue()).to(syncWaiterInfoExchange()).with(RabbitConstant.sysWaiterInfoBindKey); } }
2.3生产者
@Autowired
private RabbitTemplate rabbitTemplate;
public vod test(String phone,Integer code){
Map<String, Object> map = new HashMap<>();
map.put("phone", phone);
map.put("code", code.toString());
//消息队列发送
//param dm_sms:String [队列名称]
//param map : Object [任意数据类型]
//传递的是什么数据类型,接受的时候就得注入该数据类型
rabbitTemplate.convertAndSend(RabbitConstant.sysWaiterInfoExchange, RabbitConstant.sysWaiterInfoBindKey, map);
}
2.4 消费者
//监听该消息队列
@RabbitListener(queues = {"dm_sms"})
@Component
public class DmSms {
//消费该队列
@RabbitHandler
public void send(Map<String,Object> map){
System.out.println("短信被消费掉了----------------------");
}
}
2.5 生产者消息确认
生产者可以确认是否将消费发送到Exchange里面
- 配置文件
spring: rabbitmq: #开启生产者消息确认 publisher-confirm-type: correlated
- javaBean
@Configuration public class RabbitMqConfig implements RabbitTemplate.ConfirmCallback { @Autowired private RabbitTemplate rabbitTemplate; @Autowired private AliyunLogManager aliyunLogManager; /** * 发送消息到Exchange的回调 * 因为ConfirmCallback是一个内部类,要将rabbitTemplate注入进来 * 并且将this赋值到该接口 */ @PostConstruct public void init(){ rabbitTemplate.setConfirmCallback(this); } @Bean public MessageConverter jsonMessageConverter(){ return new Jackson2JsonMessageConverter(); } /** * Confirmation callback. * * @param correlationData correlation data for the callback. * @param ack true for ack, false for nack * @param cause An optional cause, for nack, when available, otherwise null. */ @Override public void confirm(CorrelationData correlationData, boolean ack, String cause) { String id = correlationData == null ? "":correlationData.getId(); if (ack){ aliyunLogManager.writeLog("发送交换机正常---->",id); }else{ Map<String,Object> errInfo = new HashMap<>(); errInfo.put("id", id); errInfo.put("cause", cause); aliyunLogManager.writeLog("发送交换机异常---->", JSON.toJSONString(errInfo)); } aliyunLogManager.setTag(AliyunLogTagEnum.REQUEST_INTERFACE_NAME.getCode(),"exchange->confirm"); aliyunLogManager.send(); } }
- 生产者
@Autowired private RabbitTemplate rabbitTemplate; public vod test(String phone,Integer code){ Map<String, Object> map = new HashMap<>(); map.put("phone", phone); map.put("code", code.toString()); CorrelationData correlationData = new CorrelationData(phone); //消息队列发送 //param dm_sms:String [队列名称] //param map : Object [任意数据类型] //传递的是什么数据类型,接受的时候就得注入该数据类型 rabbitTemplate.convertAndSend(RabbitConstant.sysWaiterInfoExchange, RabbitConstant.sysWaiterInfoBindKey, map,correlationData ); }
2.6消息退回
当消息抵达Exchange的时候还需要传递到Queue,当传递到Queue的过程中失败的话该消息是被直接丢弃的,但是我们可以监控不可达Queue的消息
- 配置文件
spring: rabbitmq: #开启消息退回 publisher-returns: true
- javaBean
@Configuration public class RabbitMqConfig implements RabbitTemplate.ReturnCallback { @Autowired private RabbitTemplate rabbitTemplate; @Autowired private AliyunLogManager aliyunLogManager; /** * 消息从Exchange到Queue的回调 * 因为ReturnCallback 是一个内部类,要将rabbitTemplate注入进来 * 并且将this赋值到该接口 */ @PostConstruct public void init(){ rabbitTemplate.setReturnCallback(this); } /** * Returned message callback. * * @param message 消息体 * @param replyCode 失败Code * @param replyText 失败原因 * @param exchange 失败的交换机 * @param routingKey 失败的路由key */ @Override public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) { } }