RabbitMQ学习笔记

RabbitMQ

消息中间件的概念:
消息中间件独特的优势就是可异步处理.而不需要定时去检查,redis也可以,但需要定时去查,一致性较差.消息队列则不存在,也不是绝对的,消息过多也会积压.
消息中间件随之带来的问题:
	如何选择同步和异步处理?
	消息安全?丢失重复如何搞?
	延迟如何降低
	消息的顺序问题
	是否重发?如何保证幂等性
消息中间件的使用场景:
	流量削峰,分流,限流,缓冲,队列机制,只能保证最终一致性的,消息驱动.
MQ的选择:
开源自己能修复.
行业内流行的技术.社区活跃.问题好解决.bug与稳定性较好.
消息可靠、支持集群、性能要好.
几个MQ的区别与共同点:

在这里插入图片描述

RabbitMQ:
	AMQP协议
	轻量级、灵活的配置、多种语言支持
	无法堆积消息;性能三个中最差;二次开发和拓展较为复杂;erlang是爱立信公司的开发语言.
RocketMQ:借鉴了kafka的设计
	JMS规范
	只支持java.兼容性还是一般.
Kafka:
	可靠性最高,可伸缩、消息持久化、消息分区(666)、副本和容错.
	批处理和异步处理设计较好,如果压缩,那么就可以处理2000万级的消息.但是延迟性无发保证哦.
MQ的应用场景:
 典型案例:秒杀 秒杀这种高并发的难题,永远是推动技术的关键点.上了缓存,可以避免了数据库崩溃,上了MQ,就可以避免服务器的压力.
 高并发,为了减轻后面绝大部分业务的压力,用上MQ,就可以适当减轻.
某勾的B端和C端架构案例:
B端的更新,需要快速的通知到C端,这时定时任务,缓存,都无法达到快速,只能使用通知形式来告知C端,可通知的有zk和mq,zk并不适合大量请求,所以mq就假设在中间

JMS规范和AMQP协议:

JMS java消息服务 java message service
	报文头和消息主体,头由官方指定的字段

在这里插入图片描述

消息体类型:
	简单文本
	序列化对象
	属性集合
	字节流
	原始值流
	无有效负载消息
体系结构:
	供应商产品 适配器 适配其他的MQ
	clinet 
	producer
	consumer
	message
	queue
	topic
对象模型:
	connection factory连接工厂 创建连接
	Connection 连接接口
	Destination 接口,目标 决定往哪发,主题还是点
	Session 会话
	MessageConsumer
	MessageProducer
	Message 具体的消息类型实体对象

在这里插入图片描述
在这里插入图片描述

点对点模型:图1
	投递消息到JMS queue ,一条消息只能被一个消费者获得.多个消费者轮训获取消息,不会重复获得
发布订阅模式:图2
	设置一个主题,生产者向主题里发送消息,订阅了主题的消费者都会得到消息.可重复获得.生产者只管发,如果没消费者收到那么会丢失,但可设置持久化.消费者上线会重发.
传递方式:
	默认不持久化消息,需要设置.
供应商:
	一些主流的开源MQ和商业的MQ.
JMS的问题:
	点对点集群没有问题,但是主题情况下的集群,那么就会出现问题.多应用集群下,单个应用集群就会出现重复消费.要不就用queue多个,要不就在分布式上锁或者hash负载
JMS的特性:
	需要供应商桥接.
	只能支持java
	没有AMQP灵活
	AMQP不需要桥接

AMQP 高级消息队列协议:

在这里插入图片描述

	只要遵守该协议的语言,都可以使用rabbit MQ.不管多么冷门.
	一些概念:
		publisher发送者
		consumer消费者
		server 服务实例 broker
		virtual host 虚机
		exchange 交换器
		routing key路由键
		bindings绑定关系
		message queue 消息容器
	传输层架构:
		一个长的消息,会切为很多个小块,称之为负载,前头称之为帧头,最后成为帧尾
	数据类型:
	协议协商:
		先握手协商,三次握手那些,添加一些选项和要求,客户端回复才能开始正式的通信.这样可以提前约定好一些配置,防止传输数显问题.
	数据帧界定:
		1:每个连接发一个帧,简单但是慢
		2:添加边界,简单但是解析慢
		3:计算数据大小,发送前加上该数据帧的大小,这样解析很快AMQP使用该种
	AMQP实现JMS客户端:
		有一些局限性:
			JMS不支持服务器会话
			XA事物支持接口没有实现
			队列选择器未实现
			支持SSL和桃姐选项,但使用RabbitMQ客户端提供的SSL协议
			RabbitMQ不支持JMS的Noloacl订阅功能,禁止消费者接收通过自身的连接发布的消息,可以调用包含no local的方法,但该方法将被忽略

RabbitMQ架构:

