微服務即時通信系統---(三)框架學習

目錄

brpc

RPC框架

核心概念

工作原理

介紹

安裝

頭文件包含和編譯時指明庫 

類與接口介紹

日志輸出類與接口

protobuf類與接口

Closure類 

RpcController類

服務端類與接口

ServerOptions類

Server類

ClosureGuard類

HttpHeader類

Controller類

客戶端類與接口

 ChannelOptions類

Channel類

使用

同步調用

proto文件

server端

client端

Makefile

異步調用

client端

封裝channel

封裝思想(結合etcd服務發現模塊的回調函數)

ServiceChannel類

ServiceChannelManager類

代碼測試

main.proto

reg.cc

dis.cc

Makefile

測試結果

本章主要是學習和使用本項目中所需使用到的一些框架。

brpc

RPC框架

RPC(Remote Procedure Call,遠程過程調用)框架,是一種用于實現分布式系統中跨網絡調用遠程服務的工具。

它允許程序像調用本地函數一樣調用遠程服務器上的函數,隱藏了底層網絡通信的復雜性。

舉例:想要實現一個a + b的函數,我們只需寫好函數頭,然后在函數內部調用遠程服務器上的a+b函數,遠程服務器計算完成之后返還結果。

核心概念

客戶端(Client)發起遠程調用的程序。
服務端(Server)提供遠程服務的程序。
存根(Stub)客戶端代理,負責將調用請求打包并發送給服務端。
骨架(Skeleton)

服務端代理,負責接收請求并調用實際的服務實現。

工作原理

調用客戶端通過存根發起遠程調用。
序列化存根將調用信息序列化為網絡傳輸格式。
傳輸序列化后的數據通過網絡發送到服務端。
反序列化服務端的骨架接收并反序列化數據。
執行骨架調用本地服務實現。
返回服務端將結果序列化后返回給客戶端。
反序列化客戶端存根接收并反序列化結果,返回給調用者。

介紹

brpc是用C++編寫的工業級RPC框架,常用于搜索、存儲、機器學習、廣告、推薦等高性能系統。

特點:

能搭建在一個端口支持多協議的服務,或訪問各種服務。
Server能同步或異步處理請求。
Client支持同步、異步、半同步,或使用組合channels簡化復雜的分庫或并發訪問。
通過http界面調試服務,使用cpu、heap、contention profilers。
獲得更好的延時和吞吐。
把你組織中使用的協議快速地加入brpc,或定制各類組件,包括命名服務,負載均衡。

安裝

先安裝依賴:

sudo apt-get install 
git g++ make libssl-dev libprotobuf-dev libprotoc-dev protobuf-compiler libleveldb-dev

通過github上的brpc源碼進行安裝。

brpc的github地址:https://github.com/apache/brpc.git

通過命令安裝:

# 克隆遠端倉庫
git clone https://github.com/apache/brpc.git# 進入工作目錄
cd brpc/# 創建build
mkdir build && cd build# 使用cmake構建Makefile
cmake .. -DCMAKE_INSTALL_PREFIX=/usr && cmake --build . -j6# make安裝
make && sudo make install

頭文件包含和編譯時指明庫 

#include <brpc/channel.h>
#include <brpc/server.h>
#include <butil/logging.h>
-lbrpc -lssl -lleveldb -lcrypto -lprotobuf -lgflags

類與接口介紹

日志輸出類與接口

本項目采用spdlog進行日志輸出,這里只是想關閉brpc自帶的日志輸出系統。

/usr/include/butil/logging.h:

