当前位置: 首页 > news >正文

[RabbitMQ] RabbitMQ运维问题

🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:
🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm=1001.2014.3001.5482
🍕 Collection与数据结构 (93平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀线程与网络(96平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
🍃 Spring(97平均质量分)https://blog.csdn.net/2301_80050796/category_12724152.html?spm=1001.2014.3001.5482
🎃Redis(97平均质量分)https://blog.csdn.net/2301_80050796/category_12777129.html?spm=1001.2014.3001.5482
🐰RabbitMQ(97平均质量分) https://blog.csdn.net/2301_80050796/category_12792900.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
在这里插入图片描述

目录

  • 1. 多机多节点
  • 2. 单机多结点
  • 3. 结点宕机演示
  • 4. 仲裁队列
    • 4.1 Raft协议
    • 4.2 Raft协议之下的消息复制
  • 5. 仲裁队列的使用
  • 6. HAProxy负载均衡
    • 6.1 安装
    • 6.2 使用

一台RabbitMQ服务器接收消息的数量是有限的,假如一个RabbitMQ的服务器每秒可以接受消息的数量是1000条,但是假如我们每秒钟需要接收10万条消息的时候,这时候我们就必须通过搭建多个RabbitMQ结点来解决问题.
RabbitMQ集群允许消费者和生产者在RabbitMQ单个节点崩溃的时候继续运行,当失去一个RabbitMQ结点的时候,客户端可以能过重新连接到集群中的其他任何节点并继续生产或者消费.
接下来我们来介绍如何有效搭建一个RabbitMQ集群.

1. 多机多节点

需要注意的是我们在搭建一个具有多态服务器的集群的时候,需要这些服务器在同一个局域网中.我们使用三台云服务器来搭建集群.

  1. 首先我们需要在三台服务器上安装RabbitMQ程序.安装见前面的文章.
  2. 之后我们为了节点和节点之间相互识别,用来构成一个集群,我们需要在每个节点的hosts文件中**配置节点IP地址和节点的名称.
    首先我们需要找到每个节点的hosts文件,并查看.
vim /etc/hosts

之后我们需要在hosts文件中配置其他节点的相关信息.格式为IP+主机名称.

#rabbitmq
10.0.0.232 iZ2vc7a1n9gvhfp589oav8Z
10.0.0.233 iZ2vc7a1n9gvhfp589oav6Z
10.0.0.234 iZ2vc7a1n9gvhfp589oav7Z

这里我们可以通过more /etc/hostname指令来查看每个主机的名称.
在这里插入图片描述

  1. 配置Erlang Cookie
    RabbitMQ结点之间使用Cookie来进行身份验证,确认他们之间是否被允许相互通信,为了使得两个结点之间可以相互进行通信,我们==必须使得每个节点之间具有相同的共享密钥,称为Erlang Cookie.这是一个字符串,通常存储在本地文件中.
    在RabbitMQ启动的时候,Erlang虚拟机会自动创建该文件,通常位于/var/lib/rabbitmq/.erlang.cookie$HOME/.erlang.cookie.
    首先停止掉所有的结点服务.
systemctl stop rabbitmq-server

之后配置Erlang Cookie,只需要把结点上的.erlang.cookie文件分别拷贝到另外的两个结点上就可以.

#拷贝node3节点的文件到node1
scp /var/lib/rabbitmq/.erlang.cookie 
root@iZ2vc7a1n9gvhfp589oav8Z:/var/lib/rabbitmq/
#拷贝node3节点的文件到node2
scp /var/lib/rabbitmq/.erlang.cookie 
root@iZ2vc7a1n9gvhfp589oav6Z:/var/lib/rabbitmq/

拓展: Linux操作系统中的scp指令是用来在本地主机之间和远程主机之间进行安全文件拷贝的指令,基本语法格式是scp 本地文件路径 远程用户名@远程主机名:远程文件路径.

配置好之后重新启动结点即可.

rabbit-server -datached
  1. 构建集群
    为了将三个结点都连接起来,我们需要告诉另外两个结点加入拎一个结点,比如node1和node2结点加入node3结点.
    但是在加入node3之前,我们必须对两个加入的集群进行重置操作,即删除结点上之前存在的所有资源和数据:
#1. 关闭RabbitMQ服务
rabbitmqctl stop_app
#2. 重置当前节点
rabbitmqctl reset
#3.加入节点 后⾯跟的是node3节点
rabbitmqctl join_cluster rabbit@iZ2vc7a1n9gvhfp589oav7Z
#4. 启动服务
rabbitmqctl start_app
  1. 常见问题
    如果在管理界面中,发现集群中有的结点出现的Node statistics not available的情况,说明该结点在web上的管理插件还没有启用.
    在这里插入图片描述
    我们直接在节点上启动插件即可.
rabbitmq-plugins enable rabbitmq_management

2. 单机多结点

我们一般情况之下,我们只有一台服务器,我们可以使用单机多结点的方式来搭建集群,这样我们就可以不用多台服务器也可以验证集群中的某些特性.
和我们学习Redis中的集群一样,虚拟机只有一个,启动N个结点,结点和节点之间使用端口号来区分.

  1. 首先我们需要确定RabbitMQ运行没有问题.
root@iZ2ze9pwr3i8b65w9dr55dZ:~# rabbitmqctl status
Status of node rabbit@iZ2ze9pwr3i8b65w9dr55dZ ...
Runtime
  1. 再启动两个结点.端口号分别是5673和5674.
RABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management 
listener [{port,15673}]" RABBITMQ_NODENAME=rabbit2 rabbitmq-server -detached
RABBITMQ_NODE_PORT=5674 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management 
listener [{port,15674}]" RABBITMQ_NODENAME=rabbit3 rabbitmq-server -detached

接下来我们验证两个端口是否开通成功.注意放开云服务器中的端口防火墙.

在这里插入图片描述
在这里插入图片描述
3. 接下来我们就可以开始搭建集群了,首先我们停止RabbitMQ2和RabbitMQ3并重置.

root@iZ2ze9pwr3i8b65w9dr55dZ:~# rabbitmqctl -n rabbit2 stop_app
Stopping rabbit application on node rabbit2@iZ2ze9pwr3i8b65w9dr55dZ ...
root@iZ2ze9pwr3i8b65w9dr55dZ:~# rabbitmqctl -n rabbit2 reset
Resetting node rabbit2@iZ2ze9pwr3i8b65w9dr55dZ ...
root@iZ2ze9pwr3i8b65w9dr55dZ:~# rabbitmqctl -n rabbit3 stop_app
Stopping rabbit application on node rabbit3@iZ2ze9pwr3i8b65w9dr55dZ ...
root@iZ2ze9pwr3i8b65w9dr55dZ:~# rabbitmqctl -n rabbit3 reset
Resetting node rabbit3@iZ2ze9pwr3i8b65w9dr55dZ ...
  1. 把rabbit2和rabbit3添加到集群中,并重新启动.其中rabbit@iZ2ze9pwr3i8b65w9dr55dZ是主节点的主机名
root@iZ2ze9pwr3i8b65w9dr55dZ:~# rabbitmqctl -n rabbit2 join_cluster rabbit@iZ2ze9pwr3i8b65w9dr55dZ
Clustering node rabbit2@iZ2ze9pwr3i8b65w9dr55dZ with rabbit@iZ2ze9pwr3i8b65w9dr55dZ
root@iZ2ze9pwr3i8b65w9dr55dZ:~# rabbitmqctl -n rabbit3 join_cluster rabbit@iZ2ze9pwr3i8b65w9dr55dZ
Clustering node rabbit3@iZ2ze9pwr3i8b65w9dr55dZ with rabbit@iZ2ze9pwr3i8b65w9dr55dZ
root@iZ2ze9pwr3i8b65w9dr55dZ:~# rabbitmqctl -n rabbit2 start_app
Starting node rabbit2@iZ2ze9pwr3i8b65w9dr55dZ ...
root@iZ2ze9pwr3i8b65w9dr55dZ:~# rabbitmqctl -n rabbit3 start_app
Starting node rabbit3@iZ2ze9pwr3i8b65w9dr55dZ ...
  1. 查看集群状态
root@iZ2ze9pwr3i8b65w9dr55dZ:~# rabbitmqctl cluster_status -n rabbit
Cluster status of node rabbit@iZ2ze9pwr3i8b65w9dr55dZ ...
BasicsCluster name: rabbit@iZ2ze9pwr3i8b65w9dr55dZDisk Nodesrabbit2@iZ2ze9pwr3i8b65w9dr55dZ
rabbit3@iZ2ze9pwr3i8b65w9dr55dZ
rabbit@iZ2ze9pwr3i8b65w9dr55dZRunning Nodesrabbit2@iZ2ze9pwr3i8b65w9dr55dZ
rabbit3@iZ2ze9pwr3i8b65w9dr55dZ
rabbit@iZ2ze9pwr3i8b65w9dr55dZ

通过集群中的主节点可以查看到其他结点的状态.
在这里插入图片描述

3. 结点宕机演示

集群搭建好之后,也会存在一定的问题,结点在宕机的时候,其他结点的数据不会在进行同步,我们下面来进行演示:

  1. 首先添加队列,rabbit结点添加一个,rabbit2添加一个.
    在这里插入图片描述
    在这里插入图片描述
  2. 添加之后,集群中的其他结点中也会把队列的信息进行同步.
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

注意这里与我们前面的Redis的主从模式不同,RabbitMQ的主从节点都可以写入信息,也会在其他的结点中进行同步,但是Redis只能在主节点中进行写数据,从结点中只可以读数据.

  1. 往testQueue队列中发送一条消息.发送之后其他从节点的队列中也会有消息.
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  2. 接下来我们进行宕机演示,我们关闭rabbit(主)结点.
    在这里插入图片描述
    在这里插入图片描述
    两个从结点的消息队列和队列中的信息均已经丢失.
    如何解决这种消息丢失的问题呢,我们就需要引入仲裁队列.

4. 仲裁队列

RabbitMQ的仲裁队列是一种基于Raft一致性算法实现持久化,复制的FIFO队列,使用仲裁队列可以在RabbitMQ结点之间进行数据的复制,从而达到一个结点宕机的时候,队列仍然可以提供服务的效果.Raft算法我们在之前Redis的文章中曾经介绍过.

4.1 Raft协议

Raft是⼀种用于管理和维护分布式系统一致性的协议,它是一种共识算法,旨在实现高可用性和数据的持久性.Raft通过在节点间复制数据来保证分布式系统中的一性,即使在节点故障的情况下也能保证数据不会丢失.
共识算法(Consensus Algorithm),它允许多个分布式节点就某个值或一系列值达成⼀致性协议.即使在⼀些节点发生故障,网络分区或其他问题的情况下,共识算法也能保证系统的一致性和数据的可靠性.接下来我们就来详细介绍一下Raft算法.
Raft使用Quorum机制来实现共识和容错,我们将对Raft集群的操作必须得到大多数(大于总结点数的一半)结点的同意才可以提交.在RabbitMQ集群中,该算法一般用来选取主节点.

  1. 结点角色
    Raft集群必须存在一个主节点(leader),客户端向集群发起的所有操作都必须经过主节点的处理,所以Raft的核心算法中的最重要的部分就是选主.没有主节点集群就无法工作.在执行了选主过程之后,集群中每一个结点都会识别出一个特定的,唯一的leader.

在Raft算法中,每个节点都处于一下的三种角色之一.

  • leader(领导) : 负责处理所有客户的情况,并将这些请求作为日志复制到Follower.Leader会定期向Follower发送心跳包,一维持领导者的地位,防止Follower进入选举过程.
  • follower(跟随者): 接收来自Leader的日志条目,并在本地应用这些条目.跟随者不会直接处理客户端请求.
  • Candidate(候选者): 当在一段时间没有收到来自Leader的心跳包之后,他会变得不确定Leader是否任然可用,在这种情况之下,跟随者会转变为候选者,并开始尝试通过投票的方式成为新的Leader.
    它们之间的转换关系如下:
    在这里插入图片描述
  1. 任期
    Raft将时间划分成任意长度的任期,每一段任期从一次选举开始,在这个时候会有一个或者是多个候选者会尝试成为Leader,在成功完成一次Leader的选举之后,该结点就会一直是集群的Leader直到任期结束,之后进行下一次的Leader选举.在某些情况之下一次选举无法选举出Leader,这个时候任期会以没有Leader而结束.同时进行新的任期(包含一次新的选举)会重新开始.
    在这里插入图片描述
    每个节点中都保存着一个current term,在通信的时候带上这个term的值.
    每个结点中都存储着一个当前的任期号.该任期号回随着时间单调递增,结点之间通信的时候会交换当前的任期号,**如果一个结点当前的任期号比其他结点小,那么他就将自己的任期号更新为较大的哪个值,如果一个Candidate或者Leader发现者自己的任期号已经过期,会立即回到follower状态.如果一个结点接收了一个带着过期的任期号的请求,那么他就会拒绝这次的请求.

Raft算法中服务器节点之间主要采用RPC进行通信,主要有两类RPC请求:

  • RequestVote RPCs: 请求投票,由candidate在选举过程中发出.
  • AppendEntries RPCs:追加条目,由leader发出,用来做日志复制和提供心跳机制,即心跳包.
  1. 选举详细过程
    Raft采用心跳机制来触发Leader选举,当服务器启动的时候,都是follower状态,如果follower在指定的时间之内没有收到来自Leader的心跳(有三种情况,一是还没有选举出Leader,二是Leader宕机,三是Leader与follower之间网络发生故障),则会主动发起选举.
    在这里插入图片描述
    率先超时的结点,自增当前的任期号之后切换为候选者状态,并给自己投一票.以并行的方式向其他结点发送一个投票请求.之后等待其他结点的回复.
    在这里插入图片描述
    这个过程中,各个结点可能出现三种结果
    • 赢得选举,成为Leader.
    • 其他结点赢得选举,他自行切换到follower.
    • 一段时间之内没有收到投票,保持候选者状态,继续发出选举.

投票要求

  • 每个服务器节点会按照先来后到的原则只投给一个候选者.每个节点手中只有一票的权利.

接下来我们对这三种情况进行说明:

  • 第一种情况,赢得选举之后,新的Leader会立刻给所有的结点发送消息,广而告之,避免其他的结点触发新的选举.
    在这里插入图片描述
  • 第二种情况,比如前面有三个结点ABC同时发起选举,而A的选举消息先到达了C,C给A投出了一票,当B到达C的时候,C手中已经没有投票的权利了,这时候A就胜出了,A胜出之后,会给BC发送心跳消息,结点B发现A的term不低于自己的term,知道已经有了Leader了,于是把自己转换成为了follower.
    在这里插入图片描述
  • 第三种情况: 没有任何节点可以获得最多的投票,比如所有的follower同时变为了Candidate,然后他们的票都会投给自己,这样就都没有Candidate能得到的超过半数的投票了.当这种情况发生的时候,每个Candidate都会进行一次超时响应,然后通过自增任期号来开启新一轮选举,如果没有额外的措施,这种结果会一直持续下去.
    在这里插入图片描述
    为了可以解决上述的问题,Raft采用随机选取超时时间来确保很少产生无结果的投票.为了防止投票一开始就会被瓜分掉,选举时间是从一个固定的区间中随机选择.这样可以把结点之间分散开来一确保在大多数的情况下会只有一个服务器率先超时,那么这个时候,他就可以赢得选举并在其他服务器结束超时之前发送心跳.

4.2 Raft协议之下的消息复制

每个仲裁队列都有多个副本,他包含一个主和多个从副本.replication factor为5的仲裁队列将会有一个主副本和4个从副本.每个副本都在不同的RabbitMQ结点上.
生产者和消费者只会与主副本进行交互,主副本在将这些命令复制到从副本,当主副本所在的结点宕机的时候,其中一个从副本会被选举成为主副本,继续提供服务.
在这里插入图片描述

5. 仲裁队列的使用

  1. 创建仲裁队列
  • 使用Spring框架进行创建
@Bean
public Queue quorumQueue(){return QueueBuilder.durable("quorum_queue").quorum().build();
}
  • 在管理界面进行创建
    在这里插入图片描述
  1. 接收发送消息
    仲裁队列接收发送消息和普通的队列是一样的.
  2. 宕机演示
  • 首先创建一个仲裁队列
    在这里插入图片描述
  • 给仲裁队列发送一条消息
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    三个结点的仲裁队列都存储了消息.
  1. 停止主副本所在的结点
root@iZ2ze9pwr3i8b65w9dr55dZ:~# rabbitmqctl -n rabbit stop_app
Stopping rabbit application on node rabbit@iZ2ze9pwr3i8b65w9dr55dZ ...

停掉之后我们发现其他结点的仲裁队列仍然存在.

6. HAProxy负载均衡

当我们使用集群的策略来对负载能力做进一步的提升的时候,但这里还存在一些问题.
想一想我们在写代码的时候,集群中有三个结点,我们在写代码的时候,该访问那个结点呢?当然是那个结点都可以.这时候就存在两个问题:

  1. 如果我们访问的是node1,node1挂了,程序会出现问题,所以最好是有一个统一的入口,一个结点故障的时候,流量可以及时转移到其他的结点.
  2. 如果所有的客户端都与node1连接,那么node1的网络负载必然会大大增加,而其他结点由于没有那么多的负载而造成了资源的浪费.
    这时候负载均衡显得格外的重要.
    在这里插入图片描述
    引入负载均衡之后,我们在写代码的过程中,就会统一连接负载均衡所在的端口号,由负载均衡来决定一个客户端该和集群中的那一个节点来连接,当有一个结点宕机的时候,负载均衡还会自动把消息重新分配到其他的结点上.
    这里我们主要讲解的是使用HAProxy来实现负载均衡.

6.1 安装

首先我们需要在Linux操作系统中安装AHPorxy.

  1. 安装HAProxy
#更新软件包
sudo apt-get update
#安装HAProxy
sudo apt-get install haproxy
  1. 验证安装
root@iZ2ze9pwr3i8b65w9dr55dZ:~/lottery# sudo systemctl status haproxy
● haproxy.service - HAProxy Load BalancerLoaded: loaded (/lib/systemd/system/haproxy.service; enabled; vendor preset: enabled)Active: active (running) since Sun 2025-01-12 20:48:35 CST; 16min agoDocs: man:haproxy(1)file:/usr/share/doc/haproxy/configuration.txt.gzProcess: 830 ExecStartPre=/usr/sbin/haproxy -Ws -f $CONFIG -c -q $EXTRAOPTS (code=exited, status=0/S>Main PID: 941 (haproxy)Tasks: 3 (limit: 1917)Memory: 71.9MCPU: 126msCGroup: /system.slice/haproxy.service├─ 941 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -S /run/haprox>└─1065 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -S /run/haprox>Jan 12 20:48:34 iZ2ze9pwr3i8b65w9dr55dZ systemd[1]: Starting HAProxy Load Balancer...
Jan 12 20:48:35 iZ2ze9pwr3i8b65w9dr55dZ haproxy[941]: [NOTICE]   (941) : New worker #1 (1065) forked
Jan 12 20:48:35 iZ2ze9pwr3i8b65w9dr55dZ systemd[1]: Started HAProxy Load Balancer.
  1. 修改haporxy.cfg
    vim /etc/haproxy/haproxy.cfg
    追加一下内容:
# haproxy web 管理界⾯
listen statsbind *:8100 mode httpstats enablestats realm Haproxy\ Statistics stats uri /stats auth admin:admin
# 配置负载均衡
listen rabbitmqbind *:5670mode tcpbalance roundrobinserver rabbitmq1 127.0.0.1:5672 check inter 5000 rise 2 fall 3server rabbitmq2 127.0.0.1:5673 check inter 5000 rise 2 fall 3server rabbitmq3 127.0.0.1:5674 check inter 5000 rise 2 fall 3

在HAProxy的配置文件中,listen stats是用来设置一个监听器的指令,这个监听器就是专门用户HAProxy的统计信息页面.这些统计信息可以通过web界面来访问.
4. 重启HAProxy
5. 查看HAProxy
在这里插入图片描述

6.2 使用

  1. 修改配置文件
    引入HAProxy之后,RabbitMQ的集群使用和单机使用方式⼀样,只不过需要把RabbitMQ的IP和port改为HAProxy的IP和port.
host: 182.92.204.253
port: 5670
  1. 声明队列
@Bean
public Queue clusterQueue(){return QueueBuilder.durable("cluster_queue").quorum().build();
}
  1. 发送消息
@RequestMapping("/cluster")
public String cluster(){rabbitTemplate.convertAndSend("","cluster_queue","test...");return "发送成功";
}

相关文章:

[RabbitMQ] RabbitMQ运维问题

🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...

GenAIOps:生成式 AI 运维 - 实用指南

https://medium.com/google-cloud/genaiops-operationalize-generative-ai-a-practical-guide-d5bedaa59d78​​​​​​ 作者:Dr Sokratis Kartakis 从创意到生产:使用生成式 AI 和运维 (GenAIOps) 概述 生成式 AI (GenAI) 的世界充满了令人兴奋的可…...

用户界面软件04

后果 使用这种架构很容易对两个层面的非功能性需求进行优化,但是你仍然需要小心不要将功能 需求重复实现。 现在,两个层面可能有完全不同的设计。比如,用户界面层可能使用配件模型(Widget Model), 以大量的…...

分布式系统设计:Java的秘密基地布局

分布式系统设计是Java企业级开发中的一个关键领域,它涉及到构建高可用、可扩展、高性能的系统。以下是分布式系统设计的一些核心概念和实践: 3.1 分布式系统的特点 分布式系统由多个独立的计算机节点组成,这些节点通过网络连接在一起&#x…...

【Redis学习 | 第5篇】Redis缓存 —— 缓存的概念 + 缓存穿透 + 缓存雪崩 + 缓存击穿

文章目录 完成任务1. 什么是缓存2. 添加商户缓存3. 缓存更新策略3.1 主动更新 4. 缓存穿透5. 缓存雪崩6. 缓存击穿6.1 使用互斥锁查询商铺信息6.2 使用逻辑过期查询商铺信息 7. 封装 Redis 工具类 完成任务 1. 什么是缓存 缓存:数据交换的缓冲区(Cache…...

MySQL索引覆盖(覆盖索引, Covering Index)

文章目录 说明MySQL索引覆盖(覆盖索引, Covering Index)覆盖索引的概念覆盖索引的示例示例查询及索引覆盖情况覆盖索引的性能优势覆盖索引的实现条件覆盖索引 vs 非覆盖索引覆盖索引的限制如何设计覆盖索引覆盖索引的实际案例场景 1:电商系统…...

VUE3 provide 和 inject,跨越多层级组件传递数据

provide 和 inject 是 Vue 3 提供的 API,主要用于实现祖先组件与后代组件之间的依赖注入。它们可以让你在组件树中,跨越多层组件传递数据,而不需要通过 props 或事件的方式逐层传递。这个机制主要用于状态共享、插件系统或某些跨层级的功能。…...

【UE5 C++课程系列笔记】29——在UE中使用第三方库的流程

目录 前言 步骤 一、新建插件 二、创建第三方库 三、使用第三方库 前言 主要就是介绍如何将普通C++工程生成的头文件和.dll导入到UE中去使用。 步骤 一、新建插件 1. 打开插件浏览器选项卡 2. 打开插件创建器 3. 选择“第三方库”,这里命名为“MyThirdPartyLibrary…...

Type-C双屏显示器方案

在数字化时代,高效的信息处理和视觉体验已成为我们日常生活和工作的关键需求。随着科技的进步,一款结合了便携性和高效视觉输出的设备——双屏便携屏,逐渐崭露头角,成为追求高效工作和娱乐体验人群的新宠。本文将深入探讨双屏便携…...

20250112面试鸭特训营第20天

更多特训营笔记详见个人主页【面试鸭特训营】专栏 250112 1. TCP 和 UDP 有什么区别? 特性TCPUDP连接方式面向连接(需要建立连接)无连接(无需建立连接)可靠性可靠的,提供确认、重传机制不可靠&#xff0c…...

使用conda出现requests.exceptions.HTTPError 解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

玩转大语言模型——langchain调用ollama视觉多模态语言模型

系列文章目录 玩转大语言模型——ollama导入huggingface下载的模型 玩转大语言模型——langchain调用ollama视觉多模态语言模型 langchain调用ollama视觉多模态语言模型 系列文章目录前言使用Ollama下载模型查找模型下载模型 测试模型ollama测试langchain测试加载图片加载模型…...

【玩转MacBook】mdfind命令搜索

mdfind 是 macOS 上的一个命令行工具,它允许用户根据元数据来查找文件。mdfind 使用 Spotlight 索引来快速搜索文件系统中的项目。这意味着它可以非常快地找到文件,因为它不直接在磁盘上搜索,而是查询由 Spotlight 维护的索引数据库。 基本用…...

数据结构与算法之二叉树: LeetCode 637. 二叉树的层平均值 (Ts版)

二叉树的层平均值 https://leetcode.cn/problems/average-of-levels-in-binary-tree/description/ 描述 给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值与实际答案相差 1 0 − 5 10^{-5} 10−5 以内的答案可以被接受 示例 1 输入:root…...

【巨实用】Git客户端基本操作

本文主要分享Git的一些基本常规操作,手把手教你如何配置~ ● 一个文件夹中初始化Git git init ● 为了方便以后提交代码需要对git进行配置(第一次使用或者需求变更的时候),告诉git未来是谁在提交代码 git config --global user.na…...

从预训练的BERT中提取Embedding

文章目录 背景前置准备思路利用Transformer 库实现 背景 假设要执行一项情感分析任务,样本数据如下 可以看到几个句子及其对应的标签,其中1表示正面情绪,0表示负面情绪。我们可以利用给定的数据集训练一个分类器,对句子所表达的…...

BGP 泄露

大家读完觉得有帮助记得关注和点赞!!! 目录 1. BGP 是什么? 2. 什么是 BGP 泄露? 3. 今天发生了什么? 4. 正常和被劫持状态下的路由示意图 5. 受影响区域 6. 责任在谁? 7. 有办法避免这…...

IntelliJ IDEA和MAVEN基本操作:项目和缓存存储到非C盘

为了将 IntelliJ IDEA 的所有项目和缓存存储到 C 盘以外的地方,以下是你需要调整的设置和步骤: 1. 更改项目默认存储位置 打开 IntelliJ IDEA。点击顶部菜单的 File > Settings (Windows)或 IntelliJ IDEA > Preferences &…...

Leetcode 3418. Maximum Amount of Money Robot Can Earn

Leetcode 3418. Maximum Amount of Money Robot Can Earn 1. 解题思路2. 代码实现 题目链接:3418. Maximum Amount of Money Robot Can Earn 1. 解题思路 这一题我的思路比较暴力,就是一个动态规划,本质上就是全量遍历,然后找到…...

occ的开发框架

occ的开发框架 1.Introduction This manual explains how to use the Open CASCADE Application Framework (OCAF). It provides basic documentation on using OCAF. 2.Purpose of OCAF OCAF (the Open CASCADE Application Framework) is an easy-to-use platform for ra…...

SYS_OP_MAP_NONNULL NULL的等值比较

无意在数据库中发现了这个操作SYS_OP_MAP_NONNULL。 SYS_OP_MAP_NONNULL应该不是数据库中的对象,因为在DBA_OBJECTS中根本找不到它,而在STANDARD和DBMS_STANDARD包中也找不到函数说明。 SQL> SELECT * 2 FROM DBA_OBJECTS 3 WHERE OBJECT_NAME…...

acwing_3196_I‘m stuck

acwing_3196_I’m stuck // // Created by HUAWEI on 2024/11/17. // #include<iostream> #include<cstring> #include<algorithm>using namespace std;const int N 50 5; char g[N][N];// 地图 bool str1[N][N], str2[N][N]; // 判断1&#xff0c;判断2 …...

C++实现设计模式---状态模式 (State)

状态模式 (State) 状态模式 是一种行为型设计模式&#xff0c;它允许对象在运行时根据内部状态的改变来动态改变其行为。通过将状态相关的行为封装到独立的类中&#xff0c;状态模式使得状态的切换更加清晰和灵活。 意图 将对象的行为和状态分离&#xff0c;随着状态的改变动…...

【1】Word:邀请函

目录 题目 文字解析 流程 题目 文字解析 考生文件夹☞Word.docx☞一定要用ms打开&#xff0c;wps打开作答无效☞作答完毕&#xff0c;F12或者手动另存为&#xff08;考生文件夹&#xff1a;路径文件名&#xff09; 注意&#xff1a;一定要检查&#xff0c;很有可能你前面步…...

作业(一)

1、shell 脚本写出检测 /tmp/size.log 文件如果存在显示它的内容&#xff0c;不存在则创建一个文件将创建时间写入。 # vim a.sh#!/bin/bash​#先对文件/tmp/size.log 是否存在进行判断 if [ -f /tmp/size.log ]; #如果存在&#xff0c;则用cat命令显示文件内容thencat /tmp/…...

[SAP ABAP] APPEND INITIAL LINE 追加空行

语法格式 APPEND INITIAL LINE TO itab.示例1 SFLIGHT(航班) 输出结果&#xff1a; 示例2 我们可以使用下面的语法进行内表分配指针&#xff0c;追加空行并赋值的操作 APPEND INITIAL LINE TO lt_tab ASSIGNING FIELD-SYMBOL(<lfs_val>). REPORT z437_test_2025.* 自…...

Meilisearch ASP.Net Core API 功能demo

安装 MeiliSearch 0.15.5 0.15.5demo code using Meilisearch; using System.Data; using System.Text.Json; using System.Text.Json.Serialization;namespace MeiliSearchAPI {public class MeilisearchHelper{public MeilisearchHelper(){DefaultClient…...

口碑很好的国产LDO芯片,有哪些?

在几乎任何一个电路设计中&#xff0c;都可能会使用LDO&#xff08;低压差线性稳压器&#xff09;这个器件。 虽然LDO不是什么高性能的IC&#xff0c;但LDO芯片市场竞争异常激烈。最近几年&#xff0c;诞生了越来越多的精品国产LDO&#xff0c;让人看得眼花缭乱。 业内人士曾经…...

深入浅出C#线程池ThreadPool:提升程序性能的利器

深入浅出C#线程池ThreadPool&#xff1a;提升程序性能的利器 在C#编程中&#xff0c;线程是并发编程的基石&#xff0c;它使我们能够同时执行多个任务&#xff0c;提升程序的响应速度和效率。然而&#xff0c;直接创建和管理线程会带来一定的开销&#xff0c;例如线程创建和销…...

git问题

拉取项目代码后&#xff0c;出现 1、找回未commit的代码 2、记录不全&#xff0c;只是显示部分代码记录...

Code-Server 项目介绍与部署指南

搜索关注&#xff0c;分享更多有趣的知识。 在这里插入图片描述 1. 概述 GitHub&#xff1a; https://github.com/coder/code-server 在日常学习和工作中&#xff0c;Visual Studio Code&#xff08;VSCode&#xff09;已成为许多开发者的首选代码编辑器。然而&#xff0c;其…...

NAT技术

NAT技术 1. NAT原理 NAT&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;是用于在本地网络中使用私有地址&#xff0c;在连接互联网时转而使用全局 IP 地址的技术。NAT实际上是为解决IPv4地址短缺而开发的技术。路由器构建了子网&#xff0c;将…...

pytest 常用插件

pytest 提供了许多功能强大的插件来增强测试体验和执行能力。以下是一些常用的 pytest 插件介绍&#xff0c;并结合 pytest.main() 进行使用的示例。 1. pytest-xdist pytest-xdist 插件用于并行化测试的执行&#xff0c;可以将测试分配到多个 CPU 核心并行运行&#xff0c;从…...

Avalonia 入门笔记(零):概述

Avalonia 是一个基于 .NET 和 Skia 的开源、跨平台 UI 框架&#xff0c;支持 Windows、Linux、macOS、iOS、Android 和 WebAssembly。Skia 是一个基于 C 的开源 2D 渲染引擎&#xff0c;Avalonia 通过 Skia 自绘 UI 控件&#xff0c;保证在全平台具有一致的观感 基于 .NET 的跨…...

19_TypeScript 声明文件 --[深入浅出 TypeScript 测试]

TypeScript 声明文件&#xff08;.d.ts 文件&#xff09;用于描述 JavaScript 库或模块的类型信息&#xff0c;使得 TypeScript 编译器能够在使用这些库时提供类型检查和智能感知。声明文件并不包含任何实现代码&#xff0c;只定义了接口、类、函数等的类型签名。这对于确保类型…...

如何当前正在运行的 Elasticsearch 集群信息

要查看当前正在运行的 Elasticsearch 集群信息&#xff0c;可以通过以下几种方法&#xff1a; 1. 使用 _cluster/health API _cluster/health API 返回集群的健康状态、节点数量、分片状态等信息。可以用 curl 命令直接访问&#xff1a; curl -X GET "http://localhost…...

【ArcGIS微课1000例】0138:ArcGIS栅格数据每个像元值转为Excel文本进行统计分析、做图表

本文讲述在ArcGIS中,以globeland30数据为例,将栅格数据每个像元值转为Excel文本,便于在Excel中进行统计分析。 文章目录 一、加载globeland30数据二、栅格转点三、像元值提取至点四、Excel打开一、加载globeland30数据 打开配套实验数据包中的0138.rar中的tif格式栅格土地覆…...

【hadoop学习遇见的小问题】centos常见配置 添加组用户权限 修改主机名等

1、指定静态ip vi /etc/sysconfig/network-scripts/ifcfg-eth0修改BOOTPROTO为static BOOTPROTOstatic IPADDR192.168.80.145 NETMASK255.255.255.0 GATEWAY192.168.80.2IPADDR、NETMASK用ifconfig命令即可查看 GATEWAY如何查看&#xff08;编辑—虚拟网络编辑器—上面选择NA…...

16_Redis Lua脚本

Redis Lua脚本是Redis提供的一种强大的扩展机制。 1.Redis Lua脚本介绍 1.1 基本概念 Redis Lua脚本允许开发者将一段Lua语言编写的代码发送给Redis服务器执行。这项功能自Redis 2.6版本引入以来,为用户提供了强大的灵活性和扩展能力,使得可以在Redis内部直接处理复杂的业…...

Appium版本升级,需要注意哪些点:使用UiAutomator2Options传递capabilities

mac上安装的是较新的Appium版本&#xff0c;在跑之前写的Android UI 自动化代码时报错&#xff1a;AttributeError: dict object has no attribute to_capabilities。 查了一下资料&#xff0c;这是因为较新的 Selenium 和 Appium 版本要求使用 Options 类来定义能力&#xff…...

MySQL的增删改查(基础)-下篇

修改 真正在改硬盘了&#xff0c;这样的修改是“持久有效”。一定要确保&#xff0c;update的修改是改对了&#xff0c;改出问题来就麻烦。指定update的时候&#xff0c;如果当前不指定任何条件&#xff0c;就会针对所有的行都能生效&#xff01; (把整个表都给改了)。 案例 --…...

Mysql--基础篇--事务(ACID特征及实现原理,事务管理模式,隔离级别,并发问题,锁机制,行级锁,表级锁,意向锁,共享锁,排他锁,死锁,MVCC)

在MySQL中&#xff0c;事务&#xff08;Transaction&#xff09;是一组SQL语句的集合&#xff0c;这些语句一起被视为一个单一的工作单元。事务具有ACID特性&#xff0c;确保数据的一致性和完整性。通过事务&#xff0c;可以保证多个操作要么全部成功执行&#xff0c;要么全部不…...

Android系统定制APP开发_如何对应用进行系统签名

前言 当项目开发需要使用系统级别权限或frame层某些api时&#xff0c;普通应用是无法使用的&#xff0c;需要在AndroidManifest中配置sharedUserId&#xff1a; AndroidManifest.xml中的android:sharedUserId“android.uid.system”&#xff0c;代表的意思是和系统相同的uid&a…...

Vue篇-06

1、路由简介 vue-rooter&#xff1a;是vue的一个插件库&#xff0c;专门用来实现SPA应用 1.1、对SPA应用的理解 1、单页 Web 应用&#xff08;single page web application&#xff0c;SPA&#xff09;。 2、整个应用只有一个完整的页面 index.html。 3、点击页面中的导航链…...

学习threejs,导入wrl格式的模型

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.VRMLLoader wrl模型加…...

winform第三方界面开源库AntdUI的使用教程保姆级环境设置篇

1. AntdUI 1.1. 导入项目 1.1.1. 首先新建一个空白的基于.net的Winfrom项目1.1.2. 复制AntdUI中src目录到我们的解决方案下面1.1.3. 解决方案下添加现有项目1.1.4. 添加项目引用 1.2. 编写代码 1.2.1. 改写Form1类&#xff0c;让其继承自public partial class Form1 : AntdUI.W…...

likeshop同城跑腿系统likeshop回收租赁系统likeshop多商户商城安装及小程序对接方法

前言&#xff1a;首先likeshop是一个开发平台&#xff0c;是一个独创的平台就像TP内核平台一样&#xff0c;你可以在这个平台上开发和衍生出很多伟大的产品&#xff0c;以likeshop为例&#xff0c;他们开发出商城系统&#xff0c;团购系统&#xff0c;外卖点餐系统&#xff0c;…...

java -jar启动项目报错:XXX.jar中没有主清单属性

XXX.jar中没有主清单属性 1、错误复现2、错误原因3、解决方案 java -jar启动项目报错&#xff1a;XXX.jar中没有主清单属性 1、错误复现 今天使用springboot给项目打了jar包&#xff0c;使用命令启动时报错&#xff0c;截图如下&#xff1a; 2、错误原因 项目的pom文件配置如…...

浅谈云计算03 | 云计算的技术支撑(云使能技术)

云计算的技术支撑 一、定义与内涵1.1 定义与内涵 二、云计算使能技术架构2.1 宽带网络和 Internet 架构2.2 数据中心技术2.3 虚拟化技术2.4 Web 技术2.5 多租户技术2.6 服务技术 一、定义与内涵 1.1 定义与内涵 云计算技术包含一些基础的关键技术&#xff0c;这里称为使能技术…...

使用LinkedList手撕图的邻接表

主要是学习图的邻接表的核心结构等等&#xff0c;话不多说直接上代码&#xff1a; import java.util.LinkedList;public class GrapAdj {private int n ; // 表示图中顶点的数量。private LinkedList<Integer>[] adj;public GrapAdj(int n){this.n n;adj new LinkedLis…...