较为热门的一个MQ,高可靠、易拓展、高可用、功能丰富,语言种类支持丰富,冷门语言都可支持.遵循AMQP协议,Erlang开发.插件支持MQTT其他协议.MQTT是互联网使用较多的协议.报文简洁;

整体架构:

在这里插入图片描述

Exchange交换器类型:
fanout:
	把消息发送到与它绑定的消息队列,广播形式,多个队列都会收到,消息发出没有客户端在线就丢失
direct:
	消息会routingkey 和 binding key都匹配的队列,也可多个队列.但一条消息只能发到给一个队列.bk是生产者去指定的.
topic:
	通过通配符,发送到匹配的队列,rk为具体的字符串,bk为通配模式,rk匹配了多个bk的队列,可广播.
header:
	根据头信息进行匹配,性能较差,不咋用.
数据存储机制:
持久化的消息内存和磁盘都会保存,内存不够的话内存中的会清除
非持久化一般都在内存,内存压力大进行刷盘减轻内存压力
存储分为两部分,队列索引和消息存储
索引文件存储 .idx 存储路径、是否被消费、是否被消费ack
文件名从0开始,每个文件存储默认16384条信息,再就另起一个文件.
数据存储为rdq文件,也有一个容量,超出就会再起一个文件,和索引文件一样.
消息通过queue_index_embed_msgs_below决定存储在索引还是数据文件,默认4096B,大于就是数据文件存储,小于就是索引文件.rebbitmq.conf可设置该参数
读取消息时通过msg_id找到对应存储文件.还有锁的机制,store去请求锁
删除消息,当文件中的消息被消费确认了后,消费确认率达到一定数值后,就会进行锁定文件合并,后面文件写入到前面,删除后面的文件.

在这里插入图片描述

队列结构: 
	alpha 消息和索引都在内存
	beta 索引在内存, 消息在硬盘
	gama 部分索引和消息在硬盘, 另一部分在内存 
	derta 索引和消息都在硬盘
获取消息:
	1. 首先会从Q4中获取消息,如果获取成功则返回。
	2. 如果Q4为空,则尝试从Q3中获取消息,系统首先会判断Q3是否为空,如果为空则返回队列为空,即此时队列中无消息。
	3. 如果Q3不为空,则取出Q3中的消息;进而再判断此时Q3和Delta中的长度,如果都为空,则可以认为 Q2、Delta、 Q3、Q4 全部为空,此时将Q1中的消息直接转移至Q4,下次直接从Q4 中获取消息。
	4. 如果Q3为空,Delta不为空,则将Delta的消息转移至Q3中,下次可以直接从Q3中获取消息。在将消息从Delta转移到Q3的过程中,是按照索引分段读取的,首先读取某一段,然后判断读取的消息的个数与Delta中消息的个数是否相等,如果相等,则可以判定此时Delta中己无消息,则直接将Q2和刚读取到的消息一并放入到Q3中,如果不相等,仅将此次读取到的消息转移到Q3。
	消息堆积为什么会性能下降?
	不断堆积消息,占用内存,内存吃紧就会开始对磁盘进行IO,后期拿消息就会在磁盘中IO读取,这样大大降低性能.

安装和配置RabbitMQ:

需要安装Erlang23.0.2-1
Rabbit3.8.4
MQ还依赖Linux中的socat   yum一下
一些部署的命令:
	启用RabbitMQ的管理插件
	rabbitmq-plugins enable rabbitmq_management
	开启RabbitMQ
	systemctl start rabbitmq-server 或者 rabbitmq-server
	后台启动
	rabbitmq-server -detached
	添加用户
	rabbitmqctl add_user root 123456
	给用户添加权限 给root用户在虚拟主机"/"上的配置、写、读的权限
	rabbitmqctl set_permissions root -p / ".*" ".*" ".*"
	给用户设置标签
	rabbitmqctl set_user_tags root administrator 
	用户的标签和权限:

在这里插入图片描述

RabbitMQ常用命令:
	 前台启动Erlang VM和RabbitMQ :rabbitmq-server 
	 后台启动 :rabbitmq-server -detached 
	 停止RabbitMQ和Erlang VM :rabbitmqctl stop 
	 查看所有队列 :rabbitmqctl list_queues 
	 查看所有虚拟主机 :rabbitmqctl list_vhosts 
	 在Erlang VM运行的情况下启动RabbitMQ应用 :rabbitmqctl start_app rabbitmqctl stop_app 
	 查看节点状态 :rabbitmqctl status 
	 查看所有可用的插件 :rabbitmq-plugins list 
	 启用插件 :rabbitmq-plugins enable <plugin-name> 
	 停用插件 :rabbitmq-plugins disable <plugin-name> 
	 添加用户 :rabbitmqctl add_user username password 
	 列出所有用户: rabbitmqctl list_users 
	 删除用户: rabbitmqctl delete_user username 
	 清除用户权限: rabbitmqctl clear_permissions -p vhostpath username 
	 列出用户权限: rabbitmqctl list_user_permissions username 
	 修改密码: rabbitmqctl change_password username newpassword 
	 设置用户权限: rabbitmqctl set_permissions -p vhostpath username ".*" ".*" ".*" 
	 创建虚拟主机: rabbitmqctl add_vhost vhostpath 
	 列出所以虚拟主机: rabbitmqctl list_vhosts 
	 列出虚拟主机上的所有权限: rabbitmqctl list_permissions -p vhostpath 
	 删除虚拟主机: rabbitmqctl delete_vhost vhost vhostpath 
	 移除所有数据,要在 rabbitmqctl stop_app 之后使用: rabbitmqctl reset
