【brpc学习实践十一】session-local与thread-local应用与brpc抽象工厂模式实践

什么是session-local与thread-local

百度内的检索程序大量地使用了thread-local storage (缩写TLS),有些是为了缓存频繁访问的对象以避免反复创建,有些则是为了在全局函数间隐式地传递状态。你应当尽量避免后者,这样的函数难以测试,不设置thread-local变量甚至无法运行。session-local与thread-local是brpc解决thread-local问题的两种机制,实际上还有一种,可自行查阅官网文档。这两种机制其实就是提供了一个保存rpc请求过程中的用户关注数据的保存、处理接口。

session-local

session-local data与一次server端RPC绑定: 从进入service回调开始,到调用server端的done结束,不管该service是同步还是异步处理。 session-local data会尽量被重用,在server停止前不会被删除。

设置ServerOptions.session_local_data_factory后访问Controller.session_local_data()即可获得session-local数据。若没有设置,Controller.session_local_data()总是返回NULL。

若ServerOptions.reserved_session_local_data大于0,Server会在提供服务前就创建这么多个数据。

struct MySessionLocalData {MySessionLocalData() : x(123) {}int x;
};class EchoServiceImpl : public example::EchoService {
public:...void Echo(google::protobuf::RpcController* cntl_base,const example::EchoRequest* request,example::EchoResponse* response,google::protobuf::Closure* done) {...brpc::Controller* cntl = static_cast<brpc::Controller*>(cntl_base);// Get the session-local data which is created by ServerOptions.session_local_data_factory// and reused between different RPC.MySessionLocalData* sd = static_cast<MySessionLocalData*>(cntl->session_local_data());if (sd == NULL) {cntl->SetFailed("Require ServerOptions.session_local_data_factory to be set with a correctly implemented instance");return;}...
struct ServerOptions {...// The factory to create/destroy data attached to each RPC session.// If this field is NULL, Controller::session_local_data() is always NULL.// NOT owned by Server and must be valid when Server is running.// Default: NULLconst DataFactory* session_local_data_factory;// Prepare so many session-local data before server starts, so that calls// to Controller::session_local_data() get data directly rather than// calling session_local_data_factory->Create() at first time. Useful when// Create() is slow, otherwise the RPC session may be blocked by the// creation of data and not served within timeout.// Default: 0size_t reserved_session_local_data;
};

session_local_data_factory的类型为DataFactory,我们需要实现其中的CreateData和DestroyData。
brpc的DataFactory源码:

class DataFactory {
public:virtual ~DataFactory() {}// Implement this method to create a piece of data.// Notice that this method is const.// Returns the data, NULL on error.virtual void* CreateData() const = 0;// Implement this method to destroy a piece of data that was created// by Create().// Notice that this method is const.virtual void DestroyData(void*) const = 0;
};

实际上只是实现了一个抽象工厂的基类,对于产品族、具体工厂类都没有定义,这些是由具体业务去实现的。
注意:CreateData和DestroyData会被多个线程同时调用,**必须线程安全。**通常我们会在继承DataFactory的相关操作中添加锁保障线程安全。后面会有例子讲到。

class MySessionLocalDataFactory : public brpc::DataFactory {
public:void* CreateData() const {return new MySessionLocalData;}  void DestroyData(void* d) const {delete static_cast<MySessionLocalData*>(d);}  
};MySessionLocalDataFactory g_session_local_data_factory;int main(int argc, char* argv[]) {...brpc::Server server;brpc::ServerOptions options;...options.session_local_data_factory = &g_session_local_data_factory;...

我们需要将具体产品类的对象指针传入DestroyData以便brpc能帮我们回收资源,这里的资源回收是无需我们人工干预的,brpc已经帮我们进行管理:
如下源码:
在server start的时候就会根据传入的tls参数来进行启动一个sever bthread,随后在server结束时我们传入的具体session local数据会被抽象DestroyData指针调用destroy掉。

 // Init _keytable_pool always. If the server was stopped before, the pool// should be destroyed in Join()._keytable_pool = new bthread_keytable_pool_t;if (bthread_keytable_pool_init(_keytable_pool) != 0) {LOG(ERROR) << "Fail to init _keytable_pool";delete _keytable_pool;_keytable_pool = NULL;return -1;}if (_options.thread_local_data_factory) {_tl_options.thread_local_data_factory = _options.thread_local_data_factory;if (bthread_key_create2(&_tl_options.<

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/183697.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

哪些因素会影响香港服务器的下载速度_Maizyun

哪些因素会影响香港服务器的下载速度&#xff1f; 随着互联网的普及和快速发展&#xff0c;越来越多的企业和个人选择使用香港服务器来托管其网站、应用程序和其他在线服务。 然而&#xff0c;很多因素可能会影响香港服务器的下载速度。 本文将探讨影响香港服务器下载速度的几…

Java中xml映射文件是干什么的

Java中的XML映射文件主要用于将Java对象与XML文档之间进行转换。它通常用于处理数据交换和存储&#xff0c;例如将Java对象转换为XML格式以便在网络上传输或保存到文件中&#xff0c;或者将XML文档解析为Java对象以进行处理。这种转换可以通过Java的JAXB&#xff08;Java Archi…

springMVC实验(二)—调式工具APIFOX的使用

【知识要点】 后端开发调试工具 前后端分离已经成为互联网类软件开发主流模式&#xff0c;没有前端操作的支持&#xff0c;如何调试后端程序的就是开发人员必须解决的问题。如&#xff1a;get类请求可以直接使用浏览器就能模拟测试&#xff0c;但是post、put等类型的请求&…

layui 日期选择框弹出后消失

原因是窗口太小&#xff0c;日期窗碰撞边缘后会消失&#xff0c;解决方法是增加 trigger: click 属性。 laydate.render({ elem: #kp_date , type: date , trigger: click });

thinkphp5.1 验证器

thinkPHP5——验证器的使用总结-CSDN博客

YoloV8改进策略:AKConv即插即用,轻松涨点

文章目录 摘要1、引言2、相关工作3、方法3.1、定义初始采样位置3.2、可变卷积操作3.3、扩展AKConv4、实验4.1、在COCO2017上的目标检测实验4.2、在VOC 7+12上的目标检测实验4.3、在VisDrone-DET2021上的目标检测实验4.4、比较实验4.5、探索初始采样形状5、分析讨论6、结论Yolov…

数据结构与算法-D1数据结构引入

1、结构体 2、内存(malloc) 意义&#xff1a; 1、提高编程能力 2、可复用性、可维护性、可读性、效率更高 数据结构&#xff1a;研究数据之间关系&#xff0c;包括逻辑结构、存储结构、数据操作 逻辑结构&#xff1a; 按每个元素可能具有的直接前趋数和直接后趋数将逻辑结构…

Ubuntu 环境下 NFS 服务安装及配置使用

需求&#xff1a;公司内部有多台物理服务器&#xff0c;需要A服务器上的文件让B服务器访问&#xff0c;也就是两台服务器共享文件&#xff0c;当然也可以对A服务器上的文件做权限管理&#xff0c;让B服务器只读或者可读可写 1、NFS 介绍 NFS 是 Network FileSystem 的缩写&…

前端纯js导入导出json配置文件

在做后台系统需求的时候&#xff0c;有个需求是需要把当前表单配置导出&#xff0c;在另一个配置项下&#xff0c;导入这些配置&#xff0c;相当于做了一下配置拷贝。通常我们导出下载一个文件&#xff0c;是先向后端发起请求&#xff0c;由后端处理数据后&#xff0c;再返回文…

交调与互调

交调与互调 概念参考&#xff1a; 《高频电子线路》张肃文 《射频技术》于宝明、丁宁 交调&#xff08;Cross-modulation&#xff09; 如果接收机的前端电路选择性不够好&#xff0c;是有用信号与干扰信号同时加到接收机的输入端&#xff0c;而且这两种信号都是受音频调制…

jvm 调优参数

-XX:AlwaysPreTouch 指定JVM启动时即刻分配整个堆内存空间&#xff1b;应用启动会变慢&#xff0c;但是运行时变快。 -XX:MaxRAMPercentage60.0 指定JVM最大堆内存使用比例为60%&#xff1b;适用于容器部署 -XX:MinRAMPercentage60.0 指定JVM最小堆内存使用比例为60%&#xff1…

可以在电脑桌面展示工作计划表的软件

很多上班族都表示自己在工作时&#xff0c;会面临大量且复杂的工作任务&#xff0c;这时候就会拖延工作&#xff0c;或者感觉时间不够用&#xff0c;所以需要有明确的工作计划来指导自己如何分类时间和精力&#xff0c;确保每项工作任务都能够按时完成。如果需要制定每天的工作…

力扣labuladong一刷day22天二分搜索共2题

力扣labuladong一刷day22天二分搜索共2题 一、704. 二分查找 题目链接&#xff1a;https://leetcode.cn/problems/binary-search/ 思路&#xff1a;典型的二分查找&#xff0c;如果是左闭右闭那么说明left < right 。如果左闭右开那么说明 left < right class Solutio…

C++学习之路(十二)C++ 用Qt5实现一个工具箱(增加一个XML文本格式化功能)- 示例代码拆分讲解

上篇文章&#xff0c;我们用 Qt5 实现了在小工具箱中添加了《进制转换器功能》功能。为了继续丰富我们的工具箱&#xff0c;今天我们就再增加一个平时经常用到的功能吧&#xff0c;就是「 XML文本格式化 」功能。下面我们就来看看如何来规划开发一个这样的小功能并且添加到我们…

模拟算法【1】

文章目录 &#x1f600;1576. 替换所有的问号&#x1f606;题目&#x1f929;算法原理&#x1f642;代码实现 &#x1f60a;495.提莫攻击&#x1fae0;题目&#x1f609;算法原理&#x1f917;代码实现 模拟算法 通俗的来说&#xff0c;模拟算法就是依葫芦画瓢&#xff0c;将题…

React 签字手写签名组件 react-signature

安装依赖包 npm install uiw/react-signature示例代码 import React, { useRef } from "react"; import Signature from uiw/react-signature;export default function App() {const $svg useRef(null);const handle (evn) > $svg.current?.clear();return (…

Rust语言入门教程(十四) - 闭包Closure

什么是闭包 闭包在 Rust 中是非常强大的功能&#xff0c;允许你编写更灵活和表达性的代码。闭包的语法和功能在某些方面类似于其他语言&#xff08;如 JavaScript 或 Python&#xff09;中的匿名函数或 lambda 表达式。 在Rust中&#xff0c;当我们想要生成一个新的线程&…

[ISCTF2023] Crypto/PWN/Reverse

最近新生赛还挺多&#xff0c;不过这个开始后注册页面就被删了&#xff0c;没注册上。拿别人的附件作了下。 Crypto 七七的欧拉 这题只给了n,e,c这种情况一般正常没法解&#xff0c;猜n不正常 import gmpy2 import libnum from crypto.Util.number import *flagbISCTF{****…

【C/C++笔试练习】this指针的概念、初始化列表、const对象调用、构造和析构函数、继承和组合、重载和多态、虚函数的定义、计算日期到天数转换、幸运的袋子

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;this指针的概念&#xff08;2&#xff09;初始化列表&#xff08;3&#xff09;const对象调用&#xff08;4&#xff09;构造和析构函数&#xff08;5&#xff09;继承和组合&#xff08;6&#xff09;重载和多态&#x…

7Docker搭建es和kibana

一、安装es 1.拉取镜像 sudo docker pull elasticsearch:7.12.0 elasticsearch:7.12.0:我安装的版本是7.12.0&#xff0c;可以根据实际的情况安装 创建docker容器挂在的目录&#xff1a; sudo mkdir -p /opt/elasticsearch/config sudo mkdir -p /opt/elasticsearch/data s…