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. 搭建sonar,推动代码质量管理

    最近比较关注devops相关的文章,尝试搭建sonarqube服务,进行代码质量的分析和管理,先记录下本地环境的搭建和分析过程. 一.sonarqube服务搭建 官网地址:http://www.son ...

  2. vscode配置

    默认的挺难看的 颜色主题换成 Monokai Dimmed 用户设置 // 将设置放入此文件中以覆盖默认设置 { "editor.fontFamily": "Monaco ...

  3. day26:面向对象进阶:set、get、del反射和内置

    三 __setattr__,__delattr__,__getattr__ __开头的都是内置的,不定义系统都会有.如果自己定义的话,就会覆盖系统内置的,执行自定义的部分(是否有完成设置的语法,有的话 ...

  4. 【DNS】简单聊聊DNS如何工作

    随便聊聊 我们知道,网络上传输的数据包是一层一层的包起来的,典型的是mac地址层,ip层,tcp/udp层,应用层数据 这么几个层,那用户在浏览器中打开www.baidu.com数据包如何传到baid ...

  5. JVM GC算法 CMS 详解(转)

    前言 CMS,全称Concurrent Low Pause Collector,是jdk1.4后期版本开始引入的新gc算法,在jdk5和jdk6中得到了进一步改进,它的主要适合场景是对响应时间的重要性 ...

  6. 将yyyyMMdd,dd/MM/yyyy 类型字符串转换为datetime 类型 yyyy-MM-dd C#

    DateTime ConvertDate = DateTime.ParseExact(", "yyyyMMdd", null, System.Globalization. ...

  7. 自实现CAS原理JAVA版,模拟下单库存扣减

    在做电商系统时,库存是一个非常严格的数据,根据CAS(check and swap)原来下面对库存扣减提供两种方法,一种是redis,一种用java实现CAS. 第一种 redis实现: 以下这个类是 ...

  8. TensorFlow中max pooling层各参数的意义

    官方教程中没有解释pooling层各参数的意义,找了很久终于找到,在tensorflow/python/ops/gen_nn_ops.py中有写: def _max_pool(input, ksize ...

  9. 69 个经典 Spring 面试题和答案

    Spring 概述 什么是spring?Spring 是个java企业级应用的开源开发框架.Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用.Spring 框架目标 ...

  10. 【转】PL/SQL Developer各个窗口的功能

    源地址:http://www.codeweblog.com/pl-sql-developer%E5%90%84%E4%B8%AA%E7%AA%97%E5%8F%A3%E7%9A%84%E5%8A%9F ...