-*kill 掉rabbitmq时会出现一个epmd进程,负责通信(4369)集群之间和端口映射的守护进程
设置权限的允许拒绝代码:^$拒绝,*.允许

RabbitMQ工作流程:

生产者:
1:建立TCP连接,建立通道
2:声明交换器,检查mq的交换器是否匹配,是否持久化
3:声明一个消息队列,检查与mq的队列是否一致,检查其中的属性
4:交换器与队列进行绑定.
5:通过通道开始发送消息到broker,包含RK、BK等信息.
6:MQ的交换器根据RK和BK进行查找相应的队列,找到就存储到队列中
7:找不到就选择丢弃还是退回给生产者
8:关闭通道和连接
消费者:
1:与MQ连接,建立通道
2:一种主动拉取,一种被动等待推送.
3:拿到消息开始处理
4:处理完毕给MQ ack确认,也可自动确认,收到消息就给MQ ack
相关代码:
生产者:
添加依赖 rabbitmq
获取ConnectionFactory
		setHost("hostname")
		setVHost("/");
		setUsername();
		setPassword();
		setPort(5672);
Connection初始化 factory.new
Channel初始化 connection.create
channel通道创建队列.queue
	参数:
	队列名
	是否持久化 durable
	是否排他 exclusive
	是否自动清除 auto-delete
	队列属性, null表默认.
channel创建交换器.exchange
	参数:
	交换器名称 
	交换器类型
	是否持久化 durable
	是否自动清除 auto-delete
	交换器属性 null代表默认
channel交换器队列绑定queueBind
	队列名
	交换器名
	routing key自定义一个rk
channel发送消息basicpublish
	交换器名
	rk
	消息属性对象BasicProperties
	消息的字节流
channel关闭
connection关闭
消费者:
主动拉取:
工厂创建 ConnectionFactory factory = new ConnectionFactory();
setUri("amqp://root:123456@host:5672/vhost的uri代码")
获取连接 Connection conn = factory.newConnection();
创建通道 Channel channel = conn.createChannel(); 
保险一下主动创建队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null);
channel.basicGet() 获取消息
	获取队列名 
	是否自动ack
getBody()获取消息具体内容
关闭通道
等待推送:
工厂创建
setUri("amqp://root:123456@host:5672/vhost的uri代码")
获取连接
创建通道
保险一下主动创建队列
channel.basicConsume()
	队列名
	有消息的处理方法
关闭通道.
关闭连接.
连接和通道的关系:
线程对应一个通道,多个通道可使用一个复用的TCP连接.提高效率,减少消耗.

rabbitMQ的源码 都参照着AMQP协议的架构进行的拓展.大部分的方法都是AMQP提供的方法
RabbitMQ的连接工厂生产的连接底层是AMQP协议的模型,AMQP协议TCP连接底层使用javaNIO模型,并使用selector机制进行多通道复用一个TCP连接进行通信.

RabbitMQ工作模式:

工作模式中一些知识点:
临时队列:
	当生产者无法确定哪些队列接收这些消息,也就是没有明确队列时,AMQP就会随机建立一个队列与交换器绑定,然后发送给该队列中的消费者,但是该消费者得绑定生产者的交换器.
绑定:
	队列与交换器绑定了,交换器不会去匹配rk,直接发送给绑定的队列中.
默认交换器:
	不声明交换器.直接声明一个队列,然后就发送消息
工作队列:direct类型交换器
	一堆消息均衡的发送到每个节点,而不是广播形式.分布式应用常用的模式.
发布订阅模式:fanout类型交换器
	消息发送到交换器,交换器将消息发送到匹配的主题中,消费者订阅了匹配的主题就可接收到消息,属于广播,主要匹配的主题都可以收到,订阅主题的消费者也都能收到适合日志型的消息发送.操作记录,通知类等等.
路由模式:(多消费者)
	生产者发送多种类型的消息,每种携带不同的RK,消费者订阅时,根据自己需要的消息生成队列,与交换器绑定,交换器根据生产者发消息携带的RK路由到匹配的队列,消费者就能收到消息了
