【brpc学习案例实践一】rpc服务构造基本流程
前言
在c++rpc框架中,brpc简直越用越爽,平时工作中也常用到brpc,一直没来得及总结,抽空写点,也供自己查阅用。下附几个常用学习地址:
brpc官网开源地址:
https://github.com/luozesong/brpc/blob/master/docs/cn/redis_client.md
protobuf官方文档:
https://protobuf.dev/programming-guides/proto2/
brpc使用流程
1、定义proto
一般包含request、response、echoservice三种proto,echoservice在里面会定义一个rpc(stub)桩函数,proto编译器会生成一个与定义的stub接口同名的抽象接口,在用户只需要继承echoservice实现自己的service类之后,重写该stub函数即可。如果不定义自己的echoservice接口,一些场景也可使用brpc内部已经定义好的service接口,像nsheadservice,用户直接继承该类,实现自己的ProcessNsheadRequest()接口函数即可。
下面来看两种proto定义的例子:
- 自定义rpc service
# Tell protoc to generate base classes for C++ Service. modify to java_generic_services or py_generic_services for java or python.
option cc_generic_services = true;message EchoRequest {required string message = 1;
};
message EchoResponse {required string message = 1;
};
service EchoService {rpc Echo(EchoRequest) returns (EchoResponse);
};
上面我们在proto里面定义了EchoService服务,我们在下面定义自己的MyEchoService继承该EchoService类,重写proto自动编译生成的抽象接口Echo即可。
class MyEchoService : public EchoService {
public:void Echo(::google::protobuf::RpcController* cntl_base,const ::example::EchoRequest* request,::example::EchoResponse* response,::google::protobuf::Closure* done) {// This RAII object calls done->Run() automatically at exit.brpc::ClosureGuard done_guard(done);brpc::Controller* cntl = static_cast<brpc::Controller*>(cntl_base);// fill responseresponse->set_message(request->message());}
};
继承brpc内部service接口(以nshead为例):
class Fw2NsheadService : public ::baidu::rpc::NsheadService {
public:Fw2NsheadService(App* app);virtual ~Fw2NsheadService();void ProcessNsheadRequest(const baidu::rpc::Server& server,baidu::rpc::Controller* cntl,const baidu::rpc::NsheadMessage& request,baidu::rpc::NsheadMessage* response,baidu::rpc::NsheadClosure* done) {bus::log::LogClosureGuard done_guard(cntl, done);int ret = HTTP_STATUS_SERVER_ERROR;if (cntl->Failed()) {LOG(FATAL) << "Controller Failed Before Process, Reason:" << cntl->ErrorText();BUS_SET_ERRNO(ret);return;}ret = _app->Execute(request.body, response->body);BUS_SET_ERRNO(ret);
}private:App* _app;
};
2、proto定义好之后,需要实现生成的service接口(上面已讲过)
需实现自己的service响应函数。另外我们通常需要在自己的sevice函数中初始化一个done_guard或自己手动调用done->run():
brpc::ClosureGuard done_guard(done);
done由框架创建,递给服务回调,包含了调用服务回调后的后续动作,包括检查response正确性,序列化,打包,发送等逻辑。done_guard就是为了保证退出服务自动调用,释放资源。如果我们需要实现异步服务,除了手动调用done->run()外,还可以使用done_guard.release()
3、定义服务对象brpc::Server server;
默认构造后的Server不包含任何服务,也不会对外提供服务,仅仅是一个对象。
4、给服务对象添加服务实例
通过如下方法插入你的Service实例。
int AddService(google::protobuf::Service* service, ServiceOwnership ownership);
若ownership参数为SERVER_OWNS_SERVICE,Server在析构时会一并删除Service,意味着我们自己定义的服务实例也会被删除,如果还需要该service实例,应设为SERVER_DOESNT_OWN_SERVICE。
插入MyEchoService代码如下:
brpc::Server server;
MyEchoService my_echo_service;
if (server.AddService(&my_echo_service, brpc::SERVER_DOESNT_OWN_SERVICE) != 0) {LOG(FATAL) << "Fail to add my_echo_service";return -1;
}
5、启动服务
brpc::ServerOptions options; // 包含了默认值
options.xxx = yyy;
...
server.Start(..., &options);
start的接口有多种:
int Start(const char* ip_and_port_str, const ServerOptions* opt);
int Start(EndPoint ip_and_port, const ServerOptions* opt);
int Start(int port, const ServerOptions* opt);
int Start(const char *ip_str, PortRange port_range, const ServerOptions *opt); // r32009后增加
options
为NULL时所有参数取默认值。一个服务只能监听一个端口,如果要监听多个端口需要起多个服务。
6、停止服务
server.Stop(closewait_ms); // closewait_ms实际无效,出于历史原因未删
server.Join();
Stop()不会阻塞,Join()会。分成两个函数的原因在于当多个Server需要退出时,可以先全部Stop再一起Join,如果一个个Stop/Join,可能得花费Server个数倍的等待时间。
不管closewait_ms是什么值,server在退出时会等待所有正在被处理的请求完成,同时对新请求立刻回复ELOGOFF错误以防止新请求加入。这么做的原因在于只要server退出时仍有处理线程运行,就有访问到已释放内存的风险。如果你的server“退不掉”,很有可能是由于某个检索线程没结束或忘记调用done了。
当client看到ELOGOFF时,会跳过对应的server,并在其他server上重试对应的请求。所以在一般情况下brpc总是“优雅退出”的,重启或上线时几乎不会或只会丢失很少量的流量。
RunUntilAskedToQuit()函数可以在大部分情况下简化server的运转和停止代码。在server.Start后,只需如下代码即会让server运行直到按到Ctrl-C。
// Wait until Ctrl-C is pressed, then Stop() and Join() the server.
server.RunUntilAskedToQuit();// server已经停止了,这里可以写释放资源的代码。
Join()完成后可以修改其中的Service,并重新Start。
相关文章:
【brpc学习案例实践一】rpc服务构造基本流程
前言 在crpc框架中,brpc简直越用越爽,平时工作中也常用到brpc,一直没来得及总结,抽空写点,也供自己查阅用。下附几个常用学习地址: brpc官网开源地址: https://github.com/luozesong/brpc/blob…...

Redis数据的持久化
Redis的持久化有两种方式: RDB(Redis Database)和AOF(Append Only File) 目录 一、RDB 保存方式 2、rdb在redis.conf文件中的配置 二、AOF 1、保存方式 2、aof方式持久化在redis.conf文件中的配置 三、持久化建…...

uniapp App 端 版本更新检测
function checkVersion() { var req { //升级检测数据 appid: plus.runtime.appid, version: plus.runtime.version }; const timestamp Date.parse(new Date()); config.server.query_news uni.reque…...

python用最小二乘法实现平面拟合
文章目录 数学原理代码实现测试 数学原理 平面方程可写为 A x B y C z D 0 AxByCzD0 AxByCzD0 假设 C C C不为0,则上式可以改写为 z a x b y d zaxbyd zaxbyd 则现有一组点 { p i } \{p_i\} {pi},则根据 x i , y i x_i,y_i xi,yi以及平面…...

SpringCloud微服务:Nacos和Eureka的区别
目录 配置: 区别: ephemeral设置为true时 ephemeral设置为false时(这里我使用的服务是order-service) 1. Nacos与eureka的共同点 都支持服务注册和服务拉取 都支持服务提供者心跳方式做健康检测 2. Nacos与Eu…...
基于Springboot+Vue的校园在线打印预约系统
基于SpringbootVue的校园在线打印预约系统的设计与实现 (1) 注册功能:允许学生、教职员工注册账户,并提供安全的身份验证机制,确保只有授权用户可以使用系统。 (2) 登录功能:店家或学生可以使用各自账号登录。登录后允许修改用户…...

计算机毕业设计选题推荐-掌心办公微信小程序/安卓APP-项目实战
✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...
1.1二分查找
二分查找,主要是针对基本有序的数据来进行查找target。 二分法的思想很简单,因为整个数组是有序的,数组默认是递增的。 1.1 使用条件 用于查找的内容逻辑上来说是需要有序的查找的数量只能是一个,而不是多个 1.2 简介 首先选…...

提升工作效率,打造精细思维——OmniOutliner 5 Pro for Mac
在当今快节奏的工作环境中,如何高效地组织和管理我们的思维和任务成为了关键。而OmniOutliner 5 Pro for Mac正是为此而生的一款强大工具。无论你是专业写作者、项目经理还是学生,OmniOutliner 5 Pro for Mac都能帮助你提升工作效率,打造精细…...

idea显示pom.xml文件漂黄警告 Dependency maven:xxx:xxx is vulnerable
场景: idea警告某些maven依赖包有漏洞或者依赖传递有易受攻击包,如下: 解决: 1、打开idea设置,找到 File | Settings | Editor | Inspections 2、取消上述两项勾选即可...

Linux中安装部署环境(JAVA)
目录 在Linux中安装jdk 包管理器yum安装jdk JDK安装过程中的问题 验证安装jdk 在Linux中安装tomcat 安装mysql 在Linux中安装jdk jdk在Linux中的安装方式有很多种, 这里介绍最简单的方法, 也就是包管理器方法: 包管理器yum安装jdk Linux中常见的包管理器有: yumaptp…...

Zabbix Proxy分布式监控
目录 Zabbix Proxy简介 实验环境 proxy端配置 1.安装仓库 2.安装zabbix-proxy 3.创建初始数据库 4.导入初始架构和数据,系统将提示您输入新创建的密码 5.编辑配置文件 /etc/zabbix/zabbix_proxy.conf,配置完成后要重启。 agent客户端配置 zabbix…...
前端设计模式之【代理模式】
文章目录 前言介绍例子场景优缺点标题五后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:前端设计模式 🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误&…...

Canal+Kafka实现MySQL与Redis数据同步(二)
CanalKafka实现MySQL与Redis数据同步(二) 创建MQ消费者进行同步 在application.yml配置文件加上kafka的配置信息: spring:kafka:# Kafka服务地址bootstrap-servers: 127.0.0.1:9092consumer:# 指定一个默认的组名group-id: consumer-group…...
NOIP2023模拟19联测40 诡异键盘
题目大意 有一个键盘,上面有 n 1 n1 n1个按键,按下按键 1 ≤ i ≤ n 1\leq i\leq n 1≤i≤n会打印出字符串 S i S_i Si,按下按键 n 1 n1 n1会删掉结尾的 K K K个字符,如果不足 K K K个字符则全部删完,问打印出 S …...
算法设计与分析 | 众数问题(c语言)
题目 所谓众数,就是对于给定的含有N个元素的多重集合,每个元素在S中出现次数最多的成为该元素的重数, 多重集合S重的重数最大的元素成为众数。例如:S{1,2,2,2,3,5},则多重集S的众数是2,其重数为3。 现在你…...
sql server外键设置
SQL Server外键设置 简介 在关系型数据库中,外键是一种约束,用于确保数据的完整性和一致性。外键约束定义了一个表中的列与另一个表中的列之间的关系,它可以用来保证数据的一致性、防止数据的破坏和数据冗余。在SQL Server中,我们…...
R语言实现多变量孟德尔随机化分析(1)
多变量孟德尔随机化分析调整了潜在混杂因素的影响。 1、调整哪些因素?参考以往文献。可以分别调整,也可以一起调整。 2、解决了什么问题?某个暴露相关的SNP,往往与某个或者某几个混杂因素相关。可以控制混杂偏倚。 3、如何解释…...

搭建 AI 图像生成器 (SAAS) php laravel
今天来搭一套,AI 图像生成器 是基于 Openai DALLE 2 和 Openai DALLE 3 以及 Stability AI 和稳定扩散 API 构建的脚本,为用户提供了使用简单的提示和大小生成独特自定义图像的可能性。在这个平台上,创意得以快速、高效地实现,借助…...
Maven引用本地jar包
先上命令: mvn install:install-file -Dfile..\.m2\repository\jl1.0.1.jar -DgroupId"com.liz.local" -DartifactId"jl" -Dversion"1.0.1" -Dpackagingjar 参数注释: -Dfile: jar 包路径(建议放在 meven 的 repository&…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...