kafka 与 RocketMQ对比
问题 1: 为什么使用消息队列?
消息队列的作用:
削峰填谷
解耦
异步
具体的使用场景:
问题 1: 实际没有用过
比如: IM 系统; 秒杀/抢票的削峰填谷
服务搭建
Kafka
- 写一个 docker-compose.yml
version: '3'name: kafka-groupservices:zookeeper-test:image: zookeeperports:- "2181:2181"volumes:- zookeeper_vol:/data- zookeeper_vol:/datalog- zookeeper_vol:/logscontainer_name: zookeeper-testkafka-test:image: wurstmeister/kafkaports:- "9092:9092"environment:KAFKA_ADVERTISED_HOST_NAME: "localhost"KAFKA_ZOOKEEPER_CONNECT: "zookeeper-test:2181"KAFKA_LOG_DIRS: "/kafka/logs"volumes:- kafka_vol:/kafkadepends_on:- zookeeper-testcontainer_name: kafka-testvolumes:zookeeper_vol: {}kafka_vol: {}
- 运行docker compose
docker compose -f <yml 的文件路径> up -d
- 运行 sdk(go-Kafka)功能测试
const (topic = "test-topic"brokerAddress = "localhost:9092"
)func TestKafka() {ctx := context.Background()// 1. 发送消息produceMessage(ctx)// 2. 启动消费者go consumeMessages()// 3. 等待10秒time.Sleep(10 * time.Second)fmt.Println("测试完成,退出程序")
}func produceMessage(ctx context.Context) {writer := &kafka.Writer{Addr: kafka.TCP(brokerAddress),Topic: topic,Balancer: &kafka.LeastBytes{},}defer writer.Close()msg := kafka.Message{Key: []byte("test-key"),Value: []byte(fmt.Sprintf("测试消息 - %s", time.Now().Format(time.RFC3339))),}if err := writer.WriteMessages(ctx, msg); err != nil {log.Fatalf("发送消息失败: %v", err)}fmt.Printf("已发送消息: %s\n", msg.Value)
}func consumeMessages() {reader := kafka.NewReader(kafka.ReaderConfig{Brokers: []string{brokerAddress},Topic: topic,GroupID: "test-group",MinBytes: 10e3,MaxBytes: 10e6,})defer reader.Close()fmt.Println("消费者已启动...")for {msg, err := reader.ReadMessage(context.Background())if err != nil {log.Printf("消费错误: %v", err)continue}fmt.Printf("消费到消息: %s\n", msg.Value)}
}
RocketMQ
编写 docker-compose.yml
version: '3.8'
services:namesrv:image: sha256:a1f797e48d967647d4c61b67130891c7ef4763fd33bddc6c2eba3067330305e8container_name: rmqnamesrvports:- 9876:9876networks:- rocketmqcommand: sh mqnamesrvbroker:image: sha256:a1f797e48d967647d4c61b67130891c7ef4763fd33bddc6c2eba3067330305e8container_name: rmqbrokerports:- 10909:10909- 10911:10911- 10912:10912volumes:- ./broker.conf:/home/rocketmq/rocketmq-5.3.2/conf/broker.confenvironment:- NAMESRV_ADDR=rmqnamesrv:9876depends_on:- namesrvnetworks:- rocketmqcommand: sh mqbroker -c /home/rocketmq/rocketmq-5.3.2/conf/broker.confproxy:image: sha256:a1f797e48d967647d4c61b67130891c7ef4763fd33bddc6c2eba3067330305e8container_name: rmqproxynetworks:- rocketmqdepends_on:- broker- namesrvports:- 8080:8080- 8081:8081restart: on-failureenvironment:- NAMESRV_ADDR=rmqnamesrv:9876command: sh mqproxy
networks:rocketmq:driver: bridge
运行docker compose
cd 到存放 docker-compose.yml 的文件夹
或者docker compose up 指定文件
- up 指定文件
docker compose -f < compose.yml文件路径> up -d
修改配置文件(解决网络问题)
- 进入容器
docker exec -it rmqbroker bash
- 修改配置
echo "brokerIP1 = 127.0.0.1" >> ../conf/broker.conf
- 重新运行
docker-compose restart
或者使用命令强行设置 IP
docker exec rmqbroker sh mqadmin updateBrokerConfig -b broker-name -k brokerIP1 -v 127.0.0.1 -n 127.0.0.1:9876
- 检查IP 是否设置好
docker exec rmqnamesrv sh mqadmin clusterList -n 127.0.0.1:9876
创建一个 topic
sh ./mqadmin updateTopic -n localhost:9876 -t test-topic -c DefaultCluster -a +message.type=NORMAL
运行skd尝试发送与接收功能
发送
// 测试 1: 单元测试:生产者发消息
func TestProducer(t *testing.T) {// 创建生产者实例p, err := rocketmq.NewProducer(// 设置 NameServer 地址producer.WithNameServer([]string{"127.0.0.1:9876"}),// 设置生产者组名producer.WithGroupName("test_producer_group"),// 设置重试次数producer.WithRetry(2),)if err != nil {fmt.Printf("create producer error: %s\n", err.Error())return}// 启动生产者err = p.Start()if err != nil {fmt.Printf("start producer error: %s\n", err.Error())return}defer p.Shutdown()// 准备发送的消息msg := &primitive.Message{Topic: TestTopic,Body: []byte("Hello RocketMQ From Go Client"),}// 设置消息标签msg.WithTag("TestTag")// 设置消息键msg.WithKeys([]string{"TestKey"})// 发送消息ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()res, err := p.SendSync(ctx, msg)if err != nil {fmt.Printf("send message error: %s\n", err.Error())} else {fmt.Printf("send message success: result=%s\n", res.String())}// 等待中断信号优雅关闭sig := make(chan os.Signal, 1)signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)<-sig
}
接收
func TestConsumer(t *testing.T) {// 创建消费者实例c := NewConsumer(//消费组consumer.WithGroupName("testGroup"),// namesrv地址consumer.WithNameServer([]string{"127.0.0.1:9876"}),//消费模式consumer.WithConsumeFromWhere(consumer.ConsumeFromFirstOffset),)defer c.Shutdown()// 订阅主题c.Subscribe(TestTopic, Handler1)// 创建生产者p := NewProducer(// 设置 NameServer 地址producer.WithNameServer([]string{"127.0.0.1:9876"}),// 设置生产者组名producer.WithGroupName("test_producer_group"),// 设置重试次数producer.WithRetry(2),)// 启动生产者err := p.Producer.Start()if err != nil {fmt.Printf("start producer error: %s\n", err.Error())return}defer p.Producer.Shutdown()for i := 0; i < 10; i++ {err = p.SendMsg(TestTopic, []byte(fmt.Sprintf("Hello RocketMQ From Go Client %d", i)))if err != nil {fmt.Printf("send message error: %s\n", err.Error())return}}// 等待 5s 后退出time.Sleep(5 * time.Second)
}
event-bus 多消费者
func TestConsumer2(t *testing.T) {// 创建消费者实例1c1 := NewConsumer(//消费组consumer.WithGroupName("testGroup1"),// namesrv地址consumer.WithNameServer([]string{"127.0.0.1:9876"}),//消费模式consumer.WithConsumeFromWhere(consumer.ConsumeFromFirstOffset),)defer c1.Shutdown()// 订阅主题c1.Subscribe(TestTopic, Handler1)// 创建消费者实例2c2 := NewConsumer(//消费组consumer.WithGroupName("testGroup2"),// namesrv地址// namesrv地址consumer.WithNameServer([]string{"127.0.0.1:9876"}),//消费模式consumer.WithConsumeFromWhere(consumer.ConsumeFromFirstOffset),)defer c2.Shutdown()// 订阅主题c2.Subscribe(TestTopic, Handler2)// 创建生产者producerSend()// 等待 5s 后退出time.Sleep(5 * time.Second)
}
压力测试:
Kafka
batch-size(批量大小)
- 批量传输是提升吞吐量的关键参数,主要是提高传输效率(减少发送的次数)
条件: 发送线程数:1; topic 分区数 15 ; 数据大小:79 字节
go-kafka sdk测试结果
Batch-Size | 吞吐量 (MB/s) | 发送数据 (条/s) |
---|---|---|
1 | 2.7 | 34,177 |
500 | 21.3 | 269,620 |
1000 | 22.1 | 279,746 |
5000 | 24 | 303,797 |
10000 | 24.3 | 307,595 |
15000 | 25.8 | 326,582 |
20000 | 25.8 | 326,582 |
25000 | 25.2 | 318,987 |
30000 | 25.5 | 322,785 |
35000 | 26.1 | 330,380 |
50000 | 21.3 | 269,620 |
Kafka 自带的压测脚本 测试结果
batch.size | 记录发送速率 (records/sec) | 吞吐量 (MB/sec) | 平均延迟 (ms) | 最大延迟 (ms) | 50th 百分位延迟 (ms) | 95th 百分位延迟 (ms) | 99th 百分位延迟 (ms) | 99.9th 百分位延迟 (ms) | 备注 |
---|---|---|---|---|---|---|---|---|---|
无设置 | 214,334.71 | 140.43 | 213.22 | 500.00 | 200 | 310 | 413 | 480 | 默认配置 |
5,000 | 70,993.48 | 46.51 | 658.11 | 2,310.00 | 633 | 747 | 1,142 | 2,058 | 服务器负载较低,性能较差 |
10,000 | 134,605.81 | 88.19 | 345.87 | 637.00 | 335 | 428 | 533 | 631 | 性能显著提升 |
15,000 | 199,399.20 | 130.64 | 234.3 | 378.0 | 233 | 343 | 496 | 872 | 服务器接近负载上限 |
15,000 (二次) | 186,382.87 | 122.11 | 247.37 | 948.00 | 233 | 343 | 496 | 872 | 略有下降,服务器负载较高 |
20,000 | 250,269.04 | 163.97 | 177.39 | 514.00 | 168 | 264 | 390 | 504 | 性能进一步提升 |
25,000 | 297,300.51 | 194.78 | 119.14 | 420.00 | 127 | 194 | 371 | 413 | 最佳性能 |
根据两个压测结果来看:
batch-size 越大,吞吐量越高,性能的瓶颈在于 troughput 的大小(接口 QPS/程序每秒能发多少数据给 Kafka)
- batch-size 如何选择: 根据业务接口的 QPS 进行确定;在固定的 QPS 调用的情况下,batch-size 增加到一定值之后变化就不大了
- 比如在 go 的 sdk 的情况下测试,batch-size 1000-5000 波动并不多,5000 之后甚至还有下降的趋势
分区数:发送数据(MB/s)
条件: 发送线程数 1; batch-size:5000;数据大小 79 字节
go sdk测试结果
分区数 | 吞吐量 (MB/s) | 发送数据 (条/s) |
---|---|---|
1 | 25.5 | 322,785 |
5 | 25 | 316,456 |
10 | 25.4 | 321,518 |
15 | 25 | 316,456 |
20 | 24 | 303,797 |
Kafka 自带脚本压测结果
分区数 | 记录发送速率 (records/sec) | 吞吐量 (MB/sec) | 平均延迟 (ms) | 最大延迟 (ms) | 50th 百分位延迟 (ms) | 95th 百分位延迟 (ms) | 99th 百分位延迟 (ms) | 99.9th 百分位延迟 (ms) |
---|---|---|---|---|---|---|---|---|
5 | 457,163.76 | 299.52 | 25.63 | 596.00 | 2 | 140 | 263 | 585 |
10 | 483,582.38 | 316.83 | 37.15 | 423.00 | 5 | 172 | 244 | 375 |
15 | 603,718.91 | 395.54 | 28.11 | 540.00 | 4 | 122 | 172 | 513 |
20 | 594,459.64 | 389.47 | 17.25 | 558.00 | 2 | 88 | 246 | 529 |
结论:
- 两个压测的数据差距非常大,可以说是背道而驰
- 因为分区的作用是改变多线程下的磁盘 IO;
- Kafka 每个分区都是一个单独的文件,单线程读写其实就是一个文件 IO 的效率,会有上下波动;但是并不大也就是一个文件的 IO 效率
- 但是在多线程情况下,IO 的效率将是每个文件的 IO 的总和(这一点可以很明显的体现在多线程读取 情况下,多分区的读取效率明显大幅提升
消费-线程数(15 分区)
sdk测试结果
消费者数量 | 每个线程消费数据 (条/5s) | 每秒消费的总条数 (条/s) | 吞吐量 (MB/s) |
---|---|---|---|
1 | 7,931,777 | 1,586,355 | 119.9 |
3 | 4,221,217; 4,263,885; 4,130,602 | 2,523,141 | 190.6 |
6 | 2,738,983; 2,735,468; 2,630,453; 2,649,757; 2,739,442; 2,641,324 | 3,183,086 | 240.5 |
9 | 2,009,912; 1,968,823; 1,975,723; 1,965,374; 2,039,036; 1,968,965; 1,961,928; 1,899,827; 1,887,832 | 3,563,936 | 269.3 |
12 | 1,634,192; 1,623,847; 1,608,319; 1,705,832; 1,621,312; 1,696,289; 1,587,789; 1,634,192; 1,639,367; 1,666,854; 1,633,038; 1,672,544 | 3,950,318 | 298.5 |
15 | 1,832,556; 1,766,294; 1,810,132; 1,758,385; 1,791,158; 1,780,809; 1,784,259; 1,826,931; 1,800,389; 1,769,654; 1,791,158; 1,758,385; 1,813,582; 1,798,058; 1,785,984 | 5,337,870 | 403.3 |
**结论: **
- 当 (消费者数量<=分区数量): 消费者越多,消费越快
- 当(消费者数量>分区数量): 消费者越多,消费速度影响不大
- 原因是一个分区只能同时被一个消费者持有(相同 groupId 情况下),当消费者数量>分区情况下,有的消费者将无法获取到分区,进而无法消费到消息,知道有消费者的分区释放,才会尝试获取分区
- **在在 15 分区,20 个消费者情况下压力测试: 有 5 个分区没有消费到一条消息
**
RocketMQ
生产
生产者数量
生产者线程数 | 吞吐量 (MB/s) | 折算消息量 (万条/s) |
---|---|---|
1 | 0.4 | 4.0 |
5 | 0.5 | 5.0 |
10 | 0.6 | 6.0 |
100 | 0.6 | 6.0 |
1000 | 0.5 | 5.0 |
**
**
批量大小(batch-size)
批量大小(条) | 吞吐量 (MB/s) | 折算消息量(万条/s) |
---|---|---|
10 | 0.5 | 5.0 |
500 | 5.0 | 50.0 |
1000 | 7.0 | 70.0 |
1500 | 8.6 | 86.0 |
2000 | 8.0 | 80.0 |
2500 | 9.0 | 90.0 |
3000 | 10.0 | 100.0 |
4000 | 10.3 | 103.0 |
5000 | 10.2 | 102.0 |
6000 | 10.6 | 106.0 |
10000 | 12.0 | 120.0 |
消费
消费者数量
消费者数量 | 各消费者消息数 (5秒) | 总消费量 (条) | 每秒总消费量 (条/s) | 吞吐量 (MB/s) |
---|---|---|---|---|
1 | [206,712] | 206,712 | 41,342 | 1.97 |
2 | [92,960, 93,272] | 186,232 | 37,246 | 1.78 |
3 | [90,064, 45,784, 45,800] | 181,648 | 36,330 | 1.73 |
4 | [45,418, 45,480, 45,120, 44,968] | 180,986 | 36,197 | 1.73 |
5 | [35,304, 35,336, 34,920, 35,008, 0] | 140,568 | 28,114 | 1.34 |
10 | [42,840, 43,184, 42,880, 43,039, 0×6] | 171,943 | 34,389 | 1.64 |
问题: 为什么消费者越多,性能月底?
按照 Kafka 的压测数据来讲,生产者与消费者数量越高,效率应该增加(在数量<分区数时)
其他配置
RocketMQ
生产者类型
- sync:同步发送;阻塞等待发送结果;
- async:异步发送;不会阻塞等待发送结果;
消费者类型:
- push: 监听的形式,监听 broker 的消息
- pull: 接口调用的形式,从通过调用接口的方式获取 broker 消息
消息的类型:
- 普通消息:
特点: 不保证顺序,性能最高
- 顺序消息(FIFO): 消息保证顺序消费
- 延时(delay):延时消息(只有到延时时间才可以消费)
- 事务:两阶段提交,开始是半提交状态,可以进行 rollback 与 commit 操作
kafka
生产者类型
- sync:同步发送;阻塞等待发送结果;
- async:异步发送;不会阻塞等待发送结果;
高可用
参考:https://rocketmq-learning.com/faq/ons-user-question-history16752/
RocketMQ 的高可用主要分为两个方面:
- 数据的冗余: RocketMQmaster 可以配置 selve 节点,冗余数据,保证数据不丢失;当 master 故障,selve 节点会接替成为新的 master 进行工作
- leader 节点选举: 当 RocketMQ 的中心节点(leader)宕机,其他节点会进行选举(raft 算法);选择出新的 leader 节点;保证服务的正常运行
消息队列幂等
消息队列的幂等主要分为两个阶段
- 消息队列的幂等:
- 避免发送方的重试导致出现多条消息,确保消息队列同一条消息
- 一般会使用全局唯一的 id 对消息进行去重,确保不会出现相同的消息
- 消费者(客户端)的幂等
- 避免消费者超时重试导致的重复消费问题
- 每条消息都回有全局唯一 id,每次消费都回先检查消息是否消费过了
case:
订单问题:
每一笔订单都回有一个全局唯一的订单 id; 每次消费都回检查是否消费过
参考
https://kafka.apache.org/documentation/#introduction
https://rocketmq.apache.org/zh/docs/featureBehavior/01normalmessage
https://blog.csdn.net/m0_71513446/article/details/143386962
https://rocketmq-learning.com/faq/ons-user-question-history16752/
若有收获,就点个赞吧
相关文章:
kafka 与 RocketMQ对比
问题 1: 为什么使用消息队列?服务搭建KafkaRocketMQ编写 docker-compose.yml运行docker compose修改配置文件(解决网络问题)创建一个 topic运行skd尝试发送与接收功能 压力测试:Kafkabatch-size(批量大小)分区数:发送数据(MB/s)消费-线程数(15 分区) RocketMQ生产生产者数量批…...
instnatid模型加载器放在哪里
一般根据节点名称来放,如果没有就新建 ComfyUI\models\instantid...
Spring Boot自动配置原理解析
文章目录 前言一、SpringBootConfiguration二、EnableAutoConfiguration2.1、AutoConfigurationPackage2.2、Import(AutoConfigurationImportSelector.class) 三、ComponentScan四、自动配置源码4.1、获取所有候选的自动配置类4.2、过滤不满足条件的自动配置 总结 前言 在常规的…...
LlamaIndex实现(基于PDF|CSV文件)RAG检索增强生成:NaiveRAG
什么是 RAG? RAG(Retrieval-Augmented Generation,检索增强生成) 是一种结合 信息检索(Retrieval) 和 文本生成(Generation) 的AI技术,用于提升大语言模型(L…...
分布式系统面试总结:3、分布式锁(和本地锁的区别、特点、常见实现方案)
仅供自学回顾使用,请支持javaGuide原版书籍。 本篇文章涉及到的分布式锁,在本人其他文章中也有涉及。 《JUC:三、两阶段终止模式、死锁的jconsole检测、乐观锁(版本号机制CAS实现)悲观锁》:https://blog.…...
vue3搭建实战项目笔记三
vue3搭建实战项目笔记三 3.1.行高偏移问题3.2.谷歌浏览器上不能定位3.2.2 移动端css隐藏滚动条 3.3.获取列表的数据3.3.1 服务器返回十万条数据3.3.2 分页展示数据3.3.2 防止展示数据为空报错 3.4.上拉加载数据3.4.1 加载更多数据3.4.2 监听页面滚动到底部3.4.3 监听滚动的时机…...
【商城实战(101)】电商未来已来:新技术引领商城发展新航向
【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配,乃至运营推广策略,102 章内容层层递进。无论是想…...
深入解析最大公约数(GCD)与最小公倍数(LCM)的C++实现
深入解析最大公约数(GCD)与最小公倍数(LCM)的C实现 一、GCD与LCM的数学定义 1. 最大公约数(GCD) 两个或多个整数共有约数中最大的一个。 例如: GCD(12, 18) 6GCD(21, 14) 7 2. 最小公倍数…...
低功耗LPWAN模块开发指南:远距离无线通信与边缘计算融合实战
在远程资产追踪、野外环境监测等场景中,稳定可靠的长距离通信与超低功耗是系统设计的核心挑战。eFish-SBC-RK3576通过 原生双UART接口 USB OTG扩展能力 ,可无缝集成主流LPWAN模组(LoRa/NB-IoT),实现“数据采集-边…...
【质量管理】纠正、纠正措施和预防的区别与解决问题的四重境界
“质量的定义就是符合要求”,我们在文章【质量管理】人们对于质量的五个错误观念-CSDN博客中提到过,这也是质量大师克劳士比所说的。“质量的系统就是预防”,防止出现产品不良而造成的质量损失。 质量问题的解决可以从微观和宏观两个方面来考…...
STM32F103_LL库+寄存器学习笔记12 - 提高串口通讯程序的健壮性:异常监控 + 超时保护机制
导言 首先,进行USART和DMA状态监测、记录异常状态并主动处理,是高健壮性嵌入式系统开发的核心思想之一。 这种机制看似复杂,实则能有效保障系统长期、稳定地运行: 提升通讯可靠性。降低维护成本。增强系统自恢复能力。 因此&…...
搜索-BFS
马上蓝桥杯了,最近刷了广搜,感觉挺有意思的,广搜题类型都差不多,模板也一样,大家写的时候可以直接套模板 这里给大家讲一个比较经典的广搜题-迷宫 题目问问能否走到 (n,m) 位置,假设最后一个点是我们的&…...
Keil调试(RTT Debug 断点)
调试 打印操作 方式接口优缺点串口打印TXRX简单,但是占用串口,速度慢,重定向fputc简单RTT打印SWDIOSWCLK速度快,不占额外接口,直接移植RTT库断点打印SWDIOSWCLKDebug的时候断点操作SWOSWDIOSWCLKSWO需要连接SWO引脚,重定向fputc简单 这里我只介绍RTT打印和断点打印; 一. RT…...
【jQuery】插件
目录 一、 jQuery插件 1. 瀑布流插件: jQuery 之家 http://www.htmleaf.com/ 2. 图片懒加载: jQuery 插件库 http://www.jq22.com/ 3. 全屏滚动 总结不易~ 本章节对我有很大收获,希望对你也是~~~ 一、 jQuery插件 jQuery 功能…...
leetcode 28 Find the Index of the First Occurrence in a String
直接用kmp算法 class Solution { public:int strStr(string haystack, string needle) {return kmp(haystack,needle);}int kmp(std::string &text,std::string &pattern){int n text.size();int m pattern.size();if(m 0)return 0;std::vector<int> next;ne…...
nginx 动静分离
一.动静分离 1.动静分离的好处 Apache Tocmat 严格来说是一款java EE服务器,主要是用来处理 servlet请求。处理css、js、图片这些静态文件的IO性能不够好,因此,将静态文件交给nginx处理,可以提高系统的访问速度,减少…...
1.2 斐波那契数列模型:LeetCode 面试题 08.01. 三步问题
动态规划解三步问题:LeetCode 面试题 08.01. 三步问题 1. 题目链接 LeetCode 面试题 08.01. 三步问题 题目要求:小孩上楼梯,每次可以走1、2或3步,计算到达第 n 阶台阶的不同方式数,结果需对 1e9 7 取模。 2. 题目描述…...
关于AutoMapper
AutoMapper 概述 AutoMapper 是一个基于约定的对象 - 对象映射库,主要用于在不同对象类型之间自动映射属性值。它能根据配置的映射规则,将源对象的属性值填充到目标对象中,避免了手动编写大量繁琐的对象映射代码。 作用 提升开发效率&…...
是否每一层之间都要线性变换和激活函数?
1. 神经网络层的基本组成 一个典型的神经网络层通常包含两个步骤: 线性变换(加权求和): z Wx} b 其中W 是权重矩阵,b是偏置向量,是输入,z 是线性输出。激活函数: 其中,…...
golang 的reflect包的常用方法
目录 reflect 包方法总结 类型 (Type) 方法 值 (Value) 方法 代码示例: reflect 包方法总结 p : Person{Name: "小明", Age: 22}t : reflect.TypeOf(&p)v : reflect.ValueOf(p) 类型 (Type) 方法 方法名描述示例 Na…...
CentOS 7 安装 EMQX (MQTT)
CentOS 7 安装 EMQX 通过 Yum 源安装 EMQX 支持通过 Yum 源安装,您可通过以下 Yum 命令从中自动下载和安装 EMQX。 通过以下命令配置 EMQX Yum 源: curl -s https://assets.emqx.com/scripts/install-emqx-rpm.sh | sudo bash安装以下依赖项ÿ…...
Flask项目部署:Flask + uWSGI + Nginx
目录 1,网络架构 2,环境安装 2.1,安装yum:Shell软件包管理器 2.2 安装python 2.3 安装uWSGI 2.4 安装Flask 3,上传工程包到服务器,打包Flask项目 4,创建和配置 uwsgi 配置文件 uwsgi.ini 4.1配置文件 4.2配置文件注释详解 5,启动服务 6,安装nginx 7,nginx配置 8,…...
软件工程面试题(十五)
1、servlet 创建过程以及ruquest,response,session的生命周期? Servlet的创建过程: 第一步 public class AAA extends HttpServlet{ 实现对应的doxxx方法 } 第二步: 在web.xml中配置 <servlet> <servlet-name></servlet-name> <servlet-c…...
当Kafka化身抽水马桶:论组件并发提升与系统可用性的量子纠缠关系
《当Kafka化身抽水马桶:论组件并发提升与系统可用性的量子纠缠关系》 引言:一场OOM引发的血案 某个月黑风高的夜晚,监控系统突然发出刺耳的警报——我们的数据发现流水线集体扑街。事后复盘发现:Kafka集群、Gateway、Discovery服…...
python和Java的区别
Python和Java是两种流行的编程语言,它们之间有一些重要的区别: 语法:Python是一种动态类型的脚本语言,语法简洁明了,通常使用缩进来表示代码块。Java是一种静态类型的编程语言,语法更为严格,需要…...
QFlightInstruments飞行仪表控件库
QFlightInstruments 是一个开源的飞行仪表控件库,专为基于 Qt 的应用程序设计。它提供了一系列仿真实飞机仪表的组件,适用于飞行模拟软件、航空电子系统或任何需要高仿真飞行仪表显示的项目。 主要功能 高仿真飞行仪表:包括空速表、高度表、…...
可发1区的超级创新思路(python\matlab实现):MPTS+Lconv+注意力集成机制的Transformer时间序列模型
首先声明,该模型为原创!原创!原创!且该思路还未有成果发表,感兴趣的小伙伴可以借鉴! 应用场景 该模型主要用于时间序列数据预测问题,包含功率预测、电池寿命预测、电机故障检测等等。 一、模型整体架构(本文以光伏功率预测为例) 本模型由多尺度特征提取模块(MPTS)…...
Nginx — Nginx版本升级
例如:将10.224.11.220、10.224.11.221、10.208.11.220 三台服务器上的Nginx从1.21.1版本升级到1.23.3版本。 一、Nginx升级步骤 步骤一:备份老版本的Nginx(10.224.11.220、10.224.11.221、10.208.11.220) #关闭Nginx cd /usr/l…...
CSS学习笔记6——网页布局
目录 一、元素的浮动属性、清除浮动 清除浮动的其他方法 1、使用空标签清除浮动影响 2、使用overflow属性清除浮动 3、使用伪元素清除浮动影响 原理 overflow属性 二、元素的定位 1、相对定位 2、绝对定位 编辑 3、固定定位 z-index层叠等级属性 一、元素的浮动…...
C语言【指针二】
引言 介绍:const修饰指针,野指针 应用:指针的使用(strlen的模拟实现),传值调用和传指调用 一、const修饰指针 1.const修饰变量 简单回顾一下前面学过的const修饰变量:在变量前面加上const&…...
第十六届蓝桥杯模拟二(串口通信)
由硬件框图可以知道我们要配置LED 和按键 一.LED 先配置LED的八个引脚为GPIO_OutPut,锁存器PD2也是,然后都设置为起始高电平,生成代码时还要去解决引脚冲突问题 二.按键 按键配置,由原理图按键所对引脚要GPIO_Input 生成代码,在文件夹中添加code文件夹,code中添加fun.…...
Java List 集合取交集、并集、差集、补集
在Java中,集合操作是编程中非常常见的需求,尤其是在处理数据集合时,如List、Set等。本文将详细介绍如何在Java中实现List集合的交集、并集、差集和补集操作,并提供代码示例和实现方法。 1. 交集操作 交集是指两个集合中都存在的元…...
SkyWalking+Springboot实战
1、下载SkyWalking APM 1.手动下载 Downloads | Apache SkyWalkinghttps://skywalking.apache.org/downloads/ 2.链接下载 https://dlcdn.apache.org/skywalking/10.2.0/apache-skywalking-apm-10.2.0.tar.gzhttps://dlcdn.apache.org/skywalking/10.2.0/apache-skywalking-…...
【小兔鲜】day01 项目、Vue3介绍、组合式API、小案例
【小兔鲜】day01 项目、Vue3介绍、组合式API、小案例 0. 市场上Vue前端工程师用到的技术1. Vue3小兔鲜先导课1.1 技术栈1.2 项目规模1.3 项目亮点1.4 课程安排 2. 认识Vue32.1 Vue3组合式API体验 3. create-vue创建Vue3项目3.1 新建项目结构3.2 小节3.3 补充说明npm init vuela…...
【Pandas DataFrame】
以下是 Pandas DataFrame 的核心知识点总结,用结构化分类帮你高效记忆关键操作和概念: 1. 基础操作 创建DataFrame 方法代码示例说明从字典创建df pd.DataFrame({A: [1,2], B: [3,4]})字典键为列名,值为数据从列表创建df pd.DataFrame([[…...
华为OD机试2025A卷 - 生成回文素数(Java Python JS C++ C )
最新华为OD机试 真题目录:点击查看目录 华为OD面试真题精选:点击立即查看 题目描述 求出大于或等于 N 的最小回文素数。 如果一个数大于 1,且其因数只有 1 和它自身,那么这个数是素数。 例如,2,3,5,7,11 以及 13 是素数。 如果一个数从左往右读与从右往左读是一…...
Jenkins教程(自动化部署)
Jenkins教程(自动化部署) 1. Jenkins是什么? Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,广泛用于项目开发,具有自动化构建、测试和部署等功能。Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行&…...
C#里使用libxl的对齐/边框/颜色
一份好的EXCEL文件,通道会有不同的颜色和边框来表示。 以便表示一些重要的信息,这样才能让人们一眼就看到需要关注的信息。 如下面所示: 要显示上面的内容,需要使用下面的例子: private void button12_Click(object sender, EventArgs e){var book = new ExcelBook();if…...
虚拟pinctrl驱动
之前呢,我们讲解了在内核中pinctrl子系统是怎么实现的,今天我们来尝试一下自己去写一个pinctrl子系统: 首先呢,我们来看看一个pinctrl子系统需要做的事情: 上面的话,我们看了一个pinctrl子系统需要的三大功能以及在驱…...
pycharm虚拟环境项目转移后配置解释器
添加解析器提示:无效的 Python SDK 解决方法 在到电脑安装python解析器,复制:python.exe和pythonw.exe 项目虚拟环境venv/Scripts Python解释器添加 项目现有虚拟环境,就可以正常使用...
蓝桥杯嵌入式学习笔记
用博客来记录一下参加蓝桥杯嵌入式第十六届省赛的学习经历 工具环境准备cubemx配置外部高速时钟使能设置串口时钟配置项目配置 keil配置烧录方式注意代码规范头文件配置 模块ledcubemx配置keil代码实现点亮一只灯实现具体操作的灯,以及点亮还是熄灭 按键cubemx配置k…...
0201-jsx语法基础-jsx-仿低代码平台项目
文章目录 1.jsx标签2.jsx属性3.jsx 事件3.1 声明事件3.2 使用事件(对象) 4. typescript类型基础4.1 类型声明4.2 事件函数传递自定义参数 5.插入js变量6. 条件判断7. 循环结语 1.jsx标签 jsx标签与html标签区别: 首字母大小写 大写是自定义组…...
在MCU工程中优化CPU工作效率的几种方法
在嵌入式系统开发中,优化 CPU 工作效率对于提升系统性能、降低功耗、提高实时性至关重要。Keil 作为主流的嵌入式开发工具,提供了多种优化策略,包括 关键字使用、内存管理、字节对齐、算法优化 等。本文将从多个方面介绍如何在 Keil 工程中优…...
Elasticsearch 的搜索功能
Elasticsearch 的搜索功能 建议阅读顺序: Elasticsearch 入门Elasticsearch 搜索(本文)Elasticsearch 搜索高级Elasticsearch 高级 1. 介绍 使用 Elasticsearch 最终目的是为了实现搜索功能,现在先将文档添加到索引中,…...
【鸿蒙5.0】向用户申请麦克风授权
#效果图 步骤 在 config.json 里声明权限:在项目的 config.json 文件中添加麦克风权限的声明,告知系统应用需要使用该权限。检查权限状态:在代码里检查应用是否已经获得了麦克风权限。请求权限:若应用未获得麦克风权限࿰…...
数据结构与算法分析:树与哈希表(一)
遇到的问题,都有解决方案,希望我的博客能为你提供一点帮助。 一、概述 背景:链表处理大量数据时,线性访问耗时多。二叉查找树多数操作平均运行时间为 O (log N),相对于链表树更加高效。 1.预备知识 1.1. 树的定义与…...
VBA第三十四期 VBA中怎么用OnKey事件
我们在VBA设计中经常需要使用到OnKey方法,特别是在窗口设计中比如我们想用到翻页按键,则就可以来建立一个OnKey事件。Setup_OnKey过程运行以后,就会达到最终效果,按PgDn键会将指针下移一行,按PgUp键会将指针上移一行。…...
HarmonyOS NEXT开发进阶(十五):日志打印 hilog 与 console.log 的区别
文章目录 一、前言二、两者区别对比三、HiLog 详解四、拓展阅读 一、前言 在日常开发阶段,日志打印是调试程序非常常用的操作,在鸿蒙的官方文档中介绍了hilog这种方式,前端转过来的开发者发现console.log也可以进行日志打印,而且…...
Skynet 框架中 gateserver、gate、watchdog 的关系
一、概述 在 Skynet 框架的网络通信架构中,gateserver、gate、watchdog 是三个核心组件,共同实现客户端连接的监听、管理和业务逻辑的分发。其设计目标是通过分层解耦,提升网络层的稳定性与业务逻辑的灵活性。 二、组件职责 1. gateserve…...
第11章:优化I/O_《C++性能优化指南》_notes
第十一章核心知识点详解 11.1 读取文件的优化技巧 重点:减少内存分配、使用大缓冲区、优化函数调用链。 难点:理解系统调用开销与缓冲区大小的权衡。 代码示例与详解 示例1:使用高效函数签名和减少内存分配 #include <fstream> #inc…...