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. sp_who_lock

    USE MyDataBase GO /****** Object: StoredProcedure [dbo].[sp_who_lock] Script Date: 4/10/2015 ******/ ...

  2. wampserver修改mysql默认字符集

    [client] default-character-set=utf8 [mysqld]character_set_server = utf8 重启服务

  3. LeetCode "Is Subsequence"

    There are 3 possible approaches: DP, divide&conquer and greedy. And apparently, DP has O(n^2) co ...

  4. Android引用项目出现ClassNotFoundException

    Android中在引用其他工程,尤其是github中的相关库时,如果引用关系设置的不对,很容易出现ClassNotFoundException,例如下面的异常信息 07-26 12:47:51.549 ...

  5. dispatch_set_target_queue 说明

    参照:http://blog.csdn.net/growinggiant/article/details/41077221 http://codingobjc.com/blog/2013/05/07/ ...

  6. HTTP返回码总结(转)

    HTTP协议状态码表示的意思主要分为五类 ,大体是 :   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~  1×× 保留   2×× 表示请求成功地接收   3×× 为完成请求客户需进一步 ...

  7. ORDER BY 1,2 desc

    ORDER BY 1,2 desc     --先按照选择列里的第一列进行升序排序,再按选择列的第二列降序排序    --选择列是指查询语句中select后面跟着的字段(1,2は検索の列)

  8. selenium 关于富文本的处理

    http://www.cnblogs.com/xiaobaichuangtianxia/p/5889999.html

  9. List接口

    1.List接口实现的方式有两种ArrayList 和 LinkedList ArrayList实现了可变的数组,允许保存所有元素包括null,缺点是删除的比较慢 LinkedList删除对象比较快, ...

  10. 查看MS SQL SERVER 错误日志

    查看目的: 错误日志的查看是确保过程已成功完成(例如,备份和恢复操作,批处理命令,或其他脚本和过程).这可以帮助检测任何当前或潜在的问题,包括自动恢复信息(尤其是如果SQL Server实例已停止并重 ...