主题模式:(多生产者)
	不同的消息生产者,发送有略微区别的消息,但又一些共同点,比如类型相同,地点不同,或者地点相同类型不同.这时候就主要topic主题模式来根据消息的BK进行通配过滤,符合BK的就接收,否则不接收.
	通配符规则:
		.负责区分间隔
		*:1个单词 a.* a.c可以,a.b.c不行了就
		#:0或多个  a.# a.b.c可以了
	queueBind(队列,交换器,RK)方法设置通配规则,就是绑定队列的方法,只不过把RK换成了通配.

Spring整合MQ:

Spring-amqp AMQP的封装
spring-rabbit rabbit的封装
添加后者就行;
配置文件xml:
	rabbit:connection-actory
	rabbit:admin 交换器队列等工具类
	rabbit:template  消息模板类
	rabbit:queue 队列声明
	rabbit:direct-exchange 交换器声明
		rabbit:bindings
			rabbit:binding key="bk" exchange="可以绑定其他交换器" queue="队列名"
RabbitTemplate对象负责对消息进行管理
MessagePropertiesBuilder负责消息的属性
MessageBuider对象负责创建消息
推送模式:
	配置文件:
	rabbit:listener-container
		rabbit:listener ref="实现了ChannelAwareMeesageListener或MessageListener监听器的bean Id" queue="队列名"

注解整合:

创建工厂bean,new一个工厂别给定uri
创建rabbitTemplate,把工厂给进去
创建rabbitAdmin工具类,把工厂给进去
创建队列 QueueBuilder创建
创建交换器 四个类型交换器都有相关的实体对象. 
创建绑定 BindingBuilder 来绑定
发消息用的对象:
RabbitTemplate对象负责对消息进行管理
MessagePropertiesBuilder负责消息的属性
MessageBuider对象负责创建消息
注解的推送模式:
配置类:
多出的配置
SimpleRabbitListenerContainerFactory(还有其他交换器类型的工厂类)
	注入连接
	注入确认模式setAcknowledgeMode(自动、常规、不确认)
	注入消费者数量(最小多少并发)setConcurrentConsumers 
	注入最大消费者数量(最大并发)setMaxConcurrentConsumers
	注入批次消费信息数量setBatchSize
@EnableRabbit 开启监听模式
创建监听类,创建一个方法添加注解@RabbitListener(队列名)
方法中的可选参数:
	@Payload String str 消息内容
	Message 消息对象
	MessageProperties 
	@Header  具体头信息的属性
	@Headers 头全部信息

SpringBoot整合RabbitMQ

依赖start-amqp
不需要创建工厂什么的了,只需要创建队列、交换器和绑定对象就行
配置:
	host、vhost、username、password、port
可以使用AmqpTemplate,和RabbitTemplate一样

Rabbit高级特性:

消息可靠性:
消息一致性:分布式锁和消息队列
消息队列的做法:
	生产消费端异常处理
		异常处理重发spring yml可配置retry
	MQ事务机制
		一发一确认为一个事物,可回滚,但不建议使用.性能消耗太大
	生产者确认机制
		MQ收到消息并存储到内存或硬盘时,返回ack确认,ack会携带收到消息的编号,以回应生产者发送的哪条消息成功接收了
		代码实现:
			//标记为ack确认通道
			channel.confirmSelect();
		Spring boot:
			配置文件新增:
			spring.rabbitmq.publisher-confirm-type=correlated 
			spring.rabbitmq.publisher-returns=true
			代码:
			rabbitTemplate.setConfirmCallback()发送确认函数
		批处理解决同步等待的性能问题:
		攒几个等待一次,但也不是最佳
		异步处理.攒几个启动线程
	消费者确认机制
	持久化消息
	broker的集群
	消费端限流
	消息幂等性(处理多少次结果都一直)
持久化存储机制:
交换器持久化:创建时设置durable
队列持久化:创建时设置durable
消息持久化:
BasicProperties 里deliveryMode设置为2,
AMQP.BasicProperties.builder()来创建,发送消息方法时,将properties传入
数据存储位置:粘贴文档.太长了.
消费者确认机制:
确认模式:
	none自行捕获异常
	auto:不主动捕获异常.
	manual:手动ack模式,处理完业务需要手动设置ack;
代码实现:
	推送模式下basicConsume方法时,设置autoAck为false,该方法的第二个参数,使用该多态方法有个回调函数需要实现.在该方法进行处理.
		确认方法:channel.basicack(消息标识,是否批量确认)
		批量驳回:channel.basicNack(消息标识,,是否回列)
		单条驳回:channel.basicReject(消息标识,是否回列)
	springboot模式:
		支持的配置:
			#最大重试次数 spring.rabbitmq.listener.simple.retry.max-attempts=5 
			#是否开启消费者重试(为false时关闭消费者重试,意思不是“不重试”,而是一直收到消息直到jack 确认或者一直到超时) spring.rabbitmq.listener.simple.retry.enabled=true 
			#重试间隔时间(单位毫秒) spring.rabbitmq.listener.simple.retry.initial-interval=5000 
			# 重试超过最大次数后是否拒绝 spring.rabbitmq.listener.simple.default-requeue-rejected=false 
			#ack模式 spring.rabbitmq.listener.simple.acknowledge-mode=manual
		RabbitListener注解中添加ackMode:确认模式
		拉取模式:
			rabbitTemplate.execute()消费确认方法
