C++ - 仿 RabbitMQ 實現消息隊列(1)(環境搭建)
- 什么是消息隊列
- 核心特點
- 核心組件
- 工作原理
- 常見消息隊列實現
- 應用場景
- 優缺點
- 項目配置
- 開發環境
- 技術選型
- 更換軟件源
- 安裝一些工具
- 安裝epel 軟件源
- 安裝 lrzsz 傳輸工具
- 安裝git
- 安裝 cmake
- 安裝 SQLite3
- 安裝GTest
- 安裝高版本 gcc/g++編譯器
- 1. 確認可用的 GCC 工具集版本
- 2. 安裝默認的 GCC 工具集
- 3. 正確的啟用方式
- 4. 永久啟用(可選)
- 安裝Protobuf
- 1. 解壓源碼包
- 2. 進入源碼目錄
- 3. 生成配置腳本
- 4. 配置編譯選項
- 5. 編譯源碼
- 6. 安裝到系統
- 7. 更新動態庫緩存
- 完整流程總結
- 驗證安裝
- 安裝 Muduo
我們今天來開一個新的項目仿 RabbitMQ 實現消息隊列,這個項目更加接近公司的開發流程,開發和測試各個方面都會涉及到。不過在這之前,我們先來了解一下什么是消息隊列,消息隊列是用來干嘛的。
什么是消息隊列
消息隊列(Message Queue)是一種用于在分布式系統或應用程序之間傳遞消息的通信機制,它通過一個中間存儲結構(隊列)來管理消息的傳遞,允許發送方和接收方以異步的方式交互。消息隊列的核心作用是解耦生產者和消費者,提升系統的可擴展性、可靠性和性能。
核心特點
-
解耦性
生產者(發送方)和消費者(接收方)無需直接通信,也無需知道彼此的存在。雙方通過消息隊列進行交互,降低了系統間的耦合度。 -
異步通信
生產者將消息發送到隊列后,無需等待消費者立即處理,可以繼續執行其他任務。消費者可以按自己的節奏處理消息,提高系統響應速度。 -
削峰填谷
在流量高峰時,消息隊列可以緩沖大量請求,避免系統過載。消費者可以逐步處理隊列中的消息,平穩系統負載。 -
可靠性
消息隊列通常提供持久化存儲,即使消費者崩潰或網絡中斷,消息也不會丟失,確保數據不丟失。
核心組件
-
生產者(Producer)
負責生成消息并將其發送到消息隊列中。 -
消息隊列(Message Queue)
中間存儲結構,用于臨時存儲消息,支持消息的持久化、排序和分發。 -
消費者(Consumer)
從消息隊列中獲取消息并進行處理。
工作原理
- 生產者發送消息:生產者將消息發送到指定的隊列中。
- 消息存儲:消息隊列將消息持久化存儲,等待消費者處理。
- 消費者拉取或推送消息:消費者從隊列中獲取消息(拉取模式)或通過訂閱機制接收消息(推送模式)。
- 消息處理:消費者處理消息,并可能返回處理結果。
- 消息確認(可選):消費者處理完成后,向消息隊列發送確認信號,隊列可以刪除或標記消息為已處理。
常見消息隊列實現
-
RabbitMQ
- 基于AMQP協議的開源消息代理,支持多種消息模式(如發布/訂閱、路由、主題)。
- 適合需要靈活路由和復雜消息模式的場景。
-
Kafka
- 高吞吐量的分布式消息系統,常用于大數據和實時流處理。
- 支持持久化日志、分區和副本,適合大規模數據處理。
-
ActiveMQ
- 基于JMS規范的開源消息代理,支持多種協議(如AMQP、STOMP、MQTT)。
- 適合企業級應用和集成場景。
-
Redis Stream
- Redis 5.0引入的流數據結構,支持簡單的消息隊列功能。
- 適合輕量級、低延遲的場景。
-
Amazon SQS/Azure Service Bus
- 云服務提供商提供的托管消息隊列服務,適合云原生應用。
應用場景
-
異步任務處理
例如:用戶注冊后發送歡迎郵件、訂單處理后更新庫存。 -
應用解耦
例如:電商系統中,訂單服務、支付服務和物流服務通過消息隊列解耦。 -
流量削峰
例如:秒殺活動中,將用戶請求暫存到消息隊列,后臺服務逐步處理。 -
日志處理
例如:將應用日志發送到消息隊列,由日志收集服務統一處理。 -
事件驅動架構
例如:微服務架構中,服務之間通過事件消息進行通信。
優缺點
優點:
- 解耦生產者和消費者,降低系統復雜度。
- 支持異步通信,提高系統響應速度。
- 提供削峰填谷能力,增強系統穩定性。
- 支持消息持久化,確保數據不丟失。
缺點:
- 引入了額外的組件,增加了系統復雜度。
- 消息順序和重復消費等問題需要額外處理。
- 消息隊列本身可能成為性能瓶頸(需合理設計)。
我們這次的項目圍繞著RabbitMQ 模擬實現一個簡單的消息隊列
項目配置
開發環境
組件 | 版本/工具 |
---|---|
操作系統 | CentOS9 / Ubuntu-22.04 |
代碼編輯器 | VSCode / Vim |
編譯調試工具 | g++ / gdb |
構建工具 | Makefile |
技術選型
類別 | 選擇 |
---|---|
開發主語言 | C++ |
序列化框架 | Protobuf 二進制序列化 |
網絡通信方案 | 自定義應用層協議 + muduo庫(推薦,適用于TCP長連接及高并發場景) 或者自定義應用層協議 + 原生socket(復雜度較高) |
數據庫 | SQLite3 |
單元測試框架 | Gtest |
更換軟件源
首先,我們得要首先把軟件源換成國內的,如果使用系統本身的軟件源,就要訪問國外的網站,速度會非常慢。
我們換成清華大學的鏡像源:
https://mirrors.tuna.tsinghua.edu.cn/
執行以下的代碼:
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),具體作用如下:
- 使用
sudo tee
命令將后面的內容寫入/etc/yum.repos.d/CentOS-Stream.repo
文件(需要管理員權限) << 'EOF'
表示將后續內容作為標準輸入,直到遇到EOF
結束標記- 文件內容配置了三個軟件源倉庫:
[baseos]
:基礎操作系統軟件包[appstream]
:應用程序包[extras]
:額外軟件包
每個倉庫配置包含:
name
:倉庫描述名稱(標明是清華鏡像源)baseurl
:指定軟件包的下載地址(使用清華大學開源鏡像站)gpgcheck=1
:啟用 GPG 簽名驗證gpgkey
:指定 GPG 密鑰位置用于驗證軟件包
這樣配置后,當你使用 yum
或 dnf
命令安裝軟件時,系統會從清華大學的鏡像站點下載 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 軟件源
sudo dnf install epel-release
安裝 lrzsz 傳輸工具
sudo dnf install lrzsz
安裝git
sudo dnf install git
安裝 cmake
sudo dnf install cmake
安裝 SQLite3
sudo dnf install sqlite-devel
安裝GTest
sudo dnf install gtest gtest-devel
ls /usr/include/gtest/gtest.h
安裝高版本 gcc/g++編譯器
在 CentOS Stream 9 中,gcc-toolset-11
可能不再直接提供,或者它的包名稱/倉庫配置發生了變化。以下是解決方案:
1. 確認可用的 GCC 工具集版本
運行以下命令查看當前可用的 GCC 相關包:
dnf search gcc-toolset
我們這里選擇12版本
2. 安裝默認的 GCC 工具集
CentOS Stream 9 可能默認提供 GCC Toolset 12 或更高版本:
sudo dnf install gcc-toolset-12
3. 正確的啟用方式
在 CentOS Stream 9 中,gcc-toolset-12
不再通過 module load
啟用,而是通過 直接加載環境變量:
source /opt/rh/gcc-toolset-12/enable
然后驗證 GCC 版本:
gcc --version
4. 永久啟用(可選)
如果希望每次登錄自動啟用,可以將以下內容添加到 ~/.bashrc
:
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
然后執行以下代碼:
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. 解壓源碼包
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. 進入源碼目錄
cd protobuf-21.12
- 作用:切換到解壓后的 Protobuf 源碼目錄,準備進行編譯。
3. 生成配置腳本
./autogen.sh
- 作用:運行
autogen.sh
腳本,生成configure
文件(如果源碼包未提供預生成的configure
文件)。 - 適用場景:
某些開源項目(如 Protobuf)使用autotools
構建系統,需要先運行autogen.sh
生成configure
腳本。
4. 配置編譯選項
./configure
- 作用:運行
configure
腳本,檢測系統環境(如編譯器、庫路徑等),并生成Makefile
。 - 關鍵行為:
- 檢查系統是否安裝了必要的依賴(如
g++
、make
、libtool
等)。 - 生成針對當前系統的編譯配置(如優化選項、安裝路徑等)。
- 檢查系統是否安裝了必要的依賴(如
- 自定義選項:
可以通過參數指定安裝路徑(如./configure --prefix=/usr/local/protobuf
)。
5. 編譯源碼
make -j$(nproc)
- 作用:使用
make
編譯 Protobuf 源碼。 - 參數說明:
-j$(nproc)
:啟用多線程編譯,$(nproc)
自動獲取 CPU 核心數,加速編譯過程。
- 結果:生成可執行文件和庫(如
protoc
編譯器、libprotobuf.so
等)。
6. 安裝到系統
sudo make install
- 作用:將編譯好的 Protobuf 文件安裝到系統目錄(如
/usr/local/bin
、/usr/local/lib
)。 - 權限要求:需要
sudo
權限,因為安裝到系統目錄需要管理員權限。 - 安裝內容:
- 可執行文件(如
protoc
)安裝到/usr/local/bin
。 - 庫文件(如
libprotobuf.*
)安裝到/usr/local/lib
。 - 頭文件安裝到
/usr/local/include
。
- 可執行文件(如
7. 更新動態庫緩存
sudo ldconfig
- 作用:更新系統的動態庫緩存,使新安裝的 Protobuf 庫(
libprotobuf.so
)能被系統識別。 - 必要性:
如果不運行ldconfig
,程序在運行時可能找不到新安裝的庫,導致報錯(如libprotobuf.so: cannot open shared object file
)。
完整流程總結
- 解壓源碼:
tar -xzf protobuf-all-21.12.tar.gz
- 進入目錄:
cd protobuf-21.12
- 生成配置腳本:
./autogen.sh
- 配置環境:
./configure
- 編譯代碼:
make -j$(nproc)
- 安裝到系統:
sudo make install
- 更新庫緩存:
sudo ldconfig
驗證安裝
安裝完成后,可以通過以下命令驗證 Protobuf 是否安裝成功:
protoc --version # 檢查 protoc 版本
如果輸出版本號(如 libprotoc 3.21.12
),則安裝成功。
安裝 Muduo
先獲取一下zip包:
wget https://gitee.com/hansionz/mq/raw/master/resource/muduo-master.zip
unzip muduo-master.zip
cd muduo-master
Muduo 需要以下依賴:
sudo dnf install -y gcc-c++ cmake make \boost-devel openssl-devel protobuf-devel \zlib-devel curl-devel
然后進行編譯
# 進入 Muduo 源碼目錄
cd muduo-master# 使用 CMake 構建
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release .. # 推薦 Release 模式
make -j$(nproc) # 并行編譯
最后進行安裝:
sudo make install
然后進入到bin目錄我們可以來測試一下:
執行:
./protobuf_server 9091
然后復制SSH渠道,執行:
./protobuf_client 0.0.0.0 9091