三阶段--RabbitMQ消息队列

RabbitMQ消息队列

什么是消息队列?
当我们秒杀抢购商品的时候,系统提醒我们稍等排队中,这种排队结算,就用到了消息队列机制,一个一个处理,而不是某个时间突然融入大批量查询新增把数据库搞宕机,所以,消息队列的本质就是削峰填谷,为服务保驾护航。

什么是MQ?
Message Queue,消息队列,一种应用程序对应用程序的通信方法。
应用程序读写出入队列消息进行通信,无需专用连接。
消息传递时程序之间,通过消息中发送数据进行通信,而不是通过直接调用彼此来通信,除去了接收和发送应用程式,同时执行的要求。
项目中,将一些无需即时返回,而且耗时的操作提取出来,进行***异步处理***,节省服务器请求响应时间,从而提高i系统吞吐量。

核心功能

  • 解耦(将不同系统分离开)

  • 冗余(存储)

  • 扩展性

  • 削峰

  • 可恢复性

  • 顺序保证

  • 缓冲

  • 异步通信

消息队列的模式

两种模式:P2P模式(安全);Publish/Subscribe
一对一和一对多的两种模式

同类型产品:
1.kafka时linkedin开源分布式发布-订阅消息,目前归属于Apache顶级项目。kafka主要特点时基于Pull的模式来处理消息消费,追求高吞吐量,一开始就用于日志收集和传输。0.8版本开始支持复制,不支持事务,对于消息的重复、丢失、错误,是没有严格要求的,适合产生大量数据的互联网服务的数据收集业务,一般应用于大数据日志处理,或者对实时性、可靠性要求不高的场景使用,比如说elk日志收集。
2.rabbitmq
3.rocketmq

RabbitMQ详解

RabbitMQ是在AMQP基础上实现的,什么是AMQP?是一个协议,advanced message queuing prootocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议。为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。可复用的企业消息系统。
使用的语言是Erlang编写的开源消息队列,支持很多协议,重量级,适合企业级开发,同时实现了一个Broker框架,对路由,负载均衡,数据持久化都有很好的支持。

rabbitmq架构

在这里插入图片描述

  • Message 消息头和消息体组成,消息体不透明,由一些可选属性组成,包括路由键(routing-key)、优先级(routing-key)、持久性存储(delivery-mode)等
  • Publisher 消息生产者,向交换机发送消息的客户端程序,也可以理解为一个Java程序,如下所示。
  • Exchange 交换器,接收生产者publisher发送的消息,并且将这些消息路由发送给服务器中的队列中,消息先经过交换器exchang,然后再到队列里。三种交换器类型:direct、fanout、topic
  • Queue 消息的容器也是消息的终点,用来保存信息,直到发送给消费者cunsumeer,一个信息可以投入一个或者多个队列,消息一致在队列里面,等待消费者连接到这个队列将其取走。
  • Bingding 绑定,用户消息队列和交换器之间的关联
  • Virtual host 就是一个盒子,放两个东西,一个是exchange 一个是queue
  • Broker 中间人,也可以理解为rabbitmq的实体
  • Conection 连接,rabbitmq服务器和app服务建立的TCP连接
  • Channel 信道,发布消息、接收消息、订阅消息都是通过信道完成的,conection连接的tcp连接一旦打开,就会创建AMQP信道。
  • Cunsumer 消费者,与producer类似,一个Java程序,从一个消息队列中取得消息的客户端应用程序。如下所示。
public class Procuder {
	
	private static final Logger log = LoggerFactory.getLogger(Procuder.class);
	
	public static void main(String[] args) throws IOException, TimeoutException {
		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.setHost(RabbitMQCommon.RABBITMQ_HOST);
		connectionFactory.setPort(RabbitMQCommon.RABBITMQ_PORT);
		connectionFactory.setVirtualHost(RabbitMQCommon.RABBITMQ_DEFAULT_VIRTUAL_HOST);
		// 2 通过连接工厂创建连接
		Connection connection = connectionFactory.newConnection();
		// 3 通过connection创建一个Channel
		Channel channel = connection.createChannel();
		Map<String, Object> headers = new HashMap<>();
		headers.put("myHeaders1", "111");
		headers.put("myHeaders2", "222");
		AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder().deliveryMode(2).contentEncoding("UTF-8")
				.expiration("10000").headers(headers).build();
		// 4 通过Channel发送数据
		for (int i = 0; i < 5; i++) {
			String msg = "Hello RabbitMQ!";
			// 1 exchange 2 routingKey
			log.info("生产端,test001: {}", msg);
			channel.basicPublish("", "test001", properties, msg.getBytes());
		}
		// 5 记得要关闭相关的连接
		channel.close();
		connection.close();
	}
}

public class Procuder {
	
	private static final Logger log = LoggerFactory.getLogger(Procuder.class);
	
