以下测试是在mac环境,因为rabbitmq是基于erlang语言开发,所以运行环境必须先安装erlang版本21:
- 升级erlang至21
- brew uninstall --ignore-dependencies erlang # 如果之前有安装旧版本的话,必须先卸载
- brew search erlang
- brew install erlang
- erl #验证,如果输出含有Erlang/OTP 21,表示安装成功!
接着安装rabbitmq,我本地的安装目录是/Users/r/services/rabbitmq:
- 下载 https://www.rabbitmq.com/install-generic-unix.html
- 解压
- tar xzvf rabbitmq-server-generic-unix-3.7.14.tar.xz
- mv rabbitmq-server-generic-unix-3.7.14 rabbitmq
- cd/Users/r/services/rabbitmq
- 启动
- ./sbin/rabbitmq-server
- 开启管理插件
- ./sbin/rabbitmq-plugins enable rabbitmq_management
- http://localhost:15672/ 默认账号密码:guest/guest
- 下载rabbitmqadmin
- http://localhost:15672/cli/rabbitmqadmin
- cp ~/Downloads/rabbitmqadmin /Users/r/services/rabbitmq/sbin/
- chmod 755 /Users/r/services/rabbitmq/sbin/rabbitmqadmin
测试消息发布流程:核心是先定义exchange,再定义queue,最后,使用routing_key绑定exchange和queue。
-
-
- ./rabbitmqadmin declare exchange name=my-exchange1 type=fanout
- ./rabbitmqadmin declare queue name=my-queue1 durable=false
- ./rabbitmqadmin declare binding source=my-exchange1 destination=my-queue1 destination_type=queue routing_key=mykey1
- ./rabbitmqadmin publish routing_key=mykey1 exchange=my-exchange1 payload="this is my testing"
- ./rabbitmqadmin get queue=my-queue1
- 第二组,同样的exchange,不同的outing_key和queue:
- ./rabbitmqadmin declare queue name=my-queue2 durable=false
- ./rabbitmqadmin declare binding source=my-exchange1 destination=my-queue2 destination_type=queue routing_key=mykey2
- ./rabbitmqadmin publish routing_key=mykey2 exchange=my-exchange1 payload="this is my testing"
- ./rabbitmqadmin get queue=my-queue
-
架构图:引自 https://blog.csdn.net/zhengzizhi/article/details/77032148
rabbitmq的dashboard: http://localhost:15672/ 账号密码默认是guest
利用dashaboard,创建账户springcloud/123456,下面会用到。注意分配权限vhost '/'给新建的账户,否则下面的java程序会报错:
2019-04-10 01:24:48.488 ERROR 73558 --- [tContainer#0-33] o.s.a.r.l.SimpleMessageListenerContainer : Failed to check/redeclare auto-delete queue(s).
Caused by: com.rabbitmq.client.ShutdownSignalException: connection error; protocol method: #method<connection.close>(reply-code=530, reply-text=NOT_ALLOWED - access to vhost '/' refused for user 'springcloud', class-id=10, method-id=40)
下面讲解如何在springboot中引入rabbitmq,创建项目rabbitmq-hello ,引入依赖spring-boot-starter-amqp:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
application.properties:
spring.application.name=rabbitmq-hello
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=springcloud
spring.rabbitmq.password=123456
spring.rabbitmq.virtual-host=/
定义exchange,queue,binding:
package com.sc.rabbitmqhello;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitConfig {
@Bean(name = "myDirectExchange")
public DirectExchange getDirectExchange() {
return new DirectExchange("my-direct-exchange");
}
@Bean(name = "myFirstQueue")
public Queue getMyFirstQueue() {
return new Queue("my-first-queue");
}
@Bean
public Binding bindingQueueOneToDirectExchange(
@Qualifier("myFirstQueue") Queue myFirstQueue,
@Qualifier("myDirectExchange") DirectExchange myDirectExchange) {
return BindingBuilder.bind(myFirstQueue).to(myDirectExchange).with("routingKey.First");
}
}
Receiver监听队列:
package com.sc.rabbitmqhello;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class Receiver {
@RabbitListener(queues = "my-first-queue")
public void firstConsumer(String payload) {
System.out.println("I am my-first-queue: " + String.valueOf(payload));
}
}
Sender使用routingKey发送消息到exchange:
package com.sc.rabbitmqhello;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class Sender {
@Autowired
private AmqpTemplate rabbitTemplate;
public void send(){
String context = "hello " + new Date();
System.out.println("Sender: " + context);
this.rabbitTemplate.convertAndSend("my-direct-exchange", "routingKey.First", context);
}
}
测试例子:
package com.sc.rabbitmqhello;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class RabbitmqHelloApplicationTests {
@Autowired
private Sender sender;
@Test
public void contextLoads() {
this.sender.send();
}
}
现运行主程序,再运行测试例子,可见收到消息: