RabbitMQ笔记(高级篇)

RabbitMQ笔记_高级篇

  • 问题
  • 代码准备
    • 1. 新建生产者
    • 2. 新建消费者
  • RabbitMQ 高级特性
    • 1. 消息的可靠投递☆
      • 1.1 两种模式
      • 1.2 测试confirm 确认模式
      • 1.3 测试return 退回模式
      • 1.4 小结
    • 2. Consumer ACK☆
      • 2.1 三种ACK
      • 2.2 测试手动ACK
      • 2.3 小结
      • 2.4 消息可靠性总结
    • 3. 消费端限流
      • 测试消费端限流
      • 小结
    • 4. TTL(Time To Live)
      • 控制台添加ttl队列
      • 添加交换机
      • 绑定交换机和队列
      • 消息发布
      • 代码演示
      • 小结
    • 5.死信队列DLX☆
      • 消息成为死信的三种情况☆
      • 队列绑定死信交换机
      • 代码测试
        • 测试结果
      • 小结
    • 6.延迟队列☆
      • 代码演示
      • 小结
    • 7.日志与监控(了解)
      • RabbitMQ日志
      • web管控台监控
      • rabbitmqctl管理和监控
    • 8.消息追踪
      • Firehose
      • rabbitmq_tracing
  • RabbitMQ应用问题☆
    • 1.消息可靠性保障
      • 消息补偿机制
    • 2.消息幂等性处理
      • 乐观锁解决方案
  • RabbitMQ集群搭建
    • 3.1 集群方案的原理
    • 3.2 单机多实例部署
    • 3.3 集群管理
    • 3.4 RabbitMQ镜像集群配置
    • 3.5 负载均衡-HAProxy
      • 3.5.1 安装HAProxy
      • 3.5.2 配置HAProxy
      • 启动HAproxy负载

问题

消息可靠性

消息幂等性

mq高可用


代码准备

1. 新建生产者

https://gitee.com/lixiaogou/rabbitmq/tree/master/extensions-spring-rabbitmq-producer

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2. 新建消费者

https://gitee.com/lixiaogou/rabbitmq/tree/master/extensions-spring-rabbitmq-consumer

image-20210206085348174


RabbitMQ 高级特性

image-20210204110540289

1. 消息的可靠投递☆

在使用 RabbitMQ 的时候,作为消息发送方希望杜绝任何消息丢失或者投递失败场景。RabbitMQ 为我们提供了两种方式用来控制消息的投递可靠性模式。

1.1 两种模式

  • confirm 确认模式
  • return 退回模式

RabbitMQ 整个消息投递的路径为:producer—>rabbitmq broker—>exchange—>queue—>consumer

  1. 消息从 producer --> exchange 会返回一个 confirmCallback 。
  2. 消息从 exchange --> queue 投递失败则会返回一个 returnCallback 。

我们将利用这两个callback 控制消息的可靠性投递l

1.2 测试confirm 确认模式

开启确认模式

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

定义ConfirmCallBack回调函数

image-20210204160530801

ConfirmCallBack源码

image-20210204155751064

image-20210204155912410


1.3 测试return 退回模式

开启回退模式

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

定义ReturnCallback回调函数

image-20210204162159769

ReturnCallback源码

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.4 小结

确认模式

  • 消息从 producer --> exchange 会返回一个 confirmCallback 。
  • 设置 ConnectionFactory 的 publisher-confirms="true" 开启 确认模式
  • 使用 rabbitTemplate.setConfirmCallback 设置回调函数。当消息发送到exchange后回调confirm方法。在方法中判断ack,如果为true,则发送成功,如果为false,则发送失败,需要处理。

退回模式

  • 消息从 exchange --> queue 投递失败会返回一个 returnCallback 。
  • 设置 ConnectionFactory 的 publisher-returns="true" 开启 退回模式。
  • 使用rabbitTemplate.setReturnCallback设置退回函数,设置rabbitTemplate.setMandatory(true)参数,当消息从exchange路由到queue失败后,会将消息退回给producer。并执行回调函数returnedMessage。

事务

  • 在RabbitMQ中也提供了事务机制,但是性能较差,此处不做讲解。

  • 使用channel下列方法,完成事务控制:

    • txSelect(),用于将当前channel设置成transaction模式
    • txCommit(),用于提交事务
    • txRollback(),用于回滚事务

