RocketMQ的介绍和环境搭建
一、介绍
我也不知道是啥,知道有什么用、怎么用就行了,说到mq(MessageQueue)就是消息队列,队列是先进先出的一种数据结构,但是RocketMQ不一定是这样,简单的理解一下,就是临时存储的数据的一个临时仓库,货送到了就行了
作用一般有三个
- 异步:服务器把客户端请求放到RocketMQ,服务器就可以继续处理其它请求,RocketMQ可以按照自己的规则推送到对应的服务器进行处理
- 解耦:比如订单服务和库存服务直接,如果不用队列,下单必须等库存响应才能返回,这样依赖性太强,服务中间加入中间件可以降低服务直接的依赖
- 削峰:洪峰流量时,大量请求涌入,如果处理不过来服务器就容易瘫痪,就像处理水患一样,中间挖一个坑蓄水,RocketMQ就相当于这个坑,再把消息发到对应的下游服务器
二、单机部署
RocketMQ下载地址:下载 | RocketMQ

对bin目录下的runserver.sh和runbroker.sh两个脚本进行一下修改,主要是jvm的的内存参数设置
vim runserver.sh
# 找到choose_gc_options 根据jdk版本配置合适的内存大小
JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"vim runbroker.sh
# 找到choose_gc_options 根据jdk版本配置合适的内存大小
JAVA_OPT="${JAVA_OPT} -Xmn512m -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:-UseParNewGC"
JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g"
1、启动nameserver服务
cd /usr/local/rocketmq/rocketmq-all-5.0.0-bin-release
# 后台启动
nohup bin/mqnamesrv &
# 查看是否启动成功
less nohup.out
# 查看java进程NamesrvStartup服务
jps
2、启动broker服务
配置环境遍历NAMESRV_ADDR
vi ~/.profile
#最后一行添加如下内容
export NAMESRV_ADDR='localhost:9876'
#source生效
source ~/.profile
启动broker服务
cd /usr/local/rocketmq/rocketmq-all-5.0.0-bin-release
vim conf/broker.conf
#在最后一行添加如下 意思是开启自动创建topic
autoCreateTopicEnable=true
#启动broker
nohup bin/mqbroker &
# 查看是否启动成功
less nohup.out
# 查看java进程BrokerStartup服务
jps
3、关闭
1)、在实际服务部署时,通常会将RocketMQ的部署地址添加到环境变量当中。例如使用vi ~/.bash_profile指令,添加以下内容。
export ROCKETMQ_HOME=/app/rocketmq/rocketmq-all-4.9.5-bin-releasePATH=$ROCKETMQ_HOME/bin:$PATHexport PATH
这样就不必每次进入RocketMQ的安装目录了。直接可以使用mqnamesrv 和mqbroker指令。
2)、停止RocketMQ服务可以通过mqshutdown指令进行
mqshutdown namesrv # 关闭nameserver服务
mqshutdown broker # 关闭broker服务
4、测试收发消息
#通过指令启动RocketMQ的消息生产者发送消息
bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
#启动消息消费者接收之前发送的消息
bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
5、搭建RocketMQ可视化界面
在RocketMQ下载页找到RocketMQ Dashboard进行源码的下载,解压后在maven环境下进行编译
mvn clean package -Dmaven.test.skip=true
编译完成后,在源码的target目录下会生成可运行的jar包rocketmq-dashboard-1.0.0.jar。接下来可以将这个jar包上传到服务器上
cd /usr/local/rocketmq
mkdir rocketmq-dashboard
cd rocketmq-dashboard
#上传文件到此目录后,新建application.yml(如果出现错误可以不添加yml文件)
vim application.yml
application.yml内容如下
rocketmq: config: namesrvAddrs: - 192.168.146.128:9876#结果启动RocketMQ可视化界面的jar包
java -jar rocketmq-dashboard-1.0.0.jar 1>dashboard.log 2>&1 &
查看dashboard.log文件们没有报错的情况下访问部署的所在机器的ip:8080(默认)

三、集群搭建
如果单节点部署,nameserver或者broker挂了都不能正常访问RocketMQ了,针对这种情况可以基于集群部署,先是对集群做了如下部署规划

