前言

首先从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. Elasticsearch JavaApi

    官网JavaApi地址:https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-search.html 博 ...

  2. springmvc 请求经过controller后静态资源无法访问的问题

    经过RequestMapping(“xx”)后 转发请求时会在url里面附带地址, 导致访问静态资源文件失败, 解决办法是在 spring-mvc.xml文件中加上 <mvc:default-s ...

  3. PAT1006:Sign In and Sign Out

    1006. Sign In and Sign Out (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue ...

  4. linux几种定时函数的使用

    Linux定时函数介绍: 在程序开发过程中,我们时不时要用到一些定时器,通常如果时间精度要求不高,可以使用sleep,uslepp函数让进程睡眠一段时间来实现定时, 前者单位为秒(s),后者为微妙(u ...

  5. Linux kernel的中断子系统之(三):IRQ number和中断描述符

    返回目录:<ARM-Linux中断系统>. 总结: 二描述了中断处理示意图,以及关中断.开中断,和IRQ number重要概念. 三介绍了三个重要的结构体,irq_desc.irq_dat ...

  6. xml序列化和反序列化(一)

    最近项目中需要调用第三方webservice,入参和出参采用xml格式,大致如下: 入参: <?xml version="1.0" encoding="utf-8& ...

  7. SVN使用教程2017.10.6

    http://www.cnblogs.com/mq0036/p/5250198.html

  8. 巩固java(二)----JVM堆内存结构及垃圾回收机制

    前言:        我们在运行程序时,有时会碰到内存溢出(OutOfMemoryError)的问题,为了解决这种问题,我们有必要了解JVM的内存结构和垃圾回收机制. 正文: 1.JVM堆内存结构   ...

  9. 究竟谁在绑架中国的4G政策?

    2009年中国正式发放3G牌照以来,尽管在开始阶段受到了应用不足的困扰,但是随着智 能手机的迅速推广,3G移动通信也开始在中国得到了飞速的发展.就在消费者以及市场 逐步接受并广泛应用该技术之际,4G通 ...

  10. 排序系列 之 快速排序算法 —— Java实现

    基本思想: 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变 ...