消费端限流:
对生产者端进行限制,不再发送新的消息到MQ, MQ设置阻断,拦截,暂停发布消息的连接,从而达到限流的目的
配置文件设置:
	rabbitmq.conf中配置:
默认credit flow的流控机制,监控队列、通道、连接,
QoS保证机制.限制通道中接收却未被ack的消息数量,只针对推送模式有效,主动拉取不行,只能是ack型的消息,当达到设置的阈值后,MQ就停止向消费端发送消息.确认一条,MQ就再发送一条,始终保持你有设置阈值内的消息等待ack
	代码实现:
		channel.basicQoS((可选)未确认的消息大小(rabbit没有实现),(必须)最大等待ACK消息条数,(可选)手否通道内所有消费者生效,)
总结-消息可靠性保障:
1:最多一次
	消息会丢失.因为不会重发,不持久化.适合非关键性的一些消息.
2:最少一次
	开启事务机制和确认机制
	消息、队列持久化
	交换器备份
	手动确认
3:恰好一次:
	无法保障该情况.
	可能会因为网络错误导致重发
	消费端设置消息幂等性,比如批次号,时间流水号.保证每条消息都是处理一次,再次处理不影响最终结果.
	支付宝铁律:一锁二判三操作
	数据库索引唯一性,插入冲突.
可靠性分析:
firehose组件,可靠性分析,将正常生产出的消息复制发送到2个单独的队列,1个记录生产出的消息记录,1个记录消费的消息记录.
开启firehose: ctl trace_on [-p vhost]
关闭:ctl trace_off
rabbit tracing: 分析插件
	比firehose相比对了日志,更清晰的查看消息内容.需要在management进行配置.
	通过插件开启

TTL机制:

rabbitTTL机制可以设置消息过期:
	代码:创建队列的argment Map里扔
	x-message-ttl:队列中消息过期时间
	x-expries:没有消费者情况下,也没有被使用的队列过期的时间.
	命令行:
	ctl set_policy 策略名 ".*" '{"策略名":策略值}' --apply-to queues 
	可持续添加表更新
springboot:
	创建队列bean时 在queue new时添加arg集合
	在发消息时设置过期时间properties

死信队列:

如果一个队列消息过期了,那么我们可以将它转到另一个队列里,由该队列的消费者来处理.这就是死信队列
死信交换器DLX,消息过期后被转发的DLX,与DLX绑定的队列就为死信队列DLQ;
死信队列需要的属性:
	x-meesage-ttl:消息过期时间
	x-dead-letter-exchange:指定死信队列
	x-dead-letter-routing-key:指定死信的RK

延迟队列:

消息发到队列后,设置不立即被消费.间隔一段时间或者设置固定时间再消费该消息.
1:通过死信队列来实现延迟队列,死信队列为正常的业务队列,发消息的队列就成为了延迟队列.但会出现问题,消息过期从队列尾部拿取,而前面的队列早已过期,失去延迟队列的意义
2:rabbitmq_delayed_message_exchange插件实现,缓存到延迟交换机中,根据TTL机制等待到期后根据RK发送到指定队列,再被该队列的消费者消费.这样的话就不会被队列的特性所影响,是在交换机上做过期处理.
	下载该插件,安装:
		把.ez的插件放到rabbit目录下的plugins中即可,rabbit自动搞嘛.
	代码:
	添加属性:x-delayed-type:交换器类型
	创建交换器时交换器的类型设置为了x-delayed-message,交换器真实的类型被扔到了属性里.
	设置过期时间的属性被自定义为:x-delay

RabbitMQ集群:

主备兔子窝模式:
	备份节点不提供服务,主节点故障进行转移.主备通过共享存储进行共享存储.
铲子模式shovel:
	在生产节点创建了备份队列,生产者发消息时也会发到备份队列一份,或者生产者生产队列已满时直接发送给备份队列.被shovel消费,再作为生产者转发到另一个MQ的队列中.
集群模式cluster:
	所有节点彼此备份节点数据:
		队列元数据、交换器明能属性、绑定关系元数据、vhost内队列、交换器和绑定提供命名空间和属性
	镜像复制:
		ALL主节点会将镜像队列复制到所有从节点上,其他节点的队列也会把队列复制到其他节点上,避免交叉浪费.
	联邦模式 插件: 
		交换器federation plugin 队列federation plugin
		节点消息同步插件.
		通过单相连接,从交换器或者队列同步到从节点交换器或队列中.
	异地多活:
		可伸缩、异地伸缩
		容灾性能好.网络影响大
		成本有效利用
