C++ - 仿 RabbitMQ 实现消息队列(1)(环境搭建)

C++ - 仿 RabbitMQ 实现消息队列(1)(环境搭建)

我们今天来开一个新的项目仿 RabbitMQ 实现消息队列,这个项目更加接近公司的开发流程,开发和测试各个方面都会涉及到。不过在这之前,我们先来了解一下什么是消息队列,消息队列是用来干嘛的。

什么是消息队列

消息队列(Message Queue)是一种用于在分布式系统或应用程序之间传递消息的通信机制,它通过一个中间存储结构(队列)来管理消息的传递,允许发送方和接收方以异步的方式交互。消息队列的核心作用是解耦生产者和消费者,提升系统的可扩展性、可靠性和性能。

核心特点

  1. 解耦性

    生产者(发送方)和消费者(接收方)无需直接通信,也无需知道彼此的存在。双方通过消息队列进行交互,降低了系统间的耦合度。

  2. 异步通信

    生产者将消息发送到队列后,无需等待消费者立即处理,可以继续执行其他任务。消费者可以按自己的节奏处理消息,提高系统响应速度。

  3. 削峰填谷

    在流量高峰时,消息队列可以缓冲大量请求,避免系统过载。消费者可以逐步处理队列中的消息,平稳系统负载。

  4. 可靠性

    消息队列通常提供持久化存储,即使消费者崩溃或网络中断,消息也不会丢失,确保数据不丢失。

核心组件

  1. 生产者(Producer)

    负责生成消息并将其发送到消息队列中。

  2. 消息队列(Message Queue)

    中间存储结构,用于临时存储消息,支持消息的持久化、排序和分发。

  3. 消费者(Consumer)

    从消息队列中获取消息并进行处理。

工作原理

  1. 生产者发送消息:生产者将消息发送到指定的队列中。
  2. 消息存储:消息队列将消息持久化存储,等待消费者处理。
  3. 消费者拉取或推送消息:消费者从队列中获取消息(拉取模式)或通过订阅机制接收消息(推送模式)。
  4. 消息处理:消费者处理消息,并可能返回处理结果。
  5. 消息确认(可选):消费者处理完成后,向消息队列发送确认信号,队列可以删除或标记消息为已处理。

常见消息队列实现

  1. RabbitMQ

    • 基于AMQP协议的开源消息代理,支持多种消息模式(如发布/订阅、路由、主题)。
    • 适合需要灵活路由和复杂消息模式的场景。
  2. Kafka

    • 高吞吐量的分布式消息系统,常用于大数据和实时流处理。
    • 支持持久化日志、分区和副本,适合大规模数据处理。
  3. ActiveMQ

    • 基于JMS规范的开源消息代理,支持多种协议(如AMQP、STOMP、MQTT)。
    • 适合企业级应用和集成场景。
  4. Redis Stream

    • Redis 5.0引入的流数据结构,支持简单的消息队列功能。
    • 适合轻量级、低延迟的场景。
  5. Amazon SQS/Azure Service Bus

    • 云服务提供商提供的托管消息队列服务,适合云原生应用。

应用场景

  1. 异步任务处理

    例如:用户注册后发送欢迎邮件、订单处理后更新库存。

  2. 应用解耦

    例如:电商系统中,订单服务、支付服务和物流服务通过消息队列解耦。

  3. 流量削峰

    例如:秒杀活动中,将用户请求暂存到消息队列,后台服务逐步处理。

  4. 日志处理

    例如:将应用日志发送到消息队列,由日志收集服务统一处理。

  5. 事件驱动架构

    例如:微服务架构中,服务之间通过事件消息进行通信。

优缺点

优点

  • 解耦生产者和消费者,降低系统复杂度。
  • 支持异步通信,提高系统响应速度。
  • 提供削峰填谷能力,增强系统稳定性。
  • 支持消息持久化,确保数据不丢失。

缺点

  • 引入了额外的组件,增加了系统复杂度。
  • 消息顺序和重复消费等问题需要额外处理。
  • 消息队列本身可能成为性能瓶颈(需合理设计)。

我们这次的项目围绕着RabbitMQ 模拟实现一个简单的消息队列

项目配置

开发环境

组件 版本/工具
操作系统 CentOS9 / Ubuntu-22.04
代码编辑器 VSCode / Vim
编译调试工具 g++ / gdb
构建工具 Makefile

技术选型

类别 选择
开发主语言 C++
序列化框架 Protobuf 二进制序列化
网络通信方案 自定义应用层协议 + muduo库(推荐,适用于TCP长连接及高并发场景) 或者自定义应用层协议 + 原生socket(复杂度较高)
数据库 SQLite3
单元测试框架 Gtest

更换软件源

首先,我们得要首先把软件源换成国内的,如果使用系统本身的软件源,就要访问国外的网站,速度会非常慢。

我们换成清华大学的镜像源:

https://mirrors.tuna.tsinghua.edu.cn/

执行以下的代码:

bash 复制代码
sudo tee /etc/yum.repos.d/CentOS-Stream.repo << 'EOF'
[baseos]
name=CentOS Stream 9 - BaseOS (Tsinghua)
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos-stream/9-stream/BaseOS/x86_64/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial

[appstream]
name=CentOS Stream 9 - AppStream (Tsinghua)
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos-stream/9-stream/AppStream/x86_64/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial

[extras]
name=CentOS Stream 9 - Extras (Tsinghua)
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos-stream/SIGs/9-stream/extras/x86_64/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
EOF

这段代码是在配置 CentOS Stream 9 的 YUM 软件仓库(repository),具体作用如下:

  1. 使用 sudo tee 命令将后面的内容写入 /etc/yum.repos.d/CentOS-Stream.repo 文件(需要管理员权限)
  2. << 'EOF' 表示将后续内容作为标准输入,直到遇到 EOF 结束标记
  3. 文件内容配置了三个软件源仓库:
    • [baseos]:基础操作系统软件包
    • [appstream]:应用程序包
    • [extras]:额外软件包

每个仓库配置包含:

  • name:仓库描述名称(标明是清华镜像源)
  • baseurl:指定软件包的下载地址(使用清华大学开源镜像站)
  • gpgcheck=1:启用 GPG 签名验证
  • gpgkey:指定 GPG 密钥位置用于验证软件包

这样配置后,当你使用 yumdnf 命令安装软件时,系统会从清华大学的镜像站点下载 CentOS Stream 9 的软件包,速度会比官方源更快(特别是在中国境内)。

注意:这段代码会覆盖同名的现有仓库配置文件,如果之前有其他配置会被替换。

大家注意一下三个部分的baseurl,如果路径不对,是会失败的,这里给大家指明一下路径:

baseos的baseurl:

https://mirrors.tuna.tsinghua.edu.cn/centos-stream/9-stream/BaseOS/x86_64/

appstream的baseurl:

https://mirrors.tuna.tsinghua.edu.cn/centos-stream/9-stream/AppStream/x86_64/os/

extras的baseurl:

https://mirrors.tuna.tsinghua.edu.cn/centos-stream/SIGs/9-stream/extras/x86_64/

安装一些工具

安装epel 软件源

bash 复制代码
sudo dnf install epel-release

安装 lrzsz 传输工具

bash 复制代码
sudo dnf install lrzsz

安装git

bash 复制代码
sudo dnf install git


安装 cmake

bash 复制代码
sudo dnf install cmake

安装 SQLite3

bash 复制代码
sudo dnf install sqlite-devel

安装GTest

bash 复制代码
sudo dnf install gtest gtest-devel
bash 复制代码
ls /usr/include/gtest/gtest.h

安装高版本 gcc/g++编译器

在 CentOS Stream 9 中,gcc-toolset-11 可能不再直接提供,或者它的包名称/仓库配置发生了变化。以下是解决方案:


1. 确认可用的 GCC 工具集版本

运行以下命令查看当前可用的 GCC 相关包:

bash 复制代码
dnf search gcc-toolset

我们这里选择12版本

2. 安装默认的 GCC 工具集

CentOS Stream 9 可能默认提供 GCC Toolset 12 或更高版本:

bash 复制代码
sudo dnf install gcc-toolset-12

3. 正确的启用方式

在 CentOS Stream 9 中,gcc-toolset-12 不再通过 module load 启用,而是通过 直接加载环境变量

bash 复制代码
source /opt/rh/gcc-toolset-12/enable

然后验证 GCC 版本:

bash 复制代码
gcc --version

4. 永久启用(可选)

如果希望每次登录自动启用,可以将以下内容添加到 ~/.bashrc

bash 复制代码
echo 'source /opt/rh/gcc-toolset-12/enable' >> ~/.bashrc
source ~/.bashrc

安装Protobuf

这里建议大家先在windows上下好了传到Linux上:

下载链接(如果有VPN,可以开一个,下得快):

https://github.com/protocolbuffers/protobuf/releases/download/v3.2
0.2/protobuf-all-3.20.2.tar.gz

然后执行以下代码:

bash 复制代码
tar -xzf protobuf-all-21.12.tar.gz
cd protobuf-21.12
./autogen.sh
./configure
make -j$(nproc)
sudo make install
sudo ldconfig

这段代码是用于从源码编译并安装 Protocol Buffers (Protobuf) 的完整流程。Protobuf 是 Google 开发的一种高效的数据序列化格式,广泛用于网络通信和数据存储。以下是每一步的详细解释:


1. 解压源码包

bash 复制代码
tar -xzf protobuf-all-21.12.tar.gz
  • 作用 :解压名为 protobuf-all-21.12.tar.gz 的压缩包。
  • 参数说明
    • -x:解压文件。
    • -z:使用 gzip 解压(针对 .tar.gz 文件)。
    • -f:指定文件名。
  • 结果 :生成 protobuf-21.12 目录,包含 Protobuf 的源码。