namespace logging {// TODO(avi): do we want to do a unification of character types here?
#if defined(OS_WIN)
typedef wchar_t LogChar;
#else
typedef char LogChar;
#endif// Where to record logging output? A flat file and/or system debug log
// via OutputDebugString.
enum LoggingDestination {LOG_TO_NONE             = 0,LOG_TO_FILE             = 1 << 0,LOG_TO_SYSTEM_DEBUG_LOG = 1 << 1,LOG_TO_ALL = LOG_TO_FILE | LOG_TO_SYSTEM_DEBUG_LOG,// On Windows, use a file next to the exe; on POSIX platforms, where// it may not even be possible to locate the executable on disk, use// stderr.
#if defined(OS_WIN)LOG_DEFAULT = LOG_TO_FILE,
#elif defined(OS_POSIX)LOG_DEFAULT = LOG_TO_SYSTEM_DEBUG_LOG,
#endif
};struct BUTIL_EXPORT LoggingSettings {// The defaults values are:////  logging_dest: LOG_DEFAULT//  log_file:     NULL//  lock_log:     LOCK_LOG_FILE//  delete_old:   APPEND_TO_OLD_LOG_FILELoggingSettings();LoggingDestination logging_dest;// The three settings below have an effect only when LOG_TO_FILE is// set in |logging_dest|.const LogChar* log_file;LogLockingState lock_log;OldFileDeletionState delete_old;
};// This function may be called a second time to re-direct logging (e.g after
// loging in to a user partition), however it should never be called more than
// twice.
inline bool InitLogging(const LoggingSettings& settings) {return BaseInitLoggingImpl(settings);
}

通過logging::LoggingDestination::LOG_TO_NONE + LoggingSettings::logging_dest + InitLogging來將日志的輸出地設為0,即不輸出。 

#include <butil/logging.h>int main(int argc, char *argv[])
{logging::LoggingSettings settings;settings.logging_dest = logging::LoggingDestination::LOG_TO_NONE;logging::InitLogging(settings);return 0;
}

protobuf類與接口

Closure類 

/usr/include/google/protobuf/stubs/callback.h:

namespace google {
namespace protobuf {class PROTOBUF_EXPORT Closure {public:Closure() {}virtual ~Closure();virtual void Run() = 0;
};// See Closure.
inline Closure* NewCallback(void (*function)()) {return new internal::FunctionClosure0(function, true);
}}
}

Closure 類用于定義異步操作完成后的回調邏輯。它是一個抽象類,用戶需要繼承并實現 Run() 方法,該方法在 RPC 調用完成時被調用。

主要功能:

  • 回調機制Closure 允許用戶在 RPC 調用完成后執行自定義邏輯。

  • 資源管理:通過 NewCallback() 函數創建 Closure 對象,自動管理其生命周期。

即:Closure類中的Run方法,是在客戶端完成RPC調用之后的回調函數。

RpcController類

 /usr/include/google/protobuf/service.h:

namespace google {
namespace protobuf {
class PROTOBUF_EXPORT RpcController {// After a call has finished, returns true if the call failed.  The possible// reasons for failure depend on the RPC implementation.  Failed() must not// be called before a call has finished.  If Failed() returns true, the// contents of the response message are undefined.virtual bool Failed() const = 0;// If Failed() is true, returns a human-readable description of the error.virtual std::string ErrorText() const = 0;
};
}
}

RpcController 類用于控制 RPC 調用的行為和狀態,提供對調用過程的控制接口。

主要功能:

  • 調用控制:支持取消、重置等操作。

  • 狀態查詢:檢查調用是否完成、是否失敗等。

  • 錯誤處理:獲取錯誤信息和狀態碼。

常用方法:

  • Reset():重置控制器狀態,用于復用。

  • Failed():檢查調用是否失敗。

  • ErrorText():獲取錯誤信息。

  • SetFailed():手動標記調用為失敗。

  • StartCancel():取消調用。

服務端類與接口

ServerOptions類

/usr/include/brpc/server.h:

namespace brpc{
struct ServerOptions {// connections without data transmission for so many seconds will be closed// Default: -1 (disabled)int idle_timeout_sec// Number of pthreads that server runs on. Notice that this is just a hint,// you can't assume that the server uses exactly so many pthreads because// pthread workers are shared by all servers and channels inside a// process. And there're no "io-thread" and "worker-thread" anymore,// brpc automatically schedules "io" and "worker" code for better// parallelism and less context switches.// If this option <= 0, number of pthread workers is not changed.// Default: #cpu-coresint num_threads;};// Represent server's ownership of services.
enum ServiceOwnership {SERVER_OWNS_SERVICE, // 添加服務失敗時, 服務器自動刪除服務對象SERVER_DOESNT_OWN_SERVICE // 添加服務失敗時, 服務器不會刪除服務對象
};
}

向 brpc 服務器添加服務,通常是指用戶實現一個基于 Protobuf 定義的服務接口,并將其注冊到 brpc 服務器中。這個過程確實需要用戶重寫服務函數,但不僅僅是簡單的函數重寫,而是需要遵循一定的規范和流程。

以下是向 brpc 服務器添加服務的詳細步驟:

  1. 使用 Protobuf 定義服務接口。

  2. 實現服務接口中的虛函數(即重寫服務函數)。

  3. 將服務實例注冊到 brpc 服務器。

