【微服务即时通讯系统】——brpc远程过程调用、百度开源的RPC框架、brpc的介绍、brpc的安装、brpc使用和功能测试
文章目录
- brpc
- 1. brpc的介绍
- 1.1 rpc的介绍
- 1.2 rpc的原理
- 1.3 grpc和brpc
- 2. brpc的安装
- 3. brpc使用
- 3.1 brpc接口介绍
- 4. brpc使用测试
- 4.1 brpc同步和异步调用
brpc
1. brpc的介绍
1.1 rpc的介绍
RPC(Remote Procedure Call)远程过程调用,是一种计算机通信协议,它允许程序在不同的计算机之间进行通信和交互,就像本地调用一样。
RPC可以屏蔽了底层的网络通信细节,使得程序间的远程通信如同本地调用一样简单。RPC机制使得开发者能够构建分布式计算系统,其中不同的组件可以分布在不同的计算机上,但它们之间可以像在同一台机器上一样相互调用。
1.2 rpc的原理
服务提供者实现特定业务逻辑并注册到服务中心。
服务中心接收注册信息,为服务消费者提供服务发现通知和负载均衡功能。
服务消费者向服务中心查询服务订阅后,通过 RPC 机制发起对服务提供者的远程调用,接收并处理结果。
rpc一次调用的过程
在 RPC(远程过程调用)机制中,客户端以接口方式调用服务。客户端存根在接收到调用请求后,将方法、入参等信息组装并序列化成可网络传输的消息体(二进制流),然后找到远程服务地址,通过网络(sockets)将消息发送给服务端。
服务端存根收到消息后进行反序列化操作(将二进制流反序列化为消息对象),接着调用本地服务进行处理。服务端将处理结果返回给服务端存根,服务端存根序列化处理结果(将结果消息对象序列化为二进制流)。
再通过网络(sockets)发送至客户端。客户端存根接收到消息后进行反序列化解码(将结果二进制流反序列化为消息对象),最终客户端得到结果。
1.3 grpc和brpc
gRPC
由 Google 开发并开源。
支持 C++、Java、Python、Go 。
使用 Protocol Buffers 作为默认的接口定义语言和数据序列化格式。
基于 HTTP/2 协议,支持双向流和多路复用,能够有效地提高网络传输效率。
适用于构建分布式系统、微服务架构等场景。
bRPC
由 Baidu 开发并开源。
只支持 C++ 。
使用 Protocol Buffers 作为默认的接口定义语言和数据序列化格式。
可以在一个端口上支持多协议服务,如 HTTP/HTTPS、Redis、Thrift 等,具有很高的灵活性。
提供了一些独特的功能,如通过 HTTP 界面调试服务、使用各种性能分析工具等。
适用于搜索、存储、机器学习等高性能系统的开发。
2. brpc的安装
在 Linux 系统(ubuntu) 上安装 brpc 的基本步骤:
先安装依赖:
sudo apt-get install -y git g++ make libssl-dev libprotobuf-dev libprotoc-dev protobuf-compiler libleveldb-dev
安装 brpc:
git clone https://github.com/apache/brpc.git
cd brpc/
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
cmake --build . -j6
make && sudo make install
3. brpc使用
3.1 brpc接口介绍
日志输出类与接口:
包含头文件: #include <butil/logging.h>
namespace logging {
enum LoggingDestination {LOG_TO_NONE = 0
};
struct BUTIL_EXPORT LoggingSettings {LoggingSettings();LoggingDestination logging_dest;
};
bool InitLogging(const LoggingSettings& settings);
}
protobuf 类与接口:
namespace google {
namespace protobuf {class PROTOBUF_EXPORT Closure {public:Closure() {}virtual ~Closure();virtual void Run() = 0;
};
inline Closure* NewCallback(void (*function)());
class PROTOBUF_EXPORT RpcController {bool Failed();std::string ErrorText() ;
}
}
}
服务端类与接口:
namespace brpc {
struct ServerOptions {//无数据传输,则指定时间后关闭连接int idle_timeout_sec; // Default: -1 (disabled)int num_threads; // Default: #cpu-cores//....
}
enum ServiceOwnership {//添加服务失败时,服务器将负责删除服务对象SERVER_OWNS_SERVICE,//添加服务失败时,服务器也不会删除服务对象SERVER_DOESNT_OWN_SERVICE
};
class Server {int AddService(google::protobuf::Service* service,ServiceOwnership ownership);int Start(int port, const ServerOptions* opt);int Stop(int closewait_ms/*not used anymore*/);int Join();//休眠直到 ctrl+c 按下,或者 stop 和 join 服务器void RunUntilAskedToQuit();
}
class ClosureGuard {explicit ClosureGuard(google::protobuf::Closure* done);~ClosureGuard() { if (_done) _done->Run(); }
}
class HttpHeader {void set_content_type(const std::string& type)const std::string* GetHeader(const std::string& key)void SetHeader(const std::string& key, const std::string& value);const URI& uri() const { return _uri; }HttpMethod method() const { return _method; }void set_method(const HttpMethod method)int status_code()void set_status_code(int status_code);}
class Controller : public google::protobuf::RpcController {void set_timeout_ms(int64_t timeout_ms);void set_max_retry(int max_retry);google::protobuf::Message* response();HttpHeader& http_response();HttpHeader& http_request();bool Failed();std::string ErrorText();using AfterRpcRespFnType = std::function<void(Controller* cntl,const google::protobuf::Message* req,const google::protobuf::Message* res)>;void set_after_rpc_resp_fn(AfterRpcRespFnType&& fn)
}
客户端类与接口:
namespace brpc {
struct ChannelOptions {//请求连接超时时间int32_t connect_timeout_ms;// Default: 200 (milliseconds)//rpc 请求超时时间int32_t timeout_ms;// Default: 500 (milliseconds)//最大重试次数int max_retry;// Default: 3//序列化协议类型 options.protocol = "baidu_std";AdaptiveProtocolType protocol;//....
}
class Channel : public ChannelBase {//初始化接口,成功返回 0;int Init(const char* server_addr_and_port, const ChannelOptions* options);
4. brpc使用测试
4.1 brpc同步和异步调用
server.hpp
#include <brpc/server.h>
#include <butil/logging.h>
#include "main.pb.h"// 1. 继承于EchoService创建一个子类,并实现rpc调用的业务功能
class EchoServiceImpl : public example::EchoService
{public:EchoServiceImpl(){}~EchoServiceImpl(){}void Echo(google::protobuf::RpcController* controller,const ::example::EchoRequest* request,::example::EchoResponse* response,::google::protobuf::Closure* done) {brpc::ClosureGuard rpc_guard(done); // 对象析构时自动调用done->Run()std::cout << "收到消息:" << request->message() << std::endl;std::string str = request->message() + "--这是响应!!";response->set_message(str);//done->Run();}
};int main(int argc, char *argv[])
{// 关闭brpc的默认日志输出logging::LoggingSettings settings;settings.logging_dest = logging::LoggingDestination::LOG_TO_NONE;logging::InitLogging(settings);// 2. 构造服务器对象brpc::Server server;// 3. 向服务器对象中,新增EchoService服务EchoServiceImpl echo_service; // 添加服务失败时,服务器不会删除服务对象int ret = server.AddService(&echo_service, brpc::ServiceOwnership::SERVER_DOESNT_OWN_SERVICE);if (ret == -1) {std::cout << "添加Rpc服务失败!\n";return -1;}// 4. 启动服务器brpc::ServerOptions options;options.idle_timeout_sec = -1; // 连接空闲超时时间-超时后连接被关闭options.num_threads = 1; // io线程数量ret = server.Start(8080, &options);if (ret == -1) {std::cout << "启动服务器失败!\n";return -1;}server.RunUntilAskedToQuit(); // 休眠等待运行结束,避免对SIGINT信号进行处理return 0;
}
makefile:
all : server client
server : server.cc main.pb.ccg++ -std=c++17 $^ -o $@ -lbrpc -lgflags -lssl -lcrypto -lprotobuf -lleveldb
client : client.cc main.pb.ccg++ -std=c++17 $^ -o $@ -lbrpc -lgflags -lssl -lcrypto -lprotobuf -lleveldb
同步调用:同步调用是指客户端会阻塞收到 server 端的响应或发生错误。
#include <brpc/channel.h>
#include <thread>
#include "main.pb.h"int main(int argc, char *argv[])
{// 1. 构造Channel信道,连接服务器brpc::ChannelOptions options;options.connect_timeout_ms = -1; // 连接等待超时时间,-1表示一直等待options.timeout_ms = -1; // rpc请求等待超时时间,-1表示一直等待options.max_retry = 3; // 请求重试次数options.protocol = "baidu_std"; // 序列化协议,默认使用baidu_stdbrpc::Channel channel;int ret = channel.Init("127.0.0.1:8080", &options);if (ret == -1) {std::cout << "初始化信道失败!\n";return -1;}// 2. 构造EchoService_Stub对象,用于进行rpc调用example::EchoService_Stub stub(&channel);// 3. 进行Rpc调用example::EchoRequest req;req.set_message("你好~brpc~!");brpc::Controller cntl;example::EchoResponse rsp;stub.Echo(&cntl, &req, &rsp, nullptr); // 同步调用if (cntl.Failed() == true) {std::cout << "Rpc调用失败:" << cntl.ErrorText() << std::endl;return -1;}std::cout << "同步调用结束!\n";std::cout << "收到响应: " << rsp.message() << std::endl;return 0;
}
异步调用:异步调用是指客户端注册一个响应处理回调函数, 当调用一个 RPC 接口时立即返回,不会阻塞等待响应, 当 server 端返回响应时会调用传入的回调函数处理响应。
#include <brpc/channel.h>
#include <thread>
#include "main.pb.h"// 这个回调函数用于异步调用对象使用
void callback(brpc::Controller* cntl, ::example::EchoResponse* response)
{std::unique_ptr<brpc::Controller> cntl_guard(cntl);std::unique_ptr<example::EchoResponse> resp_guard(response);if (cntl->Failed() == true) {std::cout << "Rpc调用失败:" << cntl->ErrorText() << std::endl;return;}std::cout << "收到响应: " << response->message() << std::endl;// delete cntl;// delete response;
}int main(int argc, char *argv[])
{// 1. 构造Channel信道,连接服务器brpc::ChannelOptions options;options.connect_timeout_ms = -1; // 连接等待超时时间,-1表示一直等待options.timeout_ms = -1; // rpc请求等待超时时间,-1表示一直等待options.max_retry = 3; // 请求重试次数options.protocol = "baidu_std"; // 序列化协议,默认使用baidu_stdbrpc::Channel channel;int ret = channel.Init("127.0.0.1:8080", &options);if (ret == -1) {std::cout << "初始化信道失败!\n";return -1;}// 2. 构造EchoService_Stub对象,用于进行rpc调用example::EchoService_Stub stub(&channel);// 3. 进行Rpc调用example::EchoRequest req;req.set_message("你好~brpc~!");// 防止异步调用时 cnt rsp 出作用域被销毁,要在堆上创建对象brpc::Controller *cntl = new brpc::Controller();example::EchoResponse *rsp = new example::EchoResponse();auto clusure = google::protobuf::NewCallback(callback, cntl, rsp); // 异步调用对象stub.Echo(cntl, &req, rsp, clusure); // 异步调用std::cout << "异步调用结束!\n";std::this_thread::sleep_for(std::chrono::seconds(3));return 0;
}
相关文章:
【微服务即时通讯系统】——brpc远程过程调用、百度开源的RPC框架、brpc的介绍、brpc的安装、brpc使用和功能测试
文章目录 brpc1. brpc的介绍1.1 rpc的介绍1.2 rpc的原理1.3 grpc和brpc 2. brpc的安装3. brpc使用3.1 brpc接口介绍 4. brpc使用测试4.1 brpc同步和异步调用 brpc 1. brpc的介绍 1.1 rpc的介绍 RPC(Remote Procedure Call)远程过程调用,是一…...
鸿蒙开发(NEXT/API 12)【状态查询与订阅】手机侧应用开发
注意 该接口的调用需要在开发者联盟申请设备基础信息权限与穿戴用户状态权限,穿戴用户状态权限还需获得用户授权。 实时查询穿戴设备可用空间、电量状态。订阅穿戴设备连接状态、低电量告警、用户心率告警。查询和订阅穿戴设备充电状态、佩戴状态、设备模式。 使…...
vite中sass警告JS API过期
1.问题 在Vite创建项目中引入Sass弹出The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0 - vite中sass警告JS API过期 The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0警告提示表明你当前正在使用的 Dart Sass 版本中&#…...
睢宁自闭症寄宿学校:培养特殊孩子的未来
在自闭症儿童的教育与康复领域,每一所学校的努力都是对孩子们未来无限可能的一次深刻诠释。从江苏睢宁到广东广州,自闭症寄宿学校正以不同的方式,为这些特殊的孩子铺设一条通往未来的希望之路。其中,广州的星贝育园自闭症儿童寄宿…...
【Canvas与徽章】金圈蓝底国庆75周年徽章
【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>金边黑盾75周年</title><style type"text/css"&g…...
Java Servlet 详解
Java Servlet 是 Java 企业级应用 中的一个核心组件,特别是在 Web 应用开发中,它为服务器端处理请求提供了基础。每次用户发出请求时,Servlet 都会动态生成响应,这在构建复杂、交互式的 Web 应用时尤为重要。 什么是 Servlet&am…...
yolov8/9/10模型在安全帽、安全衣检测中的应用【代码+数据集+python环境+GUI系统】
yolov8910模型安全帽、安全衣检测中的应用【代码数据集python环境GUI系统】 yolov8/9/10模型在安全帽、安全衣检测中的应用【代码数据集python环境GUI系统】 背景意义 安全帽和安全衣在工业生产、建筑施工等高风险作业环境中是保护工人免受意外伤害的重要装备。然而࿰…...
算力共享系统中数据平面和控制平面
目录 算力共享系统中数据平面和控制平面 数据平面 控制平面 算力共享系统举例 控制流程和业务流程,在算力共享系统中举例说明 控制流程 业务流程 算力共享系统中数据平面和控制平面 在算力共享系统中,数据平面和控制平面是两个关键组成部分,它们各自承担着不同的角色…...
C++语言学习(4): identifier 的概念
1. 什么是 identifier identifier 中文意思是标识符,在 cppreference 中明确提到,identifier 是任意长度的数字、下划线、大写字母、小写字母、unicode 字符 的序列: An identifier is an arbitrarily long sequence of digits, underscores…...
浅谈计算机神经网络基础与应用
1. 绪论 随着科技的飞速发展,人工智能(AI)已经逐渐渗透到我们生活的方方面面。作为AI技术的核心组成部分,神经网络在推动这一领域的发展上扮演着至关重要的角色。本报告旨在探讨AI中的不同类型神经网络及其在实际应用中的表现和影响。我们将从神经网络的基本概念入手,逐步…...
【SpringBoot详细教程】-08-MybatisPlus详细教程以及SpringBoot整合Mybatis-plus【持续更新】
目录 🌲 MyBatis Plus 简介 🌾入门案例 🌾 MP 简介 🌲 MP 的CRUD 🌾 新增 🌾 删除 🌾 修改在进行 🌾 根据ID查询 🌾 查询所有 🌲 分页功能 🌾 设置分页参数 🌾 设置分页拦截器 🌲 优化启动 🌾 取消mbatisPlusBanner 🌾 取消Sprin…...
[20241002] OpenAI融资文件曝光,ChatGPT年收入涨4倍,月费5年内翻倍
智东西9月29日消息,据《纽约时报》9月27日报道,OpenAI的内部文件显示,该公司在8月份的月收入达到3亿美元,自2023年初以来增长了1700%,预计今年年度销售额将达到37亿美元,其中ChatGPT将带来27亿美元的收入。…...
工业缺陷检测——Windows 10本地部署AnomalyGPT工业缺陷检测大模型
0. 引言 在缺陷检测中,由于真实世界样本中的缺陷数据极为稀少,有时在几千甚至几万个样品中才会出现一个缺陷数据。因此,以往的模型只需在正常样本上进行训练,学习正常样品的数据分布。在测试时,需要手动指定阈值来区分…...
单元测试进阶-Mock使用和插桩
目录 一、基本概念 1、Mock 2、插桩(Sutbbing) 二、参考文章 一、基本概念 1、Mock Mock的作用就是不直接new对象,而是使用Mock方法或者注解Mock一个对象。 这个对象他不是new创建的对象,Mock对该对象的一些成员变量和方法…...
适用conda安装虚拟的python3环境
由于jupyter notebook 7以上的版本与jupyter_contrib_nbextensions存在冲突,导致以前使用顺手的插件无法使用了,就考虑建立一个虚拟环境,在里面使用jupyter notebook 6,以便和jupyter_contrib_nbextensions兼容。 conda简介和优势 Conda 是一个包管理器和环境管理器,它不…...
【C++】“list”的介绍和常用接口的模拟实现
【C】“list”的介绍和常用接口的模拟实现 一. list的介绍1. list常见的重要接口2. list的迭代器失效 二. list常用接口的模拟实现(含注释)三. list与vector的对比 一. list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器…...
第九篇——数列和级数(二):传销骗局的数学原理
目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么? 四、总结五、升华 一、背景介绍 文章不长,但是道理深刻;相邻两个数的差值…...
docker如何查看容器的ip
要查看Docker容器的IP地址,可以使用以下几种方法: 使用docker inspect命令: docker inspect -f {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}} <容器ID或名称> 使用docker ps和docker inspect组合: 首先查看正…...
Mysql ONLY_FULL_GROUP_BY模式详解、group by非查询字段报错
文章目录 一、问题报错二、ONLY_FULL_GROUP_BY模式2.1、什么是ONLY_FULL_GROUP_BY?2.2、为什么要使用ONLY_FULL_GROUP_BY?2.3、查看sql_mode 三、解决方法3.1、关闭only_full_group_by模式3.1.1、方法一:关闭当前会话中的only_full_group_by3…...
设计模式(2)工厂模式
让一个工厂类去生产出对象 (new )来。 我们想要一个 形状,我们用工厂去生产出,圆形,方形。 package com.example.factory2;public interface Shape {void draw(); }public class Square implements Shape {Overridep…...
二分查找算法专题(1)
找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏: 优选算法专题 目录 二分查找算法的介绍 704. 二分查找 34. 在排序数组中查找元素的第一个和 最后一个位置 35. 搜索插入位置 69. x的平…...
ACP科普:SoS不是救命
Scrum of Scrums(SoS)是一种用于协调多个Scrum团队之间工作的扩展框架,特别适用于大型项目或组织中有多个团队同时进行开发的情况。它帮助团队在保持敏捷性的同时,解决跨团队的依赖和协调问题。以下是对Scrum of Scrums的详细介绍…...
C++:模拟实现vector
目录 成员变量与迭代器 size capacity empty 迭代器有关函数 实现默认成员函数的前置准备 reserve 编辑 编辑 push_back 构造函数 无参构造 迭代器区间构造 n个val来进行构造 析构函数 拷贝构造函数 赋值重载 增删查改 clear resize pop_back inser…...
Leecode SQL 184. Department Highest Salary 找出tie
Department Highest Salary 注意!要找出 tie 的 highest salary! Write a solution to find employees who have the highest salary in each of the departments. Return the result table in any order. The result format is in the following ex…...
[Redis][典型运用][缓存]详细讲解
目录 0.什么是缓存?1.使用Redis作为缓存1.为什么用?2.如何用? 2.缓存的更新策略0.前言1.定期生成2.实时生成 3.缓存相关问题1.缓存预热(Cache Preheating)2.缓存穿透(Cache Penetration)3.缓存雪崩(Cache Avalanche)4.缓存击穿(Cache Breakdo…...
GPG error golang 1.19
1. 问题描述及原因分析 在飞腾2000的服务器,OS为Kylin Linux Advanced Server release V10环境下,docker版本为18.09.0(docker-engine-18.09.0-101.ky10.aarch64),基于容器镜像golang:1.19编译新的容器镜像࿰…...
Linux如何查看每个文件及文件夹的大小
查看当前目录下每个文件夹的大小,包括其内部所有文件: du -sh *-s:仅显示每个文件夹的总大小,而不是每个文件。-h:以人类可读的格式显示。...
Word样式的同步与重置
有时候我们需要修改Word中的样式,实现排版的个性化。 如何同步样式到其他电脑上? Word中的样式是由Normal.dotm文件控制的,对样式所有的设置和修改,都会保存到这个问题件中,所以我们只需要在设置好样式以后ÿ…...
力扣 —— 跳跃游戏
题目一(中等) 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。 示例 1&…...
SOCKS5代理和HTTP代理哪个快?深度解析两者的速度差异
在现代互联网环境中,使用代理IP已经成为了许多人日常生活和工作的必备工具。无论是为了保护隐私,还是为了访问某些特定资源,代理IP都扮演着重要的角色。今天,我们就来聊聊SOCKS5代理和HTTP代理,看看这两者到底哪个更快…...
衢州建设职业学校网站/北京官网优化公司
今天早上在写一个.scala文件时,控制台一直出现这个错误。 原本以为这个错误是找不到URL地址,不能使用local[*]这种模式,后来发现这个错误的根本是在上一行,也就是: SparkContext: Error initializing SparkContext 原…...
巴彦淖尔市 网站建设/营销型网站建设的5大技巧
整个redux的源码非常简单,所以解释很少,看代码就能看明白...... combineReducers 为啥先说这个 前提先看middleware: Redux-Middleware-源码解析, 这些都是解析createStore的前提 //传入的reducers是个对象 //将多个reducer捆成一个 export default function combineReducers(r…...
哪些网站可以做淘宝客/推广软文范文800字
mysqli我们在PHP中可以使用mysqli扩展与MySQL数据库信息交流,i表示改进,增强,它执行速度更快。mysqli扩展被封装到一个类中,它是一种面向对象的技术,不过喜欢过程化编程的用户也不用担心,mysqli也提供了一个…...
电子产品网站建设策划/磁力兔子
1. 创建一个reg文件 2. 在文件中填入如下内容并保存: Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN]"Delete SVN Folders" [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command…...
网站开发 私活/seo基础培训机构
因世界首例基因编辑婴儿引发巨大争议的贺建奎也名列其中,成为了今年榜单的“反面案例”。 12月19日零时,世界顶尖学术期刊、英国《自然》杂志(Nature)发布了2018年度影响世界的十大科学人物。其中,中国22岁天才少年曹…...
手机网站打不开的解决方法/郑州网站优化seo
一、STL简介 STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发出来 的。现在虽说它主要出现在C中,但在被引入C之前该技术就已经…...