2. 进入源码目录

bash 复制代码
cd protobuf-21.12
  • 作用:切换到解压后的 Protobuf 源码目录,准备进行编译。

3. 生成配置脚本

bash 复制代码
./autogen.sh
  • 作用 :运行 autogen.sh 脚本,生成 configure 文件(如果源码包未提供预生成的 configure 文件)。
  • 适用场景
    某些开源项目(如 Protobuf)使用 autotools 构建系统,需要先运行 autogen.sh 生成 configure 脚本。

4. 配置编译选项

bash 复制代码
./configure
  • 作用 :运行 configure 脚本,检测系统环境(如编译器、库路径等),并生成 Makefile
  • 关键行为
    • 检查系统是否安装了必要的依赖(如 g++makelibtool 等)。
    • 生成针对当前系统的编译配置(如优化选项、安装路径等)。
  • 自定义选项
    可以通过参数指定安装路径(如 ./configure --prefix=/usr/local/protobuf)。

5. 编译源码

bash 复制代码
make -j$(nproc)
  • 作用 :使用 make 编译 Protobuf 源码。
  • 参数说明
    • -j$(nproc):启用多线程编译,$(nproc) 自动获取 CPU 核心数,加速编译过程。
  • 结果 :生成可执行文件和库(如 protoc 编译器、libprotobuf.so 等)。

6. 安装到系统

bash 复制代码
sudo make install
  • 作用 :将编译好的 Protobuf 文件安装到系统目录(如 /usr/local/bin/usr/local/lib)。
  • 权限要求 :需要 sudo 权限,因为安装到系统目录需要管理员权限。
  • 安装内容
    • 可执行文件(如 protoc)安装到 /usr/local/bin
    • 库文件(如 libprotobuf.*)安装到 /usr/local/lib
    • 头文件安装到 /usr/local/include

7. 更新动态库缓存

bash 复制代码
sudo ldconfig
  • 作用 :更新系统的动态库缓存,使新安装的 Protobuf 库(libprotobuf.so)能被系统识别。
  • 必要性
    如果不运行 ldconfig,程序在运行时可能找不到新安装的库,导致报错(如 libprotobuf.so: cannot open shared object file)。

完整流程总结

  1. 解压源码tar -xzf protobuf-all-21.12.tar.gz
  2. 进入目录cd protobuf-21.12
  3. 生成配置脚本./autogen.sh
  4. 配置环境./configure
  5. 编译代码make -j$(nproc)
  6. 安装到系统sudo make install
  7. 更新库缓存sudo ldconfig

验证安装

安装完成后,可以通过以下命令验证 Protobuf 是否安装成功:

bash 复制代码
protoc --version  # 检查 protoc 版本

如果输出版本号(如 libprotoc 3.21.12),则安装成功。

安装 Muduo

先获取一下zip包:

wget https://gitee.com/hansionz/mq/raw/master/resource/muduo-master.zip

bash 复制代码
unzip muduo-master.zip
cd muduo-master

Muduo 需要以下依赖:

bash 复制代码
sudo dnf install -y gcc-c++ cmake make \
    boost-devel openssl-devel protobuf-devel \
    zlib-devel curl-devel

然后进行编译

bash 复制代码
# 进入 Muduo 源码目录
cd muduo-master

# 使用 CMake 构建
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..  # 推荐 Release 模式
make -j$(nproc)  # 并行编译

最后进行安装:

bash 复制代码
sudo make install

然后进入到bin目录我们可以来测试一下:

执行:

bash 复制代码
./protobuf_server 9091

然后复制SSH渠道,执行:

bash 复制代码
./protobuf_client 0.0.0.0 9091
相关推荐
H2X7_2 分钟前
C++之异常
开发语言·c++
wen__xvn3 分钟前
每日一题洛谷P1025 [NOIP 2001 提高组] 数的划分c++
数据结构·c++·算法
南玖yy19 分钟前
探索 C++ 语言标准演进:从 C++23 到 C++26 的飞跃
开发语言·c++·人工智能·安全·c++23·c++基础语法
xwy1388646707722 分钟前
C++复习
开发语言·c++
2301_8170316528 分钟前
C语言--字符函数
c语言·开发语言
qq_366086221 小时前
hashMap一些不太常用但非常有用的方法及使用示例
java·开发语言
刚入门的大一新生1 小时前
C++初阶-string类4
开发语言·c++
MeiYu_1231 小时前
【数据结构与算法】常见排序算法详解(C++实现)
数据结构·c++·算法·排序算法
满怀10151 小时前
【Python】os模块
开发语言·python
请来次降维打击!!!1 小时前
优选算法系列(8.多源BFS)
java·c++·算法·宽度优先