MQ 简介-RabbitMQ
一. MQ 简介
消息队列作为高并发系统的核心组件之一,能够帮助业务系统结构提升开发效率和系统
稳定性,消息队列主要具有以下特点:
- 削峰填谷:主要解决瞬时写压力大于应用服务能力导致消息丢失、系统奔溃等问题
- 系统解耦:解决不同重要程度、不同能力级别系统之间依赖导致一死全死
- 提升性能:当存在一对多调用时,可以发一条消息给消息系统,让消息系统通知相关系统
- 蓄流压测:线上有些链路不好压测,可以通过堆积一定量消息再放开来压测
目前主流的消息队列软件有 RabbitMQ、kafka、ActiveMQ、RocketMQ 等,还有小众的
消息队列软件如 ZeroMQ、Apache Qpid 等。
二. RabbitMQ
2.1 RabbitMQ 简介
RabbitMQ 官网
阿里云消息队列产品
Message Queue 的需求由来已久,在 19 世纪 80 年代金融交易中,美国高盛等公
司采用 Teknekron 公司的产品,当时的 Message queuing 软件叫做(the information
bus(TIB),后来 TIB 被电信和通讯等公司采用,然后路透社收购了 Teknekron 公
司,再然后 IBM 公司开发了 MQSeries,并且微软也开发了 Microsoft Message
Queue(MSMQ),但是这些商业 MQ 供应商的问题是厂商锁定及使用价格高昂,
于是 2001 年,Java Message queuing 试图解决锁定和交互性的问题,但对应用来
说反而更加麻烦了,于是 2004 年,摩根大通和 iMatrix 开始着手 Advanced Message
Queuing Protocol (AMQP)开放标准的开发,2006 年,AMQP 规范发布,2007
年,Rabbit 技术公司基于 AMQP 标准开发的 RabbitMQ 1.0 发布。
路透社:
(Reuters,LSE:RTR,NASDAQ: RTRSY)是世界上最早创办的通讯社之一,也是目前英国最大的
通讯社和西方四大通讯社之一,路透社是世界前三大的多媒体新闻通讯社,提供各类新闻和金融
数据,在128个国家运行。摩根大通集团:
业界称西摩或小摩,总部位于美国纽约,总资产2.5万亿美元,总存款1.5万亿美
元,占美国存款总额的25%,分行6000多家,是美国最大金融服务机构之一。iMatrix:
是一个企业级的JAVA快速开发平台。
RabbitMQ 采用 Erlang 语言开发,Erlang 语言由 Ericson 设计,Erlang 在分布式编
程和故障恢复方面表现出色,电信领域被广泛使用。
2.2 RabbitMQ 组件介绍
-
Broker: 接收和分发消息的应用,RabbitMQ Server 就是 Message Broker
-
Virtual host: 出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚
拟的分组中,类似于网络中的 namespace 概念,当多个不同的用户使用同一个
RabbitMQ server 提供的服务时,可以划分出多个 vhost,每个用户在自己的 vhost
创建 exchange/queue 等。 -
Connection: publisher/consumer 和 broker 之间的 TCP 连接。
-
Channel: 如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候
建立 TCP Connection 的开销将是巨大的,效率也较低。Channel 是在 connection
内部建立的逻辑连接,如果应用程序支持多线程,通常每个 thread 创建单独的
channel 进行通讯,AMQP method 包含了 channel id 帮助客户端和 message broker
识别 channel,所以 channel 之间是完全隔离的。Channel 作为轻量级的 Connection
极大减少了操作系统建立 TCP connection 的开销。 -
Exchange: message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing
key,分发消息到 queue 中去。常用的类型有:direct (point-to-point), topic (publish-
subscribe) and fanout (multicast)。 -
Queue: 消息最终被送到这里等待 consumer 取走。
-
Binding: exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key。
Binding 信息被保存到 exchange 中的查询表中,用于 message 的分发依据。
2.3 RabbitMQ 单机部署
2.3.1 添加主机名解析
RabbitMQ 强制要求安装其的主机名可以解析。
root@rabbit-server-node1:~# vim /etc/hosts
...
192.168.100.160 rabbit-server rabbit-server.suosuoli.cnroot@rabbit-server-node1:~# ping rabbit-server
PING rabbit-server (192.168.100.160) 56(84) bytes of data.
64 bytes from rabbit-server (192.168.100.160): icmp_seq=1 ttl=64 time=0.010 ms
^C
--- rabbit-server ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.010/0.010/0.010/0.000 ms
root@rabbit-server-node1:~# ping rabbit-server.suosuoli.cn
PING rabbit-server (192.168.100.160) 56(84) bytes of data.
64 bytes from rabbit-server (192.168.100.160): icmp_seq=1 ttl=64 time=0.010 ms
64 bytes from rabbit-server (192.168.100.160): icmp_seq=2 ttl=64 time=0.023 ms
^C
--- rabbit-server ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1015ms
rtt min/avg/max/mdev = 0.010/0.016/0.023/0.007 ms
2.3.2 安装 RabbitMQ
快速安装参考
# 使用官方的快速安装例子
root@rabbit-server-node1:~# vim install_rabbit.sh#!/bin/sh## If sudo is not available on the system,
## uncomment the line below to install it
# apt-get install -y sudosudo apt-get update -y## Install prerequisites
sudo apt-get install curl gnupg -y## Install RabbitMQ signing key
curl -fsSL https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc | sudo apt-key add -## Install apt HTTPS transport
sudo apt-get install apt-transport-https## Add Bintray repositories that provision latest RabbitMQ and Erlang 21.x releases
sudo tee /etc/apt/sources.list.d/bintray.rabbitmq.list <<EOF
## Installs the latest Erlang 22.x release.
## Change component to "erlang-21.x" to install the latest 21.x version.
## "bionic" as distribution name should work for any later Ubuntu or Debian release.
## See the release to distribution mapping table in RabbitMQ doc guides to learn more.
deb https://dl.bintray.com/rabbitmq-erlang/debian bionic erlang
deb https://dl.bintray.com/rabbitmq/debian bionic main
EOF## Update package indices
sudo apt-get update -y## Install rabbitmq-server and its dependencies
sudo apt-get install rabbitmq-server -y --fix-missing# 安装
root@rabbit-server-node1:~# bash install_rabbit.sh
...
Created symlink /etc/systemd/system/multi-user.target.wants/rabbitmq-server.service → /lib/systemd/system/rabbitmq-server.service.
Processing triggers for ureadahead (0.100.0-21) ...
Processing triggers for systemd (237-3ubuntu10.24) ...
# 安装OK
2.3.3 启动 RabbitMQ
# 在ubuntu下,会自动启动
root@rabbit-server-node1:~# systemctl status rabbitmq-server
● rabbitmq-server.service - RabbitMQ brokerLoaded: loaded (/lib/systemd/system/rabbitmq-server.service; enabled; vendor preset: enabled)Active: active (running) since Tue 2020-03-24 16:57:51 CST; 5min agoMain PID: 4946 (beam.smp)...
# 开机启动
root@rabbit-server-node1:~# systemctl enable rabbitmq-server
Synchronizing state of rabbitmq-server.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable rabbitmq-serverroot@rabbit-server-node1:~# ps -ef | grep rabbit
rabbitmq 4946 1 0 16:57 ? 00:00:06 /usr/lib/erlang/erts-10.7/bin/beam.smp -W w -A 64 -MBas ageffcbf -MHas ageffcbf -MBlmbcs 512 -MHlmbcs 512 -MMmcs 30 -P 1048576 -t 5000000 -stbt db -zdbbl 128000 -K true -- -root /usr/lib/erlang -progname erl -- -home /var/lib/rabbitmq -- -pa /usr/lib/rabbitmq/lib/rabbitmq_server-3.8.3/ebin -noshell -noinput -s rabbit boot -sname rabbit@rabbit-server-node1 -boot start_sasl -kernel inet_default_connect_options [{nodelay,true}] -sasl errlog_type error -sasl sasl_error_logger false -rabbit lager_log_root "/var/lograbbitmq" -rabbit lager_default_file "/var/log/rabbitmq/rabbit@rabbit-server-node1.log" -rabbit lager_upgrade_file "/var/log/rabbitmq/rabbit@rabbit-server-node1_upgrade.log" -rabbit feature_flags_file "/var/lib/rabbitmq/mnesia/rabbit@rabbit-server-node1-feature_flags" -rabbit enabled_plugins_file "/etc/rabbitmq/enabled_plugins" -rabbit plugins_dir "/usr/lib/rabbitmq/plugins:/usr/lib/rabbitmq/lib/rabbitmq_server-3.8.3/plugins" -rabbit plugins_expand_dir "/var/lib/rabbitmq/mnesia/rabbit@rabbit-server-node1-plugins-expand" -os_mon start_cpu_sup false -os_mon start_disksup false -os_mon start_memsup false -mnesia dir "/var/lib/rabbitmq/mnesia/rabbit@rabbit-server-node1" -ra data_dir "/var/lib/rabbitmq/mnesia/rabbit@rabbit-server-node1/quorum" -kernel inet_dist_listen_min 25672 -kernel inet_dist_listen_max 25672 --
rabbitmq 5041 1 0 16:57 ? 00:00:00 /usr/lib/erlang/erts-10.7/bin/epmd -daemon
rabbitmq 5191 4946 0 16:57 ? 00:00:00 erl_child_setup 32768
rabbitmq 5216 5191 0 16:57 ? 00:00:00 inet_gethost 4
rabbitmq 5217 5216 0 16:57 ? 00:00:00 inet_gethost 4
root 5879 1136 0 17:10 pts/0 00:00:00 grep --color=auto rabbitroot@rabbit-server-node1:~# lsof -i:15672
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
beam.smp 4946 rabbitmq 94u IPv4 43507 0t0 TCP *:15672 (LISTEN)
2.3.4 开启 WEB 管理插件
root@rabbit-server-node1:~# rabbitmq-plugins list
Listing plugins with pattern ".*" ...Configured: E = explicitly enabled; e = implicitly enabled| Status: * = running on rabbit@rabbit-server-node1|/
[ ] rabbitmq_amqp1_0 3.8.3
[ ] rabbitmq_auth_backend_cache 3.8.3
[ ] rabbitmq_auth_backend_http 3.8.3
[ ] rabbitmq_auth_backend_ldap 3.8.3
...
[ ] rabbitmq_management 3.8.3
...root@rabbit-server-node1:~# rabbitmq-plugins enable rabbitmq_management
Enabling plugins on node rabbit@rabbit-server-node1:
rabbitmq_management
The following plugins have been configured:rabbitmq_managementrabbitmq_management_agentrabbitmq_web_dispatch
Applying plugin configuration to rabbit@rabbit-server-node1...
The following plugins have been enabled:rabbitmq_managementrabbitmq_management_agentrabbitmq_web_dispatchstarted 3 plugins.
2.3.5 登录管理界面
rabbitmq 从 3.3.0 开始禁止使用 guest/guest 权限通过除 localhost 外的访问,直
接访问报错如下:
用户名和密码都是:guest
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ybwWX2xJ-1692948000972)(png/2020-03-24-17-14-00.png)]
提示:用户只能在安装 rabbitmq 的服务器登录。
修改配置文件,允许从其他主机登录管理界面;
root@rabbit-server-node1:~# vim /usr/lib/rabbitmq/lib/rabbitmq_server-3.8.3/ebin/rabbit.app
...39 {loopback_users, []}, # 去掉double尖括号及其内容
...
root@rabbit-server-node1:~# systemctl restart rabbitmq-server.service
OK
2.4 RabbitMQ 集群部署
RabbitMQ 集群工作模式有两种:
-
普通模式:创建好 RabbitMQ 之后的默认模式。
普通集群模式:queue 创建之后,如果没有其它 policy,消息实体只存在于其中
一个节点,A、B 两个 Rabbitmq 节点仅有相同的元数据,即队列结构,但队列的
数据仅保存有一份,即在创建该队列的 rabbitmq 节点(A 节点)上,当消息进入
A 节点的 Queue 中后,consumer 从 B 节点拉取时,RabbitMQ 会临时在 A、B
间进行消息传输,把 A 中的消息实体取出并经过 B 发送给 consumer,所以
consumer 可以连接每一个节点,从中取消息,该模式存在一个问题就是当 A 节点
故障后,B 节点无法取到 A 节点中还未消费的消息实体。 -
镜像模式:把需要的队列做成镜像队列。
镜像集群模式:把需要的队列做成镜像队列,存在于多个节点,属于 RabbitMQ 的
HA 方案(镜像模式是在普通模式的基础上,增加一些镜像策略)该模式解决了上述
问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不
是在 consumer 取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统
性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会
被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用,一个队列想
做成镜像队列,需要先设置 policy,然后客户端创建队列的时候,rabbitmq 集群
根据“队列名称”自动设置是普通集群模式或镜像队列。 -
集群中有两种节点类型:
- 内存节点:只将数据保存到内存
- 磁盘节点:保存数据到内存和磁盘。
内存节点虽然不写入磁盘,但是它执行比磁盘节点要好,集群中,只需要一个
磁盘节点来保存数据就足够了如果集群中只有内存节点,那么不能全部停止它
们,否则所有数据消息在服务器全部停机之后都会丢失。
-
推荐的架构设计
在一个 rabbitmq 集群里,有 3 台或以上机器,其中 1 台使用磁盘模式,其它节
点使用内存模式,内存节点访问速度更快,由于磁盘 IO 相对较慢,因此可作
为数据备份使用
2.4.1 环境
主机列表:
主机名 | IP |
---|---|
rabbit-server-node1 | 192.168.100.160 |
rabbit-server-node2 | 192.168.100.162 |
rabbit-server-node3 | 192.168.100.164 |
主机域名解析:
root@rabbit-server-node1:~# vim /etc/hosts
root@rabbit-server-node1:~# cat /etc/hosts
192.168.100.160 rabbit-server-node1 rabbit-server1.suosuoli.cn
192.168.100.162 rabbit-server-node1 rabbit-server2.suosuoli.cn
192.168.100.164 rabbit-server-node1 rabbit-server3.suosuoli.cn# 分发到其它主机
root@rabbit-server-node1:~# scp /etc/hosts 192.168.100.162:/etc/
root@192.168.100.162's password:
hosts 100% 189 347.4KB/s 00:00root@rabbit-server-node1:~# scp /etc/hosts 192.168.100.164:/etc/
root@192.168.100.164's password:
hosts 100% 189 347.4KB/s 00:00# 确认一下
root@rabbit-server-node2:~# cat /etc/hosts
192.168.100.160 rabbit-server-node1 rabbit-server1.suosuoli.cn
192.168.100.162 rabbit-server-node1 rabbit-server2.suosuoli.cn
192.168.100.164 rabbit-server-node1 rabbit-server3.suosuoli.cnroot@rabbit-server-node3:~# cat /etc/hosts
192.168.100.160 rabbit-server-node1 rabbit-server1.suosuoli.cn
192.168.100.162 rabbit-server-node1 rabbit-server2.suosuoli.cn
192.168.100.164 rabbit-server-node1 rabbit-server3.suosuoli.cn
2.4.2 在各主机安装 RabbitMQ
# 使用官方的快速安装例子
root@rabbit-server-nodeX:~# vim install_rabbit.sh#!/bin/sh## If sudo is not available on the system,
## uncomment the line below to install it
# apt-get install -y sudosudo apt-get update -y## Install prerequisites
sudo apt-get install curl gnupg -y## Install RabbitMQ signing key
curl -fsSL https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc | sudo apt-key add -## Install apt HTTPS transport
sudo apt-get install apt-transport-https## Add Bintray repositories that provision latest RabbitMQ and Erlang 21.x releases
sudo tee /etc/apt/sources.list.d/bintray.rabbitmq.list <<EOF
## Installs the latest Erlang 22.x release.
## Change component to "erlang-21.x" to install the latest 21.x version.
## "bionic" as distribution name should work for any later Ubuntu or Debian release.
## See the release to distribution mapping table in RabbitMQ doc guides to learn more.
deb https://dl.bintray.com/rabbitmq-erlang/debian bionic erlang
deb https://dl.bintray.com/rabbitmq/debian bionic main
EOF## Update package indices
sudo apt-get update -y## Install rabbitmq-server and its dependencies
sudo apt-get install rabbitmq-server -y --fix-missing# 安装
root@rabbit-server-nodeX:~# bash install_rabbit.sh
...
Created symlink /etc/systemd/system/multi-user.target.wants/rabbitmq-server.service → /lib/systemd/system/rabbitmq-server.service.
Processing triggers for ureadahead (0.100.0-21) ...
Processing triggers for systemd (237-3ubuntu10.24) ...
# 安装OK
2.4.3 启动 RabbitMQ
~# systemctl restart rabbitmq-server
~# systemctl enable rabbitmq-server
2.4.4 创建 RabbitMQ 集群
Rabbitmq 的集群是依赖于 erlang 的集群来工作的,所以必须先构建起 erlang 的
集群环境,而 Erlang 的集群中各节点是通过一个 magic cookie 来实现的,这个
cookie 存放在 /var/lib/rabbitmq/.erlang.cookie
文件中,文件是 400 的
权限,所以必须保证各节点 cookie 一致,否则节点之间就无法通信。
2.4.4.1 停止各服务器 RabbitMQ 并同步 cookie
root@rabbit-server-node1:~# systemctl stop rabbitmq-server
root@rabbit-server-node2:~# systemctl stop rabbitmq-server
root@rabbit-server-node3:~# systemctl stop rabbitmq-serverroot@rabbit-server-node1:~# scp /var/lib/rabbitmq/.erlang.cookie rabbit-server-node2:/var/lib/rabbitmq/.erlang.cookie
root@rabbit-server-node2's password:
.erlang.cookie 100% 20 42.4KB/s 00:00root@rabbit-server-node1:~# scp /var/lib/rabbitmq/.erlang.cookie rabbit-server-node3:/var/lib/rabbitmq/.erlang.cookie
root@rabbit-server-node3's password:
.erlang.cookie 100% 20 42.4KB/s 00:00
2.4.4.2 启动各服务器 RabbitMQ
root@rabbit-server-node1:~# systemctl start rabbitmq-server
root@rabbit-server-node2:~# systemctl start rabbitmq-server
root@rabbit-server-node3:~# systemctl start rabbitmq-server
2.4.4.3 创建集群
将 rabbit-server-node1 作为内存节点加入 rabbit-server-node3 成为集群,
执行以下命令:
# 停止app
root@rabbit-server-node1:~# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbit-server-node1 ...
# 清除元数据
root@rabbit-server-node1:~# rabbitmqctl reset
Resetting node rabbit@rabbit-server-node1 ...
# 加入集群,以node3为集群目标
root@rabbit-server-node1:~# rabbitmqctl join_cluster rabbit@rabbit-server-node3 --ram
Clustering node rabbit@rabbit-server-node1 with rabbit@rabbit-server-node3
# 启动app
root@rabbit-server-node1:~# rabbitmqctl start_app
Starting node rabbit@rabbit-server-node1 ...completed with 3 plugins.
将 rabbit-server-node2 作为内存节点加入 rabbit-server-node3 成为集群,
执行以下命令:
root@rabbit-server-node2:~# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbit-server-node2 ...
root@rabbit-server-node2:~# rabbitmqctl reset
Resetting node rabbit@rabbit-server-node2 ...
root@rabbit-server-node2:~# rabbitmqctl join_cluster rabbit@rabbit-server-node3 --ram
Clustering node rabbit@rabbit-server-node2 with rabbit@rabbit-server-node3
root@rabbit-server-node2:~# rabbitmqctl start_app
Starting node rabbit@rabbit-server-node2 ...completed with 3 plugins.
2.4.4.4 将集群设置为镜像模式
在 node1 或者 node2 执行下面的命令:
root@rabbit-server-node2:~# rabbitmqctl set_policy ha-all "#" '{"ha-mode":"all"}'
Setting policy "ha-all" for pattern "#" to "{"ha-mode":"all"}" with priority "0" for vhost "/" ...
2.4.4.5 验证集群状态
root@rabbit-server-node2:~# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit-server-node2 ...
BasicsCluster name: rabbit@rabbit-server-node3Disk Nodes
# 磁盘节点:集群中至少有一个节点是磁盘节点用于数据持久化
rabbit@rabbit-server-node3RAM Nodes
# 内存节点
rabbit@rabbit-server-node1
rabbit@rabbit-server-node2Running Nodes
# 正在运行的节点
rabbit@rabbit-server-node1
rabbit@rabbit-server-node2
rabbit@rabbit-server-node3Versions
# 软件版本
rabbit@rabbit-server-node1: RabbitMQ 3.8.3 on Erlang 22.3
rabbit@rabbit-server-node2: RabbitMQ 3.8.3 on Erlang 22.3
rabbit@rabbit-server-node3: RabbitMQ 3.8.3 on Erlang 22.3Alarms(none)Network Partitions(none)ListenersNode: rabbit@rabbit-server-node1, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@rabbit-server-node1, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@rabbit-server-node1, interface: [::], port: 15672, protocol: http, purpose: HTTP API
Node: rabbit@rabbit-server-node2, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@rabbit-server-node2, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@rabbit-server-node2, interface: [::], port: 15672, protocol: http, purpose: HTTP API
Node: rabbit@rabbit-server-node3, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@rabbit-server-node3, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@rabbit-server-node3, interface: [::], port: 15672, protocol: http, purpose: HTTP APIFeature flagsFlag: drop_unroutable_metric, state: enabled
Flag: empty_basic_get_metric, state: enabled
Flag: implicit_default_bindings, state: enabled
Flag: quorum_queue, state: enabled
Flag: virtual_host_metadata, state: enabled
2.4.5 WEB 界面查看集群
各个服务器启用 web 管理界面,不启用 web 插件的 rabbitmq 服务器,会在 web 节点提示节点
统计信息不可用(Node statistics not available)
root@rabbit-server-node2:~# rabbitmq-plugins enable rabbitmq_management
root@rabbit-server-node3:~# rabbitmq-plugins enable rabbitmq_management
2.5 RabbitMQ 常用命令
# 新建vhost
root@rabbit-server-node1:~# rabbitmqctl add_vhost stevenux
Adding vhost "stevenux" ...# 列出vhost
root@rabbit-server-node1:~# rabbitmqctl list_vhosts
Listing vhosts ...
name
/
stevenux# 列出队列
root@rabbit-server-node1:~# rabbitmqctl list_queues
Timeout: 60.0 seconds ...
Listing queues for vhost / ...# 删除vhost
root@rabbit-server-node1:~# rabbitmqctl delete_vhost stevenux
Deleting vhost "stevenux" ...# 新建用户
root@rabbit-server-node1:~# rabbitmqctl add_user stevenux stevenux
Adding user "stevenux" ...# 改用户密码
root@rabbit-server-node1:~# rabbitmqctl change_password stevenux 1233211234567
Changing password for user "stevenux" ...root@rabbit-server-node1:~# rabbitmqctl add_vhost stevenux
Adding vhost "stevenux" ...# 设置stevenux用户对vhost stevenux有读写权限
root@rabbit-server-node1:~# rabbitmqctl set_permissions -p stevenux stevenux ".*" ".*" ".*"Setting permissions for user "stevenux" in vhost "stevenux" ...
三. 使用 python 与操作 RabbitMQ
publisher
import pika
import jsoncredentials = pika.PlainCredentials('stevenux', '1233211234567')
connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.100.160',port=5672,virtual_host='stevenux',credentials=credentials))
channel = connection.channel()
result = channel.queue_declare(queue='python-test')for i in range(10):message = json.dumps({'OrderId': "1000%s" % i})channel.basic_publish(exchange='',routing_key='python-test',body=message)print(message)connection.close()
consumer
import pika
import timecredentials = pika.PlainCredentials('stevenux', '1233211234567')
connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.100.160',port=5672,virtual_host='stevenux',credentials=credentials))
channel = connection.channel()
channel.queue_declare(queue='python-test', durable=False)def callback(ch, method, properties, body):ch.basic_ack(delivery_tag=method.delivery_tag)print(body.decode())channel.basic_consume('python-test', callback)
channel.start_consuming()
相关文章:
MQ 简介-RabbitMQ
一. MQ 简介 消息队列作为高并发系统的核心组件之一,能够帮助业务系统结构提升开发效率和系统 稳定性,消息队列主要具有以下特点: 削峰填谷:主要解决瞬时写压力大于应用服务能力导致消息丢失、系统奔溃等问题系统解耦:解决不同重要程度、不…...
强化学习(2)
强化学习(1) 1.多智能体深度强化学习重要性采样 多智能体深度强化学习(Multi-Agent Deep Reinforcement Learning,MADRL)是指在多智能体环境下使用深度强化学习算法进行协同学习。重要性采样(Importance Sampling)是…...