不要想用一台机器来搭建,否则就会出现这个错误

正式开始,下面开了三台机器,ip依次是192.168.64.133、192.168.64.134、192.168.64.128
第一步,先按照之前的步骤配置nameserver然后启动
#三台机器启动nameserver都是一样的操作
cd /usr/local/rocketmq/rocketmq-all-4.9.5-bin-release
vim bin/runserver.sh
# 找到choose_gc_options 根据jdk版本配置合适的内存大小
JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
# 后台启动
nohup bin/mqnamesrv &
# 查看是否启动成功
less nohup.out
# 查看java进程NamesrvStartup服务
jps
第二步配置并启动broker主从集群
1)、在192.168.64.133上配置broker-a,修改conf/2m-2s-async/broker-a.properties,把原来的注释掉,添加如下内容
#所属集群名字,名字一样的节点就在同一个集群内
brokerClusterName=rocketmq-cluster
#broker名字,名字一样的节点就是一组主从节点。
brokerName=broker-a
#brokerid,0就表示是Master,>0的都是表示 Slave
brokerId=0
#nameServer地址,分号分割
namesrvAddr=192.168.64.133:9876;192.168.64.134:9876;192.168.64.128:9876
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
deleteWhen=04
fileReservedTime=120
#存储路径
storePathRootDir=/usr/local/rocketmq/store
storePathCommitLog=/usr/local/rocketmq/store/commitlog
storePathConsumeQueue=/usr/local/rocketmq/store/consumequeue
storePathIndex=/usr/local/rocketmq/store/index
storeCheckpoint=/usr/local/rocketmq/store/checkpoint
abortFile=/usr/local/rocketmq/store/abort
#Broker 的角色
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
#Broker 对外服务的监听端口
listenPort=10911
2)、在192.168.64.134上配置broker-a的slave,修改conf/2m-2s-async/broker-a-s.properties,把原来的注释掉,添加如下内容
#所属集群名字,名字一样的节点就在同一个集群内
brokerClusterName=rocketmq-cluster
#broker名字,名字一样的节点就是一组主从节点。
brokerName=broker-a
#brokerid,0就表示是Master,>0的都是表示 Slave
brokerId=1
#nameServer地址,分号分割
namesrvAddr=192.168.64.133:9876;192.168.64.134:9876;192.168.64.128:9876
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
deleteWhen=04
fileReservedTime=120
#存储路径
storePathRootDir=/usr/local/rocketmq/storeSlave
storePathCommitLog=/usr/local/rocketmq/storeSlave/commitlog
storePathConsumeQueue=/usr/local/rocketmq/storeSlave/consumequeue
storePathIndex=/usr/local/rocketmq/storeSlave/index
storeCheckpoint=/usr/local/rocketmq/storeSlave/checkpoint
abortFile=/usr/local/rocketmq/storeSlave/abort
#Broker 的角色
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
#Broker 对外服务的监听端口
listenPort=11011
3)、在192.168.64.134上配置broker-b,修改conf/2m-2s-async/broker-b.properties,把原来的注释掉,添加如下内容
#所属集群名字,名字一样的节点就在同一个集群内
brokerClusterName=rocketmq-cluster
#broker名字,名字一样的节点就是一组主从节点。
brokerName=broker-b
#brokerid,0就表示是Master,>0的都是表示 Slave
brokerId=0
#nameServer地址,分号分割
namesrvAddr=192.168.64.133:9876;192.168.64.134:9876;192.168.64.128:9876
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
deleteWhen=04
fileReservedTime=120
#存储路径
storePathRootDir=/usr/local/rocketmq/store
storePathCommitLog=/usr/local/rocketmq/store/commitlog
storePathConsumeQueue=/usr/local/rocketmq/store/consumequeue
storePathIndex=/usr/local/rocketmq/store/index
storeCheckpoint=/usr/local/rocketmq/store/checkpoint
abortFile=/usr/local/rocketmq/store/abort
#Broker 的角色
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
#Broker 对外服务的监听端口
listenPort=10911
4)、在192.168.64.133上配置broker-b的slave,修改conf/2m-2s-async/broker-b-s.properties,把原来的注释掉,添加如下内容
#所属集群名字,名字一样的节点就在同一个集群内
brokerClusterName=rocketmq-cluster
#broker名字,名字一样的节点就是一组主从节点。
brokerName=broker-b
#brokerid,0就表示是Master,>0的都是表示 Slave
brokerId=1
#nameServer地址,分号分割
namesrvAddr=192.168.64.133:9876;192.168.64.134:9876;192.168.64.128:9876
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
deleteWhen=04
fileReservedTime=120
#存储路径
storePathRootDir=/usr/local/rocketmq/storeSlave
storePathCommitLog=/usr/local/rocketmq/storeSlave/commitlog
storePathConsumeQueue=/usr/local/rocketmq/storeSlave/consumequeue
storePathIndex=/usr/local/rocketmq/storeSlave/index
storeCheckpoint=/usr/local/rocketmq/storeSlave/checkpoint
abortFile=/usr/local/rocketmq/storeSlave/abort
#Broker 的角色
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
#Broker 对外服务的监听端口
listenPort=11011
这样就完成了2主2从集群的配置。配置过程汇总有几个需要注意的配置项:
-
store开头的一系列配置:表示RocketMQ的存盘文件地址。在同一个机器上需要部署多个Broker服务时,不同服务的存储目录不能相同。
-
listenPort:表示Broker对外提供服务的端口。这个端口默认是10911。在同一个机器上部署多个Broker服务时,不同服务占用的端口也不能相同。
-
如果你使用的是多网卡的服务器,比如阿里云上的云服务器,那么就需要在配置文件中增加配置一个brokerIP1属性,指向所在机器的外网网卡地址。
第三步,启动broker服务
在启动之前还是需要配置jvm参数(所有机器都一样)
vim bin/runbroker.sh
JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g"
先启动在192.168.64.133的broker-a和broker-b-s服务
cd /usr/local/rocketmq/rocketmq-all-4.9.5-bin-release
nohup bin/mqbroker -c ./conf/2m-2s-async/broker-a.properties &
nohup bin/mqbroker -c ./conf/2m-2s-async/broker-b-s.properties &
再启动192.168.64.134的broker-b和broker-a-s服务
cd /usr/local/rocketmq/rocketmq-all-4.9.5-bin-release
nohup bin/mqbroker -c ./conf/2m-2s-async/broker-b.properties &
nohup bin/mqbroker -c ./conf/2m-2s-async/broker-a-s.properties &
第四步,检查broker集群状态
bin/mqadmin clusterList