2. Consumer ACK☆

ack指Acknowledge,确认。 表示消费端收到消息后的确认方式。

2.1 三种ACK

  • 自动确认:acknowledge=“none” (默认)

当消息一旦被Consumer接收到,则自动确认收到,并将相应消息从 RabbitMQ 的消息缓存中移除。在实际业务处理中,很可能消息接收到,但是业务处理出现异常,而此时消息已经从缓存中移除,那么该消息就会丢失

  • 手动确认:acknowledge=“manual”

在业务处理成功后,调用channel.basicAck(),进行手动签收,如果业务出现异常,则调用channel.basicNack()方法,让生产者自动重新发送消息。

  • 根据异常情况确认:acknowledge=“auto”,(这种方式使用麻烦,不常用

2.2 测试手动ACK

  1. 生产者配置文件
  2. 生产者测试代码
  3. 消费者配置文件
  4. 消费者监听器
  5. 消费者测试类

2.3 小结

  • 消费者配置文件中,将rabbit:listener-container标签中设置acknowledge=“manual”
  • 如果在消费端没有异常,则调用channel.basicAck(deliveryTag,false)方法,手动确认签收消息
  • 如果在消费端出现异常,则在catch中调用 basicNack或 basicReject,拒绝消息,让MQ重发消息。

2.4 消息可靠性总结

  1. 持久化

    • exchange要持久化
    • queue要持久化
    • message要持久化
  2. 生产方确认Confirm

    • confirm 确认模式

    • return 退回模式

  3. 消费方确认Ack

    • 自动确认:acknowledge=“none”
    • 手动确认:acknowledge=“manual”
    • 根据异常情况确认:acknowledge=“auto”
  4. Broker高可用(集群)

3. 消费端限流

image-20210204102048057

测试消费端限流

消费端配置文件prefetch="xx"

监听器代码

消费端测试类

发送端测试类

小结

  • 消费端rabbit:listener-container 中配置 prefetch属性设置消费端一次拉取多少消息

  • 消费端的确认模式一定为手动确认。acknowledge=“manual”

image-20210204211304237

4. TTL(Time To Live)

TTL 全称 Time To Live(存活时间/过期时间)。当消息到达存活时间后,还没有被消费,会被自动清除。RabbitMQ可以对消息设置过期时间,也可以对整个队列(Queue)设置过期时间。

image-20210204102201794

控制台添加ttl队列

test_queue_ttl

image-20210205103535219

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

添加交换机

test_exchange_ttl

image-20210205103956729


image-20210205104052071

绑定交换机和队列

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

消息发布

image-20210205104449730

image-20210205104714490

等待10秒过了存活时间,消息没有被消费,自动清除

image-20210205104730808

代码演示

生产者配置文件

生产者发送消息

每次测试之后都查看控制台

小结

  • 设置队列过期时间:x-message-ttl,单位:ms(毫秒),会对整个队列消息统一过期。
  • 设置消息过期时间:expiration。单位:ms(毫秒),当该消息在队列头部时(消费时),会单独判断这一消息是否过期,根据是否过去决定是否需要移除。
  • 如果两者都进行了设置,以时间短的为准。

5.死信队列DLX☆

死信队列,英文缩写:DLX 。Dead Letter Exchange(死信交换机),当消息成为Dead message后,可以被重新发送到另一个交换机,这个交换机就是DLX。

image-20210204102346053

消息成为死信的三种情况☆

  1. 队列消息长度到达限制;

  2. 消费者拒接消费消息,basicNack/basicReject,且消息不重新放入原目标队列,requeue=false;

  3. 原队列存在消息过期设置,消息到达过期时间未被消费;

队列绑定死信交换机

给队列设置参数: x-dead-letter-exchange 和 x-dead-letter-routing-key

image-20210204102456613

代码测试

步骤

  1. 生产者配置声明死信队列(queue_dlx)和死信交换机(exchange_dlx)
  2. 生产者配置声明正常的队列(test_queue_dlx)和交换机(test_exchange_dlx)
    3. 生产者配置正常队列绑定死信交换机 设置两个参数:
    1. x-dead-letter-exchange:死信交换机名称
    2. x-dead-letter-routing-key:发送给死信交换机的routingkey

生产者配置文件

生产者发送消息

消费者配置文件监听死信队列

测试结果
  1. 发送到正常队列,正常队列消息过期后,消息自动进入到死信队列,死信队列有1条消息

    image-20210205114934864

  2. 正常队列有十条消息,死信队列也有十条,正常队列消息过期后,死信队列有20条消息

image-20210205134125290

image-20210205134141849

  1. 正常队列有1条消息,然后消费端拒绝接收之后,死信队列就有1条消息

image-20210205134753666

image-20210205135051824

小结

  1. 死信交换机、死信队列 和 普通的没有区别

  2. 当消息成为死信后,如果该队列绑定了死信交换机,则消息会被死信交换机重新路由到死信队列

  3. 消息成为死信的三种情况:

    1. 队列消息长度到达限制;

    2. 消费者拒接消费消息,并且不重回队列;

    3. 原队列存在消息过期设置,消息到达超时时间未被消费;

6.延迟队列☆

延迟队列,即消息进入队列后不会立即被消费,只有到达指定时间后,才会被消费。

  • 需求:

    1. 下单后,30分钟未支付,取消订单,回滚库存。
    2. 新用户注册成功7天后,发送短信问候。
  • 实现方式:

    1. 定时器
    2. 延迟队列

image-20210204102742922

很可惜,在RabbitMQ中并未提供延迟队列功能。但是可以使用:TTL+DLX 实现延迟队列的效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

代码演示

生产者配置文件

       1. 定义死信交换机(order_exchange_dlx)和队列(order_queue_dlx)2. 定义正常交换机(order_exchange)和队列(order_queue)3. 绑定,设置正常队列过期时间为30分钟

生产者发送消息

消息发送结果:10秒内位于正常队列中,十秒之后进入死信队列

消费端配置

消费端接收消息

消息接收结果:启动消费端之后,私信队列中的消息都被消费端手动ACK了

小结

  • 延迟队列,即消息进入队列后不会立即被消费,只有到达指定时间后,才会被消费。
  • 在RabbitMQ中并未提供延迟队列功能。但是可以使用:TTL+DLX 实现延迟队列的效果。

7.日志与监控(了解)

RabbitMQ日志

RabbitMQ默认日志存放路径: /var/log/rabbitmq/rabbit@xxx.log

日志包含了RabbitMQ的版本号、Erlang的版本号、RabbitMQ服务节点名称、cookie的hash值、RabbitMQ配置文件地址、内存限制、磁盘限制、默认账户guest的创建以及权限配置等等。

web管控台监控

rabbitmqctl管理和监控

查看队列
# rabbitmqctl list_queues
查看exchanges
# rabbitmqctl list_exchanges
查看用户
# rabbitmqctl list_users
查看连接
# rabbitmqctl list_connections
查看消费者信息
# rabbitmqctl list_consumers
查看环境变量
# rabbitmqctl environment
查看未被确认的队列
# rabbitmqctl list_queues  name messages_unacknowledged
查看单个队列的内存使用
# rabbitmqctl list_queues name memory
查看准备就绪的队列
# rabbitmqctl list_queues name messages_ready

8.消息追踪

在使用任何消息中间件的过程中,难免会出现某条消息异常丢失的情况。对于RabbitMQ而言,可能是因为生产者或消费者与RabbitMQ断开了连接,而它们与RabbitMQ又采用了不同的确认机制;也有可能是因为交换器与队列之间不同的转发策略;甚至是交换器并没有与任何队列进行绑定,生产者又不感知或者没有采取相应的措施;另外RabbitMQ本身的集群策略也可能导致消息的丢失。这个时候就需要有一个较好的机制跟踪记录消息的投递过程,以此协助开发和运维人员进行问题的定位。

在RabbitMQ中可以使用Firehose和rabbitmq_tracing插件功能来实现消息追踪。

Firehose

firehose的机制是将生产者投递给rabbitmq的消息,rabbitmq投递给消费者的消息按照指定的格式发送到默认的exchange上。这个默认的exchange的名称为amq.rabbitmq.trace,它是一个topic类型的exchange。发送到这个exchange上的消息的routing key为 publish.exchangename 和 deliver.queuename。其中exchangename和queuename为实际exchange和queue的名称,分别对应生产者投递到exchange的消息,和消费者从queue上获取的消息。

注意:打开 trace 会影响消息写入功能,适当打开后请关闭。

rabbitmqctl trace_on:开启Firehose命令

rabbitmqctl trace_off:关闭Firehose命令

rabbitmq_tracing

rabbitmq_tracing和Firehose在实现上如出一辙,只不过rabbitmq_tracing的方式比Firehose多了一层GUI的包装,更容易使用和管理。

启用插件:rabbitmq-plugins enable rabbitmq_tracing


RabbitMQ应用问题☆

1.消息可靠性保障

需求:100%确保消息发送成功

消息补偿机制

image-20210204105903097

流程:producer–>1业务数据入库–>

  • 2发送消息到Q1–>consumer监听消息Q1、消费Q1、操作consumerDB,consumer发送确认消息到Q2–>回调检查服务监听确认消息Q2、消费Q2、将消息写入MDB数据库
  • 3发送延迟消息到Q3–>回调检查服务–>6监听延迟消息Q3–>消费Q3–>比对MDB中是否有该消息,
    • 有该消息不做处理,
    • 没有该消息–>8调用producer,重新发送消息,如此循环下去

定时检查服务检查数据库数据,重新调用producer发送消息

2.消息幂等性处理

幂等性指一次和多次请求某一个资源,对于资源本身应该具有同样的结果。也就是说,其任意多次执行对资源本身所产生的影响均与一次执行的影响相同。

在MQ中指,消费多条相同的消息的结果与消费该消息一次的结果相同。

乐观锁解决方案

image-20210204110033863


RabbitMQ集群搭建

摘要:实际生产应用中都会采用消息队列的集群方案,如果选择RabbitMQ那么有必要了解下它的集群方案原理

一般来说,如果只是为了学习RabbitMQ或者验证业务工程的正确性那么在本地环境或者测试环境上使用其单实例部署就可以了,但是出于MQ中间件本身的可靠性、并发性、吞吐量和消息堆积能力等问题的考虑,在生产环境上一般都会考虑使用RabbitMQ的集群方案。

3.1 集群方案的原理

RabbitMQ这款消息队列中间件产品本身是基于Erlang编写,Erlang语言天生具备分布式特性(通过同步Erlang集群各节点的magic cookie来实现)。因此,RabbitMQ天然支持Clustering。这使得RabbitMQ本身不需要像ActiveMQ、Kafka那样通过ZooKeeper分别来实现HA方案和保存集群的元数据。集群是保证可靠性的一种方式,同时可以通过水平扩展以达到增加消息吞吐量能力的目的。

1565245219265

3.2 单机多实例部署

由于某些因素的限制,有时候你不得不在一台机器上去搭建一个rabbitmq集群,这个有点类似zookeeper的单机版。真实生成环境还是要配成多机集群的。有关怎么配置多机集群的可以参考其他的资料,这里主要论述如何在单机中配置多个rabbitmq实例。

主要参考官方文档:https://www.rabbitmq.com/clustering.html

首先确保RabbitMQ运行没有问题

[root@super ~]# rabbitmqctl status
Status of node rabbit@super ...
[{pid,10232},{running_applications,[{rabbitmq_management,"RabbitMQ Management Console","3.6.5"},{rabbitmq_web_dispatch,"RabbitMQ Web Dispatcher","3.6.5"},{webmachine,"webmachine","1.10.3"},{mochiweb,"MochiMedia Web Server","2.13.1"},{rabbitmq_management_agent,"RabbitMQ Management Agent","3.6.5"},{rabbit,"RabbitMQ","3.6.5"},{os_mon,"CPO  CXC 138 46","2.4"},{syntax_tools,"Syntax tools","1.7"},{inets,"INETS  CXC 138 49","6.2"},{amqp_client,"RabbitMQ AMQP Client","3.6.5"},{rabbit_common,[],"3.6.5"},{ssl,"Erlang/OTP SSL application","7.3"},{public_key,"Public key infrastructure","1.1.1"},{asn1,"The Erlang ASN1 compiler version 4.0.2","4.0.2"},{ranch,"Socket acceptor pool for TCP protocols.","1.2.1"},{mnesia,"MNESIA  CXC 138 12","4.13.3"},{compiler,"ERTS  CXC 138 10","6.0.3"},{crypto,"CRYPTO","3.6.3"},{xmerl,"XML parser","1.3.10"},{sasl,"SASL  CXC 138 11","2.7"},{stdlib,"ERTS  CXC 138 10","2.8"},{kernel,"ERTS  CXC 138 10","4.2"}]},{os,{unix,linux}},{erlang_version,"Erlang/OTP 18 [erts-7.3] [source] [64-bit] [async-threads:64] [hipe] [kernel-poll:true]\n"},{memory,[{total,56066752},{connection_readers,0},{connection_writers,0},{connection_channels,0},{connection_other,2680},{queue_procs,268248},{queue_slave_procs,0},{plugins,1131936},{other_proc,18144280},{mnesia,125304},{mgmt_db,921312},{msg_index,69440},{other_ets,1413664},{binary,755736},{code,27824046},{atom,1000601},{other_system,4409505}]},{alarms,[]},{listeners,[{clustering,25672,"::"},{amqp,5672,"::"}]},{vm_memory_high_watermark,0.4},{vm_memory_limit,411294105},{disk_free_limit,50000000},{disk_free,13270233088},{file_descriptors,[{total_limit,924},{total_used,6},{sockets_limit,829},{sockets_used,0}]},{processes,[{limit,1048576},{used,262}]},{run_queue,0},{uptime,43651},{kernel,{net_ticktime,60}}]

停止rabbitmq服务

[root@super sbin]# service rabbitmq-server stop
Stopping rabbitmq-server: rabbitmq-server.

启动第一个节点:

[root@super sbin]# RABBITMQ_NODE_PORT=5673 RABBITMQ_NODENAME=rabbit1 rabbitmq-server startRabbitMQ 3.6.5. Copyright (C) 2007-2016 Pivotal Software, Inc.##  ##      Licensed under the MPL.  See http://www.rabbitmq.com/##  ############  Logs: /var/log/rabbitmq/rabbit1.log######  ##        /var/log/rabbitmq/rabbit1-sasl.log##########Starting broker...completed with 6 plugins.

启动第二个节点:

web管理插件端口占用,所以还要指定其web插件占用的端口号。

[root@super ~]# RABBITMQ_NODE_PORT=5674 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15674}]" RABBITMQ_NODENAME=rabbit2 rabbitmq-server startRabbitMQ 3.6.5. Copyright (C) 2007-2016 Pivotal Software, Inc.##  ##      Licensed under the MPL.  See http://www.rabbitmq.com/##  ############  Logs: /var/log/rabbitmq/rabbit2.log######  ##        /var/log/rabbitmq/rabbit2-sasl.log##########Starting broker...completed with 6 plugins.

结束命令:

rabbitmqctl -n rabbit1 stop
rabbitmqctl -n rabbit2 stop

rabbit1操作作为主节点:

[root@super ~]# rabbitmqctl -n rabbit1 stop_app  
Stopping node rabbit1@super ...
[root@super ~]# rabbitmqctl -n rabbit1 reset	 
Resetting node rabbit1@super ...
[root@super ~]# rabbitmqctl -n rabbit1 start_app
Starting node rabbit1@super ...
[root@super ~]# 

rabbit2操作为从节点:

[root@super ~]# rabbitmqctl -n rabbit2 stop_app
Stopping node rabbit2@super ...
[root@super ~]# rabbitmqctl -n rabbit2 reset
Resetting node rabbit2@super ...
[root@super ~]# rabbitmqctl -n rabbit2 join_cluster rabbit1@'super' ###''内是主机名换成自己的
Clustering node rabbit2@super with rabbit1@super ...
[root@super ~]# rabbitmqctl -n rabbit2 start_app
Starting node rabbit2@super ...

查看集群状态:

[root@super ~]# rabbitmqctl cluster_status -n rabbit1
Cluster status of node rabbit1@super ...
[{nodes,[{disc,[rabbit1@super,rabbit2@super]}]},{running_nodes,[rabbit2@super,rabbit1@super]},{cluster_name,<<"rabbit1@super">>},{partitions,[]},{alarms,[{rabbit2@super,[]},{rabbit1@super,[]}]}]

web监控:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.3 集群管理

rabbitmqctl join_cluster {cluster_node} [–ram]
将节点加入指定集群中。在这个命令执行前需要停止RabbitMQ应用并重置节点。

rabbitmqctl cluster_status
显示集群的状态。

rabbitmqctl change_cluster_node_type {disc|ram}
修改集群节点的类型。在这个命令执行前需要停止RabbitMQ应用。

rabbitmqctl forget_cluster_node [–offline]
将节点从集群中删除,允许离线执行。

rabbitmqctl update_cluster_nodes {clusternode}

在集群中的节点应用启动前咨询clusternode节点的最新信息,并更新相应的集群信息。这个和join_cluster不同,它不加入集群。考虑这样一种情况,节点A和节点B都在集群中,当节点A离线了,节点C又和节点B组成了一个集群,然后节点B又离开了集群,当A醒来的时候,它会尝试联系节点B,但是这样会失败,因为节点B已经不在集群中了。

rabbitmqctl cancel_sync_queue [-p vhost] {queue}
取消队列queue同步镜像的操作。

rabbitmqctl set_cluster_name {name}
设置集群名称。集群名称在客户端连接时会通报给客户端。Federation和Shovel插件也会有用到集群名称的地方。集群名称默认是集群中第一个节点的名称,通过这个命令可以重新设置。

3.4 RabbitMQ镜像集群配置

上面已经完成RabbitMQ默认集群模式,但并不保证队列的高可用性,尽管交换机、绑定这些可以复制到集群里的任何一个节点,但是队列内容不会复制。虽然该模式解决一项目组节点压力,但队列节点宕机直接导致该队列无法应用,只能等待重启,所以要想在队列节点宕机或故障也能正常应用,就要复制队列内容到集群里的每个节点,必须要创建镜像队列。

镜像队列是基于普通的集群模式的,然后再添加一些策略,所以你还是得先配置普通集群,然后才能设置镜像队列,我们就以上面的集群接着做。

设置的镜像队列可以通过开启的网页的管理端Admin->Policies,也可以通过命令。

rabbitmqctl set_policy my_ha “^” ‘{“ha-mode”:“all”}’

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • Name:策略名称
  • Pattern:匹配的规则,如果是匹配所有的队列,是^.
  • Definition:使用ha-mode模式中的all,也就是同步所有匹配的队列。问号链接帮助文档。

3.5 负载均衡-HAProxy

HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案,包括Twitter,Reddit,StackOverflow,GitHub在内的多家知名互联网公司在使用。HAProxy实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。

3.5.1 安装HAProxy

//下载依赖包
yum install gcc vim wget
//上传haproxy源码包
//解压
tar -zxvf haproxy-1.6.5.tar.gz -C /usr/local
//进入目录、进行编译、安装
cd /usr/local/haproxy-1.6.5
make TARGET=linux31 PREFIX=/usr/local/haproxy
make install PREFIX=/usr/local/haproxy
mkdir /etc/haproxy
//赋权
groupadd -r -g 149 haproxy
useradd -g haproxy -r -s /sbin/nologin -u 149 haproxy
//创建haproxy配置文件
mkdir /etc/haproxy
vim /etc/haproxy/haproxy.cfg

3.5.2 配置HAProxy

配置文件路径:/etc/haproxy/haproxy.cfg

#logging options
globallog 127.0.0.1 local0 infomaxconn 5120chroot /usr/local/haproxyuid 99gid 99daemonquietnbproc 20pidfile /var/run/haproxy.piddefaultslog globalmode tcpoption tcplogoption dontlognullretries 3option redispatchmaxconn 2000contimeout 5sclitimeout 60ssrvtimeout 15s	
#front-end IP for consumers and producterslisten rabbitmq_clusterbind 0.0.0.0:5672mode tcp#balance url_param userid#balance url_param session_id check_post 64#balance hdr(User-Agent)#balance hdr(host)#balance hdr(Host) use_domain_only#balance rdp-cookie#balance leastconn#balance source //ipbalance roundrobinserver node1 127.0.0.1:5673 check inter 5000 rise 2 fall 2server node2 127.0.0.1:5674 check inter 5000 rise 2 fall 2listen statsbind 172.16.98.133:8100mode httpoption httplogstats enablestats uri /rabbitmq-statsstats refresh 5s

启动HAproxy负载

/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg
//查看haproxy进程状态
ps -ef | grep haproxy访问如下地址对mq节点进行监控
http://172.16.98.133:8100/rabbitmq-stats

代码中访问mq集群地址,则变为访问haproxy地址:5672


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/238308.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【即插即用篇】YOLOv8改进实战 | 引入 Involution(内卷),用于视觉识别的新一代神经网络!涨点神器!

YOLOv8专栏导航:点击此处跳转 前言 YOLOv8 是由 YOLOv5 的发布者 Ultralytics 发布的最新版本的 YOLO。它可用于对象检测、分割、分类任务以及大型数据集的学习,并且可以在包括 CPU 和 GPU 在内的各种硬件上执行。 YOLOv8是一种尖端的、最先进的 (SOTA) 模型,它建立在以前成…

CSS 网页制作-学成在线

1、 准备工作 1.1 项目目录 网站根目录是指存放网站的第一层文件夹&#xff0c;内部包含当前网站的所有素材&#xff0c;包含HTML、CSS、图片、JavaScript等等。 1.2 版心效果 可以发现都是呈现版心居中的效果&#xff0c;但是每次都写一次太麻烦了&#xff0c;可以把版心居中…

python可以做小程序研发嘛,python能做微信小程序吗

大家好&#xff0c;给大家分享一下python可以做微信小程序开发吗&#xff0c;很多人还不知道这一点。下面详细解释一下。现在让我们来看看&#xff01; 大家好&#xff0c;给大家分享一下用python编写一个小程序&#xff0c;很多人还不知道这一点。下面详细解释一下用python代码…

java设计模式学习之【命令模式】

文章目录 引言命令模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用股票示例代码地址 引言 想象一下&#xff0c;你在一个忙碌的厨房里&#xff0c;厨师们正忙于准备各种菜肴。每当服务员带来一个新订单时&#xff0c;他们不会直接对厨师说需要做什么菜。相…

flutter开发实战-设置bottomNavigationBar中间按钮悬浮效果

flutter开发实战-设置bottomNavigationBar中间按钮悬浮的效果 在使用tabbar时候&#xff0c;可以使用bottomNavigationBar来设置中间凸起的按钮&#xff0c;如下 一、效果图 中间按钮凸起的效果图如下 二、实现代码 我们使用BottomAppBar 一个容器&#xff0c;通常与[Sscaf…

2023年PMP证书的含金量有多高?对于企业来说有多大的价值?

PMP含金量更多的是“敲门砖”作用&#xff0c;公司招聘的门槛 当然现在PMP管理模式也很热门&#xff0c;各大企业都有引进改良应用在公司的项目上&#xff0c;之前在校友群里面大家在讨论PMP 的作用也有说到这一点&#xff0c;给大家看看吧。 至于为什么PMP认证从国外引进大陆…

⭐Unity 读取本地图片再区域裁剪

现在需求是将本地的图片读取之后再区域截图成新的图片 话不多说直接上代码 using UnityEngine; using System.IO;public class LocalRegionCapture : MonoBehaviour {public string fullScreenImagePath "Assets/SavedImages/fullScreenScreenshot.png";public str…

【PyQt学习篇 · ⑭】:QTableView的使用

文章目录 QTableView的使用示例 QTableView的使用 QTableView 是 PyQt 中用于显示表格数据的窗口部件&#xff0c;它提供了一个灵活的方式来显示和编辑数据。下面是一些关于 QTableView 的使用的具体信息&#xff1a; 创建 QTableView 对象&#xff1a; from PyQt5.QtWidgets …

python/C 生成beta分布的随机数

python/C 生成beta分布的随机数 文章目录 python/C 生成beta分布的随机数前言一、beta分布理论知识二、python 生成服从beta分布的随机数三、C语言生成服从beta分布的随机数 前言 想把一个算法用C语言实现&#xff0c;其中涉及到了beta分布取随机数&#xff0c;记录一下结果 一…

雀巢困在业绩和质量里

撰稿|行星 来源|贝多财经 雀巢集团CEO马克施奈德曾在2023年中报中表示&#xff0c;后疫情时代居家消费已恢复常态&#xff0c;从而消除了制约雀巢部分品类增长的阻碍。 但就雀巢前三季度财报而言&#xff0c;该公司在全球及大中华区的销售额均有所下降&#xff0c;有机增长主…

如何使用Java的GeoTools地理库计算WGS84坐标下的两个经纬度之间得距离

介绍 本章讲解如何使用Java的GeoTools地理库计算基于WGS84坐标的两点之间的距离。适用于后台服务的距离计算。 GeoTools介绍 GeoTools是开源的Java地理信息计算库。GeoServer地图引擎就是基于GeoTools库构建得地图服务,可以说非常强大。 官网地址:https://docs.geotools.o…

Baumer工业相机堡盟工业相机如何通过BGAPI SDK实现Raw格式的图像保存(C#)

Baumer工业相机堡盟工业相机如何通过BGAPI SDK实现Raw格式的图像保存&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机通过SDK实现Raw格式的图像保存的技术背景通过SDK获取相机信息的代码分析Baumer工业相机回调函数里保存原始图像数据Baumer保存Raw图像格式重要核心代…

【JS】按照a>b>c>d>e>f的优先级,将a,b,c,d,e,f元素进行筛选,选出三个不为空字符的元素进行字符拼接

设计思路&#xff1a; 1、定义一个数组&#xff0c;把元素按照优先级进行排序&#xff1b; 2、 使用 filter() 方法过滤掉空字符串元素&#xff0c;得到一个新的数组; 3、在排序函数中&#xff0c;循环数组&#xff0c;使用 indexOf() 方法获取元素 a 和 b 在数组中的索引&a…

描述一个bug及定义bug的级别

&#xff08;一&#xff09;描述一个bug 描述一个bug&#xff0c;需要以下几个因素&#xff1a; 故障标题、故障发现的版本、故障类别&#xff08;功能/兼容/界面&#xff09;、故障优先级、故障描述&#xff08;测试环境、测试步骤、预期结果、实际结果&#xff09;。 举个例…

MySQL,使用Union组合查询

1、基本使用 Union可将多条select语句组合成一个结果集&#xff0c;常见的使用场景有2种&#xff1a; 在单个查询中&#xff0c;从不同的表返回类似结构的数据&#xff1b;对单个表执行多个查询&#xff0c;按单个查询返回数据。 例&#xff1a;检索出所有价格<50的产品&…

批发订货系统小程序怎么推广 四个方案高效获客

微信小程序基于强社交属性&#xff0c;天然自带引流特性&#xff0c;但毕竟小程序也只是一个工具&#xff0c;想要快速获客&#xff0c;还是需要商家主动采取一些措施的。下面分享是个方法&#xff0c;尤其是最后一个&#xff0c;是十分凑效的。大家点个关注点个赞&#xff0c;…

Android 权限申请

在Android中&#xff0c;从Android 6.0&#xff08;API级别23&#xff09;开始&#xff0c;应用在运行时需要动态申请权限。以下是一些步骤来动态申请权限&#xff1a; 在应用的清单文件&#xff08;AndroidManifest.xml&#xff09;中声明需要的权限。例如&#xff0c;如果应…

从零开发短视频电商 在AWS上用SageMaker部署自定义模型

文章目录 简介使用model.tar.gz1.从huggingface上下载模型2.自定义代码3.打包为tar 文件4.上传model.tar.gz到S35.部署推理 使用hub1.在sagemaker上新建个jupyterlab2.上传官方示例ipynb文件3.指定HF_MODEL_ID和HF_TASK进行部署和推理 inference.py官方示例 简介 原始链接&…

解决win10下强制设置web浏览器为microsoft edge的方法

目录 问题场景实现方法禁止edge默认选项设置默认浏览器 反思 问题场景 因为一些特殊的原因&#xff0c;我需要第二个浏览器&#xff0c;我的第一个浏览器是google的chrome浏览器&#xff0c;所以我选择的是windows的默认浏览器&#xff0c;就是microsoft edge浏览器&#xff0…

【Java】Mybatis

MyBatis JavaEE三层框架&#xff1a;表现层、业务层、持久层。 现在开始学习持久层。持久层就是负责与数据库打交道的代码。 框架&#xff1a;就是一个半成品软件。在框架的基础上&#xff0c;可以更加高效地写出代码。 1、MyBatis快速入门 1、准备工作&#xff08;创建sp…