Visual Studio 2022的MFC框架——theApp全局对象
我是荔园微风,作为一名在IT界整整25年的老兵,今天我们来重新审视一下Visual Studio 2022下开发工具的MFC框架知识。 MFC中的WinMain函数是如何与MFC程序中的各个类组织在一起的呢?MFC程序中的类是如何与WinMain函数关联起来的呢?…...

SpringBoot Cache
一、基本概念 Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。 Spring Cache 提供了一层抽象,底层可以切换不同的缓存实现,例如: • EHCache • Caffeine …...

vue 简单实验 自定义组件 component
1.代码 <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"components-demo"><button-counter></button-counter> </div> <script> // 创建一个Vue 应用 const ap…...

C++ 改善程序的具体做法 学习笔记
1、尽量用const enum inline替换#define 因为#define是做预处理操作,编译器从未看见该常量,编译器刚开始编译,它就被预处理器移走了,而#define的本质就是做替换,它可能从来未进入记号表 解决方法是用常量替换宏 语言…...

Unity 之 GameObject.Find()在场景中查找指定名称的游戏对象
文章目录 GameObject.Find 是 Unity 中的一个函数,用于在场景中查找指定名称的游戏对象。这个函数的主要作用是根据游戏对象的名称来查找并返回一个引用,使您能够在代码中操作该对象。以下是有关 GameObject.Find 的详细介绍: 函数签名&…...

