mq系列rabbitmq-01简介,安装,api操作

本文详细介绍了RabbitMQ的基本概念,包括Server、Virtual Host、Exchange、Message Queue等,并提供了安装步骤。此外,还深入探讨了RabbitMQ的API调用,包括简单模式、工作队列模式,以及消息确认、队列和消息持久化等关键概念。通过实例代码展示了如何使用Java进行RabbitMQ的消息发布和消费,以及发布订阅和主题路由模式的应用。
摘要由CSDN通过智能技术生成

mq系列rabbitmq-01简介,安装,api操作

原创  2017年11月08日 11:43:08

一。rabbitmq介绍

     RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue高级消息队列 )的开源实现 主要包含以下组件

   1.Server(broker): 接受客户端连接,实现AMQP消息队列和路由功能的进程。
   2.Virtual Host:其实是一个虚拟概念,类似于权限控制组,一个Virtual Host里面可以有若干个Exchange和Queue,但是权限控制的最小粒度是Virtual Host
   3.Exchange:接受生产者发送的消息,并根据Binding规则将消息路由给服务器中的队列。ExchangeType决定了Exchange路由消息的行为,例如,在RabbitMQ中,ExchangeType有direct、Fanout和Topic三种,不同类型的Exchange路由的行为是不一样的。
   4.Message Queue:消息队列,用于存储还未被消费者消费的消息。
   5.Message: 由Header和Body组成,Header是由生产者添加的各种属性的集合,包括Message是否被持久化、由哪个Message Queue接受、优先级是多少等。而Body是真正需要传输的APP数据。
   6.Binding:Binding联系了Exchange与Message Queue。Exchange在与多个Message Queue发生Binding后会生成一张路由表,路由表中存储着Message Queue所需消息的限制条件即Binding Key。当Exchange收到Message时会解析其Header得到Routing Key,Exchange根据Routing Key与Exchange Type将Message路由到Message Queue。Binding Key由Consumer在Binding Exchange与Message Queue时指定,而Routing Key由Producer发送Message时指定,两者的匹配方式由Exchange Type决定。 
  7.Connection:连接,对于RabbitMQ而言,其实就是一个位于客户端和Broker之间的TCP连接。
  8.Channel:信道,仅仅创建了客户端到Broker之间的连接后,客户端还是不能发送消息的。需要为每一个Connection创建Channel,AMQP协议规定只有通过Channel才能执行AMQP的命令。一个Connection可以包含多个Channel。之所以需要Channel,是因为TCP连接的建立和释放都是十分昂贵的,如果一个客户端每一个线程都需要与Broker交互,如果每一个线程都建立一个TCP连接,暂且不考虑TCP连接是否浪费,就算操作系统也无法承受每秒建立如此多的TCP连接。RabbitMQ建议客户端线程之间不要共用Channel,至少要保证共用Channel的线程发送消息必须是串行的,但是建议尽量共用Connection。
 9.Command:AMQP的命令,客户端通过Command完成与AMQP服务器的交互来实现自身的逻辑。例如在RabbitMQ中,客户端可以通过publish命令发送消息,txSelect开启一个事务,txCommit提交一个事务。


二。rabbitmq安装

1》安装rabbitmq

