RabbitMQ 从入门到精通:从工作模式到集群部署实战(二)
接上篇:《RabbitMQ 从入门到精通:从工作模式到集群部署实战(一)》
链接
文章目录
- 4.安装RabbitMQ Messaging Topology Operator
- 裸金属环境部署RabbitMQ
- 部署单实例
- 部署集群
4.安装RabbitMQ Messaging Topology Operator
使用 cert-manager 安装Messaging Topology Operator
在k8s集群上安装 cert-manager 版本 1.2.0+。例如,对于版本 1.3.1,请运行:
wget https://github.com/jetstack/cert-manager/releases/download/v1.3.1/cert-manager.yamlkubectl apply -f cert-manager.yaml
要安装 Operator,请运行以下命令:
wget https://github.com/rabbitmq/messaging-topology-operator/releases/latest/download/messaging-topology-operator-with-certmanager.yamlkubectl apply –f messaging-topology-operator-with-certmanager.yaml
使用生成的自有证书安装Messaging Topology Operator
此方式因涉及自建私有证书,具体步骤可以参考官方文档:
https://www.rabbitmq.com/kubernetes/operator/install-topology-operator#install-with-generated-certificates
使用Kubernetes 内部非默认域名
默认情况下,Kubernetes 内部域名为.cluster.local。kubeadm可以将其配置为其他名称,例如my.cluster.domain。在这种情况下,Messaging Topology Operator可以将自定义域名附加到用于与 RabbitMQ 交互的连接字符串中。
要配置消息传递拓扑操作员以在连接字符串中附加域名,请将环境变量设置MESSAGING_DOMAIN_NAME为您的域名,例如".my.cluster.domain"。
修改Messaging Topology Operator部署清单文件,在Deployment配置段中向spec. template… spec. container. Command增加一个env,名称MESSAGING_DOMAIN_NAME和值为您的域名如:messaging-topology-operator-with-certmanager.yaml
apiVersion: apps/v1
kind: Deployment
metadata:[...]name: messaging-topology-operatornamespace: rabbitmq-system
spec:template:[...]spec:containers:- command:- /managerenv:- name: OPERATOR_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: MESSAGING_DOMAIN_NAMEvalue: "my.cluster.domain"
Messaging Topology Operator使用
创建queue和Policy
以下清单将在namepace名为rabbitmq-test下,默认虚拟主机中创建一个名为“queue-t1-rabbitmq-test”的队列:
cat queue-t1-rabbitmq-test.yaml
apiVersion: rabbitmq.com/v1beta1
kind: Queue
metadata:name: queue-t1namespace: rabbitmq-test
spec:name: queue-t1-rabbitmq-testautoDelete: falsedurable: truerabbitmqClusterReference:name: rabbitmq-cluster01namespace: rabbitmq-test
kubectl apply -f queue-t1-rabbitmq-test.yaml
queue.rabbitmq.com/queue-t1 createdkubectl get queue -n rabbitmq-test
NAME AGE
queue-t1 17s
以下清单将在namepace名为rabbitmq-test下创建名为“policy-example”的policy
cat policy.yaml
apiVersion: rabbitmq.com/v1beta1
kind: Policy
metadata:name: policy-examplenamespace: rabbitmq-test
spec:name: lazy-queuepattern: "^lazy-queue-" # matches any queue begins with "lazy-queue-"applyTo: "queues"definition:queue-mode: lazyrabbitmqClusterReference:name: rabbitmq-cluster01namespace: rabbitmq-test
kubectl apply -f policy.yaml
policy.rabbitmq.com/policy-example createdkubectl get policy -n rabbitmq-test
NAME AGE
policy-example 54s
创建exchange和binding
以下清单将在namepace名为rabbitmq-test下创建名为“rabbitmq-test”的exchange
cat exchange.yaml
cat exchange.yaml
apiVersion: rabbitmq.com/v1beta1
kind: Exchange
metadata:name: fanoutnamespace: rabbitmq-test
spec:name: fanout-exchange # name of the exchangetype: fanout # default to 'direct' if not provided; can be set to 'direct', 'fanout', 'headers', and 'topic'autoDelete: falsedurable: truerabbitmqClusterReference:name: rabbitmq-cluster01namespace: rabbitmq-test
kubectl apply -f exchange.yaml
exchange.rabbitmq.com/fanout createdkubectl get exchange -n rabbitmq-test
NAME AGE
fanout 13s
以下清单将在namepace名为rabbitmq-test下将名为“rabbitmq-test”的exchange与名为“queue-t1-rabbitmq-test”的queue 进行绑定
cat binding.yaml
apiVersion: rabbitmq.com/v1beta1
kind: Binding
metadata:name: bindingnamespace: rabbitmq-test
spec:source: fanout-exchange # an existing exchangedestination: queue-t1-rabbitmq-test # an existing queuedestinationType: queue # can be 'queue' or 'exchange'routingKey: "queue-t1-rabbitmq-test"rabbitmqClusterReference:name: rabbitmq-cluster01namespace: rabbitmq-test
kubectl apply -f binding.yaml
binding.rabbitmq.com/binding created
创建的binding无法通过kubectl 命令列出,但通过RabbitMQ的管理UI可以看到。
创建用户及授权
可以使用 Messaging Topology Operator 创建 RabbitMQ 用户并分配用户权限
对账号(admin-user01)、密码(123123.com)进行base64加密:
echo -n 'admin-user01' | base64
YWRtaW4tdXNlcjAxecho -n '123123.com' | base64
MTIzMTIzLmNvbQ==
创建secret
vim secret-admin-user01.yaml
apiVersion: v1
kind: Secret
metadata:name: admin-user-secretnamespace: rabbitmq-test # 指定rabbitmq-cluster01的namespace
type: Opaque
data:username: YWRtaW4tdXNlcjAx # base64 编码后的用户名password: MTIzMTIzLmNvbQ== # base64 编码后的密码
kubectl apply -f secret-admin-user01.yaml
secret/admin-user01-secret created
创建Rabbitmq 账号资源,需要引用上面步骤创建的secret
vim my-admin-user01.yaml
apiVersion: rabbitmq.com/v1beta1
kind: User
metadata:name: my-admin-user01namespace: rabbitmq-test
spec:tags:- administratorrabbitmqClusterReference:name: rabbitmq-cluster01 # rabbitmqCluster must exist in the same namespace as this resourcenamespace: rabbitmq-testimportCredentialsSecret:name: admin-user01-secret # must match the name of the Secret
kubectl apply -f my-admin-user01.yaml
user.rabbitmq.com/my-admin-user01 created
创建Rabbitmq 账号授权资源
vim permission-admin-user10.yaml
apiVersion: rabbitmq.com/v1beta1
kind: Permission
metadata:name: admin-user01-permissionnamespace: rabbitmq-test
spec:vhost: "/"user: "admin-user01" # name of the RabbitMQ userpermissions:write: ".*"configure: ".*"read: ".*"rabbitmqClusterReference:name: rabbitmq-cluster01namespace: rabbitmq-test
kubectl apply -f permission-admin-user10.yaml
permission.rabbitmq.com/admin-user01-permission created
创建虚拟主机
以下YAML将在名为“rabbitmq-cluster01”的 RabbitmqCluster 中创建名为“test”的虚拟主机:
vim vhost01.yaml
apiVersion: rabbitmq.com/v1beta1
kind: Vhost
metadata:name: test-vhost01 # name of this custom resourcenamespace: rabbitmq-test
spec:name: test01 # name of the vhostrabbitmqClusterReference:name: rabbitmq-cluster01namespace: rabbitmq-test
kubectl apply -f vhost01.yaml
vhost.rabbitmq.com/test-vhost01 created
kubectl get vhost -n rabbitmq-test
NAME AGE
test-vhost01 2s
更新
一些自定义资源属性是不可变的,Messaging Topology Operator 实现了验证 webhook 来阻止对不可变字段的更新。禁止的更新将被拒绝。例如:
kubectl apply -f test-queue.yaml
Error from server (Forbidden):
...
Resource: "rabbitmq.com/v1beta1, Resource=queues", GroupVersionKind: "rabbitmq.com/v1beta1, Kind=Queue"
Name: "example", Namespace: "rabbitmq-system"
for: "test-queue.yaml": admission webhook "vqueue.kb.io" denied the request: Queue.rabbitmq.com "example" is forbidden: spec.name: Forbidden: updates on name, vhost, and rabbitmqClusterReference are all forbidden
无法更新的属性已记录在Messaging Topology Operator API 文档中,URL:https://github.com/rabbitmq/messaging-topology-operator/blob/main/docs/api/rabbitmq.com.ref.asciidoc
删除
删除自定义资源会删除 RabbitMQ 集群中相应的资源。Messaging Topology Operator 会在所有自定义资源上设置 kubernetes finalizers。如果对象已在 RabbitMQ 集群中删除,或者 RabbitMQ 集群已删除,Messaging Topology Operator 会删除自定义资源,而不会尝试删除 RabbitMQ 对象。
跨命名空间
默认情况下,Messaging Topology Operator 只协调使用RabbitMQ Cluster Kubernetes Operator 创建的RabbitMQ集群所在namespace下的创建消息拓扑资源请求。如果需要创建的建消息拓扑资源在其他的namesapce,需要在namespace 下添加相关注解annotations.rabbitmq.com/topology-allowed-namespaces
如下图,RabbitMQ集群所在的的namespace为rabbitmq-test,如果需要Messaging Topology Operator 额外协调rabbitmq-01和rabbitmq-02 两个namespace下消息拓扑资源,需要进行如下配置,多个namespace使用逗号分隔,中间不能有空格。可以设置为“*”,则为协调所有namesapce
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:name: rabbitmq-cluster01namespace: rabbitmq-testannotations:rabbitmq.com/topology-allowed-namespaces: "rabbitmq-01,rabbitmq-02"
如果在没有允许的namespace中创建消息拓扑资源,如下图中为“my-app2”,Topology Operator 的pod会有相关日志提示:
示例如下:
在namespace为my-app2下创建名称为queue-t1的queue, 在rabbitmq中的名称为queue-t1-my-app2
apiVersion: rabbitmq.com/v1beta1
kind: Queue
metadata:name: queue-t1 # name of this custom resource; does not have to the same as the actual queue namenamespace: my-app2
spec:name: queue-t1-my-app2 # name of the queuerabbitmqClusterReference:name: rabbitmq-cluster01namespace: rabbitmq-test
虽然使用kuberct 命令在namespace可以获取到列表,
但在rabbitmq中没有创建名字为queue-t1-my-app2的queue:
故障排查
如果无法创建某些 RabbitMQ 拓扑对象,可通过Messaging Topology Operator 的pod日志进行排查。
kubectl -n rabbitmq-system logs -l app.kubernetes.io/name=messaging-topology-operator
另外还可以使用kubectl desribe命令查看资源的详细信息:
kubectl describe queue queue-t1 -n rabbitmq-test
Name: queue-t1
Namespace: rabbitmq-test
Labels: <none>
Annotations: <none>
API Version: rabbitmq.com/v1beta1
Kind: Queue
Metadata:Creation Timestamp: 2024-10-25T09:46:27ZFinalizers:deletion.finalizers.queues.rabbitmq.com
…Vhost: /
Status:Conditions:Last Transition Time: 2024-10-25T09:46:27ZReason: SuccessfulCreateOrUpdateStatus: TrueType: ReadyObserved Generation: 2
Events:Type Reason Age From Message- - - -Normal SuccessfulDeclare 7h2m (x6 over 47h) queue-controller Successfully declare queue
裸金属环境部署RabbitMQ
OS及内核:
[root@rbt01 ~]# cat /etc/redhat-release
BigCloud Enterprise Linux For Euler release 21.10 (LTS-SP2)[root@rbt01 ~]# uname -a
Linux rbt01 4.19.90-2107.6.0.0208.16.oe1.bclinux.x86_64 #1 SMP Tue Jul 18 10:06:28 CST 2023 x86_64 x86_64 x86_64 GNU/Linux
Erlang和RabbitMQ版本匹配关系参考官方文档:
https://www.rabbitmq.com/docs/3.13/which-erlang#redhat
本文档选用Erlang:v26.2.5.4和RabbitMQ: v3.13.7
部署单实例
关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
安装Erlang
Erlang官方推荐使用各系统平台预安装包进行安装,Euler 21.10使用以下rmp包进行安装,下载地址:https://github.com/rabbitmq/erlang-rpm/releases/download/v26.2.5.4/erlang-26.2.5.4-1.el7.x86_64.rpm
执行安装及通过验证版本号测试是否安装成功
# 安装
yum install erlang-26.2.5.4-1.el7.x86_64.rpm# 查看版本
erl -version
Erlang (SMP,ASYNC_THREADS) (BEAM) emulator version 14.2.5.4
部署RabbitMQ
二进制包下载地址:
https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.13.7/rabbitmq-server-generic-unix-3.13.7.tar.xz
创建rabbitmq普通用户并设置密码,用于管理rabbitmq
useradd rabbitmq
passwd rabbitmq
解压下载好的二进制安装包到/opt目录下,并做软连接
tar xf rabbitmq-server-generic-unix-3.13.7.tar.xz -C /opt/
cd /opt/
ln -s /opt/rabbitmq_server-3.13.7/ /opt/rabbitmq
ln -s /opt/rabbitmq/sbin/* /usr/local/sbin/
安装完成后,默认没有配置文件,可以从官网下载示例,放到/opt/rabbitmq/etc/rabbitmq下,
https://github.com/rabbitmq/rabbitmq-server/blob/main/deps/rabbit/docs/rabbitmq.conf.example
可以根据实际需要参考下面的官方文档进行参数配置:
https://www.rabbitmq.com/docs/3.13/configure#config-items
修改rabbitmq 目录权限
chown –R rabbitmq:rabbitmq /opt/rabbitmq*
使用rabbitmq账号并启动服务:
su – rabbitmq
rabbitmq-server -detached
查看服务进程及监听端口号,默认会监听5672,25672 两个端口
5672用于接受rabbitmq 客户端连接请求
25672 用于集群模式下集群间通信
关闭服务命令:
rabbitmqctl shutdown
启动web管理插件,实现web 浏览器图形界面管理。
rabbitmq-plugins enable rabbitmq_management
启动web管理插件插件后,RabbitMQ会另外启动15672端口用户web服务。
使用服务器IP和15672端口访问web管理页面。
创建账号密码并设置权限
以下命令创建了admin账号并设置密码为:Admin.123,将其标记为administrator,并设置了对/ 有所有权限
rabbitmqctl add_user admin Admin.123
rabbitmqctl set_user_tags admin administrator
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
使用admin账号登录web管理页面
解决web管理界面提示:
⚠ All stable feature flags must be enabled after completing an upgrade. [Learn more]
- 导航到特性标志页面:
在RabbitMQ管理界面的左侧菜单中,找到并点击“Admin”选项。
在“Admin”页面中,找到并点击“Feature Flags”选项。 - 启用特性标志:
在“Feature Flags”页面中,你会看到一个列表,其中包含了所有可用的特性标志。
检查每个特性标志的状态,确保所有标记为“stable”(稳定)的特性标志都被启用。如果发现有未启用的稳定特性标志,请将其启用。
列出功能标志:
rabbitmqctl list_feature_flags
要启用功能标志(或所有当前禁用的标志):
rabbitmqctl enable_feature_flag <all | name>
开启detailed_queues_endpoint 功能标志
rabbitmqctl enable_feature_flag detailed_queues_endpoint
Feature Flags介绍:
官方文档:https://www.rabbitmq.com/docs/3.13/feature-flags
功能标记是一种机制,用于控制哪些功能在所有集群节点上被视为已启用或可用。如果启用了功能标记,则其相关功能(或行为)也会启用。如果没有启用,则集群中的所有节点都将禁用该功能(行为)。
功能标志子系统允许不同版本的 RabbitMQ 节点确定它们是否兼容,然后相互通信,尽管它们具有不同的版本,因此可能具有不同的功能集或实现细节。
引入此子系统是为了允许在不关闭整个集群的情况下对集群成员进行滚动升级。
至此RabbitMQ单实例部署完成。
部署集群
服务器列表
(3个节点保持一致)
[root@rbt01 ~]# tail -n 3 /etc/hosts
192.168.18.11 rbt01
192.168.18.12 rbt02
192.168.18.13 rbt03
分别在3个节点按照“单实例部署”步骤部署完成
参考上面章节
所有节点配置主机域名解析
vim /etc/hosts
192.168.18.11 rbt01
192.168.18.12 rbt02
192.168.18.13 rbt03
节点间同步cookie文件
Erlang cookie 是用于RabbitMQ 节点和CLI 工具之间身份验证的共享密钥。该值存储在通常称为 Erlang cookie 文件的文件中。
服务帐户和运行用户使用的 Cookie 文件rabbitmqctl必须同步,CLI 工具才能rabbitmqctl正常运行。集群中的所有节点必须具有相同的 Cookie 值(Cookie 文件内容)。
同步cooker前确保rabbitmq进程是关闭状态。
[root@rbt01 ~]# rabbitmqctl shutdown[root@rbt02 ~]# rabbitmqctl shutdown[root@rbt03 ~]# rabbitmqctl shutdown
在 UNIX 系统上,cookie 通常位于$HOME/.erlang.cookie
如果使用rabbitmq普通用户启动rabbitmq服务,.erlang.cookie文件的路径为:/home/rabbitmq/.erlang.cookie
.erlang.cookie 文件内容可以是自定义的字符串
将rbt01节点上/home/rabbitmq/.erlang.cookie 文件复制到rbt02,rbt03
[root@rbt01 ~]# scp .erlang.cookie rbt02:$PWD
.erlang.cookie [root@rbt01 ~]# scp .erlang.cookie rbt03:$PWD
.erlang.cookie
并确保所有节点/home/rabbitmq/.erlang.cookie的属主,属组是rabbitmq
权限是400
chown –R rabbit:rabbit /home/rabbitmq/.erlang.cookie
chmod 400 /home/rabbitmq/.erlang.cookie
配置集群方式一,在配置文件中增加如下配置:
/opt/rabbitmq/etc/rabbitmq/rabbitmq.conf
cluster_name = rbt-cluster01
cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_configcluster_formation.classic_config.nodes.1 = rabbit@rbt01
cluster_formation.classic_config.nodes.2 = rabbit@rbt02
cluster_formation.classic_config.nodes.3 = rabbit@rbt03
在所有节点启动服务,集群将自动形成
[rabbitmq@rbt01 ~]$ rabbitmq-server –detached[rabbitmq@rbt02 ~]$ rabbitmq-server –detached[rabbitmq@rbt03 ~]$ rabbitmq-server –detached
在rbt01节点日志中查看有相关日志:
2024-11-05 11:23:41.793897+08:00 [info] <0.734.0> node rabbit@rbt02 up
2024-11-05 11:23:43.066480+08:00 [info] <0.734.0> rabbit on node rabbit@rbt02 up
2024-11-05 11:24:01.294927+08:00 [info] <0.734.0> node rabbit@rbt03 up
2024-11-05 11:24:02.705850+08:00 [info] <0.734.0> rabbit on node rabbit@rbt03 up
配置集群方式二,不需在rabbitmq.conf配置文件定义,使用以下命令配置集群
将rbt02节点加入集群
[rabbitmq@rbt02 ~]$ rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rbt02 ...[rabbitmq@rbt02 ~]$ rabbitmqctl join_cluster rabbit@rbt01
Clustering node rabbit@rbt02 with rabbit@rbt01[rabbitmq@rbt02 ~]$ rabbitmqctl start_app
Starting node rabbit@rbt02 ...
将rbt03节点加入集群
[rabbitmq@rbt03 ~]$ rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rbt03 ...[rabbitmq@rbt03 ~]$ rabbitmqctl join_cluster rabbit@rbt01
Clustering node rabbit@rbt03 with rabbit@rbt01[rabbitmq@rbt03 ~]$ rabbitmqctl start_app
Starting node rabbit@rbt03 ...
查看集群状态
[rabbitmq@rbt01 ~]$ rabbitmqctl cluster_status
Cluster status of node rabbit@rbt01 ...
BasicsCluster name: rabbit@rbt01
Total CPU cores available cluster-wide: 12Disk Nodesrabbit@rbt01
rabbit@rbt02
rabbit@rbt03Running Nodesrabbit@rbt01
rabbit@rbt02
rabbit@rbt03Versionsrabbit@rbt01: RabbitMQ 3.13.7 on Erlang 26.2.5.4
rabbit@rbt02: RabbitMQ 3.13.7 on Erlang 26.2.5.4
rabbit@rbt03: RabbitMQ 3.13.7 on Erlang 26.2.5.4
…
相关文章:

RabbitMQ 从入门到精通:从工作模式到集群部署实战(二)
接上篇:《RabbitMQ 从入门到精通:从工作模式到集群部署实战(一)》 链接 文章目录 4.安装RabbitMQ Messaging Topology Operator 裸金属环境部署RabbitMQ部署单实例部署集群 4.安装RabbitMQ Messaging Topology Operator 使用 cer…...

编程AI深度实战:大模型哪个好? Mistral vs Qwen vs Deepseek vs Llama
随着开源 LLM 的发展,越来越多的模型变得专业化,“代码”LLM 变得非常流行。这些 LLM 旨在比其 “常识” 对应物更小,但旨在超越更大的通用模型的编码性能。 这些模型以极低的成本提供大型模型的功能,进一步使本地 LLM 空间民主化…...
11.kafka开启jmx
方式一: 1.进入/opt/kafka_2.13-3.3.2/bin目录 命令: cd /opt/kafka_2.13-3.3.2/bin [root@rhel77 ~]# cd /opt/kafka_2.13-3.3.2/bin [root@rhel77 bin]# pwd /opt/kafka_2.13-3.3.2/bin [root@rhel77 bin]# 2.备份kafka-run-class.sh 命令: cp kafka-run-class.sh …...
基于钉钉API的连接器实现:企业数据集成与自动化管理
文章目录 概要背景与需求钉钉API概述连接器实现小结 概要 在当今数字化时代,企业面临着海量数据的管理与整合挑战。钉钉作为国内广泛使用的办公协作平台,提供了丰富的API接口,支持企业进行数据集成与自动化管理。本文将介绍如何通过钉钉API实…...
JAVA 二维列表的基础操作与异常
在Java中创建二维 ArrayList(即嵌套列表)的方法有多种,下面我将详细介绍常用的几种方式,并分析它们的区别和适用场景。 1. 使用嵌套 ArrayList 创建二维列表 方法一:直接嵌套 ArrayList 这是最常用的方法,…...

将仓库A分支同步到仓库B分支,并且同步commit提交
一、 问题 有一仓库A 和 一仓库B, 需要将仓库A分支a1所有提交同步推送到仓库B分支b1上 二、 解决 2.1、 首先需要仓库A、仓库B的权限, 2.2、将仓库A clone到本地, 进入A目录,并且切换到a1分支 cd A ## A 为A仓库clone到本地代…...

使用java代码操作rabbitMQ收发消息
SpringAMQP 将来我们开发业务功能的时候,肯定不会在控制台收发消息,而是应该基于编程的方式。由于RabbitMQ采用了AMQP协议,因此它具备跨语言的特性。任何语言只要遵循AMQP协议收发消息,都可以与RabbitMQ交互。并且RabbitMQ官方也…...

mysql8安装时提示-缺少Microsoft Visual C++ 2019 x64 redistributable
MySQL8.0安装包mysql-8.0.1-winx64进行安装,提示:This application requires Visual Studio 2019 x64Redistributable, Please install the Redistributable then runthis installer again。出现这个错误是因为我们电脑缺少Microsoft Visual C 这个程序&…...

WindowsServer搭建内网Gitea【中文更方便使用】
特点: 轻量级:占用系统资源少,对服务器硬件要求较低,适合小型企业或团队使用。部署和维护相对简单,即使没有专业的运维人员也能轻松搭建。 功能齐全:具备基本的代码托管功能,如仓库管理、分支管…...

leetcode 907. 子数组的最小值之和
题目如下 数据范围 观察数据范围理论上平方复杂度的算法计算次数逼近1e9还不至于超时,但是由于有mod 1e9导致超时。所以本题不能靠暴力枚举来解决。 所以我们可以思考如何在枚举上面减少计算次数:第一种枚举法:最外层i控制子数组的左边界&…...
WordPress自定义.js文件排序实现方法
在WordPress中,要将插件引用的.js文件放到所有.js文件之后加载,可以通过以下方法实现: 方法一:调整wp_enqueue_script的加载顺序 在插件的主文件中,使用wp_enqueue_script函数加载.js文件时,将$in_footer…...

摄像头模块烟火检测
工作原理 基于图像处理技术:分析视频图像中像素的颜色、纹理、形状等特征。火焰通常具有独特的颜色特征,如红色、橙色等,且边缘呈现不规则形状,还会有闪烁、跳动等动态特征;烟雾则表现为模糊、无固定形状,…...

【拼十字——树状数组】
题目 暴力代码 30% #include <bits/stdc.h> using namespace std; using ll long long; const int N 1e5 10; const int mod 1e9 7; int n; int l[N], w[N], c[N]; int main() {cin >> n;ll ans 0;for (int i 1; i < n; i){cin >> l[i] >> …...

脚手架开发【实战教程】prompts + fs-extra
创建项目 新建文件夹 mycli_demo 在文件夹 mycli_demo 内新建文件 package.json {"name": "mycli_demo","version": "1.0.0","bin": {"mycli": "index.js"},"author": "","l…...

Fiddler Classic(HTTP流量代理+半汉化)
目录 一、关于Fiddler (一) Fiddler Classic (二) Fiddler Everywhere (三) Fiddler Everywhere Reporter (四) FiddlerCore (五) 总结 二、 软件安全性 1. 软件安装包 2. 软件汉化dll 三、安装与半汉化 1. 正常打开安装包点击下一步安装即可,安装路径自…...

基于yolov11的阿尔兹海默症严重程度检测系统python源码+onnx模型+评估指标曲线+精美GUI界面
【算法介绍】 基于YOLOv11的阿尔兹海默症严重程度检测系统是一种创新的医疗辅助工具,旨在通过先进的计算机视觉技术提高阿尔兹海默症的早期诊断和病情监测效率。阿尔兹海默症是一种渐进性的神经退行性疾病,通常表现为认知障碍、记忆丧失和语言障碍等症状…...
玩转Docker | 使用Docker部署httpd服务
玩转Docker | 使用Docker部署httpd服务 前言一、准备工作环境确认检查操作系统准备网站目录和配置文件二、拉取httpd镜像三、运行httpd容器运行容器命令检查容器状态四、验证httpd服务浏览器访问测试错误排查五、容器管理与维护查看容器状态停止和启动容器更新网站内容和配置六…...

力扣1022. 从根到叶的二进制数之和(二叉树的遍历思想解决)
Problem: 1022. 从根到叶的二进制数之和 文章目录 题目描述思路复杂度Code 题目描述 思路 遍历思想(利用二叉树的先序遍历) 1.在先序遍历的过程中,用一个变量path记录并更新其经过的路径上的值,当遇到根节点时再将其加到结果值res上; 2.该题…...

排序算法--基数排序
核心思想是按位排序(低位到高位)。适用于定长的整数或字符串,如例如:手机号、身份证号排序。按数据的每一位从低位到高位(或相反)依次排序,每次排序使用稳定的算法(如计数排序&#…...

【AIGC魔童】DeepSeek核心创新技术(二):MLA
【AIGC魔童】DeepSeek核心创新技术(二):MLA 1. MLA框架的定义与背景2. MLA框架的技术原理(1)低秩联合压缩(2)查询的低秩压缩(3)旋转位置嵌入(RoPE)…...
Mac: docker安装以后报错Command not found: docker
文章目录 前言解决办法(新的)解决步骤(原来的)不推荐总结 前言 本操作参考 http://blog.csdn.net/enhenglhm/article/details/137955756 原作者,更详细请,查看详细内容请关注原作者。 一般,…...

Golang 并发机制-7:sync.Once实战应用指南
Go的并发模型是其突出的特性之一,但强大的功能也带来了巨大的责任。sync.Once是由Go的sync包提供的同步原语。它的目的是确保一段代码只执行一次,而不管有多少协程试图执行它。这听起来可能很简单,但它改变了并发环境中管理一次性操作的规则。…...

react关于手搓antd pro面包屑的经验(写的不好请见谅)
我们先上代码,代码里面都有注释,我是单独写了一个组件,方便使用,在其他页面引入就行了 还使用了官方的Breadcrumb组件 import React, { useEffect, useState } from react; import { Breadcrumb, Button } from antd; import { …...

Android修行手册-五种比较图片相似或相同
Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材…...

设计模式.
设计模式 一、介绍二、六大原则1、单一职责原则(Single Responsibility Principle, SRP)2、开闭原则(Open-Closed Principle, OCP)3、里氏替换原则(Liskov Substitution Principle, LSP)4、接口隔离原则&am…...

使用PyCharm创建项目以及如何注释代码
创建好项目后会出现如下图所示的画面,我们可以通过在项目文件夹上点击鼠标右键,选择“New”菜单下的“Python File”来创建一个 Python 文件,在给文件命名时建议使用英文字母和下划线的组合,创建好的 Python 文件会自动打开&#…...

LabVIEW与PLC交互
一、写法 写命令立即读出 写命令后立即读出,在同一时间不能有多个地方写入,因此需要在整个写入后读出过程加锁 项目中会存在多个循环并行执行该VI,轮询PLC指令 在锁内耗时,就是TCP读写的实际耗时为5-8ms,在主VI六个…...

Idea 2024.3 使用CodeGPT插件整合Deepseek
哈喽,大家好,我是浮云,最近国产大模型Deepseek异常火爆,作为程序员我也试着玩了一下,首先作为简单的使用,大家进入官网,点击开始对话即可进行简单的聊天使用,点击获取手机app即可安装…...
[论文笔记] Deepseek-R1R1-zero技术报告阅读
启发: 1、SFT&RL的训练数据使用CoT输出的格式,先思考再回答,大大提升模型的数学与推理能力。 2、RL训练使用群体相对策略优化(GRPO),奖励模型是规则驱动,准确性奖励和格式化奖励。 1. 总体概述 背景与目标 报告聚焦于利用强化学习(RL)提升大型语言模型(LLMs)…...

VUE之组件通信(三)
1、$refs与$parent 1)概述: $refs用于:父——>子。$parent用于:子——>父。 2)原理如下: 属性说明$refs值为对象,包含所有被ref属性标识的DOM元素或组件实例。$parent值为对象&#x…...