flink on yarn with kerberos 边缘提交
flink on yarn 带kerberos 远程提交 实现 flink kerberos 配置 先使用ugi进行一次认证正常提交 import com.google.common.io.Files; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.apache.flink.client.cli.CliFrontend; import o…...

NodeJS的简介以及下载和安装
本章节会带大家下载并安装NodeJs 以及简单的入门,配有超详细的图片,一步步带大家进行下载与安装 NodeJs简介关于前端与后端Node是什么?为什么要学习NodeNodeJS的优点: NodeJS的下载与安装NodeJS的下载: NodeJS的快速入…...
量化面试-概率题
文章目录 一、题目1.糖果罐(绿皮书79页)2 折木棍(绿皮书89页)3 第一张ACE(绿皮书95页)4 n个均匀分布之和(绿皮书95页) 二、答案1. 糖果罐2 折木棍3 第一张ACE4 n个均匀分布之和 一、…...
【spark】java类在spark中的传递,scala object在spark中的传递
记录一个比较典型的问题,先讲一下背景,有这么一个用java写的类 public class JavaClass0 implements Serializable {private static String name;public static JavaClass0 getName(String str) {if (name null) {namestr;}return name;}... }然后在sp…...
php 文字生成图片保存到本地
你可以使用PHP的GD库来生成图片并保存到本地。首先,你需要确保你的PHP环境已经安装了GD库。然后,你可以使用GD库的函数来创建一个画布,并在上面绘制文字。最后,使用imagepng或imagejpeg函数将画布保存为PNG或JPEG格式的图片文件。…...
面试手撕—二叉搜索树及其后序遍历
一、引言 在面试地平线的时候,聊到了二叉搜索树,让手撕二叉搜索树,以下是要求 1、用类模板实现二叉搜索树 2、写一个函数,实现给一个vector数组,转换成二叉搜索树 3、写出二叉搜索树的后序遍历 二、代码实现 #inc…...
Java数据结构面试题以及答案
本专栏记录Java后端开发相关的面试题,欢迎大家阅读专栏的其他文章。 目录 1.B树和B树的区别?B树和B树的优点分别是? 2.排序算法的种类和复杂度 3.HashMap和Hashtable的原理、区别、应用场景 4.ConcurrentHashMap的原理、应用场景 5.Arra…...