  4. 啟動服務器并處理客戶端請求。

Server類
namespace brpc{
class Server {// Start on IP_ANY:port.int Start(int port, const ServerOptions* opt);// Stop accepting new connections and requests from existing connections.// Returns 0 on success, -1 otherwi

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/71802.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/71802.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/71802.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

初識.git文件泄露

.git 文件泄露 當在一個空目錄執行 git init 時&#xff0c;Git 會創建一個 .git 目錄。 這個目錄包含所有的 Git 存儲和操作的對象。 如果想備份或復制一個版本庫&#xff0c;只需把這個目錄拷貝至另一處就可以了 這是一種常見的安全漏洞&#xff0c;指的是網站的 .git 目錄…

百度百舸 DeepSeek 一體機發布,支持昆侖芯 P800 單機 8 卡滿血版開箱即用

在私有云環境中成功部署 DeepSeek 滿血版并實現性能調優&#xff0c;并不是一件容易的事情。選擇合適的 GPU 配置、安裝相應的環境、成功部署上線業務、加速推理任務加速、支撐多用戶并發 …… 完成業務測試&#xff0c;成功融入生產業務中。 為了幫助企業快速實現 DeepSeek 服…

Mysql 主從集群同步延遲問題怎么解決

主從復制工作原理類比 假設主庫是快遞總倉&#xff0c;從庫是各個分店的倉庫&#xff1a; 總倉每次發貨/退貨都會記錄快遞單&#xff08;binlog&#xff09; 分店派快遞員&#xff08;I/O線程&#xff09;去總倉取快遞單 總倉安排一個打包員&#xff08;binlog dump線程&…

ASP.NET Core 簡單文件上傳

使用異步 JavaScript 和 XML&#xff08;AJAX&#xff09;進行簡單的文件上傳&#xff1b;用 C# 編寫的服務器端代碼。 使用AJAX和ASP.NET Core MVC上傳文件再簡單不過了。這不依賴于jQuery。此代碼允許上傳多個文件&#xff0c;并與 .NET Core 3.1、.NET 6和.NET 8兼容。 如果…

iOS指紋歸因詳解

iOS 指紋歸因&#xff08;Fingerprint Attribution&#xff09;詳解 1. 指紋歸因的概念 指紋歸因&#xff08;Fingerprint Attribution&#xff09;是一種無 ID 歸因&#xff08;ID-less Attribution&#xff09;技術&#xff0c;主要用于廣告跟蹤、用戶識別或流量分析。它基…

GMII(Gigabit Media Independent Interface)詳解

一、GMII的定義與作用 GMII&#xff08;千兆介質無關接口&#xff09;是用于千兆以太網&#xff08;1Gbps&#xff09;的標準化接口&#xff0c;連接 MAC層&#xff08;數據鏈路層&#xff09;與 PHY芯片&#xff08;物理層&#xff09;。其核心目標是支持高速數據傳輸&#x…

C++對象模型之C++額外成本

1.介紹 C與C最大的區別&#xff0c;無疑在于面向對象&#xff0c;面向對象編程給C帶來了強大的特性和靈活性。但同時也帶來了一定的運行時和編譯時的開銷。下面介紹C對象模型的額外成本及其來源。 2.C的額外成本 &#xff08;1&#xff09;虛函數和動態多態的成本 虛函數表&am…

【Excel】【VBA】根據內容調整打印區域

Excel VBA&#xff1a;自動調整打印區域的實用代碼解析 在Excel中&#xff0c;我們經常需要調整打印區域。今天介紹一段VBA代碼&#xff0c;它可以根據C列的內容自動調整打印區域。 Dim ws As Worksheet Dim lastRow As Long Dim r As Long 設置當前工作表 Set ws ActiveSh…

【關于seisimic unix中使用suedit指令無法保存問題】

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、如何修改頭文件二、出現的問題嘗試解決使用ls顯示文件屬性使用chmod修改文件屬性 總結 前言 提示&#xff1a;這里可以添加本文要記錄的大概內容&#xff…

微前端qiankun打包部署

官網&#xff1a;API 說明 - qiankun 前提&#xff1a;后臺項目&#xff0c;在主應用設置菜單&#xff0c;微應用渲染組件&#xff0c;沒有使用路由跳轉loadMicroApp 1.token需要使用setGlobalState&#xff0c;傳參或者方法用的setGlobalState 2.打包沒有使用Nginx 3.有需…

POST請求提交數據的三種方式及通過Postman實現

1、什么是POST請求&#xff1f; POST請求是HTPP協議中一種常用的請求方法&#xff0c;它的使用場景是向客戶端向服務器提交數據&#xff0c;比如登錄、注冊、添加等場景。另一種常用的請求方法是GET&#xff0c;它的使用場景是向服務器獲取數據。 2、POST請求提交數據的常見編…

【一起學Rust | 框架篇 | Tauri2.0框架】在Tauri應用中設置Http頭(Headers)

文章目錄 前言一、配置準備1. 檢查版本2. 使用條件3. 支持的請求頭&#xff08;并不是全部支持&#xff09; 二、使用步驟1. 如何配置header2. 框架集成1. 對于Vite系列、Nuxt、Next.js這種前端框架Vite系列框架Angular系列框架Nuxt系列框架Next.js系列框架 2. 對于Yew和Leptos…

Uniapp 開發中遇到的坑與注意事項:全面指南

文章目錄 1. 引言Uniapp 簡介開發中的常見問題本文的目標與結構 2. 環境配置與項目初始化環境配置問題解決方案 項目初始化注意事項解決方案 常見錯誤與解決方案 3. 頁面與組件開發頁面生命周期注意事項示例代碼 組件通信與復用注意事項示例代碼 樣式與布局問題注意事項示例代碼…

【藍橋杯集訓·每日一題2025】 AcWing 6135. 奶牛體檢 python

6135. 奶牛體檢 Week 1 2月21日 農夫約翰的 N N N 頭奶牛站成一行&#xff0c;奶牛 1 1 1 在隊伍的最前面&#xff0c;奶牛 N N N 在隊伍的最后面。 農夫約翰的奶牛也有許多不同的品種。 他用從 1 1 1 到 N N N 的整數來表示每一品種。 隊伍從前到后第 i i i 頭奶牛的…

算法系列之搜素算法-二分查找

在算法中&#xff0c;查找算法是處理數據集合的基礎操作之一。二分查找&#xff08;Binary Search&#xff09;是一種高效的查找算法&#xff0c;適用于有序數組或列表。本文將介紹二分查找的基本原理、Java實現。 二分查找介紹 二分查找是一種在有序數組中查找特定元素的算法…

JVM生產環境問題定位與解決實戰(三):揭秘Java飛行記錄器(JFR)的強大功能

提到飛行記錄器&#xff0c;或許你的腦海中并未立刻浮現出清晰的畫面&#xff0c;但一說起“黑匣子”&#xff0c;想必大多數人都能恍然大悟&#xff0c;知曉其重要性及用途。在航空領域&#xff0c;黑匣子作為不可或缺的設備&#xff0c;默默記錄著飛行過程中的每一項關鍵數據…

C#開發——ConcurrentDictionary集合

ConcurrentDictionary<TKey, TValue> 是 C# 中一個專為多線程場景設計的線程安全字典集合&#xff0c;位于 System.Collections.Concurrent 命名空間中。它允許多個線程同時對字典進行讀寫操作&#xff0c;而無需額外的同步措施。 一、集合特征 此集合有如下特征…

Unity百游修煉(2)——Brick_Breaker詳細制作全流程

一、項目簡介 Brick Breaker 是一款經典的打磚塊游戲&#xff0c;本次案例將使用 Unity 引擎來實現該游戲的核心功能。 游戲畫面如下&#xff1a; Brick_ breaker 二、項目結構概覽和前期準備 &#xff08;1&#xff09;在 Unity 項目視圖中&#xff0c;我們可以看到幾個重要…

KubeSphere平臺安裝

KubeSphere簡介 KubeSphere 是一款功能強大的容器管理平臺&#xff0c;以下是其簡介&#xff1a; 1&#xff09;基本信息 開源項目&#xff1a;基于 Apache-2.0 授權協議開源&#xff0c;由 Google Go、Groovy、HTML/CSS 和 Shell 等多種編程語言開發。基礎架構&#xff1a;…

UE5銷毀Actor,移動Actor,簡單的空氣墻的制作

1.銷毀Actor 1.Actor中存在Destory()函數和Destoryed()函數 Destory()函數是成員函數&#xff0c;它會立即標記 Actor 為銷毀狀態&#xff0c;并且會從場景中移除該 Actor。它會觸發生命周期中的銷毀過程&#xff0c;調用 Destroy() 后&#xff0c;Actor 立即進入銷毀過程。具體…