也可以通过rocketmq dashboard查看,我之前添加yml启动报错,不知道怎么回事,欢迎大佬留言解决,其实rocketmq dashboard可以这样配置nameserver的地址
rocketmq: config: namesrvAddrs: - 192.168.64.133:9876 - 192.168.64.134:9876- 192.168.64.128:9876
具体查看集群结果就是如图

在RocketMQ的这种主从架构的集群下,客户端发送的消息会分散保存到broker-a和broker-b两个服务上,然后每个服务都配有slave服务,可以备份对应master服务上的消息,这样就可以防止单点故障造成的消息丢失问题。
有个问题就是主节点挂了,为了保证数据的完整性不会选举新的主节点,因为如果因为网络波动出现脑裂问题很有可能会丢失数据
把broker-b和broker-a-s也就是把192.168.64.134的broker服务停掉,看下什么状态,操作如下命令
bin/mqshutdown broker

四、升级高可用集群

在Dledger集群中,就不再单独指定各个broker的服务,而是由这些broker服务自行进行选举,产生一个Leader角色的服务,响应客户端的各种请求。而其他的broker服务,就作为Follower角色,负责对Leader上的数据进行备份
Dledger集群的选举是通过Raft协议进行的,Raft协议是一种多数同意机制。也就是每次选举需要有集群中超过半数的节点确认,才能形成整个集群的共同决定。同时,这也意味着在Dledger集群中,只要有超过半数的节点能够正常工作,那么整个集群就能正常工作。因此,在部署Dledger集群时,通常都是部署奇数台服务,这样可以让集群的容错性达到最大。
还是用之前的机器,ip依次是192.168.64.133、192.168.64.134、192.168.64.128
第一步:部署nameserver
这一步和之前部署主从集群没有区别,不需要做过多的配置,直接在三台服务器上启动nameserver服务即可。
第二步:对Broker服务进行集群配置
在conf/dledger目录下,RocketMQ默认给出了三个配置文件,这三个配置文件可以在单机情况下直接部署成一个具有三个broker服务的Dledger集群,我们只需要按照这个配置进行修改即可。
注:在RocketMQ运行包的bin/dledger目录下,RocketMQ还提供了一个fast-try.sh脚本。这个脚本会指定conf/deldger目录下的配置文件,直接启动有三个broker服务的Dledger集群。每个集群指定的内存大小占用1G。
在三台机器的conf/dledger目录下,都创建一个broker.conf文件,对每个broker服务进行配置。
192.168.64.133的broker.conf配置示例
vim /usr/local/rocketmq/rocketmq-all-4.9.5-bin-release/conf/dledger/broker.conf
# 文件内容如下
brokerClusterName = RaftCluster
brokerName=RaftNode00
listenPort=30911
namesrvAddr=192.168.64.133:9876;192.168.64.134:9876;192.168.64.128:9876
storePathRootDir=/usr/local/rocketmq/storeDledger/
storePathCommitLog=/usr/local/rocketmq/storeDledger/commitlog
storePathConsumeQueue=/usr/local/rocketmq/storeDledger/consumequeue
storePathIndex=/usr/local/rocketmq/storeDledger/index
storeCheckpoint=/usr/local/rocketmq/storeDledger/checkpoint
abortFile=/usr/local/rocketmq/storeDledger/abort
enableDLegerCommitLog=true
dLegerGroup=RaftNode00
dLegerPeers=n0-192.168.64.133:40911;n1-192.168.64.134:40911;n2-192.168.64.128:40911
## must be unique
dLegerSelfId=n0
sendMessageThreadPoolNums=16
192.168.64.134的broker.conf配置示例
vim /usr/local/rocketmq/rocketmq-all-4.9.5-bin-release/conf/dledger/broker.conf
# 文件内容如下
brokerClusterName = RaftCluster
brokerName=RaftNode00
listenPort=30911
namesrvAddr=192.168.64.133:9876;192.168.64.134:9876;192.168.64.128:9876
storePathRootDir=/usr/local/rocketmq/storeDledger/
storePathCommitLog=/usr/local/rocketmq/storeDledger/commitlog
storePathConsumeQueue=/usr/local/rocketmq/storeDledger/consumequeue
storePathIndex=/usr/local/rocketmq/storeDledger/index
storeCheckpoint=/usr/local/rocketmq/storeDledger/checkpoint
abortFile=/usr/local/rocketmq/storeDledger/abort
enableDLegerCommitLog=true
dLegerGroup=RaftNode00
dLegerPeers=n0-192.168.64.133:40911;n1-192.168.64.134:40911;n2-192.168.64.128:40911
## must be unique
dLegerSelfId=n1
sendMessageThreadPoolNums=16
192.168.64.128的broker.conf配置示例
vim /usr/local/rocketmq/rocketmq-all-4.9.5-bin-release/conf/dledger/broker.conf
# 文件内容如下
brokerClusterName = RaftCluster
brokerName=RaftNode00
listenPort=30911
namesrvAddr=192.168.64.133:9876;192.168.64.134:9876;192.168.64.128:9876
storePathRootDir=/usr/local/rocketmq/storeDledger/
storePathCommitLog=/usr/local/rocketmq/storeDledger/commitlog
storePathConsumeQueue=/usr/local/rocketmq/storeDledger/consumequeue
storePathIndex=/usr/local/rocketmq/storeDledger/index
storeCheckpoint=/usr/local/rocketmq/storeDledger/checkpoint
abortFile=/usr/local/rocketmq/storeDledger/abort
enableDLegerCommitLog=true
dLegerGroup=RaftNode00
dLegerPeers=n0-192.168.64.133:40911;n1-192.168.64.134:40911;n2-192.168.64.128:40911
## must be unique
dLegerSelfId=n2
sendMessageThreadPoolNums=16
这里对几个需要重点关注的配置项,做下介绍:
-
enableDLegerCommitLog: 是否启动Dledger。true表示启动
-
namesrvAddr: 指定nameserver地址
-
dLedgerGroup: Dledger Raft Group的名字,建议跟brokerName保持一致。
-
dLedgerPeers: Dledger Group内各个服务节点的地址及端口信息。同一个Group内的各个节点配置必须要保持一致。
-
dLedgerSelfId: Dledger节点ID,必须属于dLedgerPeers中的一个。同一个Group内的各个节点必须不能重复。
-
sendMessageThreadPoolNums:dLedger内部发送消息的线程数,建议配置成cpu核心数。
-
store开头的一系列配置: 这些是配置dLedger集群的消息存盘目录。如果你是从主从架构升级成为dLedger架构,那么这个地址可以指向之前搭建住主从架构的地址。dLedger集群会兼容主从架构集群的消息格式,只不过主从架构的消息无法享受dLedger集群的两阶段同步功能。
第三步:启动broker服务
和启动主从架构的broker服务一样,我们只需要在启动broker服务时,指定配置文件即可。在三台服务器上分别执行以下指令,启动broker服务
cd /usr/local/rocketmq/rocketmq-all-4.9.5-bin-release
nohup bin/mqbroker -c conf/dledger/broker.conf &
第四步:检查集群服务状态
通过rocketmq dashboard查看

