Actor模式封装MongoDB C驱动-多连接并发与自动重试

本文介绍了如何使用Actor模式封装MongoDB C驱动,以实现异步并发访问,避免同步操作在高并发场景下的性能瓶颈。通过创建SyncModb类型、ActorMongodb包装和ActoModb管理器,利用Actor的无锁特性实现多连接并发。测试示例展示了其实现效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文转自:http://www.tanjp.com (即时修正和更新)

 

Actor模式封装异步的MongoDB C驱动

MongoDB C驱动(MongoDB C Driver http://mongoc.org/),提供了同步的DB访问存储接口,在高并发的业务系统,同步操作会阻塞业务逻辑,是高并发的一大障碍。所以需要设计异步的接口来满足业务系统的需求。

利用Actor的特性,同一个Actor里面的行为,不需要加锁,也就是说Actor可以很方便地封装同步操作。

1、实现一个同步的MongoDB数据存取类型 SyncModb。

2、用Actor包装SyncModb,得到类型ActorMongodb。

3、实现ActorModb类型,该类型包含了单独的调度器(Scheduler)和舞台(Stage),和管理所有ActorMongodb。

4、ActoModb类型接收信件,创建N个ActorMongodb对象,每个ActorMongodb对象负责一个单独mongoc驱动连接,进行数据收发。

这样就实现了基于Actor模式实现可多连接并发异步接口。ActoModb对象的设计如下图:

图文代码请参照以上笔记

 

首先,实现一个同步的MongoDB数据存取类型 SyncModb,也就是说,这些接口如果直接调用会阻塞业务层逻辑。

下面只粘贴部分代码演示使用方法:

class SyncModb
{
public:
    	SyncModb();
    	~SyncModb();
    	// 配置连接地址
    	// @ps_uri, mongod的URI,格式: mongodb://username:password@127.0.0.1:27017/?authSource=collectionname
    	// @return 执行结果集合。
    	ModbResult config(const std::string & ps_uri);
	// 插入一条数据
	// @ps_dbname, 数据库名称。
	// @ps_colnname, 集合名称。
	// @ps_json, 待插入数据,json格式。
	// @ps_opts, 选项。默认为空,格式 { writeConcern : { w: <uint32>, j: <boolean>, wtimeout: <uint32> } }]
	// @pn_retry, 失败时自动重试的次数(每次重试耗时不少于0.1秒),0表示不自动重试。
	// @return 执行结果集合。
	ModbResult insert_one(const std::string & ps_dbname, const std::string & ps_colnname,
		const std::string & ps_json, const std::string & ps_opts = "");  
	// 关闭 mongodb 连接。
	void close();
	// @return mongodb已经建立连接返回true,如果未建立连接将尝试重连,重连失败返回false。
	bool connected();
	// @po_res, 根据结果集来判断网络是否有问题。
	// @return 返回true表示网络有问题,否则返回false其他问题或没问题。
	bool check_network_problem(const ModbResult & po_res);
	// ping测试Mongodb连接是否可用,每0.1秒尝试一次。
	// @ps_dbname, 数据库名称。
	// @pn_try_times, 尝试次数,取值大于零。
	// @return 0表示重试多次后还是失败,成功返回非0表示重试了多少次后成功。
	uint32 ping(const std::string & ps_dbname, uint32 pn_try_times);
private:
	mongoc_client_t	* mp_client;
	std::string ms_mongo_uri;
	uint32 mn_ping_times; //ping次数,失败时每次不少于0.1秒,默认值600,不少于1分钟。
};

然后,用Actor包装同步的MongoDB数据存取类型 SyncModb,得到类型ActorMongodb。代码如下:

 

class ActorMongodb : public Actor
{
public:
    	explicit ActorMongodb(ActorModb * pp_parent, Stage * pp_stage, uint32 pn_actorid, uint32 pn_retry_times_on_disconnected = 1, uint32 pn_ping_times = 600);
    	~ActorMongodb();
    	void init() override;

private:
    	void sync_ping(const std::string & ps_dbname, uint32 pn_qid, uint32 pn_cur_try_times);
	void op_config(Mail * pp_mail);
	void op_insert_one(Mail * pp_mail);
	void op_close(Mail * pp_mail);
private:
	const uint32 kRetryTimes;
	const uint32 kPingTimes;
	ActorModb * mp_parent;
	SyncModb * mp_modb;
};
ActorMongodb::ActorMongodb(ActorModb * pp_parent, Stage * pp_stage, uint32 pn_actorid, uint32 pn_retry_times_on_disconnected, uint32 pn_ping_times)
	: Actor(pp_stage, pn_actorid), kRetryTimes(pn_retry_times_on_disconnected), kPingTimes(pn_ping_times)
	, mp_parent(pp_parent), mp_modb(new SyncModb()){}
ActorMongodb::~ActorMongodb()
{
	SAFE_DELETE(mp_modb);
}
void ActorMongodb::init()
{
	set_operation(Ac
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值