以下測試是在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();
}
}
現運行主程序,再運行測試例子,可見收到消息: