1.安装erlang

  下载地址:http://www.erlang.org/downloads

  设置ERLANG环境变量

2.安装RabbitMQ

  下载地址: http://www.rabbitmq.com/download.html

输入命令安装各种管理插件:

D:\RabbitMQServer\rabbitmq_server-3.7.10\sbin>rabbitmq-plugins enable rabbitmq_management

重启服务

net stop rabbitmq && net start rabbitmq

登录

http://127.0.0.1:15672 默认用户名密码 guest  guest

常用命令(RabbitMQ命令在sbin目录下D:\RabbitMQServer\rabbitmq_server-3.7.10\sbin,记得设置环境变量)

rabbitmqctl delete_vhost test_vhosts 删除虚拟机test_vhosts

3. RabbitMQ知识整理

来自(https://blog.csdn.net/dreamchasering/article/details/77653512)

什么是MQ?

MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。MQ是消费-生产者模型的一个典型的代表,一端往消息队列中不断写入消息,而另一端则可以读取队列中的消息。

RabbitMQ是MQ的一种。下面详细介绍一下RabbitMQ的基本概念。

1、队列、生产者、消费者

队列是RabbitMQ的内部对象,用于存储消息。生产者(下图中的P)生产消息并投递到队列中,消费者(下图中的C)可以从队列中获取消息并消费。

多个消费者可以订阅同一个队列,这时队列中的消息会被平均分摊给多个消费者进行处理,而不是每个消费者都收到所有的消息并处理。

2、Exchange、Binding

刚才我们看到生产者将消息投递到队列中,实际上这在RabbitMQ中这种事情永远都不会发生。实际的情况是,生产者将消息发送到Exchange(交换器,下图中的X),再通过Binding将Exchange与Queue关联起来。

3、Exchange Type、Bingding key、routing key

在绑定(Binding)Exchange与Queue的同时,一般会指定一个binding key。在绑定多个Queue到同一个Exchange的时候,这些Binding允许使用相同的binding key。

生产者在将消息发送给Exchange的时候,一般会指定一个routing key,来指定这个消息的路由规则,生产者就可以在发送消息给Exchange时,通过指定routing key来决定消息流向哪里。

RabbitMQ常用的Exchange Type有三种:fanout、direct、topic。

fanout:把所有发送到该Exchange的消息投递到所有与它绑定的队列中。

direct:把消息投递到那些binding key与routing key完全匹配的队列中。

topic:将消息路由到binding key与routing key模式匹配的队列中。

附上一张RabbitMQ的结构图:

最后来具体解析一下几个问题:

1、可以自动创建队列,也可以手动创建队列,如果自动创建队列,那么是谁负责创建队列呢?是生产者?还是消费者?

如果队列不存在,当然消费者不会收到任何的消息。但是如果队列不存在,那么生产者发送的消息就会丢失。所以,为了数据不丢失,消费者和生产者都可以创建队列。那么如果创建一个已经存在的队列呢?那么不会有任何的影响。需要注意的是没有任何的影响,也就是说第二次创建如果参数和第一次不一样,那么该操作虽然成功,但是队列属性并不会改变。

队列对于负载均衡的处理是完美的。对于多个消费者来说,RabbitMQ使用轮询的方式均衡的发送给不同的消费者。

2、RabbitMQ的消息确认机制

默认情况下,如果消息已经被某个消费者正确的接收到了,那么该消息就会被从队列中移除。当然也可以让同一个消息发送到很多的消费者。

如果一个队列没有消费者,那么,如果这个队列有数据到达,那么这个数据会被缓存,不会被丢弃。当有消费者时,这个数据会被立即发送到这个消费者,这个数据被消费者正确收到时,这个数据就被从队列中删除。

那么什么是正确收到呢?通过ack。每个消息都要被acknowledged(确认,ack)。我们可以显示的在程序中去ack,也可以自动的ack。如果有数据没有被ack,那么:

RabbitMQ Server会把这个信息发送到下一个消费者。

如果这个app有bug,忘记了ack,那么RabbitMQServer不会再发送数据给它,因为Server认为这个消费者处理能力有限。

而且ack的机制可以起到限流的作用(Benefitto throttling):在消费者处理完成数据后发送ack,甚至在额外的延时后发送ack,将有效的均衡消费者的负载。

4.JAVA demo

引入RabbitMQ客户端

<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>3.6.5</version>
</dependency>

3.1 使用默认配置直接发送消息到队列

生产者

import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeoutException; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory; /**
*
* 默认发送,直接将消息发送到某个队列,默认交换机type为direct
*
* @author
* @date 2019/01/10 11:17:10
*/
public class ProducterDirectDemo {
public static void main(String[] args) throws IOException, TimeoutException { String queneName = "testQuene";
Connection connection = null;
Channel channel = null;
try {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("test_vhosts");
// 创建与RabbitMQ服务器的TCP连接
connection = factory.newConnection();
// 创建一个频道
channel = connection.createChannel();
// 声明默认的队列
channel.queueDeclare(queneName, true, false, true, null);
while (true) {
channel.basicPublish("", queneName, null, UUID.randomUUID().toString().getBytes());
Thread.sleep(1000);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (channel != null) {
channel.close();
}
if (connection != null) {
connection.close();
}
}
}
}

消费者

import java.io.IOException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope; /**
* 接收默认消息
*
* @author
* @date 2019/01/10 11:14:32
*/
public class ConsumerDirectDemo {
public static void main(String[] args) {
String queneName = "testQuene";
Connection connection = null;
Channel channel = null;
try { ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("test_vhosts");
connection = factory.newConnection();
channel = connection.createChannel(); Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println(envelope.getExchange() + "," + envelope.getRoutingKey() + "," + message);
}
};
// channel绑定队列,autoAck为true表示一旦收到消息则自动回复确认消息
channel.basicConsume(queneName, true, consumer);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

3.2 设置交换器,队列,路由发送消息

生产者

import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory; /**
* 指定交换机,队列,路由key方式
*
* @author
* @date 2019/01/10 11:19:38
*/
public class ProducterAllDemo {
public static void main(String[] args) throws IOException, TimeoutException { String queneName = "firstQueue";
String exchangeName = "amq.fanout";
String routingKey = "test1";
Connection connection = null;
Channel channel = null;
try {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("test_vhosts"); // 创建与RabbitMQ服务器的TCP连接
connection = factory.newConnection();
// 创建一个频道
channel = connection.createChannel();
// 声明交换机类型
channel.exchangeDeclare("amq.fanout", "fanout", true);
// 声明默认的队列 (也可不申明队列,使用默认队列)
channel.queueDeclare(queneName, true, false, true, null);
// String queue = channel.queueDeclare().getQueue();
// 将队列与交换机绑定
channel.queueBind(queneName, exchangeName, routingKey);
// 指定一个队列
// channel.queueDeclare(queneName, false, false, false, null);
while (true) {
channel.basicPublish(exchangeName, routingKey, null, UUID.randomUUID().toString().getBytes());
Thread.sleep(1000);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (channel != null) {
channel.close();
}
if (connection != null) {
connection.close();
}
} }
}

消费者

import java.io.IOException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope; /**
*
* @author
* @date 2019/01/10 11:19:42
*/
public class ConsumerAllDemo {
public static void main(String[] args) {
String queneName = "firstQueue";
String exchangeName = "amq.fanout";
String routingKey = "test1";
Connection connection = null;
Channel channel = null;
try {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("test_vhosts");
connection = factory.newConnection();
channel = connection.createChannel(); // 声明交换机类型
channel.exchangeDeclare(exchangeName, "fanout", true);
// 声明默认的队列(也可不申明队列,使用默认队列)
channel.queueDeclare(queneName, true, false, true, null);
// String queue = channel.queueDeclare().getQueue();
// 将队列与交换机绑定
channel.queueBind(queneName, exchangeName, routingKey); Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println(envelope.getExchange() + "," + envelope.getRoutingKey() + "," + message);
}
};
// channel绑定队列、消费者,autoAck为true表示一旦收到消息则自动回复确认消息
channel.basicConsume(queneName, true, consumer);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

RabbitMQ JAVA客户端调用例子的更多相关文章

  1. [RabbitMQ]Java客户端:源码概览

    本文简要介绍RabbitMQ提供的Java客户端中最基本的功能性接口/类及相关源码. Mavan依赖: <dependency> <groupId>com.rabbitmq&l ...

  2. Java与WCF交互(一):Java客户端调用WCF服务

    最近开始了解WCF,写了个最简单的Helloworld,想通过java客户端实现通信.没想到以我的基础,居然花了整整两天(当然是工作以外的时间,呵呵),整个过程大费周折,特写下此文,以供有需要的朋友参 ...

  3. Java与WCF交互(一):Java客户端调用WCF服务 【转】

    原文:http://www.cnblogs.com/downmoon/archive/2010/08/24/1807161.html 最近开始了解WCF,写了个最简单的Helloworld,想通过ja ...

  4. 转载——Java与WCF交互(一):Java客户端调用WCF服务

    最近开始了解WCF,写了个最简单的Helloworld,想通过java客户端实现通信.没想到以我的基础,居然花了整整两天(当然是工作以外的时间,呵呵),整个过程大费周折,特写下此文,以供有需要的朋友参 ...

  5. 使用java客户端调用redis

    Redis支持很多编程语言的客户端,有C.C#.C++.Clojure.Common Lisp.Erlang.Go.Lua.Objective-C.PHP.Ruby.Scala,甚至更时髦的Node. ...

  6. java客户端调用ftp上传下载文件

    1:java客户端上传,下载文件. package com.li.utils; import java.io.File; import java.io.FileInputStream; import ...

  7. RabbitMQ/JAVA 客户端测试(补:利用线程)

    上次进行了简单的连接测试.这次主要进行一下小小的补充.利用线程将生产者消费者代码合到一个文件中. 我是将Recv.java(消费者)文件放在一个线程里添加到Send.java(生产者)中. 代码如下: ...

  8. RABBITMQ/JAVA 客户端测试(再补:利用文件流)

    (一)这里可以先复习一下java输入输出流和文件操作--- 1.File类保存文件或目录的各种元数据信息,包括文件名.文件长度.最后修改时间.是否可读.获取当前文件的路径名.判断指定文件是否存在.获取 ...

  9. 如何在Java客户端调用RESTful服务

    在这个例子中,我们将看到如何使用java.net包实用工具,创建一个访问REST服务RESTful的客户端.当然这不是创建一个RESTful客户端最简单的方法,因为你必须自己读取服务器端的响应,以及J ...

随机推荐

  1. [Vuex系列] - Vuex中的getter的用法

    Vuex 允许我们在store中定义“getter”(可以认为是store的计算属性).就像计算属性一样,getter的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算. g ...

  2. 如何用HAProxy+Nginx实现负载均衡

    一.什么是HAProxy HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.HAProxy特别适用于那些负载特大的web站点, ...

  3. Oracle学习笔记——imp还原数据库

    1.     创建用户及指定用户名密码 create user [用户名] identified by [密码]; create user fskxjsxy  identified by fskxjs ...

  4. Hadoop错误:PipeMapRed.waitOutputThreads(): subprocess failed with code 1

    有一种原因是python文件中有语法或逻辑错误

  5. Ubuntu系统---C++之Eclipse 开始工程项目

    Ubuntu系统---C++之Eclipse 开始工程项目 安装完Eclipse,那就像其它项目一样,先要测试一下是否能用. 一.测一个hello world例子二.利用OpenCV测试一个显示图片的 ...

  6. linux实操_shell判断语句

    常用判断条件: (1)两个数的比较 = 字符串的比较 -lt 小于 -le 小于等于 -eq 等于 -gt 大于 -ge 大于等于 -ne 不等于 (2)按照文件权限进行判断 -r 有读的权限 -w ...

  7. TreadPool

    ThreadPool概述 提供一个线程池,该线程池可用于执行任务.发送工作项.处理异步 I/O.代表其他线程等待以及处理计时器. 创建线程需要时间.如果有不同的小任务要完成,就可以事先创建许多线程/在 ...

  8. [唐胡璐]Selenium技巧- Prop.Properties配置测试应用的环境和其他配置项

     prop.propertiesfile contains important info that needs to be changed before the test is run, such a ...

  9. css 禁止点击事件触发

    鼠标不可点击主要是两种表现: 1.鼠标不可点击时的显示状态 cursor: not-allowed 2.禁止触发点击事件 pointer-events:none

  10. vue中把props中的值赋值给data

    vue中把props中的值赋值给data 2018年12月26日 14:37:11 木豆mudou 阅读数 3497   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上 ...