安装过程 参考 (http://www.rabbitmq.com/install-rpm.html)

 rabbitmq-server 目前安装包被包含在 Fedora rpm仓库中 Fedora是epel库 

yum -y install epel-release.noarch
查看是否存在rabbitmq 然后安装

yum search rabbitmq-server
yum -y install rabbitmq-server
查看安装包

tail -1000 /var/log/yum.log
安装了很多erlang语言包和一个rabbitmq-server包

Nov 07 05:05:50 Installed: lksctp-tools-1.0.17-2.el7.x86_64
Nov 07 05:05:50 Installed: erlang-crypto-R16B-03.18.el7.x86_64
Nov 07 05:05:51 Installed: erlang-kernel-R16B-03.18.el7.x86_64
Nov 07 05:05:52 Installed: erlang-stdlib-R16B-03.18.el7.x86_64
Nov 07 05:05:53 Installed: erlang-erts-R16B-03.18.el7.x86_64
Nov 07 05:05:53 Installed: erlang-syntax_tools-R16B-03.18.el7.x86_64
Nov 07 05:05:53 Installed: erlang-compiler-R16B-03.18.el7.x86_64
Nov 07 05:05:54 Installed: erlang-hipe-R16B-03.18.el7.x86_64
Nov 07 05:05:55 Installed: erlang-mnesia-R16B-03.18.el7.x86_64
Nov 07 05:05:55 Installed: erlang-runtime_tools-R16B-03.18.el7.x86_64
Nov 07 05:05:56 Installed: erlang-snmp-R16B-03.18.el7.x86_64
Nov 07 05:05:56 Installed: erlang-otp_mibs-R16B-03.18.el7.x86_64
Nov 07 05:05:56 Installed: erlang-sd_notify-0.1-1.el7.x86_64
Nov 07 05:05:56 Installed: erlang-xmerl-R16B-03.18.el7.x86_64
Nov 07 05:05:56 Installed: erlang-asn1-R16B-03.18.el7.x86_64
Nov 07 05:05:57 Installed: erlang-public_key-R16B-03.18.el7.x86_64
Nov 07 05:05:57 Installed: erlang-ssl-R16B-03.18.el7.x86_64
Nov 07 05:05:57 Installed: erlang-inets-R16B-03.18.el7.x86_64
Nov 07 05:05:57 Installed: erlang-tools-R16B-03.18.el7.x86_64
Nov 07 05:05:57 Installed: erlang-sasl-R16B-03.18.el7.x86_64
Nov 07 05:05:58 Installed: erlang-os_mon-R16B-03.18.el7.x86_64
Nov 07 05:06:00 Installed: rabbitmq-server-3.3.5-34.el7.noarch
查看rabbitmq-server被安装的所有文件的位置
/etc/logrotate.d/rabbitmq-server
/etc/rabbitmq
/etc/rabbitmq/rabbitmq.config
/usr/lib/ocf/resource.d/rabbitmq/rabbitmq-server
/usr/lib/rabbitmq/bin
/usr/lib/rabbitmq/bin/rabbitmq-defaults
/usr/lib/rabbitmq/bin/rabbitmq-env
/usr/lib/rabbitmq/bin/rabbitmq-plugins
/usr/lib/rabbitmq/bin/rabbitmq-server
/usr/lib/rabbitmq/bin/rabbitmqctl
查看rabbitmq-server所有的参考文档

[root@node3 log]# rpm -qd rabbitmq-server-3.3.5-34.el7.noarch
/usr/share/doc/rabbitmq-server-3.3.5/LICENSE
/usr/share/doc/rabbitmq-server-3.3.5/LICENSE-APACHE2-ExplorerCanvas
/usr/share/doc/rabbitmq-server-3.3.5/LICENSE-APL2-Stomp-Websocket
/usr/share/doc/rabbitmq-server-3.3.5/LICENSE-Apache-Basho
/usr/share/doc/rabbitmq-server-3.3.5/LICENSE-BSD-base64js
/usr/share/doc/rabbitmq-server-3.3.5/LICENSE-BSD-glMatrix
/usr/share/doc/rabbitmq-server-3.3.5/LICENSE-MIT-EJS10
/usr/share/doc/rabbitmq-server-3.3.5/LICENSE-MIT-Flot
/usr/share/doc/rabbitmq-server-3.3.5/LICENSE-MIT-Mochi
/usr/share/doc/rabbitmq-server-3.3.5/LICENSE-MIT-Sammy060
/usr/share/doc/rabbitmq-server-3.3.5/LICENSE-MIT-eldap
/usr/share/doc/rabbitmq-server-3.3.5/LICENSE-MIT-jQuery164
/usr/share/doc/rabbitmq-server-3.3.5/LICENSE-MPL-RabbitMQ
/usr/share/doc/rabbitmq-server-3.3.5/rabbitmq.config.example
/usr/share/man/man1/rabbitmq-plugins.1.gz
/usr/share/man/man1/rabbitmq-server.1.gz
/usr/share/man/man1/rabbitmqctl.1.gz
/usr/share/man/man5/rabbitmq-env.conf.5.gz
其中比较重要的两个参考文件(这两个只是参考)
运行配置文件:rabbitmq.config.example
环境配置文件:/usr/share/man/man5/rabbitmq-env.conf.5.gz 

默认该两文件需要配置在 /etc/rabbitmq目录下 默认只有一个

[root@node3 log]# cd /etc/rabbitmq && ll
total 20
-rw-r--r-- 1 root root 18555 Aug 11  2014 rabbitmq.config
单机默认配置足够 具体配置参考官网 (http://www.rabbitmq.com/configure.html)

rabbitmq默认安装后 会添加账号rabbitmq 默认以该账号运行

[root@node3 rabbitmq]# more /etc/passwd | grep rabbitmq
rabbitmq:x:992:990:RabbitMQ messaging server:/var/lib/rabbitmq:/sbin/nologin

2》启动rabbitmq

  启动后 查看默认的端口 5672

[root@node3 rabbitmq]# netstat -aon | grep 5672
tcp        0      0 0.0.0.0:25672           0.0.0.0:*               LISTEN      off (0.00/0/0)
tcp6       0      0 :::5672                 :::*                    LISTEN      off (0.00/0/0)
查看运行状态(默认在cd /etc/init.d下)

[root@node3 rabbitmq]# service rabbitmq-server status
Redirecting to /bin/systemctl status  rabbitmq-server.service
● rabbitmq-server.service - RabbitMQ broker
   Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; disabled; vendor preset: disabled)
   Active: active (running) since Tue 2017-11-07 05:52:27 PST; 6min ago
 Main PID: 8507 (beam)
   CGroup: /system.slice/rabbitmq-server.service
           ├─8507 /usr/lib64/erlang/erts-5.10.4/bin/beam -W w -K true -A30 -P 1048576 -- -root /usr/lib64/erlang -progname...
           ├─8522 /usr/lib64/erlang/erts-5.10.4/bin/epmd -daemon
           ├─8579 inet_gethost 4
           └─8580 inet_gethost 4

Nov 07 05:52:24 node3 systemd[1]: Starting RabbitMQ broker...
Nov 07 05:52:24 node3 systemd[1]: rabbitmq-server.service: Got notification message from PID 8522, but reception on...ID 8507
Nov 07 05:52:26 node3 rabbitmq-server[8507]: RabbitMQ 3.3.5. Copyright (C) 2007-2014 GoPivotal, Inc.
Nov 07 05:52:26 node3 rabbitmq-server[8507]: ##  ##      Licensed under the MPL.  See http://www.rabbitmq.com/
Nov 07 05:52:26 node3 rabbitmq-server[8507]: ##  ##
Nov 07 05:52:26 node3 rabbitmq-server[8507]: ##########  Logs: /var/log/rabbitmq/rabbit@node3.log
Nov 07 05:52:26 node3 rabbitmq-server[8507]: ######  ##        /var/log/rabbitmq/rabbit@node3-sasl.log
Nov 07 05:52:26 node3 rabbitmq-server[8507]: ##########
Nov 07 05:52:27 node3 systemd[1]: Started RabbitMQ broker.
Nov 07 05:52:27 node3 rabbitmq-server[8507]: Starting broker... completed with 0 plugins.
Hint: Some lines were ellipsized, use -l to show in full.
关闭和查看rabiitmq的状态可以使用命令

[root@node3 system]# rabbitmqctl stop
Stopping and halting node rabbit@node3 ...
...done.
默认的日志目录是(/var/log/rabbitmq)

[root@node3 rabbitmq]# ll
total 4
-rw-r--r-- 1 rabbitmq rabbitmq 3190 Nov  7 06:12 rabbit@node3.log
-rw-r--r-- 1 rabbitmq rabbitmq    0 Nov  7 05:52 rabbit@node3-sasl.log

rabbitmq默认提供了一个web管理工具(rabbitmq_management)参考官方http://www.rabbitmq.com/management.html 默认已经安装 是一个插件

查看所有插件

[root@node3 rabbitmq]# rabbitmq-plugins list
[ ] amqp_client                       3.3.5
[ ] cowboy                            0.5.0-rmq3.3.5-git4b93c2d
[ ] eldap                             3.3.5-gite309de4
[ ] mochiweb                          2.7.0-rmq3.3.5-git680dba8
[ ] rabbitmq_amqp1_0                  3.3.5
[ ] rabbitmq_auth_backend_ldap        3.3.5
[ ] rabbitmq_auth_mechanism_ssl       3.3.5
[ ] rabbitmq_consistent_hash_exchange 3.3.5
[ ] rabbitmq_federation               3.3.5
[ ] rabbitmq_federation_management    3.3.5
[ ] rabbitmq_management               3.3.5
[ ] rabbitmq_management_agent         3.3.5
[ ] rabbitmq_management_visualiser    3.3.5
[ ] rabbitmq_mqtt                     3.3.5
[ ] rabbitmq_shovel                   3.3.5
[ ] rabbitmq_shovel_management        3.3.5
[ ] rabbitmq_stomp                    3.3.5
[ ] rabbitmq_test                     3.3.5
[ ] rabbitmq_tracing                  3.3.5
[ ] rabbitmq_web_dispatch             3.3.5
[ ] rabbitmq_web_stomp                3.3.5
[ ] rabbitmq_web_stomp_examples       3.3.5
[ ] sockjs                            0.3.4-rmq3.3.5-git3132eb9
[ ] webmachine                        1.10.3-rmq3.3.5-gite9359c7

启用该插件即可

rabbitmq-plugins enable rabbitmq_management
重启rabbitmq-server
[root@node3 rabbitmq]# service rabbitmq-server restart
Redirecting to /bin/systemctl restart  rabbitmq-server.service
浏览器访问(开启了端口 15672 当前机器ip是58.150) (http://192.168.58.150:15672/)

输入用户名 guest和guest


该管理界面有几个视图 分别是



三。rabbitmq api调用

 参考官方文档 http://www.rabbitmq.com/getstarted.html

rabbitmq 官方操作api提供了n多种语言  前面几种都会 java是本职 所以使用java



rabbitmq支持6种消息接受和转发机制 

1》简单模式(http://www.rabbitmq.com/tutorials/tutorial-one-java.html)

  单个发送者(生产者) 将消息发送到队列(每个队列都有一个唯一名字)  单个接受者(消费者)获取消息


eclipse添加maven的jar项目添加依赖

<dependency>
		  <groupId>com.rabbitmq</groupId>
		  <artifactId>amqp-client</artifactId>
		  <version>4.2.0</version>
		</dependency>
生产者代码

package cn.et.p1;

import java.io.IOException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 * 消息发送者 - 生产者
 * @author jiaozi
 *
 */
public class Pub {
	/**
	 * 队列名称
	 */
	private final static String QUEUE_NAME = "hello";
	public static void main(String[] args) throws Exception {
		//连接远程rabbit-server服务器
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost("192.168.58.150");
		factory.setPort(5672);
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();
		//定义创建一个队列
		channel.queueDeclare(QUEUE_NAME, false, false, false, null);
		String message = "Hello World!";
		//发送消息
		channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8")); //注意发送和接受段相同字符集否则出现乱码
		System.out.println(" [x] Sent '" + message + "'");
		channel.close();
		connection.close();
	}

}
消费者代码

package cn.et.p1;

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;
import com.rabbitmq.client.QueueingConsumer;

/**
 * 消息接受者 - 消费者
 * 
 * @author jiaozi
 *
 */
public class Rec {
	/**
	 * 获取消息队列名称
	 */
	private final static String QUEUE_NAME = "hello";
	/**
	 * 异步接收
	 * @throws Exception 
	 */
	public static void asyncRec() throws Exception{
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost("192.168.58.150");
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();
		//消费者也需要定义队列 有可能消费者先于生产者启动 
		channel.queueDeclare(QUEUE_NAME, false, false, false, null);
		System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
		//定义回调抓取消息
		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(" [x] Received '" + message + "'");
			}
		};
		channel.basicConsume(QUEUE_NAME, true, consumer);
	}
	
	/**
	 * 同步接收 消费者定时去抓取 
	 * 该种方式已过期
	 * @throws Exception 
	 */
	public static void asyncFalseRec() throws Exception{
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost("192.168.58.150");
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();
		channel.queueDeclare(QUEUE_NAME, false, false, false, null);
		System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
		QueueingConsumer consumer = new QueueingConsumer(channel);
		channel.basicConsume(QUEUE_NAME, true, consumer);
		while (true) {
			     QueueingConsumer.Delivery delivery = consumer.nextDelivery();
			     String message = new String(delivery.getBody());
			     System.out.println(" [x] Received '" + message + "'");
		}

	}
	
	public static void main(String[] args) throws Exception {
		asyncRec();
	}
}
发布消息到队列可以通过web管理界面查看消息  使用命令行

[root@node3 rabbitmq]# rabbitmqctl list_queues
Listing queues ...
hello   2   队列名称 队列的消息个数
...done.
web界面可以模拟添加队列 删除 模拟发送消息 也可以查看队列消息 具体自己研究


2》工作队列模式(http://www.rabbitmq.com/tutorials/tutorial-two-java.html)
 

工作队列一般用于任务分配  发布者发布任务到队列 多个消息接受者 接受消息 谁接受到某个消息 其他接受者就只能消费其他消息 队列中的

一个消息只能被一个接受者消费(类似12306抢票一样 比如某个车次 就相当于队列  该车次 出来一些座位票  一张票只能被一个人抢到 最终 所有的座位票

都被不同的人抢到 注意: 一个人可以抢多张票)



模拟 两个任务接受者 一个发布者发布6个消息   2个任务接受者抢这6个消息 一般来说都是rr轮询制 基本是平均分配给每个接受者的

发布者代码:

package cn.et.p2;

import java.io.IOException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 * 消息发送者 - 生产者
 * @author jiaozi
 *
 */
public class Pub {
	/**
	 * 队列名称
	 */
	private final static String QUEUE_NAME = "mywork";
	public static void main(String[] args) throws Exception {
		//连接远程rabbit-server服务器
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost("192.168.58.150");
		factory.setPort(5672);
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();
		//定义创建一个队列
		channel.queueDeclare(QUEUE_NAME, false, false, false, null);
		String message = null;
		//同时发送5条消息
		for(int i=0;i<=5;i++){
			message="发送第"+i+"消息";
			//发送消息
			channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));
		}
		
		System.out.println(" [x] Sent 5 message");
		channel.close();
		connection.close();
	}

}
接受任务者

package cn.et.p2;

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;
import com.rabbitmq.client.QueueingConsumer;

/**
 * 消息接受者 - 消费者
 * 
 * @author jiaozi
 *
 */
public class Rec {
	/**
	 * 获取消息队列名称
	 */
	private final static String QUEUE_NAME = "mywork";
	/**
	 * 异步接收
	 * @throws Exception 
	 */
	public static void asyncRec() throws Exception{
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost("192.168.58.150");
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();
		//消费者也需要定义队列 有可能消费者先于生产者启动 
		channel.queueDeclare(QUEUE_NAME, false, false, false, null);
		System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
		//定义回调抓取消息
		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(" [x] Received '" + message + "'");
			}
		};
		channel.basicConsume(QUEUE_NAME, true, consumer);
	}
	
	
	
	public static void main(String[] args) throws Exception {
		asyncRec();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值