RabbitMQ是一个受欢迎的消息代理,通常用于应用程序之间或者程序的不同组件之间通过消息来进行集成。本文简单介绍了如何使用 RabbitMQ,假定你已经配置好了rabbitmq服务器。

RabbitMQ是用Erlang,对于主要的编程语言都有驱动或者客户端。我们这里要用的是Java,所以先要获得Java客户端。。下面是Java客户端的maven依赖的配置。

<dependency>

<groupId>com.rabbitmq</groupId>

<artifactId>amqp-client</artifactId>

<version>3.0.4</version>

</dependency>

像RabbitMQ这样的消息代理可用来模拟不同的场景,例如点对点的消息分发或者订阅/推送。我们的程序足够简单,有两个基本的组件,一个生产者用于产生消息,还有一个消费者用来使用产生的消息。

在这个例子里,生产者会产生大量的消息,每个消息带有一个序列号,另一个线程中的消费者会使用这些消息。

抽象类EndPoint:

我们首先写一个类,将产生产者和消费者统一为 EndPoint类型的队列。不管是生产者还是消费者, 连接队列的代码都是一样的,这样可以通用一些

package co.syntx.examples.rabbitmq;

import java.io.IOException;

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.ConnectionFactory;

/**

* Represents a connection with a queue

* @author syntx

*

*/

