RabbitMQ原理架构解析:消息传递的核心机制
文章目录
- 一、RabbitMQ简介
- 1.1、概述
- 1.2、特性
- 二、RabbitMQ原理架构
- 三、RabbitMQ应用场景
- 3.1、简单模式
- 3.2、工作模式
- 3.3、发布订阅
- 3.4、路由模式
- 3.5 主题订阅模式
- 四、同类中间件对比
- 五、RabbitMQ部署
- 5.1、单机部署
- 5.2、集群部署(镜像模式)
- 5.3、K8s部署
- 六、常用命令
- 七、RabbitMQ配置详解
- 八、RabbitMQ优化
- 8.1、加大服务器带宽
- 8.2、加大内存
- 8.3、使用固态硬盘
- 8.4、增加生产者
- 8.5、增加消费者
- 8.6、改网络访问为本地访问
- 8.7、消费端使用长连接
- 8.8、消息不要超过4M
- 九、监控
- 十、常见故障与排查
- 10.1、消费慢
- 10.2、消息丢失
- 10.3、消息重复消费
- 10.4、报错“error in config file “/etc/rabbitmq/rabbitmq.config” (none): no ending found”
- 10.5、生产者发送消息报错
- 10.6、浏览器打开IP地址,无法访问 RabbitMQ(白屏没有结果)
一、RabbitMQ简介
1.1、概述
RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而群集和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。
1.2、特性
可伸缩性:集群服务
消息持久化:从内存持久化消息到硬盘,再从硬盘加载到内存
解决什么问题:
- 进程间的通讯。程序间解耦(耦合)。
- web高并发。来不及进行同步处理。”too many connections”(同步 异步切换)
二、RabbitMQ原理架构
中间的Broker表示RabbitMQ服务,每个Broker里面至少有一个Virtual host虚拟主机,每个虚拟主机中有自己的Exchange交换机、Queue队列以及Exchange交换机与Queue队列之间的绑定关系Binding。producer(生产者)和consumer(消费者)通过与Broker建立Connection来保持连接,然后在Connection的基础上建立若干Channel信道,用来发送与接收消息
名词解释:
- exchange:它指定消息按什么规则,路由到哪个列队 给消息分类
- queue:消息载体,每个消息都会被投递到一个或多个列队里面。
- binding:exchange和queue按照规则绑定
- connections:producer和consumer用TCPconnections链接到rabbitMQ
- channels:TCP中的虚拟链接。(不损耗端口号)
- Routing key 路由关键字(消息路由)
- Send Message 发送消息
- Receive Message 收消息
- Broker 缓存代理
三、RabbitMQ应用场景
3.1、简单模式
做最简单的事情,一个生产者对应一个消费者,RabbitMQ相当于一个消息代理,负责将A的消息转发给B
应用场景:将发送的电子邮件放到消息队列,然后邮件服务在队列中获取邮件并发送给收件人、聊天等
3.2、工作模式
- 一条消息只会被一个消费者接收;
- rabbit采用轮询的方式将消息是平均发送给消费者的;
- 消费者在处理完某条消息后,才会收到下一条消息。
应用场景:对于 任务过重或任务较多情况使用工作队列可以提高任务处理的速度。
3.3、发布订阅
- 每个消费者监听自己的队列。
- 生产者将消息发给broker,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将接收到消息
应用场景:用户通知,当用户充值成功或转账完成系统通知用户,通知方式有短信等多种方法 。比如邮件群发,群聊天,广告等。
3.4、路由模式
- 每个消费者监听自己的队列,并且设置routingkey。
- 生产者将消息发给交换机,由交换机根据routingkey来转发消息到指定的队列。
应用场景:如在商品库存中增加了1台iphone13,iphone13促销活动消费者指定routing key为iphone13,只有此促销活动会接收到消息,其它促销活动不关心也不会消费此routing key的消息
3.5 主题订阅模式
根据主题(Topics)来接收消息,将路由key和某模式进行匹配,此时队列需要绑定在一个模式上,#匹配一个词或多个词,*只匹配一个词。
应用场景:同上,iphone促销活动可以接收主题为iphone的消息,如iphone12、iphone13等
四、同类中间件对比
特性 | ActiveMQ | RabbitMQ | RockerMQ | Kafka |
---|---|---|---|---|
producer-comsumer(生产消费) | 支持 | 支持 | 支持 | 支持 |
pubkish-subscribe(发布订阅) | 支持 | 支持 | 支持 | 支持 |
request-reply(请求应答) | 支持 | 支持 | ||
API完整性 | 高 | 高 | 高 | 高 |
多语言支持 | 支持, JAVA优先 | 无关 | JAVA | 支持, JAVA优先 |
单机吞吐量 | 万级 | 万级 | 万级 | 十万级 |
消息延时 | 毫秒 | 微妙 | 毫秒 | 毫秒 |
可用性 | 高(主从) | 高(主从) | 高(分布式) | 高(分布式) |
消息丢失 | 低 | 低 | 理论上 不会丢失 | 理论上 不会丢失 |
消息重复 | 可控制 | 理论上 会有重复 | ||
文档完整性 | 高 | 高 | 高 | 高 |
提供快速入门 | 有 | 有 | 有 | 有 |
社区活跃度 | 高 | 高 | 中 | 高 |
商业支持 | 无 | 无 | 阿里云 | 无 |
成熟度 | 成熟 | 成熟 | 比较成熟 | 成熟日志领域 |
特点 | 功能齐全,被大量开源项目使用 | 由于Erlang语言开发,性能好 | 各环节分布式设计,多种消费模式 | 可靠性、可扩展、持久性、性能高 |
协议 | OPENWITE、STOP、REST、XMPP、AMQP | AMQP | 自定义(社区提供JMS) | PLAINTEXT、SSL、SASL_PLAINTEXT、SASL_SSL |
持久化 | 内存、文件、 数据库 | 内存、文件 | 磁盘文件 | 磁盘、文件 |
事务 | 支持 | 支持 | 支持 | 支持 |
负载均衡 | 支持 | 支持 | 支持 | 支持 |
管理界面 | 一般 | 好 | 有web console实现 | 好 |
优点 | 成熟的产品,已经在很多项目得到应用。有较多文档,各种协议支持较好,多重语言的成熟客户端 | 由于Erlang语言开发,mq性能好,管理页面丰富,多种语言支持,amqp客户端可用 | 模型简单,接口易用,阿里大规模应用性能好,支持多种消费,开发都较活跃 | 性能卓越、可用性非常高、日志领域比较成熟、功能简单、web界面友好 |
缺点 | 会莫名丢失消息,目前社区对重心版本不是太活跃,5.x维护较少,不适合大规模队列 | 由于Erlang语言开发,难度较大,不支持动态扩容 | 产品文档匮乏,没有在mq核心去实现JMS等接口,对已有系统不能完美兼容 | 消息失败不支持重试、消息顺序可能会导致消息乱序、社区更新较慢 |
五、RabbitMQ部署
5.1、单机部署
5.1.1安装erlang
yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel openssl-devel ncurses-devel
wget https://github.com/erlang/otp/releases/download/OTP-24.0/otp_src_24.0.tar.gz
tar -xzvf /otp_src_24.0.tar.gz
cd /otp_src_24.0
./configure --prefix=/usr/local/erlang --with-ssl --enable-threads --enable-smp-support --enable-kernel-poll --enable-hipe
make && make install
5.1.2安装rabbitmq
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.10.5/rabbitmq-server-3.10.5-1.el8.noarch.rpm
rpm -ivh --nodeps rabbitmq-server-3.10.5-1.el8.noarch.rpm
添加开机启动RabbitMQ服务
chkconfig rabbitmq-server on
启动RabbitMQ服务
rabbitmq-server start
后台启动RabbitMQ服务
rabbitmq-server -detached
停止RabbitMQ服务
rabbitmqctl stop
查看RabbitMQ服务状态
rabbitmqctl status
添加帐号:name 密码:
passwd rabbitmqctl add_user name passwd
赋予其administrator角色
rabbitmqctl set_user_tags name administrator
删除角色
rabbitmqctl delete_user Username
设置权限
rabbitmqctl set_permissions -p / name ".*" ".*" ".*"
查看用户的权限
rabbitmqctl list_user_permissions username
启动成功后,rabbitMQ的相关文件所在位置
- 相关命令 :/usr/lib/rabbitmq/bin/
- 相关的日志:/var/log/rabbitmq/
- 相关的配置 : /etc/rabbitmq/
- 设置的用户权限等元数据信息:/var/lib/rabbitmq/mnesia/
http://ip:15672/尝试访问rabbitmq的web页面
可能会遇到报错情况,Node的错误,大概的意思就是说,hosts中的地址和node中的地址不一样,不匹配导致的。修改hosts文件中的本机的IP地址,hosts中的本机的计算机名称和Node的节点的名称保持一致即可。
5.2、集群部署(镜像模式)
普通模式:普通集群模式,就是将 RabbitMQ 部署到多台服务器上,每个服务器启动一个 RabbitMQ 实例,多个实例之间进行消息通信。
此时我们创建的队列 Queue,它的元数据(主要就是 Queue 的一些配置信息)会在所有的 RabbitMQ 实例中进行同步,但是队列中的消息只会存在于一个 RabbitMQ 实例上,而不会同步到其他队列。
当我们消费消息的时候,如果连接到了另外一个实例,那么那个实例会通过元数据定位到 Queue 所在的位置,然后访问 Queue 所在的实例,拉取数据过来发送给消费者。
这种集群可以提高 RabbitMQ 的消息吞吐能力,但是无法保证高可用,因为一旦一个 RabbitMQ 实例挂了,消息就没法访问了,如果消息队列做了持久化,那么等 RabbitMQ 实例恢复后,就可以继续访问了;如果消息队列没做持久化,那么消息就丢了。
镜像模式:它和普通集群最大的区别在于 Queue 数据和原数据不再是单独存储在一台机器上,而是同时存储在多台机器上。也就是说每个 RabbitMQ 实例都有一份镜像数据(副本数据)。每次写入消息的时候都会自动把数据同步到多台实例上去,这样一旦其中一台机器发生故障,其他机器还有一份副本数据可以继续提供服务,也就实现了高可用。
5.2.1 配置节点
1、配置两台机器的hosts
vim /etc/hosts修改后使用
2、停止服务
rabbitmqctl stop
3、设置erlang cookie
这里将第一台的该文件复制到 其他节点,由于这个文件权限是400,为方便传输,先修改权限,所以需要先修改该文件权限为 777。
集群各节点的cookie必须保持一致,否则无法通信。
erlang是通过主机名来连接服务,必须保证各个主机名之间可以ping通。可以通过编辑/etc/hosts来手工添加主机名和IP对应关系。如果主机名ping不通,rabbitmq服务启动会失败。
注意.erlang.cookie的目录,也有可能在/var/lib/rabbitmq/.erlang.cookie
将权限和所属用户/组修改回来
node2:
chmod 400 /root/.erlang.cookie
4、启动个节点
rabbitmq-server –detached
查看集群状态
[root@test-1]# rabbitmqctl cluster_status
Cluster status of node rabbit@mq1 ...
Basics
Cluster name: rabbit@mq1.example.local #集群名称
Disk Nodes #磁盘节点
rabbit@mq1
Running Nodes #运作中节点
rabbit@mq1
Versions #版本
rabbit@mq1:
RabbitMQ 3.9.0 on Erlang 24.0.4
5.2.2创建集群
rabbitmqctl stop_app #停止 app 服务
rabbitmqctl reset #清空元数据
rabbitmqctl join_cluster rabbit@mq1 --ram #将rabbitmq-server2添加到集群当中,并成为内存节点,不加--ram默认是磁盘节点
rabbitmqctl start_app #启动 app 服务
rabbitmqctl stop_app #停止 app 服务
rabbitmqctl reset #清空元数据
rabbitmqctl join_cluster rabbit@mq1 --ram #
将rabbitmq-server2添加到集群当中,并成为内存节点,不加--ram默认是磁盘节点
rabbitmqctl start_app #启动 app 服务
将集群设置为镜像模式(只要在其中一台节点执行以下命令即可) rabbitmqctl set_policy ha-all "#" '{"ha-mode":"all"}'
http://ip:15672/尝试访问rabbitmq的web页面
5.3、K8s部署
5.3.1 创建yaml文件
包括(comfigmap、secret、rbac、sts、svc)五个yaml文件
Comfigmap:
apiVersion: v1
kind: ConfigMap
metadata:name: rabbitmq-confignamespace: test
data:enabled_plugins: |[rabbitmq_management,rabbitmq_peer_discovery_k8s].
#启用插件rabbitmq_management和rabbitmq_peer_discovery_k8srabbitmq.conf: |cluster_formation.peer_discovery_backend = rabbit_peer_discovery_k8scluster_formation.k8s.host = kubernetes.default.svc.cluster.localcluster_formation.k8s.address_type = hostname################################################## rabbit-mq is rabbitmq-cluster's namespace##################################################cluster_formation.k8s.hostname_suffix = .rabbitmq-headless.rabbit-mq.svc.cluster.localcluster_formation.node_cleanup.interval = 30cluster_formation.node_cleanup.only_log_warning = truecluster_partition_handling = autohealqueue_master_locator=min-masterscluster_formation.randomized_startup_delay_range.max = 2vm_memory_high_watermark.absolute = 1GBdisk_free_limit.absolute = 2GBloopback_users.guest = false
Secret.yaml:
用来存储rabbitmq的用户名、密码及erlang.cookie。
erlang创建步骤:erlang是集群之间互访的秘钥
首先需要生成一个erlang.cookie的文件: echo $(openssl rand -base64 32) > erlang.cookie
然后再生成base64的值 如:echo -n ‘v/sWCz4uKETUvneRyJVn87Jg15si2eGaWg54Yvefhrk=’ |base64
apiVersion: v1
kind: Secret
metadata:name: devsecretnamespace: test
type: Opaque
data:rabbitDefaulUser: "YWRtaW4=" # echo -n 'admin' |base64rabbitDefaultPass: "YWRtaW4="erlang.cookie: "di96VHZ4VmhOY1Uxc3dzTG4zOHdyMmk2S1IrTG82L2xqUEdTTFUwYmdwVDRBPQ=="
Rbac.yaml:
apiVersion: v1
kind: ServiceAccount #集群访问apiserver的凭证
metadata:name: rabbitmqnamespace: test
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: endpoint-readernamespace: test
rules:
- apiGroups: [""]resources: ["endpoints"]verbs: ["get"]
---
kind: RoleBinding #将角色绑定
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: endpoint-readernamespace: test
subjects:
- kind: ServiceAccountname: rabbitmq
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: endpoint-reader
Statefulset.yaml:
要提前创建好挂载目录
apiVersion: apps/v1
kind: StatefulSet
metadata:name: rabbitmqnamespace: test
spec:serviceName: rabbitmq-headlessselector:matchLabels:app: rabbitmq #在apps/v1中,需与 .spec.template.metadata.label 相同,用于hostname传播访问podreplicas: 3 #副本数3template:metadata:labels:app: rabbitmqspec:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: "app"operator: Invalues:- rabbitmqtopologyKey: "kubernetes.io/hostname"serviceAccountName: rabbitmqterminationGracePeriodSeconds: 10containers:- name: rabbitmqimage: rabbitmq:latestimagePullPolicy: Neverresources:limits:cpu: 1memory: 500Mirequests:cpu: 1memory: 500MivolumeMounts:- name: config-volumemountPath: /etc/rabbitmq- name: rabbitmq-datamountPath: /var/lib/rabbitmq/mnesiaports:- name: httpprotocol: TCPcontainerPort: 15672- name: amqpprotocol: TCPcontainerPort: 5672livenessProbe:exec:command: ["rabbitmq-diagnostics", "status"]initialDelaySeconds: 60periodSeconds: 60timeoutSeconds: 5readinessProbe:exec:command: ["rabbitmq-diagnostics", "status"]initialDelaySeconds: 20periodSeconds: 60timeoutSeconds: 5env:- name: RABBITMQ_DEFAULT_USERvalueFrom:secretKeyRef:key: rabbitDefaulUsername: devsecret #登陆用户名和密码都存储在一个secret对象中- name: RABBITMQ_DEFAULT_PASSvalueFrom:secretKeyRef:key: rabbitDefaultPassname: devsecret- name: RABBITMQ_ERLANG_COOKIEvalueFrom:secretKeyRef:name: devsecretkey: erlang.cookie- name: HOSTNAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: MY_POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: RABBITMQ_USE_LONGNAMEvalue: "true"- name: K8S_SERVICE_NAMEvalue: "rabbitmq-headless"- name: RABBITMQ_NODENAMEvalue: rabbit@$(HOSTNAME).$(K8S_SERVICE_NAME).$(MY_POD_NAMESPACE).svc.cluster.local- name: K8S_HOSTNAME_SUFFIXvalue: .$(K8S_SERVICE_NAME).$(MY_POD_NAMESPACE).svc.cluster.localvolumes:- name: config-volumeconfigMap:name: rabbitmq-configitems:- key: rabbitmq.confpath: rabbitmq.conf- key: enabled_pluginspath: enabled_plugins- name: rabbitmq-datahostPath:path: /root/rabbitmq/datatype: Directory
Service.yaml
kind: Service
apiVersion: v1
metadata:name: rabbitmq-headlessnamespace: test
spec:clusterIP: NonepublishNotReadyAddresses: trueports:- name: amqpport: 5672- name: httpport: 15672selector:app: rabbitmq---
kind: Service
apiVersion: v1
metadata:namespace: testname: rabbitmq-service
spec:ports:- name: httpprotocol: TCPport: 15672nodePort: 30672 #管理web界面- name: amqpprotocol: TCPport: 5672targetPort: 5672nodePort: 30671selector:app: rabbitmqtype: NodePort
5.3.2 申请资源清单(启动各个yaml文件)
kubectl apply -f rabbitmq-configmap.yaml
kubectl apply -f rabbitmq-secret.yaml
kubectl apply -f rabbitmq-rbac.yaml
kubectl apply -f rabbitmq-sts.yaml
kubectl apply -f rabbitmq-svc.yaml
5.3.3 访问Rabbirmq页面
http://ip:30672/尝试访问rabbitmq的web页面(需要手动创建用户并授权)
六、常用命令
- 用户管理
A. 查看用户列表:rabbitmqctl list_users;
B. 添加用户:rabbitmqctl add_user ;
C. 修改密码:rabbitmqctl change_password ;
D. 删除用户:rabbitmqctl delete_user ;
E. 设置用户角色:rabbitmqctl set_user_tags <tag1,tag2>,角色有
management:用户可以访问management管理插件;administrator:所有权限;
monitoring:用户可以访问management管理插件,查看所有连接、通道以及与节点相关的信息;policymaker:用户可以访问management管理插件,并管理他们有权访问的vhost的策略和参数; - 节点与应用管理
A. 启动rabbitmq应用程序:rabbitmqctl start_app;
B. 关闭rabbitmq应用程序,但Erlang VM保持运行:rabbitmqctl stop_app;
C. 关闭所有应用和节点:rabbitmqctl stop;
D. 将Rabbitmq节点返回到原始状态,包括删除数据:rabbitmqctl reset; - 集群节点
A. 查看集群状态:rabbitmqctl cluster_status;
B. 添加节点:rabbitmqctl join_cluster {–ram|–disk} rabbit@node;
C. 移除节点:rabbitmqctl forget_cluster_node rabbit@node,注意先关闭应用程序rabbitmqctl stop_app;
D. 节点健康检查:rabbitmqctl node_health_check; - 插件管理
A. 显示所有插件:rabbitmq-plugins list;
B. 启用指定的插件:rabbitmq-plugins enable rabbitmq_management rabbitmq_mqtt rabbitmq_prometheus; - 查看有效配置
A. rabbitmqctl environment
七、RabbitMQ配置详解
tcp_listeners 监听AMQP连接的端口或主机/对。
Default: [5672]
num_tcp_acceptors Erlang进程的数量,接受TCP监听器的连接数。
Default: 10
handshake_timeout 对AMQP 0-8/0-9/0-9-1握手的最大时间(在套接字连接和SSL握手之后),以毫秒为间隔
Default: 10000
ssl_listeners 如上所述,用于SSL连接。
Default: []
num_ssl_acceptors 用于接受SSL监听连接的Erlang进程的数量。
Default: 1
ssl_options SSL配置参数. 详情请看 SSL documentation.
Default: []
ssl_handshake_timeout SSL握手超时,以毫秒为间隔。
Default: 5000
vm_memory_high_watermark 触发流控制的内存阈值。详情请看 memory-based flow control.
Default: 0.4
vm_memory_high_watermark_paging_ratio 设置当内存使用超过总内存百分比多少时,队列开始将消息持久化到磁盘以释放内存。 详情请看 memory-based flow control.
Default: 0.5
disk_free_limit RabbitMQ存储数据的分区的磁盘空间限制。当可用的磁盘空间低于这个限制时,就会触发流控制。值可以相对于RAM的总数设置(例如,内存比例,1.0)。该值也可以设置为整数的字节数。或者,单位(例如“50 mb”)。默认情况下,空闲磁盘空间必须超过50MB。详情请看 Disk Alarms.
Default: 50000000
log_levels 控制日志的粒度。该值是一个日志事件类别和日志级别对的列表。
可设置级别:'none''error''warning''info' 'debug' 以上下一层级别的日志输出均包含上层级别日志输出(如: warning包含warning和error), none为不输出日志
另外,当前未分类的事件总是记录在日志中
The categories are:
channel - 所有与AMQP通道有关的事件
connection - 对于所有与网络连接有关的事件
federation - 对于所有与 federation有关的事件
mirroring - 对于与镜像队列相关的所有事件
Default: [{connection, info}]frame_max
框架最大允许大小(以字节为单位)与消费者进行数据交换。设置为0意味着“无限”,但会在一些QPid客户端触发一个bug。
设置更大的值可能会提高吞吐量;
设置较小的值可能会提高延迟。
Default: 131072channel_max
与消费者进行谈判的最大允许数量。设置为0意味着“无限”。
使用更多的通道会增加代理的内存占用。
Default: 0channel_operation_timeout 通道操作超时为毫秒(内部使用,由于消息传递协议的差异和限制而不直接暴露于客户机)。
Default: 15000heartbeat
该值表示服务器在连接中发送的心跳延迟,在几秒钟内。优化框架。如果设置为0,则会禁用心跳。客户端可能不会遵循服务器的建议,请参阅AMQP参考以了解更多细节。
在有大量连接的情况下,禁用心跳可能改善性能,但可能会导致连接在关闭非活动连接的网络设备的出现。
Default: 60 (580 prior to release 3.5.5)default_vhost 当RabbitMQ创建一个新的数据库时,创建一个虚拟主机。交换amq.rabbitmq.logwill存在于这个虚拟主机中。
Default: <<"/">>default_user 当RabbitMQ从头创建一个新数据库时,要创建用户名。
Default: <<"guest">>default_pass 默认用户的密码。
Default: <<"guest">>default_user_tags 默认用户的标记。
Default: [administrator]default_permissions 在创建时分配给默认用户的权限。
Default: [<<".*">>, <<".*">>, <<".*">>]loopback_users
只允许通过环回接口连接到代理的用户列表(即localhost)。 如果您希望允许缺省的来宾用户远程连接,则需要将其更改为 [].
Default: [<<"guest">>]cluster_nodes 当一个节点开始第一次启动时,将它设置为使集群自动发生。元组的第一个元素是节点试图集群到的节点。第二个元素是磁盘或ram,并确定节点类型。
Default: {[], disc}server_properties 键值对的列表,在连接上向客户端宣布。
Default: []collect_statistics 统计数据收集模式。主要与管理插件有关。选项有:
none (不要发布统计数据)
coarse (发出每个队列/每个通道/每个连接统计信息)
fine (发出的每条数据)
通常情况下不需要设置该参数
Default: nonecollect_statistics_interval 统计数据收集间隔以毫秒为间隔。 主要相关插件 management plugin.
Default: 5000management_db_cache_multiplier 管理插件将缓存诸如队列清单之类的代价较高的查询的时间。缓存将把最后一个查询的运行时间乘以这个值,并在此时间内缓存结果。
Default: 5auth_mechanisms 提供给客户端的SASL身份验证机制。
Default: ['PLAIN', 'AMQPLAIN']auth_backends
要使用的身份验证和授权后端列表。
rabbit\u auth\u backend\u Internal之外的其他数据库可以通过插件获得。Default: [rabbit_auth_backend_internal]reverse_dns_lookups 设置为true,让RabbitMQ对客户端连接执行反向DNS查找,并通过rabbitmqctl和管理插件呈现该信息。
Default: falsedelegate_count 用于集群内部通信的委托进程的数量。当为多核CPU时可以考虑设置该值
Default: 16trace_vhosts Used internally by the tracer. 通常情况下不需要设置该参数
Default: []tcp_listen_options 默认的套接字选项。通常情况下不需要设置该参数
Default:[{backlog, 128},{nodelay, true},{linger, {true,0}},{exit_on_close, false}]hipe_compile 设置为true,使用HiPE预编译RabbitMQ的部分,这是Erlang的即时编译器。这将增加服务器的吞吐量,以增加启动时间的成本。
您可能会看到,在启动时延迟几分钟,您的性能会提高20-50%。这些数据是高度工作负载和硬件依赖的。
HiPE支持可能不会编译到您的Erlang安装中。如果不是这样,启用这个选项只会导致一个警告消息被显示,而启动将照常进行。例如,Debian/Ubuntu用户需要安装erlangbase-base-hipe包。
HiPE在某些平台上是不可用的,尤其是Windows。
HiPE在17.5之前就已经知道了erlangp/otp版本的问题。HiPE推荐使用最新的erlangp/otp版本
Default: falsecluster_partition_handling 如何处理网络分区。可用模式:
ignore
pause_minority
{pause_if_all_down, [nodes], ignore | autoheal}
(例: ['rabbit@node1', 'rabbit@node2'])
autoheal
Default: ignorecluster_keepalive_interval 节点应该多频繁地将keepalive消息发送到其他节点(以毫秒为单位)。请注意,这与netticktime不一样; 错过的keepalive消息不会导致节点被认为挂机。
Default: 10000queue_index_embed_msgs_below 在消息的字节数中,消息将被直接嵌入到队列索引中。详情请看 persister tuning
Default: 4096msg_store_index_module 用于队列索引的实现模块。 详情请看 persister tuning
Default: rabbit_msg_store_ets_indexbacking_queue_module 队列内容的实现模块。通常情况下不需要设置该参数
Default: rabbit_variable_queuemsg_store_file_size_limit Tunable value for the persister. 通常情况下不需要设置该参数
Default: 16777216mnesia_table_loading_retry_limit 在等待集群中的Mnesia tables可用时,需要重试的次数。
Default: 10mnesia_table_loading_retry_timeout 在集群中等待每个重试的时间,以便可用
Default: 30000queue_index_max_ journal_entries Tunable value for the persister. 通常情况下不需要设置该参数
Default: 65536queue_master_locator
Queue master定位策略可用策略:
<<"min-masters">>
<<"client-local">>
<<"random">>
详情请看 documentation on queue master location
Default: <<"client-local">>lazy_queue_explicit_gc_run_operation_threshold
调优: 只有在内存压力下有延迟队列时。
这是触发垃圾收集器和其他内存减少活动的阈值。一个低的值可以降低性能,一个高的值可以提高性能,但是会导致更高的内存消耗。通常情况下不需要设置该参数
Default: 1000queue_explicit_gc_run_operation_threshold
调优: 在内存压力较大时。
这是触发垃圾收集器和其他内存减少活动的阈值。一个低的值可以降低性能,一个高的值可以提高性能,但是会导致更高的内存消耗。通常情况下不需要设置该参数
Default: 1000
八、RabbitMQ优化
8.1、加大服务器带宽
访问量大时,较长的数据容易将带宽占满。如服务器上传带宽为10M,则实际上传带宽可认为1M,每秒上传量为1M/1K=1K。如果把带宽加到100M,则每秒上传量为10K。一般情况下,RabbitMq服务器能够接受的每秒写入量为20K-50K(8G内存),因此在带宽在不足200M的时候,加大带宽会产生很明显的提升作用,再往上效果就可能不那么明显了。
8.2、加大内存
RabbitMq的机制是先将消息放在内存中,然后分批写入硬盘。小批量数据的写入基本上都放在内存中,内存数据量过大时会一边把客户端的数据往内存里写,一边将内存里的陈旧数据往硬盘里写,这样会对速度造成较严重的损耗。适度的增加内存,队列将会更多的消息放在内存中,增加系统的处理速度。
8.3、使用固态硬盘
机械硬盘的写入速度较慢,处理大量数据时机械硬盘对性能的损耗十分严重。如果要存放1亿条数据,所需要的硬盘大小为100G,建议采用100-500G固态硬盘。再加上消费端在不断的处理数据,一般待处理的消息能够达到千万级别已经相当不容易了
8.4、增加生产者
服务器可以建立多个连接,单个生产者往往不能充分利用服务器的潜能,建立多个生产者之后,服务器处理能力将会得到充分利用。一般情况下,一个生产者每秒可以传入1000-5000条消息,在1-10这个范围内,每增加一个生产者,处理速度就会相对单生产者增加一倍
8.5、增加消费者
消费者增多时,出队速度有明显改善。该方案对于出队速度的影响有限,1-10个进程范围内,相对于单进程只有一倍左右的提升,建议线程开2-5个即可,再多可能影响不大。出现该现象的原因可能是服务器带宽或硬件处理能力有限,消费者增加了也没什么用处。因为没有实际环境测试,此条只列为建议,采用前可以多做实验
8.6、改网络访问为本地访问
该方案在消费端/生产端与RabbitMq服务器部署在同一台电脑时有用,因为省略了网络传输,大大节省了处理时间。如果消费端/生产端与RabbitMq服务器分开部署,该方案就不能使用了。在代码中将IP地址127.0.0.1改为localhost即可
8.7、消费端使用长连接
如果每次消费都建立一个连接,无疑将极大的消耗网络与消费端资源,可以只建立一个长链接,所有消息都使用这个长连接来消费。此处需要注意的是,如果长连接出问题,可能会导致队列不能继续消费,需要注意做异常控制。
8.8、消息不要超过4M
消息包大小由1K到10MB,当包大小达到4.5MB时,服务器的性能出现明显的异常,传输率尤其是每秒订阅消息的数量,出现波动,不稳定;同时有一部分订阅者的TCP连接出现断开的现象。可能是客户端底层或者RabbitMQ服务端在进行拆包,组包的时候,出现了明显的压力,而导致异常的发生
九、监控
可以通过接口 来获取性能指标
http://ip:15672/api/nodes
http://IP:15672/api/queues
http://IP:15672/api/overview
通过rabbitmq_exporter来获取RabbitMQ监控指标
获取节点信息的API:
GET /api/nodes/{node} 返回单个节点的状态
GET /api/nodes 返回所有集群成员的统计信息
指标 | JSON field name |
---|---|
使用的内存总量memory used | mem_used |
内存使用阈值 | mem_limit |
当内存使用超过阈值时将触发报警memory alarm | mem_alarm |
剩余磁盘空间阈值 | disk_free_limit |
当空闲磁盘空间低于配置的限制时,将触发报警 | disk_free_alarm |
可用文件描述符总数 | fd_total |
当前使用的文件描述符 | fd_used |
尝试打开的文件描述符数量 | io_file_handle_open_attempt_count |
socket可用 | sockets_total |
已经使用的socket数量 | sockets_used |
Message store disk reads | message_stats.disk_reads |
Message store disk writes | message_stats.disk_writes |
Inter-node communication links | cluster_links |
GC runs | gc_num |
gc回收的字节 | gc_bytes_reclaimed |
erlang进程限制 | proc_total |
已经使用erlang进程 | proc_used |
正在运行的队列 | run_queue |
可以从任一节点获取集群监控数据
API:GET /api/overview
指标 | JSON field name |
---|---|
集群名称 | cluster_name |
集群范围的消息速率 | message_stats |
连接总数 | object_totals.connections |
channel总数 | object_totals.channels |
队列总数 | object_totals.queues |
消费者总数 | object_totals.consumers |
消息总数(ready+unacked) | queue_totals.messages |
准备交付的消息数量 | queue_totals.messages_ready |
未确认的消息数量 | queue_totals.messages_unacknowledged |
最近发布的消息数量 | message_stats.publish |
消息发布的速率 | message_stats.publish_details.rate |
最近发送给消费者的消息数量 | message_stats.deliver_get |
消息交付速率 | message_stats.deliver_get.rate |
单个队列监控API地址: GET /api/queues/{vhost}/{qname}
指标 | JSON field name |
---|---|
内存 | memory |
消息总数(ready+unacknowledged) | messages |
准备交付的消息数量 | messages_ready |
未确认的消息数量 | messages_unacknowledged |
最近发布的消息数量 | message_stats.publish |
消息发布速度 | message_stats.publish_details.rate |
最近交付的消息数量 | message_stats.deliver_get |
消息交付速度 | message_stats.deliver_get.rate |
其他消息状态 this document | message_stats |
整理监控指标情况
监控项 | 指标名称 | 阈值 |
---|---|---|
rabbitmq节点状态 | rabbitmq-status | != 1 紧急 |
rabbitmq节点内存使用率 | rabbitmq-node_mem_used | > 0.8中度 >0.9严重 |
rabbitmq文件句柄数使用率 | rabbitmq_fd_used | > 0.8中度 >0.9严重 |
rabbitmq堆积消息监控 | rabbitmq_queue_messages_unack | > 500中度 > 1000严重 |
rabbitmq推送错误监控 | rabbitmq_failed_to_publish_total | >5中度 |
rabbitmq可消费消息数监控 | rabbitmq_queue_messages_ready | > 5000中度 |
rabbitmq推送消息监控 | rabbitmq_queue_messages_published_total | ==0中度 |
rabbitmq消息投递监控 | rabbitmq_queue_messages_delivered_total | ==0中度 |
rabbitmq消息连接恢复 | rabbitmq_connection_recovery_total | >10中度 |
rabbitmq消息连接数 | rabbitmq_connections | ==0严重 |
rabbitmq通道 | rabbitmq_channel | ==0严重 |
rabbitmq消费者 | rabbitmq_consumers | ==0严重 |
rabbitmq的sockets使用率 | rabbitmq_sockets_used | > 0.8中度 >0.9严重 |
十、常见故障与排查
RabbitMQ注意小计(故障恢复提示):
- 保证集群中至少有一个磁盘类型的节点以防数据丢失,在更改节点类型时尤其要注意。
- 若整个集群被停掉了,应保证最后一个down掉的节点被最先启动,若不能则要使用forget_cluster_node命令将其移出集群。
- 若集群中节点几乎同时以不可控的方式down 了,此时再其中一个节点使用force_boot 命令重启节点。
- 如果加入集群后,意外关闭等造成rabbitmq-server启动不成功,可以尝试一下步骤:/var/lib/rabbitmq/mnesia 目录下存在rabbit@localhost.pid、rabbit@localhost、rabbit@localhost-plugins-expand,删除这3项后,并且删除 /var/lib/rabbitmq/ 目录下 .erlang.cookie和erl_crash.dump 再使用systemctl start rabbitmq-server启动
10.1、消费慢
问题分析:
可以看到RabbitMQ的内存 占用占用已经使用了7.8G 允许的值为 .6G左右
因为 vm_memory_high_watermark 值设置的是0.4 也就是物理内存的40% ;服务器为16G * 40% = 6.4G
一般在产生的原因是长期的生产者发送速率大于消费者消费速率导致. 触发了RabbitMQ 的流控;
解决方案:
- 增加消费者端的消费能力,或者增加消费者(根本解决)
- 控制消息产生者端的发送速率(不太现实)
- 增加mq的内存(治标不治本)
10.2、消息丢失
这个是RabbitMQ最常见的问题,RabbitMQ丢失分三种情况,生产者消息丢失,RabbitMQ消息丢失,消费者消息丢失.
- 生产者消息丢失
生产者在发送消息给RabbitMQ,在中途有可能因为网络问题导致消息丢失,我们可以选择RabbitMQ提供的事务,也可以用confirm模式,就是生产者确认
事务:
channel.tsSelect开启事务;
channel.txRollback出现问题事务回滚
channel.txCommit成功后提交事务
confirm模式:
生产者发送消息,每个消息分配一个id,如果RabbitMQ接收到消息返回ack,如果没有收到放回nack,这个时候生产者只需要重新发送这个消息即可,可以结合这个机制在内存里设置消息id的状态,多长时间没有f返回ack就是失败,重新发送消息.
事务和confirm对比:
事务是属于同步的,在你提交一个事务会阻塞在那里,其他的消息是不能继续发送的,这样很容易影响性能,而confirm是异步的就是发送完我可以继续发送另一条消息,在正常使用中推荐使用confirm模式 - RabbitMQ消息丢失
RabbitMQ数据丢失,可以用持久化分为两个步骤:
首选创建queue的时候将其设置为持久化,这样可以保证RabbitMQ持久化queue的元数据,而不会持久化queue的数据,第二步将消息的deliveryMode设置为2,就是将消息设置为持久化,此时消息就会持久化到磁盘上,即使RabbitMQ重启,也会从磁盘上恢复queue,恢复queue里的数据
跟生产者的confirm配合,如过持久化到磁盘上再返回ack,如果还没持久化就RabbitMQ挂掉了,生产者没有收到ack,还是会重新发送消息. - 消费者消息丢失
消费者有可能因为刚接到消息还没有处理就重启了,但是RabbitMQ以为他处理了,这样就会导致消息丢失,合理的解决方案是关闭自动ack,可以通过api来进行调用,等自己的代码处理完成之后,可以ack,这样即使你没有消费RabbitMQ也知道你是没有去消费的,这个时候RabbitMQ可以把消息交给其他的consumer进行消费,避免消息丢失
10.3、消息重复消费
出现原因:消费者消息消息的时候,MQ没有收到消息的ack应答。
场景:
- 消费者消费消息后没有ack。
- 消费者在消费消息后,ack时网络异常。
解决步骤:
- 消费者消费后,记录通过缓存记录消息的消费标识,消息id如redis的setnx
- 如果消费成功且ack成功,则删除记录的消息标记。
- 如果ack失败,消息下次被消费消息时候,先去查询消息的消费标识,已经消费则直接ack,未消费则继续消费。
10.4、报错“error in config file “/etc/rabbitmq/rabbitmq.config” (none): no ending found”
rabbitmq config的配置相关的官方文档: http://www.rabbitmq.com/configure.html 官方给出的一个 示例配置: https://github.com/rabbitmq/rabbitmq-server/blob/v3.8.x/deps/rabbit/docs/rabbitmq.conf.example 拷贝以上实例文档 到 对应的rabbitmq的安装目录下的文件:/etc/rabbitmq , 取名配置文件名称为 rabbitmq.config,重启rabbit,那么当前文件 就为 当前rabbit所使用。
10.5、生产者发送消息报错
channel is already closed due to channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - home node ‘rabbit@xxx’ of durable queue ‘xxx_queue’ in vhost ‘/’ is down or inaccessible, class-id=50, method-id=10)
生产者连接不上vhost’/',看报错像是服务端有问题,经排查后发现,发现服务集群有一个节点满了,导致连接到这个节点的Connection都出问题了。
解决方案:添加节点,重启生产者服务。
10.6、浏览器打开IP地址,无法访问 RabbitMQ(白屏没有结果)
服务器对应的安全组15672端口没有开启(入规则),导致浏览器无法访问到服务器的任何内容。
相关文章:
RabbitMQ原理架构解析:消息传递的核心机制
文章目录 一、RabbitMQ简介1.1、概述1.2、特性 二、RabbitMQ原理架构三、RabbitMQ应用场景3.1、简单模式3.2、工作模式3.3、发布订阅3.4、路由模式3.5 主题订阅模式 四、同类中间件对比五、RabbitMQ部署5.1、单机部署5.2、集群部署(镜像模式)5.3、K8s部署…...
C语言指针作业
//8-29 第八章作业 //3.输入10个整数,将其中最小的数第一个数对换,把最大的数与最后一个数对换 //写3个函数:①输人10个数;②进行处理;③输出10个数。 //①输人10个数, //方法一:数组索引 void main() {int arr[10];int *p arr;//printf("请输入…...
区块链:比特币-Binance
写在前面:相对于Tran和BNB而言,Binance不支持智能合约;大约每 10分钟 生成一个新区块 一、认识Binance 官方网站:Blockchain Explorer - Bitcoin Tracker & More | Blockchain.com 官方文档:Authentication – I…...
数据工程流程
** 数据工程流程图** #mermaid-svg-ArT55xCISSfZImy3 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ArT55xCISSfZImy3 .error-icon{fill:#552222;}#mermaid-svg-ArT55xCISSfZImy3 .error-text{fill:#552222;stroke…...
使用Python和Pybind11调用C++程序(CMake编译)
目录 一、前言二、安装 pybind11三、编写C示例代码四、结合Pybind11和CMake编译C工程五、Python调用动态库六、参考 一、前言 跨语言调用能对不同计算机语言进行互补,本博客主要介绍如何实现Python调用C语言编写的函数。 实验环境: Linux gnuPython3.10…...
基于springboot的县市级土地使用监控系统的设计与实现
文末获取本系统(程序源码数据库调试部署开发环境)文末可获取,系统界面在最后面。 摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的…...
Hot100 - 最大子数组和
Hot100 - 最大子数组和 最佳思路:动态规划 时间复杂度:O(n) 代码: class Solution {public int maxSubArray(int[] nums) {int sum 0;int ans Integer.MIN_VALUE;for (int i 0; i < nums.length; i) {// 如果 sum > 0,…...
Matlab 深度学习 PINN测试与学习
PINN 与传统神经网络的区别 与传统神经网络的不同之处在于,PINN 能够以微分方程形式纳入有关问题的先验专业知识。这些附加信息使 PINN 能够在给定的测量数据之外作出更准确的预测。此外,额外的物理知识还能在存在含噪测量数据的情况下对预测解进行正则…...
[STM32]从零开始的STM32 FreeRTOS移植教程
一、前言 如果能看到这个教程的话,说明大家已经学习嵌入式有一段时间了。还记得嵌入式在大多数时候指的是什么吗?是的,我们所说的学习嵌入式大部分时候都是在学习嵌入式操作系统。从简单的一些任务状态机再到复杂一些的RTOS,再到最…...
软件团队的共担责任
问责制被认为是个人与其社会系统之间的纽带,它创造了一种将个人与其行为和绩效联系起来的身份关系。在入门系列的第一篇文章《超越工具和流程:成功软件开发团队的策略》中,我们介绍了问责制的概念,并提出了以下定义: …...
代码美学:MATLAB制作渐变色
输入颜色个数n,颜色类型: n 2; % 输入颜色个数 colors {[1, 0, 0], [0, 0, 1]}; createGradientHeatmap(n, colors); 调用函数: function createGradientHeatmap(n, colors)% 输入检查if length(colors) ~ nerror(输入的颜色数量与n不一…...
Perforce SAST专家详解:自动驾驶汽车的安全与技术挑战,Klocwork、Helix QAC等静态代码分析成必备合规性工具
自动驾驶汽车安全吗?现代汽车的软件包含1亿多行代码,支持许多不同的功能,如巡航控制、速度辅助和泊车摄像头。而且,这些嵌入式系统中的代码只会越来越复杂。 随着未来汽车的互联程度越来越高,这一趋势还将继续。汽车越…...
大模型中常见的微调方法有哪些?
我整理了1000道算法面试题: 获取 这里说的微调主要是指参数微调,参数微调的方法主要有以下几种: - Adapter 在预训练模型每一层(或某些层)中添加Adapter模块(如上图左侧结构所示),微调时冻结预训练模型主体,由Ada…...
MATLAB支持的距离度量
距离度量是用于量化两个点或样本之间差异的一种方法。在不同的领域和应用场景中,距离度量的选择可能会有所不同。 欧几里得距离(Euclidean Distance):这是最直观的距离定义,适用于n维空间中的两点。对于二维空间中的点…...
c++编程玩转物联网:使用芯片控制8个LED实现流水灯技术分享
在嵌入式系统中,有限的GPIO引脚往往限制了硬件扩展能力。74HC595N芯片是一种常用的移位寄存器,通过串行输入和并行输出扩展GPIO数量。本项目利用树莓派Pico开发板与74HC595N芯片,驱动8个LED实现流水灯效果。本文详细解析项目硬件连接、代码实…...
LSA详情与特殊区域
LSA是构成LSDB的重要原材料,在OSPF中发挥很大作用。 报文 通用头部 LS age:LSA寿命,0-3600s Options:可选项 LS type:LSA类型,三要素之一 Link State ID:LSAID 三要素之一 Advertising Ro…...
Leecode刷题C语言之交替组①
执行结果:通过 执行用时和内存消耗如下: 代码如下: int numberOfAlternatingGroups(int* colors, int colorsSize) {int res 0;for (size_t i 0; i < colorsSize; i) {if (colors[i] ! colors[(i - 1 colorsSize) % colorsSize] && col…...
深入解析 Django 中数据删除的最佳实践:以动态管理镜像版本为例
文章目录 引言场景与模型设计场景描述 删除操作详解1. 删除单个 Tag2. 批量删除 Tags3. 删除前确认4. 日志记录 高阶优化与问题分析1. 外键约束与误删保护2. 并发删除的冲突处理3. 使用软删除 结合 Django Admin 的实现总结与实践思考 引言 在现代应用开发中,服务和…...
4457数字示波器 2Gpts的深度存储
4457数字示波器 2Gpts的深度存储 256级灰度等级及四种波形色彩显示 4457M系列数字示波器,带宽从1GHz到4GHz,采样率10GSa/s、20GSa/s,垂直分辨率12bit,存储深度1Gpts,最快波形捕获率70万个波形/秒,独创的…...
【笔记】轻型民用无人驾驶航空器安全操控
《轻型民用无人驾驶航空器安全操控》 理论考试培训材料 法规部分 【民用无人驾驶航空器的分类】 1、如何定义微型、轻型无人驾驶航空器? 微型无人驾驶航空器,是指空机重量小于0.25千克,最大平飞速度不超过40千米/小时,无线电发…...
【leetcode】动态规划
31. 873. 最长的斐波那契子序列的长度 题目: 如果序列 X_1, X_2, ..., X_n 满足下列条件,就说它是 斐波那契式 的: n > 3对于所有 i 2 < n,都有 X_i X_{i1} X_{i2} 给定一个严格递增的正整数数组形成序列 arr ࿰…...
嵌入式linux系统中图像处理基本方法
目录 2.1 BMP图像处理 2.1.1 BMP文件格式解析 2.1.2 代码实现:将BMP文件解析为RGB格式,在LCD上显示 2.2 JPEG图像处理 2.2.1 JPEG文件格式和libjpeg编译 2.2.2 libjpeg接口函数的解析和使用 2.2.3 使用libjpeg把JPEG文件解析为RGB格式,在LCD上显示 …...
Qt SQL模块概述
Qt SQL支持的数据库 要在项目中使用 Qt SQL 模块,需要在项目配置文件中添加下面一条设置语句: Qt sql在头文件或源文件中使用 Qt SQL 模块中的类,可以使用包含语句: #include <QtSql>这样会将某个 Qt SQL 模块中的所有类…...
PVE相关名词通俗表述方式———多处细节实验(方便理解)
PVE设置初期,对CIDR、 网关、 LinuxBridge、VLAN等很有困惑的朋友一定很需要一篇能够全面通俗易懂的方式去理解PVE 中Linux网桥的工作方式,就像操作一个英雄,多个技能,还是需要一点点去学习理解的,如果你上来就对着别人…...
C语言实现冒泡排序:从基础到优化全解析
一、什么是冒泡排序? 冒泡排序(Bubble Sort)是一种经典的排序算法,其工作原理非常直观:通过多次比较和交换相邻元素,将较大的元素“冒泡”到数组的末尾。经过多轮迭代,整个数组会变得有序。 二…...
ReentrantLock(可重入锁) Semaphore(信号量) CountDownLatch
目录 ReentrantLock(可重入锁) &Semaphore(信号量)&CountDownLatchReentrantLock(可重入锁)既然有了synchronized,为啥还要有ReentrantLock?Semaphore(信号量)如何确保线程安全呢?CountDownLatch ReentrantLock(可重入锁) &Semaphore(信号量…...
Zookeeper选举算法与提案处理概览
共识算法(Consensus Algorithm) 共识算法即在分布式系统中节点达成共识的算法,提高系统在分布式环境下的容错性。 依据系统对故障组件的容错能力可分为: 崩溃容错协议(Crash Fault Tolerant, CFT) : 无恶意行为,如进程崩溃,只要…...
Jmeter中的断言
7)断言 1--响应断言 功能特点 数据验证:验证响应数据是否包含或不包含特定的字符串、模式或值。多种匹配类型:支持多种匹配类型,如文本、正则表达式、文档等。灵活配置:可以设置多个断言条件,满足复杂的测…...
【通俗理解】隐变量的变分分布探索——从公式到应用
【通俗理解】隐变量的变分分布探索——从公式到应用 关键词提炼 #隐变量 #变分分布 #概率模型 #公式推导 #期望最大化 #机器学习 #变分贝叶斯 #隐马尔可夫模型 第一节:隐变量的变分分布的类比与核心概念【尽可能通俗】 隐变量的变分分布就像是一场“捉迷藏”游戏…...
Vivado程序固化到Flash
在上板调试FPGA时,通常使用JTAG接口下载程序到FPGA芯片中,FPGA本身是基于RAM工艺的器件,因此掉电后会丢失芯片内的程序,需要重新烧写程序。但是当程序需要投入使用时不能每一次都使用JTAG接口下载程序,一般FPGA的外围会…...
铲屎官进,2024年宠物空气净化器十大排行,看看哪款吸毛最佳?
不知道最近换毛季,铲屎官们还承受的住吗?我家猫咪每天都在表演“天女散花”,家里没有一块干净的地方,空气中也都是堆积的浮毛,幸好有宠物空气净化器这种清理好物。宠物空气净化器针对宠物浮毛设计,可以有效…...
SpringBoot 项目中使用 spring-boot-starter-amqp 依赖实现 RabbitMQ
文章目录 前言1、application.yml2、RabbitMqConfig3、MqMessage4、MqMessageItem5、DirectMode6、StateConsumer:消费者7、InfoConsumer:消费者 前言 本文是工作之余的随手记,记录在工作期间使用 RabbitMQ 的笔记。 1、application.yml 使…...
嵌入式硬件实战提升篇(二)PCB高速板设计 FPGA核心板带DDR3 PCB设计DDR全面解析
引言:设计一款高速板,供读者学习,FPGA核心板,带一颗DDR3内存,FPGA型号:XC6SLX16-2FTG256C。 随着嵌入式硬件技术的快速发展,高速板设计逐渐成为嵌入式系统设计中的核心技术之一。高速板的设计要…...
2044:【例5.12】回文字串
【题目描述】 输入一串字符,字符个数不超过100,且以“.”结束。 判断它们是否构成回文。 【输入】 一行字符串。 【输出】 是否为回文串。是输出“Yes”,否输出“No。” 【输入样例】 abccb 【输出样例】 No 代码实现 #include <stdio.h> /*2044&#x…...
Sui 链游戏开发实战:用 Move 写一个链上剪刀石头布游戏!
系列文章目录 Task1:hello move🚪 Task2:move coin🚪 Task3:move nft🚪 Task4:move game🚪 更多精彩内容,敬请期待!✌️ 文章目录 系列文章目录前言什么是 …...
Prometheus告警带图完美解决方案
需求背景 告警分析处理流程 通常我们收到 Prometheus 告警事件通知后,往往都需要登录 Alertmanager 页面查看当前激活的告警,如果需要分析告警历史数据信息,还需要登录 Prometheus 页面的在 Alerts 中查询告警 promQL 表达式,然…...
深度学习模型:循环神经网络(RNN)
一、引言 在深度学习的浩瀚海洋里,循环神经网络(RNN)宛如一颗独特的明珠,专门用于剖析序列数据,如文本、语音、时间序列等。无论是预测股票走势,还是理解自然语言,RNN 都发挥着举足轻重的作用。…...
分布式在线评测系统
OnlineJudge 前言所用技术开发环境 1. 需求分析2. 项目宏观结构3. compile_server服务设计3.1 compiler服务设计3.2 runner服务设计3.3 compile_run3.4 compile_server.cpp 4. oj_server服务设计4.1 model设计4.2 view设计4.3 control设计4.3.1 获取题目列表功能4.3.2 获取单个…...
Unity中动态生成贴图并保存成png图片实现
实现原理: 要生成长x宽y的贴图,就是生成x*y个像素填充到贴图中,如下图: 如果要改变局部颜色,就是从x1到x2(x1<x2),y1到y2(y1<y2)这个范围做处理, 或者要想做圆形就是计算距某个点(x1,y1&…...
鸿蒙多线程开发——sendable共享容器
1、异步锁机制 在介绍共享容器之前,先介绍异步锁机制。 为了解决多线程并发任务间的数据竞争问题,ArkTS引入了异步锁能力。异步锁可能会被类对象持有,因此为了更方便地在并发实例间获取同一个异步锁对象,AsyncLock对象支持跨线程…...
五天SpringCloud计划——DAY1之mybatis-plus的使用
一、引言 咱也不知道为啥SpringCloud课程会先教mybatis-plus的使用,但是教都教了,就学了吧,学完之后觉得mybatis-plus中的一些方法还是很好用了,本文作为我学习mybatis-plus的总结提升,希望大家看完之后也可以熟悉myba…...
Vue.js基础——贼简单易懂!!(响应式 ref 和 reactive、v-on、v-show 和 v-if、v-for、v-bind)
Vue.js是一个渐进式JavaScript框架,用于构建用户界面。它专门设计用于Web应用程序,并专注于视图层。Vue允许开发人员创建可重用的组件,并轻松管理状态和数据绑定。它还提供了一个虚拟DOM系统,用于高效地渲染和重新渲染组件。Vue以…...
警钟长鸣,防微杜渐,遨游防爆手机如何护航安全生产?
近年来,携非防爆手机进入危险作业区引发爆炸的新闻屡见报端。2019年山西某化工公司火灾,2018年延安某煤业瓦斯爆炸,均因工人未用防爆手机产生静电打火引发。涉爆行业领域企业量大面广,相当一部分企业作业场所人员密集,…...
中国科学院大学研究生学术英语读写教程 Unit7 Materials Science TextA 原文和翻译
中国科学院大学研究生学术英语读写教程 Unit7 Materials Science TextA 原文和翻译 Why Is the Story of Materials Really the Story of Civilisation? 为什么材料的故事实际上就是文明的故事? Mark Miodownik 1 Everything is made of something. Take away co…...
win10中使用ffmpeg和MediaMTX 推流rtsp视频
在win10上测试下ffmpeg推流rtsp视频,需要同时用到流媒体服务器MediaMTX 。ffmpeg推流到流媒体服务器MediaMTX ,其他客户端从流媒体服务器拉流。 步骤如下: 1 下载MediaMTX github: Release v1.9.3 bluenviron/mediamtx GitHub…...
代码美学2:MATLAB制作渐变色
效果: %代码美学:MATLAB制作渐变色 % 创建一个10x10的矩阵来表示热力图的数据 data reshape(1:100, [10, 10]);% 创建热力图 figure; imagesc(data);% 设置颜色映射为“cool” colormap(cool);% 在热力图上添加边框 axis on; grid on;% 设置热力图的颜色…...
gitlab:使用脚本批量下载项目,实现全项目检索
目的 当需要知道gitlab中所有项目是否存在某段代码时,gitlab免费版只提供了当个项目内的检索,当项目过多时一个个查太过繁琐。下面通过 GitLab API 将指定 Group 下的所有项目克隆到本地。此脚本会自动获取项目列表并逐一克隆它们,再在本地进…...
大型语言模型LLM - Finetuning vs Prompting
资料来自台湾大学李宏毅教授机器学课程ML 2023 Spring,如有侵权请通知下架 台大机器学课程ML 2023 Springhttps://speech.ee.ntu.edu.tw/~hylee/ml/2023-spring.php2023/3/10 课程 機器如何生成文句 内容概要 主要探讨了大型语言模型的两种不同期待及其导致的两类…...
【Python中while循环】
一、深拷贝、浅拷贝 1、需求 1)拷贝原列表产生一个新列表 2)想让两个列表完全独立开(针对改操作,读的操作不改变) 要满足上述的条件,只能使用深拷贝 2、如何拷贝列表 1)直接赋值 # 定义一个…...
Selenium 包介绍
诸神缄默不语-个人CSDN博文目录 Selenium 是一个强大的工具,主要用于自动化 Web 浏览器的操作。它支持多种编程语言(如 Python、Java、C# 等)和主流浏览器(如 Chrome、Firefox、Safari、Edge 等),广泛应用…...