停掉192.168.64.128之后的dashboard

不能停了,再停宕机超过半数只剩一台就无法选举产生新的master
相关文章:
RocketMQ的介绍和环境搭建
一、介绍 我也不知道是啥,知道有什么用、怎么用就行了,说到mq(MessageQueue)就是消息队列,队列是先进先出的一种数据结构,但是RocketMQ不一定是这样,简单的理解一下,就是临时存储的…...
【web开发】7、Django(2)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、部门列表二、部门管理(增删改)三、用户管理过渡到modelform组件四、modelform实例:靓号操作五、自定义分页组件六、datepick…...
Prometheus+Grafana可视化监控【Nginx状态】
文章目录 一、安装Docker二、安装Nginx(Docker容器方式)三、安装Prometheus四、安装Grafana五、Pronetheus和Grafana相关联六、安装nginx_exporter七、Grafana添加Nginx监控模板 一、安装Docker 注意:我这里使用之前写好脚本进行安装Docker,如果已经有D…...
R 语言的安装教程
一、下载相关软件 1、R 下载 官网:R: The R Project for Statistical Computing 找到中国镜像,下载快 历史版本点击这里 2、Rtools 下载 进入镜像后,点击这里 然后选择与上面下载的R版本相对应的版本即可 3、Rstudio 下载 官网࿱…...
uniapp-提现功能(demo)
页面布局 提现页面 有一个输入框 一个提现按钮 一段提现全部的文字 首先用v-model 和data内的数据双向绑定 输入框逻辑分析 输入框的逻辑 为了符合日常输出 所以要对输入框加一些条件限制 因为是提现 所以对输入的字符做筛选,只允许出现小数点和数字 这里用正则实现的小数点…...
Spring 篇
1、什么是 Spring? Spring是一个轻量级的IOC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。常见的配置方式有三种:基于XML的配置、基于注解的配置…...
three.js简单3D图形的使用
npm init vitelatest //创建一个vite的脚手架 选择 Vanilla 之后自己处理一下 在main.js中写入 // 导入three.js import * as THREE from three// 创建场景 const scene new THREE.Scene();// 创建相机 const camera new THREE.PerspectiveCamera(45, //视角window.inner…...
spark withColumn的使用(笔记)
目录 前言: spark withColumn的语法及使用: 准备源数据演示: 完整实例代码: 前言: withColumn():是Apache Spark中用于DataFrame操作的函数之一,它的作用是在DataFrame中添加或替换列ÿ…...
PTA:7-1 线性表的合并
线性表的合并 题目输入样例输出样例 代码解析 题目 输入样例 4 7 5 3 11 3 2 6 3输出样例 7 5 3 11 2 6 代码 #include<iostream> #include<vector> using namespace std;bool checkrep(const vector<int>& arr, int x) {for (int element : arr) {i…...
Spring 的创建和日志框架的整合
目录 一、第一个 Spring 项目 1、配置环境 2、Spring 的 jar 包 Maven 项目导入 jar 包和设置国内源的方法: 3、Spring 的配置文件 4、Spring 的核心 API ApplicationContext 4、程序开发 5、细节分析 (1)名词解释 (2&…...
11-集合和学生管理系统
1.ArrayList 集合和数组的优势对比: 长度可变添加数据的时候不需要考虑索引,默认将数据添加到末尾 1.1 ArrayList类概述 什么是集合 提供一种存储空间可变的存储模型,存储的数据容量可以发生改变 ArrayList集合的特点 长度可以变化…...
C语言进阶指针(3) ——qsort的实现
大家好,我们今天来学习回调函数qsort的实现。 首先让我们打开cplusplus.com找到qsort函数。 我们看到这个函数就可以看到它的头文件和参数信息。 #include<stdlib.h> void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const voi…...
Rust源码分析——Rc 和 Weak 源码详解
Rc 和 Weak 源码详解 一个值需要被多个所有者拥有 rust中所有权机制在图这种数据结构中,一个节点可能被多个其它节点所指向。那么如何表示图这种数据结构?在多线程中,多个线程可能会持有同一个数据?如何解决这个问题。 Rc rus…...
【网络编程】深入理解TCP协议二(连接管理机制、WAIT_TIME、滑动窗口、流量控制、拥塞控制)
TCP协议 1.连接管理机制2.再谈WAIT_TIME状态2.1理解WAIT_TIME状态2.2解决TIME_WAIT状态引起的bind失败的方法2.3监听套接字listen第二个参数介绍 3.滑动窗口3.1介绍3.2丢包情况分析 4.流量控制5.拥塞控制5.1介绍5.2慢启动 6.捎带应答、延时应答 1.连接管理机制 正常情况下&…...
社区团购商城小程序v18.1开源独立版+前端
新增后台清理缓存功能 修复定位权限 修复无法删除手机端管理员 11月新登录接口修复! 修复商家付款到零钱, 修复会员登陆不显示头像, 修复无法修改会员开添加绑定...
MATLAB入门-字符串操作
MATLAB入门-字符串操作 注:本篇文章是学习笔记,课程链接是:link MATLAB中的字符串特性: 无论是字符还是字符串,都要使用单引号来‘’表示;在MATLAB中,字符都是在矩阵中存储的,无论…...
Kong Learning
一、Kong Kong是由Mashape公司开源的可扩展的Api GateWay项目。它运行在调用Api之前,以插件的扩展方式为Api提供了管理。比如,鉴权、限流、监控、健康检查等,Kong是基于lua语言、nginx以及openResty开发的,所有拥有动态路由、负载…...
Python怎样写桌面程序
要编写Python桌面应用程序,可以使用以下几种方法: 1.使用Tkinter模块:Tkinter是Python自带的GUI工具包之一,可以使用它来创建基本的GUI界面。例如,可以创建一个简单的窗口,添加按钮、文本框等控件…...
蓝桥杯2023年第十四届省赛真题-平方差--题解
蓝桥杯2023年第十四届省赛真题-平方差 时间限制: 3s 内存限制: 320MB 提交: 2379 解决: 469 题目描述 给定 L, R,问 L ≤ x ≤ R 中有多少个数 x 满足存在整数 y,z 使得 x y2 − z2。 输入格式 输入一行包含两个整数 L, R,用一个空格分隔。 输出格…...
iText实战--根据绝对位置添加内容
3.1 direct content 概念简介 pdf内容的4个层级 层级1:在text和graphics底下,PdfWriter.getDirectContentUnder() 层级2:graphics层,Chunk, Images背景,PdfPCell的边界等 层级3:text层,Chun…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...
