Spring 練功場#6筆記-Message Queue

YungHsin
Nov 7, 2020

--

本次練功場重點:

Message Queue

Extension Function

因為前一次請假沒有跟到第五場的內容,所以這回在聽的時候稍嫌吃力了一些,這次只整理了Message Queue的部分,Extension Function就有興趣的直接看參考文章就行囉。

https://medium.com/@louis383/kotlin-extension-function-34a2384c56a9

下載專案程式碼

首先先下載這次提供的專案程式碼。

https://github.com/b2etw/Spring-Boot-Kotlin-Dojo/tree/master/stage6

用IntelliJ匯入專案打開後,去看docker-compose.yml的內容,需要rabbitmq, mysql。

在Terminal 打指令安裝

docker-compose up -d rabbitmq
docker-compose up -d mysql

然後呼叫docker ps -a看這些docker container有沒有跑起來

docker ps -a

我的電腦沒有mysql是因為我本機已經有裝了mysql server, 就讓專案直接連到本機的mysql了

查看RabbitMQ後台

docker安裝好後,可以先看RabitMQ的介面後台 在本機http://localhost:15672/ ,預設帳密是rabbitmq/rabbitmq

先測試看看專案是否有送Message

把專案DemoApplication按下綠色執行鍵跑起來,如果成功的話,會看見Run的視窗會每10秒跑出Hello Rabbit!

而在後台的介面也能看到每10秒有紫色的線尖起來,表示RabbitMQ收到了

Message是怎麼丟的呢?

到schedule/MessageSender.kt的程式碼打開看一下,裡頭有一個物件RabbitTmeplate,方法使用convertAnSend來進行丟東西到Queue的動作,然後@Scheduled(cron = “*/10 * * * * *”)表示每10秒做一次,而MessageSender這邊擔任的角色就是Producer生產者的角色了。

@Component
class MessageSender(
val rabbitTemplate: RabbitTemplate
) : Logging {

//生產者丟到Queue
@Scheduled(cron = "*/10 * * * * *")//10sec執行一次
fun sayHello() = rabbitTemplate.convertAndSend("test-exchange", "com.example.demo.mq.123", "Hello Rabbit!")
//丟Hello Rabbit到rabbit mq
}

Message是怎麼接收的?

有人產生,就有人需要做消費的動作,這裡就是照設定走,來看config/RabbitmqConfig.kt的程式碼

(1)接收Message前,要先設定queue

@Bean
fun queue() = Queue("test-queue", false)

(2)要有一個交換所(rabbitmq的專有名詞)

@Bean
fun exchange() = TopicExchange("test-exchange")

(3)把(1)(2) queue跟exchange要綁定在一起,處理routingKey是com.example.demo.mq.開頭的(如果之後你想接收兩個以上的queue,就能把routingKey取為另一個,進行個別的處理)。

@Bean
fun binding(queue: Queue, exchange: TopicExchange) = BindingBuilder.bind(queue).to(exchange).with("com.example.demo.mq.#")

(4) container設定

@Bean
fun container(connectionFactory: ConnectionFactory, listenerAdapter: MessageListenerAdapter): SimpleMessageListenerContainer {
var container = SimpleMessageListenerContainer()
container.connectionFactory = connectionFactory
container.setQueueNames("test-queue")
container.setMessageListener(listenerAdapter)
return container
}

(5)最後listenerAdapter用來指定MessageReceiver的method “receiveMsg”來接收

@Bean
fun listenerAdapter(messageReceiver: MessageReceiver) = MessageListenerAdapter(messageReceiver, "receiveMsg")
}

service/MessageReceiver.kt的程式碼就是接收到message後,執行log().info(msg)印出Hello Rabbit的。

@Component
class MessageReceiver : Logging {

fun receiveMsg(msg: String) = log().info(msg)
}

總結

以上就是rabbitmq的設定,主要都是RabbitTemplate用很多Template的design pattern實現出來,所以如果只是要會用的話,就是照上面的部分進行設定就能把Message Queue實作出來了,你也可以針對自己專案的需求去繼承RabbitTemplate自己弄一個CustomRabbitTemplate來用。

歡迎各位也一起來練功場學習Spring囉! 隔週一起來練功!

--

--

YungHsin
YungHsin

No responses yet