本文是譯文,原文請訪問:http://www.rabbitmq.com/tutorials/tutorial-one-spring-amqp.htmlhtml
RabbitMQ 是一個Brocker (消息隊列服務器),它接受和轉發消息 .java
你能夠將它當作郵局:spring
當你將要發佈的郵件放在郵箱中時,您能夠肯定郵件先生或Mailperson女士最終會將郵件發送給您的收件人。在這個比喻中,RabbitMQ是郵箱,郵局和郵遞員。windows
RabbitMQ和郵局之間的主要區別在於它不處理信紙,而是接受,存儲和轉發二進制大對象 blob(binary large object )數據 ——消息服務器
生產者僅僅只是發送。一個發送消息的程序就是生產者:併發
隊列是RabbitMQ中的郵箱的名稱。雖然消息流經RabbitMQ和您的應用程序,但它們只能存儲在隊列中。甲隊列僅由主機的存儲器和磁盤限制約束,它本質上是一個大的消息緩衝器。app
許多生產者能夠發送到一個隊列的消息,而且許多消費者能夠嘗試從一個隊列接收數據。這就是咱們表明隊列的方式:框架
消費這與生產者有相似的意義。一個消費者是一個程序,主要是等待接收信息:maven
請注意,生產者,消費者和代理沒必要駐留在同一主機上; 實際上在大多數應用中他們沒有。應用程序既能夠是生產者也能夠是消費者。編輯器
在本教程的這一部分中,咱們將使用spring-amqp庫編寫兩個程序; 發送單個消息的生產者,以及接收消息並將其打印出來的消費者。
咱們將掩蓋Spring-amqp API中的一些細節,專一於這個很是簡單的事情纔開始。它是消息傳遞的「Hello World」。
在下圖中,「P」是咱們的生產者,「C」是咱們的消費者。中間的框是一個隊列 - RabbitMQ表明消費者保留的消息緩衝區。
Spring AMQP框架
RabbitMQ說多種協議。本教程使用AMQP 0-9-1,它是一種開放的,通用的消息傳遞協議。RabbitMQ有許多不一樣語言的客戶端 。
Spring AMQP利用Spring Boot進行配置和依賴管理。Spring支持maven或gradle,但在本教程中,咱們將選擇帶有Spring Boot 1.5.2的maven
提供:
生成項目並將生成的項目解壓縮到您選擇的位置。
如今能夠將其導入您喜歡的IDE中。或者,您能夠從您喜歡的編輯器處理它。
Spring Boot提供了許多功能,但咱們只在這裏強調一些。
首先,Spring Boot應用程序能夠選擇經過application.properties或application.yml文件提供其屬性
編寫application.properties
咱們將在生成的項目中找到application.properties文件,其中沒有任何內容。
添加application.properties 配置以下:
spring.profiles.active=usage_message
logging.level.org=ERROR
tutorial.client.duration=10000
剛纔配置文件中咱們配置了一個
tutorial.client.duration=10000
可是這個配置字段不存在於任何框架jar包裏,所以咱們須要編寫一個類來處理這個屬性
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.context.ConfigurableApplicationContext; public class RabbitAmqpTutorialsRunner implements CommandLineRunner { @Value("${tutorial.client.duration:0}") private int duration; @Autowired private ConfigurableApplicationContext ctx; @Override public void run(String... args) throws Exception { // TODO Auto-generated method stub System.out.println("Ready ... running for " + duration + "ms"); Thread.sleep(duration); ctx.close(); } }
接下來咱們建立一個Java Config 文件(好比咱們起名叫作 Tut1Config.java) 用來描述咱們的Bean.
Tut1Config.java
import org.springframework.amqp.core.Queue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import com.xingyun.springamqp.business.Tut1Receiver; import com.xingyun.springamqp.business.Tut1Sender; @Profile({"tut1","hello-world"}) @Configuration public class Tut1Config { @Bean public Queue hello() { return new Queue("hello"); } @Profile("receiver") @Bean public Tut1Receiver receiver() { return new Tut1Receiver(); } @Profile("sender") @Bean public Tut1Sender sender() { return new Tut1Sender(); } }
經過上面這個配置類,咱們作了四件事
爲何要有這兩個配置文件? 由於咱們待會運行生產者和消費者的時候,能夠經過動態加載不一樣的配置文件來啓動不一樣的類。
好比咱們啓動生產者發佈信息就能夠調用這個配置:
--spring.profiles.active=hello-world,sender
當咱們想啓動消費者就動態調用這個配置
--spring.profiles.active=hello-world,receiver
接下來咱們須要修改下整個應用程序的啓動類:
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Profile; import org.springframework.scheduling.annotation.EnableScheduling; import com.xingyun.config.RabbitAmqpTutorialsRunner; @EnableScheduling @SpringBootApplication public class RabbitMq0x01SpringAmqpHelloWorldSampleApplication { @Profile("usage_message") @Bean public CommandLineRunner usage() { return new CommandLineRunner() { @Override public void run(String... arg0) throws Exception { System.out.println("This app uses Spring Profiles to control its behavior.\n"); System.out.println("Sample usage: java -jar rabbit-tutorials.jar --spring.profiles.active=hello-world,sender"); } }; } @Profile("!usage_message") @Bean public CommandLineRunner tutorial() { return new RabbitAmqpTutorialsRunner(); } public static void main(String[] args) { SpringApplication.run(RabbitMq0x01SpringAmqpHelloWorldSampleApplication.class, args); } }
當執行這個項目的jar 文件時會自動加載這個usage_message 配置,打印用法信息。
咱們在啓動類上添加@EnableScheduling,以便於開啓對定時任務的支持
如今不多有代碼須要進入發送方和接收方類。 咱們稱他們爲Tut1Receiver和Tut1Sender。
Sender利用咱們的配置和RabbitTemplate發送消息。
Tut1Sender.java
import org.springframework.amqp.core.Queue; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; public class Tut1Sender { @Autowired private RabbitTemplate template; @Autowired private Queue queue; @Scheduled(fixedDelay = 1000, initialDelay = 500) public void send() { String message = "Hello World!"; this.template.convertAndSend(queue.getName(), message); System.out.println(" [x] Sent '" + message + "'"); } }
您會注意到spring-amqp刪除了樣板代碼,只留下了須要關注的消息傳遞邏輯。
咱們在Tut1Config類中的bean定義中配置的隊列中進行自動裝配,而且像許多Spring鏈接抽象同樣,咱們使用能夠自動裝入發送器的RabbitTemplate包裝樣板rabbitmq客戶端類。
剩下的就是建立一個消息並調用模板的convertAndSend方法,該方法從咱們定義的bean和剛建立的消息中傳入隊列名。
Sending 不工做
若是這是您第一次使用RabbitMQ而且沒有看到「已發送」消息,那麼您可能會感到頭疼,想知道可能出現的問題。 也許代理是在沒有足夠的可用磁盤空間的狀況下啓動的(默認狀況下它至少須要200 MB空閒),所以拒絕接受消息。 檢查代理日誌文件以確認並在必要時減小限制。 配置文件文檔將向您展現如何設置disk_free_limit。
接收器一樣簡單。 咱們用@RabbitListener注入咱們的Receiver類並傳入隊列的名稱。
而後,咱們使用@RabbitHandler傳入咱們的receive方法,並傳入已推送到隊列的有效負載。
import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; @RabbitListener(queues = "hello") public class Tut1Receiver { @RabbitHandler public void receive(String in) { System.out.println(" [x] Received '" + in + "'"); } }
該應用程序使用Spring Profiles來控制它正在運行的教程,以及它是Sender仍是Receiver。 選擇使用配置文件運行的教程。 例如:
- {tut1|hello-world},{sender|receiver} - {tut2|work-queues},{sender|receiver} - {tut3|pub-sub|publish-subscribe},{sender|receiver} - {tut4|routing},{sender|receiver} - {tut5|topics},{sender|receiver} - {tut6|rpc},{client|server}
當咱們逐步完成其餘五個教程時,咱們將回到此列表。
在使用maven構建以後,運行應用程序可是您但願運行啓動應用程序(例如,從ide或命令行)。
咱們將展現如何從命令行運行。
查看用法
java -jar RabbitMQ_0x01_SpringAMQP-0.0.1-SNAPSHOT.jar
啓動生產者
java -jar RabbitMQ_0x01_SpringAMQP-0.0.1-SNAPSHOT --spring.profiles.active=hello-world,sender
啓動消費者
java -jar RabbitMQ_0x01_SpringAMQP-0.0.1-SNAPSHOT.jar --spring.profiles.active=hello-world,receiver
您可能但願看到RabbitMQ有哪些隊列以及它們中有多少消息。 您可使用rabbitmqctl工具(做爲特權用戶)執行此操做:
sudo rabbitmqctl list_queues
在windows 電腦上去掉sudo
rabbitmqctl.bat list_queues
生產[非]適用性免責聲明
請記住,這個和其餘教程都是教程。 他們一次展現一個新概念,可能會故意過分簡化某些事情而忽略其餘事物。
例如,爲了簡潔起見,在很大程度上省略了諸如鏈接管理,錯誤處理,鏈接恢復,併發和度量收集之類的主題。 這種簡化的代碼不該被視爲生產就緒。