单机多实例搭建:
	rabbitmq_node_port文件用于设置MQ的服务发现,对外端口
	rabbitmq_nodename文件用于设置rabbitMQ节点名称
	环境变量:
		RABBITMQ_NODE_IP_ADDRESS:将RabbitMQ绑定到一个网络接口。 如果要绑定多个网络接口,可以在配置文件中配置。 默认值:空字串。表示绑定到所有的网络接口。
		RABBITMQ_NODE_PORT:默认值:5672
		RABBITMQ_DIST_PORT:RabbitMQ节点之间通信以及节点和CLI工具通信用到的端口。 如果在配置文件中配置了kernel.inet_dist_listen_min 或者kernel.inet_dist_listen_max,则忽略该配置。 默认值:$RABBITMQ_NODE_PORT + 20000
		ERL_EPMD_ADDRESS:epmd 使用的网络接口, epmd 用于节点之间以及节点和CLI之间的通信。 默认值:所有网络接口,包括和IPv4。
		ERL_EPMD_PORT:epmd 使用的端口。 默认值:4369。
		RABBITMQ_DISTRIBUTION_BUFFER_SIZE:节点之间通信连接使用的发送数据缓冲区大小限制, 单位是KB。推荐使用小于64MB的值。 默认值:128000
		RABBITMQ_IO_THREAD_POOL_SIZE:Erlang运行时的 I/O 用到的线程数。不推荐小于32的值。 默认值:128(Linux),64(Windows)
		RABBITMQ_NODENAME:RabbitMQ的节点名称。对于Erlang节点和机器,此名称应该唯一。 通过设置此值,可以在一台机器上多个RabbitMQ节点。 默认值:rabbit@$HOSTNAME(Unix-like),rabbit@%COMPUTERNAME%(Windows)。
		RABBITMQ_CONFIG_FILE:RabbitMQ主要配置文件的路径。例如 /etc/rabbitmq/rabbitmq.conf 或 者 /data/configuration/rabbitmq.conf 是新格式的配置文件。 如果是老格式的配置文件,扩展名是 .config 或者不写。 默认值: 对于Unix: $RABBITMQ_HOME/etc/rabbitmq/rabbitmq Debian:/etc/rabbitmq/rabbitmq RPM: /etc/rabbitmq/rabbitmq MacOS(Homebrew): ${install_prefix}/etc/rabbitmq/rabbitmq , Homebrew的前缀通常是: /usr/local/ Windo%APPDATA%\RabbitMQ\rabbitmq
		RABBITMQ_ADVANCED_CONFIG_FILE:RabbitMQ带 .config 的高级配置文件路径(基于Erlang配置)。例如, /data/rabbitmq/advanced.config 。默认值:Unix: $RABBITMQ_HOME/etc/rabbitmq/advancedDebian: /etc/rabbitmq/advancedRPM: /etc/rabbitmq/advancedMacOS(Homebrew): ${install_prefix}/etc/rabbitmq/advanced , 其中Homebrew前缀通常是 /etc/local/Windows: %APPDATA%\RabbitMQ\advanced 。
		RABBITMQ_CONF_ENV_FILE:包含了环境变量定义的文件的目录(不使用 RABBITMQ_ 前缀)。 Windows上的文件名称与其他操作系同。 默认值: UNIX: $RABBITMQ_HOME/etc/rabbitmq/rabbitmq-env.conf Ubuntu和Debian: /etc/rabbitmq/rabbitmq-env.conf RPM: /etc/rabbitmq/rabbitmq-env.conf Mac(Homebrew): ${install_prefix}/etc/rabbitmq/rabbitmq-env.conf ,Homebrew的前缀一般是 /usr/local Windows: %APPDATA%\RabbitMQ\rabbitmq-env-conf.bat
		RABBITMQ_MNESIA_BASE:
		包含了RabbitMQ服务器的节点数据库、消息存储以及 集群状态文件子目录的根目录。除非显式设置了RABBITMQ_MNESIA_DIR 的值。需要确保RabbitMQ用户 在该目录拥有读、写和创建文件以及子目录的该变量一般不要覆盖。一般覆盖 RABBITMQ_MNESIA_DIR 变量。 默认值: Unix: $RABBITMQ_HOME/var/lib/rabbitmq/mnesia Ubuntu和Debian: /var/lib/rabbitmq/mnesia/RPM: /var/lib/rabbitmq/plugins MacOS(Homebrew):${install_prefix}/var/lib/rabbitmq/mnesia , 其中Homebrew的前缀一般是 /usr/localWindows: %APPDATA%\RabbitMQ
		RABBITMQ_MNESIA_DIR:RabbitMQ节点存储数据的目录。该目录中包含了数据库、 消息存储、集群成员信息以及节点其他的持状态。 默认值: 通用UNIX包: $RABBITMQ_MNESIA_BASE/$RABBITMQ_NODENAME Ubuntu和Debia$RABBITMQ_MNESIA_BASE/$RABBITMQ_NODENAME RPM: $RABBITMQ_MNESIA_BASE/$RABBITMQ_NOMacOS (Homebrew): ${install_prefix}/var/lib/rabbitmq/mnesia/$RABBITMQ_NODENAME ,Homebrew的前缀一般是 /usr/local Windows: %APPDATA%\RabbitMQ\$RABBITMQ_NODENAME
		RABBITMQ_PLUGINS_DIR:存放插件压缩文件的目录。RabbitMQ从此目录解压插件。 跟PATH变量语法类似,多个路径之间使用统的分隔符分隔 (Unix是 : ,Windows是';')。插件可以安装到该变量指定的任何目录。 路径不要有符。 默认值: 通用UNIX包: $RABBITMQ_HOME/plugins Ubuntu和Debian包: /var/lib/rabbitmq/plugins RPM: /var/lib/rabbitmq/plugins MacOS (Homebrew): ${install_prefix}/Cellar/rabbitmq/${version}/plugins , Homebrew的前缀一般是 /usr/lWindows: %RABBITMQ_HOME%\plugins
		RABBITMQ_PLUGINS_EXPAND_DIR:节点解压插件的目录,并将该目录添加到代码路径。该路径不要包含特殊字符。 默认值: UNIX: $RABBITMQ_MNESIA_BASE/$RABBITMQ_NODENAME-plugins-expand Ubuntu和Debian packages: $RABBITMQ_MNESIA_BASE/$RABBITMQ_NODENAME-plugins-expand RPM: $RABBITMQ_MNESIA_BASE/$RABBITMQ_NODENAME-plugins-expand MacOS (Homebrew): ${install_prefix}/var/lib/rabbitmq/mnesia/$RABBITMQ_NODENAME-plugins-expand Window%APPDATA%\RabbitMQ\$RABBITMQ_NODENAME-plugins-expand
		RABBITMQ_USE_LONGNAME:当设置为 true 的时候,RabbitMQ会使用全限定主机名标记节点。 在使用全限定域名的环境中使用。重置节点, 不能在全限定主机名和短名之间切换。 默认值: false 。
		RABBITMQ_SERVER_CODE_PATH:当启用运行时的时候指定的外部代码路径(目录)。 当节点启动的时候,这个是值传给 erl 的命令行默认值:(none)
		RABBITMQ_CTL_ERL_ARGS:当调用 rabbitmqctl 的时候传给 erl 的命令行参数。 可以给Erlang设置使用端口的范围: -kernel inet_dist_listen_min 35672 -kernel inet_dist_listen_max 35680 默认值:(none)
		RABBITMQ_SERVER_ERL_ARGS:当调用RabbitMQ服务器的时候 erl 的标准命令行参数。 仅用于测试目的。使用该环境变量会覆盖默认默认值: Unix*: +P 1048576 +t 5000000 + stbt db +zdbbl 128000 Windows:没有
		RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS:调用RabbitMQ服务器的时候传递给 erl 命令的额外参数。 该变量指定的变量追加到默认参数列表( RABBITMQ_SERVER_ERL_ARGS )。 默认值: Unix*: 没有 Windows: 没有
		RABBITMQ_SERVER_START_ARGS:调用RabbitMQ服务器的时候传给 erl 命令的额外参数。该变量不覆盖 RABBITMQ_SERVER_ERL_ARGS默认值:没有
		RABBITMQ_ENABLED_PLUGINS_FILE:用于指定 enabled_plugins 文件所在的位置。默认: /etc/rabbitmq/enabled_plugins
	启动命令:
	1:环境变量启动:
		export RABBITMQ_NODE_PORT=5673
		export RABBITMQ_NODENAME=rabbit1
		rabbit-server
	2:配置文件启动:
		修改存放配置文件目录的权限,安装rabbitMQ后会自动给创建一个rabbitmq的用户,chown :rabbitmq -R 目录名来修改权限,创建配置文件后也需要chown :rabbitmq 文件名来修改权限
		配置文件内容:
			management插件集群下端口修改:rabbitmq.conf:management.tcp.port=port
			远程登录配置:
			loopback_users.guest=true(false就可远程登录)
		RABBITMQ_NODENAME=nodename
		RABBITMQ_NODE_PORT=port
		RABBITMQ_CONFIG_FILE=配置文件
		rabbitmq-server
