前言

首先从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能干什么的更多相关文章

  1. C#核心基础--浅谈类和对象的概念

    浅谈类和对象的概念 一.什么是类?什么是对象? 学习一门面向对象编程语言,我们必须得知道什么是类?什么是对象? 类(Class)实际上是对某种类型的对象定义变量和方法的原型.它表示对现实生活中一类具有 ...

  2. 浅谈Java回收对象的标记和对象的二次标记过程_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 一.对象的标记 1.什么是标记?怎么标记? 第一个问题相信大家都知道,标记就是对一些已死的对象打上记号,方便垃圾收集器的 ...

  3. Unity3D 游戏开发构架篇 —— 动态大场景生成 = 区域加载+对象池管理

    项目做一个类似无尽模式的场景,想了一想,其实方法很简单,做一个相关的总结. 主要先谈一谈构架,后期附上代码. 一.区域加载 其实无尽场景的实现很简单,因为屏幕限制,那么不论何时何地,我们只能看到自己的 ...

  4. 谈一谈Java8的函数式编程(二) --Java8中的流

    流与集合    众所周知,日常开发与操作中涉及到集合的操作相当频繁,而java中对于集合的操作又是相当麻烦.这里你可能就有疑问了,我感觉平常开发的时候操作集合时不麻烦呀?那下面我们从一个例子说起. 计 ...

  5. Unity 游戏框架搭建 (二十) 更安全的对象池

    上篇文章介绍了,只需通过实现IObjectFactory接口和继承Pool类,就可以很方便地实现一个SimpleObjectPool.SimpleObjectPool可以满足大部分的对象池的需求.而笔 ...

  6. 谈一谈iOS事件的产生和传递

    谈一谈iOS事件的产生和传递 1.事件的产生 发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中. UIApplication会从事件队列中取出最前面的事件,并将事件 ...

  7. 谈一谈并查集QAQ(上)

    最近几日理了理学过的很多oi知识...发现不知不觉就有很多的知识忘记了... 在聊聊并查集的时候顺便当作巩固吧.... 什么是并查集呢? ( Union Find Set ) 是一种用于处理分离集合的 ...

  8. 谈一谈C#的事件

    谈一谈C#的事件 C#中事件基于委托,要理解事件要先理解委托,如果觉得自己关于委托不是很了解可以看看我前面写委托的文章 事件基于委托,是一种功能受限的委托,为委托提供了一种发布/订阅机制 使用委托时, ...

  9. 设计模式之美:Object Pool(对象池)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):实现 DatabaseConnectionPool 类. 实现方式(二):使用对象构造方法和预分配方式实现 ObjectPool ...

随机推荐

  1. 自己用 Netty 实现一个简单的 RPC

    目录: 需求 设计 实现 创建 maven 项目,导入 Netty 4.1.16. 项目目录结构 设计接口 提供者相关实现 消费者相关实现 测试结果 总结 源码地址:github 地址 前言 众所周知 ...

  2. oracle中通过sql查询sde中图形面积

    select st_area(shape) from XAG2011430200000M_DLTB t where objectid=330

  3. CSS 静态进度条效果

    今天学习到了实现一个静态进度条的方法,固写一篇笔记稳固一下自己的知识. 最终的效果如下,进度条放在一个框里,水平宽自适应. 现在就开始,首先写一个进度条先. .progress-bar{ /* 进度条 ...

  4. nfs 、ftp 和samba都有什么区别?

    NFS:Network File System 是已故的Sun公司制定的用于分布式访问的文件系统,它的本质是文件系统.主要在Unix系列操作系统上使用,基于TCP/IP协议层,可以将远程的计算机磁盘挂 ...

  5. 运用jieba库分词

    代码: 统计出团队中文简介中词频 import jieba txt=open("C:\\Users\\Administrator\\Desktop\\介绍.txt","r ...

  6. URL 规范 整理

    URL 规范 不用大写:(强制) 用中杠-不用下杠_:(强制) 参数列表要encode,编码使用utf-8:(强制) URI中的名词表示资源集合,使用复数形式.(建议) 增加版本号(建议) URI中统 ...

  7. python_函数设计

    >>> def check_permission(func): def wrapper(*args,**kwargs): if kwargs.get('username')!='ad ...

  8. CLR、程序集、反射和控制反转

    以前面试包括自己学习的时候经常会碰到这3个东西,也查过相关介绍,晦涩难懂,虽然看完之后,当时勉强理解,不过过一段时间又忘了.其实这篇文章可以分两篇(clr.程序集)和(反射.控制反转)来写,但它们之间 ...

  9. Windows Defender Service 是选择Windows 10系统的最大障碍!

    今天从早上开始,Windows Defender Service服务从CPU消耗资源30%一直上升到60%并且无法下降. 我一直使用的是Windows 10 Enterprise 2016长期服务支持 ...

  10. 译MassTransit 创建消息消费者

    创建消息消费者一个消息消费者是一个 可以消费一个或多个消息类型的类,指定IConsumer<T>接口,T为消息类型 public class UpdateCustomerConsumer ...