	public static void main(String[] args) throws IOException, TimeoutException {
		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.setHost(RabbitMQCommon.RABBITMQ_HOST);
		connectionFactory.setPort(RabbitMQCommon.RABBITMQ_PORT);
		connectionFactory.setVirtualHost(RabbitMQCommon.RABBITMQ_DEFAULT_VIRTUAL_HOST);
		// 2 通过连接工厂创建连接
		Connection connection = connectionFactory.newConnection();
		// 3 通过connection创建一个Channel
		Channel channel = connection.createChannel();
		Map<String, Object> headers = new HashMap<>();
		headers.put("myHeaders1", "111");
		headers.put("myHeaders2", "222");
		AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder().deliveryMode(2).contentEncoding("UTF-8")
				.expiration("10000").headers(headers).build();
		// 4 通过Channel发送数据
		for (int i = 0; i < 5; i++) {
			String msg = "Hello RabbitMQ!";
			// 1 exchange 2 routingKey
			log.info("生产端,test001: {}", msg);
			channel.basicPublish("", "test001", properties, msg.getBytes());
		}
		// 5 记得要关闭相关的连接
		channel.close();
		connection.close();
	}
}

RabbitMQ部署安装

环境

三台服务器,centos7,全部设置主机名和域名解析rabbitmq1、2、3
hostnamectl set-hostname rabbitmq1 设置主机名,退出连接再连接就更新了。

安装erlang

1.配置erlang的yum仓库

[rabbitmq_erlang]
name=rabbitmq_erlang
baseurl=https://packagecloud.io/rabbitmq/erlang/el/7/$basearch
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300
 
[rabbitmq_erlang-source]
name=rabbitmq_erlang-source
baseurl=https://packagecloud.io/rabbitmq/erlang/el/7/SRPMS
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300

yum -y install erlang

安装rabbitmq

直接下载rpm包安装即可
(下载过了 ,直接上传)
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.7.13/rabbitmq-server-3.7.13-1.el7.noarch.rpm
或者rz上传包,然后再:
yum -y install rabbitmq-server-3.7.13-1.el7.noarch.rpm

cp /usr/share/doc/rabbitmq-server-3.7.13/rabbitmq.config.example /etc/rabbitmq/rabbitmq.config
vim /etc/rabbitmq/rabbitmq.config

##61行去掉注释%%和,
{lopback_user, []}

rabbitmq-plugins enable rabbitmq_managementweb管理界面
systemctl restart rabbitmq-server启动消息队列服务
rabbitmqctl cluster_status 查看rabbitmq集群状态,现在只装了一台,所以只能看见自己的
访问iip加端口15672 默认账号密码guest

设置虚拟主机与添加用户

列出所有队列rabbitmqctl list_queues
清除所有队列rabbitmqctl reset
添加用户rabbitmqctl add_user username passwd
分配角色rabbitmqctl set_tags username administrator
新增虚拟主机rabbitmqctl add_vhost vhost_name
将新虚拟主机授权给用户rabbitmqctl set_permisssions -p vhost_name username ".*" ".*" ".*" .*表示拥有读写执行的权限。

集群部署

提供分布式高可用的 提升读写性能和数据安全性

  • cookie
    rabbitmq底层通过erlang架构来实现,所以,rabbitmqctl会启动erlang节点,并基于erlang节点使用erlang系统连接rabbitmq节点,再连接过程中需要正确的erlang cookie和节点名称。erlang节点 通过 erlang cookie 来获得认证,实现分布式,所以部署rabbitmq分布式集群要先安装erlang,并把其中一个服务的cookie复制到别节点里,以保证cookie的一致性问题。

  • 内存节点和磁盘节点
    每个rabbitmq为对等节点,也就是每个节点均提供给客户端连接,进行消息的接收和发送,节点分为内存节点和磁盘节点,一般都建立为磁盘节点,为了防止机器重启后消息消失。

  • 普通模式和镜像模式
    普通模式:消息只存在一个机器上
    镜像模式:会复制到别的机器上,高可用,but占资源

环境
  • 所有节点要在一个局域网内
  • 所有节点要有相同的erlang cookie,可以使用scp进行复制传输
  • 三台虚拟机进行测试,要求配置相同,都设置好主机名,并进行域名解析
  • 系统版本,centos7
部署

所有节点安装erlang和rabbitmq
导入rabbitmq管理界面rabbitmq-plugins enabe rabbitmq_management
设置运行节点:
scp -r /var/lib/rabbitmq/.erlang.cookie rabbitmq2:/var/lib/rabbitmq/.erlang.cookie
scp -r /var/lib/rabbitmq/.erlang.cookie rabbitmq3:/var/lib/rabbitmq/.erlang.cookie
systemctl restart rabbitmq-serverrabbitmq1节点运行rabbitmq服务,而rabbitmq2和3关闭systemctl stop rabbitmq-server
在rabbitmq2和3节点独立运行节点rabbitmq-server-datached
在rabbitmq1中rabbitmqcl cluster_status查看各个节点状态,现在只能看见当前的server信息,因为还没组成集群

添加用户admin,密码为admin(测试用。真实使用请设置复杂密码)

rabbitmqctl set_user_tags admin administrator rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*" rabbitmqctl add_user admin admin

组成集群

rabbitmq-server启动时,会一起启动节点和应用,会预先设置rabbitmq应用为standalone模式(脱机模式),注意,加入节点到集群中给,要先停止这个应用,并且将节点设置为原始状态,如果使用rabbitmqctl stop会把应用和节点都关闭,不可取,所以使用rabbitmqctl stop_app仅关闭应用,不停止节点。

将rabbitmq2、3加入到rabbitmq1里,也就是把node2、3加入到node1中
rabbitmq2、3都输入rabbitmqctl stop_app停止其应用
rabbitmqctl join_cluster rabbit@rabbitmq1加入集群
rabbitmqctl start_app加完后,启动节点2、3的应用
rabbitmqcl cluster_status 查看
over,结束

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值