集群搭建:
	将元数据拷贝一下:scp命令, 远程复制 文件路径 root@hostname:拷贝路径
	stop_app停止mq应用保持erlang
	reset清空信息
	join_cluster rabbit@节点
	踢出节点:
		先stop_app该节点
		然后forget_cluster该节点
	添加节点:
		reset一下
		join_cluster 节点名称
	集群下创建用户为集群用户,都可以使用.
镜像集群配置:
	生产消息时,不论发到哪个节点,都会被转发到master节点上,再由master转发给其他镜像节点;
	可随意更改,因为镜像集群是落到队列或交换器的,所以随时可以更改某个队列或交换器是否为镜像集群模式.
	故障转移:
		找一个版本最新的从节点,进行升主,这时有新消息就会丢失.
		出现故障转移时,如果消费者申请了故障转移通知,将会收到通知.已发送出去等待ack的消息将会重新排队.
		消费消息时主挂了而没有得到ack确认,那么这个消息会被重新消费,这时消费端需要注意重复消费问题.
		发送消息时,发送到从节点,从节点转发时master挂掉,这个消息不会丢失,新master上来后会继续转发到新的master中,
		生产者只要是与镜像节点进行交互时,是感知不到镜像与非镜像队列的区别的.
	选举策略:
		以运行时间为依据,谁长谁当主
	配置参数:
	ha-mode:
	exactly设置副本队列的个数.下面那个参数.设置数量(包括主)
	all:集群内所有都复制.
	nodes:指定节点,下面参数设置具体节点名称.
	ha-params: 配合上面模式对应的参数
	配置方式:
		ctl set_policy ha-halfmore "队列名" '{"ha-mode":"exactly","ha-params":2}' 配置过半 复制镜像队列
		再用这个命令改成1就取消了镜像复制模式;
