Tiven Wang
Wang Tiven July 31, 2017
425 favorite favorites
bookmark bookmark
share share

Deer

Message brokers are elements in telecommunication or computer networks where software applications communicate by exchanging formally-defined messages. Message brokers are a building block of message-oriented middleware.

下載本篇完整代碼 Github

Setup

添加 Spring AMQP 的 Spring Boot starter 組件

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

Application Code

Create a RabbitMQ message receiver

首先我們創建一個 Receiver 去接收壞蛋出現的事件, 並讓我們的大英雄去抓住他

@Component
public class Receiver {

	public void catchVillains(String villain) {
		try {
			// Assume hero catches the villain in 5 seconds
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("Catched villain<" + villain + ">");
	}

}

Register the listener and send a message

RabbitMQ 消息模型的核心概念是: 消息製造者不會直接發送消息給 Queue , 而是發給一個 Exchange , Exchange 負責分發消息給一個或者多個 Queue , 所以消息製造者分本不知道消息發送給了哪個 Queue.

@Configuration
public class MQConfig {

	final static String queueName = "villains-events";

	@Bean
	Queue queue() {
		return new Queue(queueName, false);
	}

	@Bean
	TopicExchange exchange() {
		return new TopicExchange("villains-events-exchange");
	}

	@Bean
	Binding binding(Queue queue, TopicExchange exchange) {
		return BindingBuilder.bind(queue).to(exchange).with(queueName);
	}

	@Bean
	SimpleMessageListenerContainer container(ConnectionFactory connectionFactory,
			MessageListenerAdapter listenerAdapter) {
		SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
		container.setConcurrentConsumers(2);
		container.setConnectionFactory(connectionFactory);
		container.setQueueNames(queueName);
		container.setMessageListener(listenerAdapter);
		return container;
	}

	@Bean
	MessageListenerAdapter listenerAdapter(Receiver receiver) {
		return new MessageListenerAdapter(receiver, "catchVillains");
	}
}
  • container.setConcurrentConsumers(2); 指定消息接收者同時可以處理2個消息

Spring Boot automatically creates a connection factory and a RabbitTemplate, reducing the amount of code you have to write.

Create a message sender

使用 RabbitTemplate 發送消息給隊列

@Component
public class Sender {

	private final RabbitTemplate rabbitTemplate;

	public Sender(RabbitTemplate rabbitTemplate) {
		this.rabbitTemplate = rabbitTemplate;
	}

	public void send(String message) throws Exception {
		System.out.println("Sending villains events...");
		rabbitTemplate.convertAndSend(MQConfig.queueName, message);
	}
}

Create villains Restful API

在controller裡增加大壞蛋叫囂的方法

@Autowired
private Sender sender;

@RequestMapping(value="/villains", method=RequestMethod.POST)
String home(@RequestParam("message") String message) throws Exception {
  sender.send(message);
    return "Done!";
}

Test

docker run --rm --name my-rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management

打开浏览器并访问:http://localhost:15672/,并使用默认用户guest登录,密码也为guest。

執行命令 mvn spring-boot:run 運行應用程序。

壞蛋出現了:

POST to http://localhost:8080/villains?message=I am here!

你可以在後台看到

Sending villains events...
Catched villain<I am here!>

連續發送多個消息,可以驗證大英雄可以同時處理兩個大壞蛋。

Deploy to CloudFoundry

部署到 CloudFoundry 之前我們需要創建一個 AMQP 服務,這裡我們使用 Pivotal CloudFoundry Marketplace 裡提供的 CloudAMQP 服務

cf create-service cloudamqp lemur try-cf-amqp

創建成功後,把 CloudAMQP 服務名稱加入 manifest 文件中,全部信息如下

---
applications:
- name: try-cf-message-broker
  buildpack: java_buildpack
  instances: 1
  memory: 200M
  host: try-cf-message-broker
  path: target/try-cf-0.0.1-SNAPSHOT.jar
  services:
  - try-cf-amqp

上傳

cf push

上傳成功之後訪問鏈接即可發送消息

https://try-cf-message-broker.cfapps.io/villains?message=I am here!

可以查看 CloudFoundry 的應用後台打印信息

cf logs try-cf-message-broker

References

Similar Posts

Comments

Back to Top