Java——它要求用户输入一个整数(实际上是一个字符串),然后计算该整数的平方值,并将结果输出。
这是一个Java程序,它要求用户输入一个整数(实际上是一个字符串),然后计算该整数的平方值,并将结果输出。程序的基本流程如下: 首先,声明并初始化变量data和result,它们的初始值都为…...

【科研论文配图绘制】task6直方图绘制
【科研论文配图绘制】task6直方图绘制 task6 主要掌握直方图的绘制技巧,了解直方图含义,清楚统计指标的添加方式 1.直方图 直方图是一种用于表示数据分布和离散情况的统计图形,它的外观和柱形图相近,但它所 表达的含义和柱形图…...

Leetcode刷题:395. 至少有 K 个重复字符的最长子串、823. 带因子的二叉树
Leetcode刷题:395. 至少有 K 个重复字符的最长子串、823. 带因子的二叉树 1. 395. 至少有 K 个重复字符的最长子串算法思路参考代码和运行结果 2. 823. 带因子的二叉树算法思路参考代码和运行结果 1. 395. 至少有 K 个重复字符的最长子串 题目难度:中等 标签&#…...

java八股文面试[多线程]——Synchronized的底层实现原理
笔试:画出Synchronized 线程状态流转实现原理图 synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized 翻译为中文的意思是同步,也称之为”同步锁“。 synchronized的作用是保证在同一时刻, 被修饰的代码块或方…...

C#,《小白学程序》第三课:类、类数组与排序
类class把数值与功能巧妙的进行了结合,是编程技术的主要进步。 下面的程序你可以确立 分数 与 姓名 之间关系,并排序。 1 文本格式 /// <summary> /// 同学信息类 /// </summary> public class Classmate { /// <summary> /…...

史上最全AP、mAP详解与代码实现
文章目录 前言一、mAP原理1、mAP概念2、准确率3、精确率4、召回率5、AP: Average Precision 二、mAP0.5与mAP0.5:0.951、mAP0.52、mAP0.5:0.95 三、mAP代码实现1、真实标签json文件格式2、模型预测标签json文件格式3、mAP代码实现4、mAP结果显示 四、模型集成mAP代码1、模型mai…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...

Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能
指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001
qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类,直接把源文件拖进VS的项目里,然后VS卡住十秒,然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分,导致编译的时候找不到了。因…...