public abstract class EndPoint{

protected Channel channel;

protected Connection connection;

protected String endPointName;

public EndPoint(String endpointName) throws IOException{

this.endPointName = endpointName;

//Create a connection factory

ConnectionFactory factory = new ConnectionFactory();

//hostname of your rabbitmq server

factory.setHost("localhost");

//getting a connection

connection = factory.newConnection();

//creating a channel

channel = connection.createChannel();

//declaring a queue for this channel. If queue does not exist,

//it will be created on the server.

channel.queueDeclare(endpointName, false, false, false, null);

}

/**

* 关闭channel和connection。并非必须,因为隐含是自动调用的。

* @throws IOException

*/

public void close() throws IOException{

this.channel.close();

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>

package co.syntx.examples.rabbitmq;

import java.io.IOException;

import java.io.Serializable;

import org.apache.commons.lang.SerializationUtils;

/**

* The producer endpoint that writes to the queue.

* @author syntx

*

*/

public class Producer extends EndPoint{

public Producer(String endPointName) throws IOException{

super(endPointName);

}

public void sendMessage(Serializable object) throws IOException {

channel.basicPublish("",endPointName, null, SerializationUtils.serialize(object));

}

}

消费者:

消费者可以以线程方式运行,对于不同的事件有不同的回调函数,其中最主要的是处理新消息到来的事件。

package co.syntx.examples.rabbitmq;

import java.io.IOException;

import java.util.HashMap;

import java.util.Map;

import org.apache.commons.lang.SerializationUtils;

import com.rabbitmq.client.AMQP.BasicProperties;

import com.rabbitmq.client.Consumer;

import com.rabbitmq.client.Envelope;

import com.rabbitmq.client.ShutdownSignalException;

/**

* 读取队列的程序端,实现了Runnable接口。

* @author syntx

*

*/

public class QueueConsumer extends EndPoint implements Runnable, Consumer{

public QueueConsumer(String endPointName) throws IOException{

super(endPointName);

}

public void run() {

try {

//start consuming messages. Auto acknowledge messages.

channel.basicConsume(endPointName, true,this);

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* Called when consumer is registered.

*/

public void handleConsumeOk(String consumerTag) {

System.out.println("Consumer "+consumerTag +" registered");

}

/**

* Called when new message is available.

*/

public void handleDelivery(String consumerTag, Envelope env,

BasicProperties props, byte[] body) throws IOException {

Map map = (HashMap)SerializationUtils.deserialize(body);

System.out.println("Message Number "+ map.get("message number") + " received.");

}

public void handleCancel(String consumerTag) {}

public void handleCancelOk(String consumerTag) {}

public void handleRecoverOk(String consumerTag) {}

public void handleShutdownSignal(String consumerTag, ShutdownSignalException arg1) {}

}

Putting it together:

在下面的测试类中,先运行一个消费者线程,然后开始产生大量的消息,这些消息会被消费者取走。

package co.syntx.examples.rabbitmq;

import java.io.IOException;

import java.sql.SQLException;

import java.util.HashMap;

public class Main {

public Main() throws Exception{

QueueConsumer consumer = new QueueConsumer("queue");

Thread consumerThread = new Thread(consumer);

consumerThread.start();

Producer producer = new Producer("queue");

for (int i = 0; i < 100000; i++) {

HashMap message = new HashMap();

message.put("message number", i);

producer.sendMessage(message);

System.out.println("Message Number "+ i +" sent.");

}

}

/**

* @param args

* @throws SQLException

* @throws IOException

*/

public static void main(String[] args) throws Exception{

new Main();

}

}

RabbitMQ 入门指南(Java)的更多相关文章

  1. RabbitMQ 入门指南——安装

    RabbitMQ好文 Rabbitmq Java Client Api详解 tohxyblog-博客园-rabbitMQ教程系列 robertohuang-CSDN-rabbitMQ教程系列 Rabb ...

  2. RabbitMQ入门指南

    消息队列(Message Queue,以下简称MQ)常用于异步系统的数据传递.若不用MQ,我们只能[在应用层]使用轮询或接口回调等方式处理,这在效率或耦合度上是难以让人满意的.当然我们也可以在系统间保 ...

  3. RabbitMQ 入门指南——初步使用

    MQ的消息持久化 https://www.rabbitmq.com/tutorials/tutorial-two-java.html When RabbitMQ quits or crashes it ...

  4. RabbitMQ入门与使用篇

    介绍 RabbitMQ是一个由erlang开发的基于AMQP(Advanced Message Queue)协议的开源实现.用于在分布式系统中存储转发消息,在易用性.扩展性.高可用性等方面都非常的优秀 ...

  5. .NET 环境中使用RabbitMQ RabbitMQ与Redis队列对比 RabbitMQ入门与使用篇

    .NET 环境中使用RabbitMQ   在企业应用系统领域,会面对不同系统之间的通信.集成与整合,尤其当面临异构系统时,这种分布式的调用与通信变得越发重要.其次,系统中一般会有很多对实时性要求不高的 ...

  6. Java Gradle入门指南之内建与定制任务类(buildSrc、Groovy等)

        上一篇随笔介绍了Gradle的安装与任务管理,这篇着重介绍Gradle的内建任务(in-built tasks)与自定义任务(custom tasks),借助Gradle提供的众多内建任务类型 ...

  7. Java程序员的Golang入门指南(下)

    Java程序员的Golang入门指南(下) 4.高级特性 上面介绍的只是Golang的基本语法和特性,尽管像控制语句的条件不用圆括号.函数多返回值.switch-case默认break.函数闭包.集合 ...

  8. Java程序员的Golang入门指南(上)

    Java程序员的Golang入门指南 1.序言 Golang作为一门出身名门望族的编程语言新星,像豆瓣的Redis平台Codis.类Evernote的云笔记leanote等. 1.1 为什么要学习 如 ...

  9. java基础(六):RabbitMQ 入门

    建议先了解为什么项目要使用 MQ 消息队列,MQ 消息队列有什么优点,如果在业务逻辑上没有此种需求,建议不要使用中间件.中间件对系统的性能做优化的同时,同时增加了系统的复杂性也维护难易度:其次,需要了 ...

随机推荐

  1. git diff提示filemode发生改变(old mode 100644、new mode 10075)

    今天clone代码,git status显示修改了大量文件,git diff提示filemode变化,如下: diff --git a/Android.mk b/Android.mkold mode ...

  2. Shiro简单配置

    注:这里只介绍Spring配置模式. 因为官方例子虽然中有更加简洁的ini配置形式,但是使用ini配置无法与spring整合.而且两种配置方法一样,只是格式不一样. 涉及的jar包 核心包shiro- ...

  3. php ffmpeg

    可以合成视频,音频视频合成等 $aurl = '../Uploads/movie/zzz.mp4'; $vurl = '../Uploads/mp3/dmd.mp3'; // exec("c ...

  4. STM32F4读写内部FLASH【使用库函数】

    STM32F4Discovery开发帮使用的STM32F407VGT6芯片,内部FLASH有1M之多.平时写的代码,烧写完之后还有大量的剩余.有效利用这剩余的FLASH能存储不少数据.因此研究了一下S ...

  5. (PHP)程序中如何判断当前用户终端是手机等移动终端

    推荐: Mobile-Detect:https://github.com/serbanghita/Mobile-Detect/blob/master/Mobile_Detect.php Detect ...

  6. css3 flex盒子布局

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. Python基础(二)之元组及字典

    元组:以一对小括号表示,不可以增删改,只可查看. 字典:以一对大括号表示,字典中含key及value,字典是无序的. 下面介绍字典和元组的一些常见操作: 一.元组 a = ('haha','xixi' ...

  8. js实现的点击div区域外隐藏div区域(转)

    首先看下JS的事件模型,JS事件模型为向上冒泡,如onclick事件在某一DOM元素被触发后,事件将跟随节点向上传播,直到有click事件绑定在某一父节点上,如果没有将直至文档的根. 阻止冒泡: 1. ...

  9. eclipse 断点使用深入技能

    原文:http://blog.jobbole.com/26435/ 摘要:调试不仅可以查找到应用程序缺陷所在,还可以解决缺陷.对于Java程序员来说,他们不仅要学会如何在Eclipse里面开发像样的程 ...

  10. Blackfin DSP(八):1D DMA与音频处理模板

    1.DMA产生的背景 在许多需要使用DSP 的场合,一般都需要大量的数据搬移工作,而如果每次数据搬移都由DSP 内核来参与完成,将大大占用DSP 内核的处理时间,从而严重影响其信号处理能力.因此,Bl ...