谈一谈对象池SafeObjectPool能干什么
前言
首先从ado.net的连接池开始了解,数据库操作通常是 new SqlConnection()、 Open()、 使用完后 Close(),整个过程相当耗时,特别是频繁建议套字接连接的过程。ado.net 驱动已经现实了连接池管理,Open() 等于申请连接,Close() 即归还资源。
Open() 的时候有几种情况:
1、有资源直接返回;
2、无可用资源,且未超过池最大设置值时,创建资源并返回;
3、无可用资源,此时会等待设置秒数,若仍然未获取资源则报错;
连接的复用使性能成数倍提升,试想网站在某一时刻突然爆增10万次,new 10万个SqlConnection对象显然会炸掉服务,创建,connect,disconnect,disponse,显然开销很大。
虽然ado.net自带的连接池已经接近完美,但在某些场合还不够用,先来一个压力测试。
SafeObjectPool与dapper比武测试
[HttpGet("vs_gen")]
async public Task<object> vs_gen() {
var select = Tag.Select;
var count = await select.CountAsync();
var items = await select.Page(page, limit).ToListAsync();
return new { count, items };
}
[HttpGet("vs_dapper")]
async public Task<object> vs_dapper() {
var conn = new SqlConnection("Data Source=.;Integrated Security=True;Initial Catalog=cms;Pooling=true;Max Pool Size=11");
conn.Open();
var count = await conn.ExecuteScalarAsync<int>("SELECT count(1) FROM[dbo].[tag] a");
//conn.Close();
//conn = new SqlConnection("Data Source=.;Integrated Security=True;Initial Catalog=cms;Pooling=true;Max Pool Size=11");
//conn.Open();
var items = await conn.QueryAsync("SELECT TOP 20 a.[id], a.[parent_id], a.[name] FROM[dbo].[tag] a");
conn.Close();
return new { count, items };
}
连接池最大分别为:10,11
使用 apache ab 命令行测试上面两个接口
ab -c 10 -n 1000 -s 6000 测试结果差不多。
-c 100 时,vs_dapper直接挂了,vs_gen没影响(使用了SafeObjectPool)
实践证明ado.net过于暴露,突然的高并发招架不住。
SafeObjectPool
它是一个对象池,可用于控制任何资源紧缺的对象,使用容器化管重复使用提升性能,有序的排队获取,使用完后归还资源。
与ado.net连接池不同的地方,SafeObjectPool 解决池用尽后,再请求不报错,进行排队等待机制,并且适用任何对象不局限于数据库连接对象。
SafeObjectPool 提供可用性检查方法,比如 redisClient 不可用时,所有Get/GetAsync都将报错,直到后台服务检查并恢复状态。
使用方法
Install-Package SafeObjectPool
var pool = new SafeObjectPool.ObjectPool<MemoryStream>(10, () => new MemoryStream(), obj => {
if (DateTime.Now.Subtract(obj.LastGetTime).TotalSeconds > 5) {
// 对象超过5秒未活动,进行操作
}
});
var obj = pool.Get(); //借
pool.Return(obj); //归还
//或者 using 自动归还
using (var obj = pool.Get()) {
}
异常
- 同步获取资源时 pool.Get()
【连接池名称】状态不可用,等待后台检查程序恢复方可使用。
SafeObjectPool.Get 获取超时(10秒),设置 Policy.IsThrowGetTimeoutException 可以避免该异常。
- 异步获取资源时 pool.GetAsync()
【连接池名称】状态不可用,等待后台检查程序恢复方可使用。
SafeObjectPool.GetAsync 无可用资源且队列过长,Policy.AsyncGetCapacity =10000。
- 后台服务检查可用性时
CheckAvailable 无法获得资源,Pool: 0/10, Get Wait: 0, GetAsync Wait: 0
扩展现实
SQLServer连接池
var pool = new System.Data.SqlClient.SqlConnectionPool("名称", connectionString, 可用时触发的委托, 不可用时触发的委托);
var conn = pool.Get();
try {
// 使用 ...
pool.Return(conn); //正常归还
} catch (Exception ex) {
pool.Return(conn, ex); //发生错误时归还
}
MySQL连接池
var pool = new MySql.Data.MySqlClient.MySqlConnectionPool("名称", connectionString, 可用时触发的委托, 不可用时触发的委托);
var conn = pool.Get();
try {
// 使用 ...
pool.Return(conn); //正常归还
} catch (Exception ex) {
pool.Return(conn, ex); //发生错误时归还
}
PostgreSQL连接池
var pool = new Npgsql.NpgsqlConnectionPool("名称", connectionString, 可用时触发的委托, 不可用时触发的委托);
var conn = pool.Get();
try {
// 使用 ...
pool.Return(conn); //正常归还
} catch (Exception ex) {
pool.Return(conn, ex); //发生错误时归还
}
结语
本文由 ado.net 连接池,衍生到 SafeObjectPool,基于 SafeObjectPool 现实了 SQLServer连接池、MySQL连接池、PostgreSQL连接池。还有很多连接对象,比如redis client、rpc client、各大消息队列client,都可以封装起来。
谢谢观看,支持开源思想和奉献。
SafeObjectPool github:https://github.com/2881099/SafeObjectPool
谈一谈对象池SafeObjectPool能干什么的更多相关文章
- C#核心基础--浅谈类和对象的概念
浅谈类和对象的概念 一.什么是类?什么是对象? 学习一门面向对象编程语言,我们必须得知道什么是类?什么是对象? 类(Class)实际上是对某种类型的对象定义变量和方法的原型.它表示对现实生活中一类具有 ...
- 浅谈Java回收对象的标记和对象的二次标记过程_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 一.对象的标记 1.什么是标记?怎么标记? 第一个问题相信大家都知道,标记就是对一些已死的对象打上记号,方便垃圾收集器的 ...
- Unity3D 游戏开发构架篇 —— 动态大场景生成 = 区域加载+对象池管理
项目做一个类似无尽模式的场景,想了一想,其实方法很简单,做一个相关的总结. 主要先谈一谈构架,后期附上代码. 一.区域加载 其实无尽场景的实现很简单,因为屏幕限制,那么不论何时何地,我们只能看到自己的 ...
- 谈一谈Java8的函数式编程(二) --Java8中的流
流与集合 众所周知,日常开发与操作中涉及到集合的操作相当频繁,而java中对于集合的操作又是相当麻烦.这里你可能就有疑问了,我感觉平常开发的时候操作集合时不麻烦呀?那下面我们从一个例子说起. 计 ...
- Unity 游戏框架搭建 (二十) 更安全的对象池
上篇文章介绍了,只需通过实现IObjectFactory接口和继承Pool类,就可以很方便地实现一个SimpleObjectPool.SimpleObjectPool可以满足大部分的对象池的需求.而笔 ...
- 谈一谈iOS事件的产生和传递
谈一谈iOS事件的产生和传递 1.事件的产生 发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中. UIApplication会从事件队列中取出最前面的事件,并将事件 ...
- 谈一谈并查集QAQ(上)
最近几日理了理学过的很多oi知识...发现不知不觉就有很多的知识忘记了... 在聊聊并查集的时候顺便当作巩固吧.... 什么是并查集呢? ( Union Find Set ) 是一种用于处理分离集合的 ...
- 谈一谈C#的事件
谈一谈C#的事件 C#中事件基于委托,要理解事件要先理解委托,如果觉得自己关于委托不是很了解可以看看我前面写委托的文章 事件基于委托,是一种功能受限的委托,为委托提供了一种发布/订阅机制 使用委托时, ...
- 设计模式之美:Object Pool(对象池)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):实现 DatabaseConnectionPool 类. 实现方式(二):使用对象构造方法和预分配方式实现 ObjectPool ...
随机推荐
- 自己用 Netty 实现一个简单的 RPC
目录: 需求 设计 实现 创建 maven 项目,导入 Netty 4.1.16. 项目目录结构 设计接口 提供者相关实现 消费者相关实现 测试结果 总结 源码地址:github 地址 前言 众所周知 ...
- oracle中通过sql查询sde中图形面积
select st_area(shape) from XAG2011430200000M_DLTB t where objectid=330
- CSS 静态进度条效果
今天学习到了实现一个静态进度条的方法,固写一篇笔记稳固一下自己的知识. 最终的效果如下,进度条放在一个框里,水平宽自适应. 现在就开始,首先写一个进度条先. .progress-bar{ /* 进度条 ...
- nfs 、ftp 和samba都有什么区别?
NFS:Network File System 是已故的Sun公司制定的用于分布式访问的文件系统,它的本质是文件系统.主要在Unix系列操作系统上使用,基于TCP/IP协议层,可以将远程的计算机磁盘挂 ...
- 运用jieba库分词
代码: 统计出团队中文简介中词频 import jieba txt=open("C:\\Users\\Administrator\\Desktop\\介绍.txt","r ...
- URL 规范 整理
URL 规范 不用大写:(强制) 用中杠-不用下杠_:(强制) 参数列表要encode,编码使用utf-8:(强制) URI中的名词表示资源集合,使用复数形式.(建议) 增加版本号(建议) URI中统 ...
- python_函数设计
>>> def check_permission(func): def wrapper(*args,**kwargs): if kwargs.get('username')!='ad ...
- CLR、程序集、反射和控制反转
以前面试包括自己学习的时候经常会碰到这3个东西,也查过相关介绍,晦涩难懂,虽然看完之后,当时勉强理解,不过过一段时间又忘了.其实这篇文章可以分两篇(clr.程序集)和(反射.控制反转)来写,但它们之间 ...
- Windows Defender Service 是选择Windows 10系统的最大障碍!
今天从早上开始,Windows Defender Service服务从CPU消耗资源30%一直上升到60%并且无法下降. 我一直使用的是Windows 10 Enterprise 2016长期服务支持 ...
- 译MassTransit 创建消息消费者
创建消息消费者一个消息消费者是一个 可以消费一个或多个消息类型的类,指定IConsumer<T>接口,T为消息类型 public class UpdateCustomerConsumer ...