HAProxy负载均衡:
	代理,对镜像复制进行负载.
	安装gcc
	解压haproxy
	make targer=linux-glibc
	make install
	也可以yum安装.
	授权:
		groupadd -r -g 149 haproxy
	添加用户:
		useradd -g haproxy -r -s /sbin/nologin 看文档....
	配置文件:
		globallog 127.0.0.1 local0 info # 服务器最大并发连接数;如果请求的连接数高于此值,将其放入请求队列,等待其它连接被释 放; 
			maxconn 5120 # chroot /tmp # 指定用户 
			uid 149 # 指定组 
			gid 149 # 让haproxy以守护进程的方式工作于后台,其等同于“-D”选项的功能 
			# 当然,也可以在命令行中以“-db”选项将其禁用; 
			daemon # debug参数 
			quiet # 指定启动的haproxy进程的个数,只能用于守护进程模式的haproxy; 
			# 默认只启动一个进程, 
			# 鉴于调试困难等多方面的原因,在单进程仅能打开少数文件描述符的场景中才使用多进程模式; 
			# nbproc 20 
			nbproc 1 
			pidfile /var/run/haproxy.pid 
		defaults 
			log global
			# tcp:实例运行于纯TCP模式,第4层代理模式,在客户端和服务器端之间将建立一个全双工的 连接,
			# 且不会对7层报文做任何类型的检查; 
			# 通常用于SSL、SSH、SMTP等应用; 
			mode tcp 
			option tcplog 
			option dontlognull 
			retries 3 
			option redispatch 
			maxconn 2000 
			# contimeout 5s 
			timeout connect 5s 
			# 客户端空闲超时时间为60秒则HA 发起重连机制 
			timeout client 60000 
			# 服务器端链接超时时间为15秒则HA 发起重连机制
			timeout server 15000 
		listen rabbitmq_cluster 
			# VIP,反向代理到下面定义的三台Real Server 
			bind 192.168.100.101:5672 
			#配置TCP模式 mode tcp 
			#简单的轮询 balance roundrobin 
			# rabbitmq集群节点配置 
			# inter 每隔五秒对mq集群做健康检查,2次正确证明服务器可用,2次失败证明服务器不可用, 并且配置主备机制 
			server rabbitmqNode1 192.168.100.102:5672 check inter 5000 rise 2 fall 2 
			server rabbitmqNode2 192.168.100.103:5672 check inter 5000 rise 2 fall 2 
			server rabbitmqNode3 192.168.100.104:5672 check inter 5000 rise 2 fall 2
			#配置haproxy web监控,查看统计信息 
			listen stats bind 192.168.100.101:9000 
			mode http 
			option httplog 
			# 启用基于程序编译时默认设置的统计报告 
			stats enable 
			#设置haproxy监控地址为http://node1:9000/rabbitmq-stats 
			stats uri /rabbitmq-stats 
			# 每5s刷新一次页面 
			stats refresh 5s
	启动:
		haproxy -f /etc/haproxy/haproxy.cfg
	代码接入haproxy:
		与正常访问没有区别;
rabbit监控平台:
prometheus监控平台,redis、rabbit都支持.grafana页面美观
源码相关:
idea安装erlang插件
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值