RabbitMQ是一個受歡迎的消息代理,通常用於應用程序之間或者程序的不同組件之間通過消息來進行集成。本文簡單介紹瞭如何使用 RabbitMQ,假定你已經配置好了rabbitmq服務器。
RabbitMQ是用Erlang,對於主要的編程語言都有驅動或者客戶端。我們這裏要用的是Java,所以先要獲得Java客戶端。。下面是Java客戶端的maven依賴的配置。
2 |
< groupId >com.rabbitmq</ groupId > |
3 |
< artifactId >amqp-client</ artifactId > |
4 |
< version >3.0.4</ version > |
像RabbitMQ這樣的消息代理可用來模擬不同的場景,例如點對點的消息分發或者訂閱/推送。我們的程序足夠簡單,有兩個基本的組件,一個生產者用於產生消息,還有一個消費者用來使用產生的消息。
在這個例子裏,生產者會產生大量的消息,每個消息帶有一個序列號,另一個線程中的消費者會使用這些消息。
抽象類EndPoint:
我們首先寫一個類,將產生產者和消費者統一爲 EndPoint類型的隊列。不管是生產者還是消費者, 連接隊列的代碼都是一樣的,這樣可以通用一些。
01 |
package co.syntx.examples.rabbitmq; |
03 |
import java.io.IOException; |
05 |
import com.rabbitmq.client.Channel; |
06 |
import com.rabbitmq.client.Connection; |
07 |
import com.rabbitmq.client.ConnectionFactory; |
10 |
*
Represents a connection with a queue |
14 |
public abstract class EndPoint{ |
16 |
protected Channel
channel; |
17 |
protected Connection
connection; |
18 |
protected String
endPointName; |
20 |
public EndPoint(String
endpointName) throws IOException{ |
21 |
this .endPointName
= endpointName; |
24 |
ConnectionFactory
factory = new ConnectionFactory(); |
27 |
factory.setHost( "localhost" ); |
30 |
connection
= factory.newConnection(); |
33 |
channel
= connection.createChannel(); |
37 |
channel.queueDeclare(endpointName, false , false , false , null ); |
42 |
*
關閉channel和connection。並非必須,因爲隱含是自動調用的。 |
45 |
public void close() throws IOException{ |
47 |
this .connection.close(); |
生產者:
生產者類的任務是向隊列裏寫一條消息。我們使用Apache Commons Lang把可序列化的Java對象轉換成 byte 數組。commons lang的maven依賴如下:
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
01 |
package co.syntx.examples.rabbitmq; |
03 |
import java.io.IOException; |
04 |
import java.io.Serializable; |
06 |
import org.apache.commons.lang.SerializationUtils; |
10 |
*
The producer endpoint that writes to the queue. |
14 |
public class Producer extends EndPoint{ |
16 |
public Producer(String
endPointName) throws IOException{ |
20 |
public void sendMessage(Serializable
object) throws IOException
{ |
21 |
channel.basicPublish( "" ,endPointName, null ,
SerializationUtils.serialize(object)); |
消費者:
消費者可以以線程方式運行,對於不同的事件有不同的回調函數,其中最主要的是處理新消息到來的事件。
01 |
package co.syntx.examples.rabbitmq; |
03 |
import java.io.IOException; |
04 |
import java.util.HashMap; |
07 |
import org.apache.commons.lang.SerializationUtils; |
09 |
import com.rabbitmq.client.AMQP.BasicProperties; |
10 |
import com.rabbitmq.client.Consumer; |
11 |
import com.rabbitmq.client.Envelope; |
12 |
import com.rabbitmq.client.ShutdownSignalException; |
16 |
*
讀取隊列的程序端,實現了Runnable接口。 |
20 |
public class QueueConsumer extends EndPoint implements Runnable,
Consumer{ |
22 |
public QueueConsumer(String
endPointName) throws IOException{ |
29 |
channel.basicConsume(endPointName, true , this ); |
30 |
} catch (IOException
e) { |
36 |
*
Called when consumer is registered. |
38 |
public void handleConsumeOk(String
consumerTag) { |
39 |
System.out.println( "Consumer
" +consumerTag
+ "
registered" ); |
43 |
*
Called when new message is available. |
45 |
public void handleDelivery(String
consumerTag, Envelope env, |
46 |
BasicProperties
props, byte []
body) throws IOException
{ |
47 |
Map
map = (HashMap)SerializationUtils.deserialize(body); |
48 |
System.out.println( "Message
Number " +
map.get( "message
number" )
+ "
received." ); |
52 |
public void handleCancel(String
consumerTag) {} |
53 |
public void handleCancelOk(String
consumerTag) {} |
54 |
public void handleRecoverOk(String
consumerTag) {} |
55 |
public void handleShutdownSignal(String
consumerTag, ShutdownSignalException arg1) {} |
Putting it together:
在下面的測試類中,先運行一個消費者線程,然後開始產生大量的消息,這些消息會被消費者取走。
01 |
package co.syntx.examples.rabbitmq; |
03 |
import java.io.IOException; |
04 |
import java.sql.SQLException; |
05 |
import java.util.HashMap; |
08 |
public Main() throws Exception{ |
10 |
QueueConsumer
consumer = new QueueConsumer( "queue" ); |
11 |
Thread
consumerThread = new Thread(consumer); |
12 |
consumerThread.start(); |
14 |
Producer
producer = new Producer( "queue" ); |
16 |
for ( int i
= 0 ;
i < 100000 ;
i++) { |
17 |
HashMap
message = new HashMap(); |
18 |
message.put( "message
number" ,
i); |
19 |
producer.sendMessage(message); |
20 |
System.out.println( "Message
Number " +
i + "
sent." ); |
26 |
*
@throws SQLException |
29 |
public static void main(String[]
args) throws Exception{ |
轉自:http://www.oschina.net/translate/getting-started-with-rabbitmq-in-java?cmp