common-pool:

对于一些对象的频繁创建会带来很大的系统开销,并且需要对对象数量进行控制来降低资源消耗,比如数据库连接,线程等

common-pool采用了缓存思想来解决这个问题,预先把一些对象资源创建好并统一保存起来,也就是保存到逻辑上的对象池中

等到需要对象时从池中直接获取,不需要时归还到池中

目前对象池技术已经有很多开源优秀的库了,比如:Java实现的Apache Commons PoolGo Commons Pool

go-common-pool就是参照Apache Commons Pool的思想,用go语言实现的一个通用对象池

原理分析

几个重要的数据结构介绍

factory:

包含了一个通用对象常用的方法集合,可以理解为一个接口,client可以根据不同的对象特性自定义操作

ObjectPool:

主要包含了对象池的一些属性方法

idleObjects是一个双向队列结构,保存一些可用对象,可以用FIFO、LIFO方式访问对象

allObjectsy是一个map结构,根据key-value形式保存对象,主要用来校验对象是否存在合法

也就是说一个对象在对象池中保存两份数据,对象池会启动一个协程定时维护对象

config:

包含对象池的一些配置

初始化过程

启动一个go run去定时维护对象池中的对象集合,主要分以下几步

第一步:检查空闲对象集合剔除即将失效或者已经失效对象(通过factory.Validate()判断),不会全量检查只会检查一定数量或者比例的空闲对象(数量可配置)

第二步:遍历allObjects集合中的所有对象,剔除失效对象

第三步:判断idleObjectsCount是否大于MinIdleCount,如果小于则创建对象,并往空闲对象队列里添加节点,直到二者相等

疑问:二者是同一个分支执行过程,既然有了第一部分的检查,不知道第二步存在的意义是什么。

获取对象:BorrowObject

首先会去idleObjects队列里面获取一个对象,如果为空说明队列里面没有现成的对象,则去创建一个新的对象

在创建对象的过程中会先更新createCount,然后判断createCount是否大于MaxTotal

如果小于则继续创建对象,调用factory.Make()创建真正的对象,更新allObjects集合,如果创建成功返回新对象,如果失败返回nil

如果大于则说明对象池容量已经达到最大值,

这时候有两种选择,一种是返回错误,一种是先阻塞当前协程,等到其他协程归还对象后发送一个信号,唤醒当前协程最终获取到对象

第二种方式中支持两个设置:

一种是无限等待时间直到有错误产生,监听一种channel即可

一种是指定超时时间,超时后返回空对象和错误,需要用select监听两个channel,除了与其他协程通信channel之外,还需要一个Timer.C channel时间超时channel

伪代码可以简化为:

func takeWhithTimeout(){
  for a:=next();a==nil;a=next() {
if 没有剩余时间了
return nil
if 可以终止了
return nil
a.f()
  }
  return a
} func (a Node) f() {
  select {
    case <-a.ch: //通知channel,获取到通知说明其队列里已经有了可用对象了,同时计算一下执行当前case后还有多少时间超时
      return 剩余时间
    case <-Time.After(timeout): //时间超时channel
      return 超时了可以终止了
  }
}

  

归还对象:ReturnObject

1. 去allObjects去检查归还对象是否合法存在

2. 校验归还对象是否有效,调用factory.Validate()

3. 判断idleObjectsCount是否大于MaxIdleCount,如果小于则添加对象到idleObjects队列,否则销毁对象

总结:

go-common-pool对象池中还有很多细节没有体现出来,上面只有对整个对象池几个重要的操作进行了一个简单版的描述,后续会更新一些细节实现上的技巧

在这里我想总结下个人认为比较重要的几点

1. 一个对象的操作make(创建)-->active(激活)-->validate(校验)-->destory(销毁)-->passivate(钝化)

创建、校验操作是很容易理解也是很常用的两个操作,一般对象定义好这两个操作就可以了。

激活、钝化不容易理解,这两个操作是相对的,一个是初始化对象,一个是反初始化对象,消除之前对象占用的一些资源,

具体需要结合应用场景,不同的对象类型比如数据库连接,socket连接,线程对应不同的操作,在翻阅了一些资料后还没找到一个很好的解释。

2. poolObject是整个对象池很核心的一个对象,对外连接factory的对象操作,对内连接allObjects、idleObjects集合的操作

idleObjects/allObjects都是通过锁机制来保证线程安全操作的

几个重要事件:

一个对象加入idleObjects时需要进行(钝化)操作

一个对象在获取时需要进行(激活-->校验)操作

一个对象在归还时需要进行(校验-->钝化)操作

其中任何一步失败都需要销毁对象

3. 获取对象时支持阻塞非阻塞两种方式

go-common-pool设计原理分析的更多相关文章

  1. Terracotta设计原理分析--(部分内容来自官方描述)

    因为工作中历史产品采用了terracotta作为分布式缓存线性扩展平台,因此不得不提前对其原理做了相关了解,当然其中很多的设计思想和oracle.memcached的设计相似,但也有自己的亮点,那就是 ...

  2. kafka知识体系-kafka设计和原理分析

    kafka设计和原理分析 kafka在1.0版本以前,官方主要定义为分布式多分区多副本的消息队列,而1.0后定义为分布式流处理平台,就是说处理传递消息外,kafka还能进行流式计算,类似Strom和S ...

  3. dubbo源码解析五 --- 集群容错架构设计与原理分析

    欢迎来我的 Star Followers 后期后继续更新Dubbo别的文章 Dubbo 源码分析系列之一环境搭建 博客园 Dubbo 入门之二 --- 项目结构解析 博客园 Dubbo 源码分析系列之 ...

  4. MyBatis的深入原理分析之1-架构设计以及实例分析

    MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简单.优雅.本文主要讲述MyBatis的架构设计思路,并且讨论MyBatis的几个核心部件,然后结合一个select查询实例, ...

  5. NOR Flash擦写和原理分析

    NOR Flash擦写和原理分析 1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直 ...

  6. Tomcat源码分析——请求原理分析(中)

    前言 在<TOMCAT源码分析——请求原理分析(上)>一文中已经介绍了关于Tomcat7.0处理请求前作的初始化和准备工作,请读者在阅读本文前确保掌握<TOMCAT源码分析——请求原 ...

  7. Atitit.异常机制的设计原理

    Atitit.异常机制的设计原理 缺陷 关键是只要知晓有一个异常表的存在,try 的范围就是体现在异常表行记录的起点和终点.JVM 在 try 住的代码区间内如有异常抛出的话,就会在当前栈桢的异常表中 ...

  8. Spring Cloud OkHttp设计原理

    Spring Cloud 框架最底层核心的组件就是服务调用方式,一般Spring Cloud框架采用的是HTTP的调用框架,本文将在 Spring Cloud应用场景下,介绍组件OkHttp3的设计原 ...

  9. Guava Cache 原理分析与最佳实践

    前言 目前大部分互联网架构 Cache 已经成为了必可不少的一环.常用的方案有大家熟知的 NoSQL 数据库(Redis.Memcached),也有大量的进程内缓存比如 EhCache .Guava ...

随机推荐

  1. KB奇遇记(6):搞笑的ERP项目团队

    早在我们来之前,KB公司这边就已经组建了ERP项目组了,当时IT就只有一个人,属网管出身.而关键用户分两种类型:专职关键用户和兼职关键用户.专职关键用户组织结构上已经调动到信息部,常驻在项目组里工作, ...

  2. Iris的R语言命令工具箱(1)

    Iris的R语言命令工具箱(1) 最近在做数据分析,使用了R语言做了些数据处理和可视化,在此记下遇到过的问题.应用过的命令.处理方式以及工具包- *版权声明:本文为博主原创文章,转载请注明本文地址.h ...

  3. MongoDB基础之十 shared分片

    水平分片实例分布图: mongodb sharding 服务器架构   1. 添加mongdb两个shared实例 # mkdir -p /home/m17 //home/m18 /home/m20 ...

  4. vs基础:无法断点调试dll项目 无法命中

    调试vs时,经常会出现,你设置了dll项目的一些断点,可f5之后,这些断点无效.时代定制的程序组的童鞋告诉你解决方法:在解决方案上右键“属性”,点击左侧树“配置属性”-->“配置”,右侧项目列表 ...

  5. java继承(一)

    虽然说java中的面向对象的概念不多,但是具体的细节还是值得大家学习研究,java中的继承实际上就是子类拥有父类所有的内容(除私有信息外),并对其进行扩展.下面是我的笔记,主要包含以下一些内容点: 构 ...

  6. HttpClient构造文件上传

    在项目中我们有时候需要使用到其他第三方的api,而有些api要求我们上传文件,search一下,下面将结果记录一下喽! 含义 ENCTYPE="multipart/form-data&quo ...

  7. 【异构计算】在Windows下使用OpenCL配置

    前言 目前,NVIDIA 和 AMD 的 Windows driver 均有支持OpenCL(NVIDIA 的正式版 driver 是从自195.62 版开始,而 AMD则是从9.11 版开始).NV ...

  8. Mac入门推荐(写给Mac小白)

    本人第一次接触Mac是在2016年10月中旬,那时由于对苹果系统的不熟悉,导致自己一开始的时候用的很不习惯,甚至还想换回Windows系统.总所周知,苹果系统的软件比较少,在此我向大家推荐一些个人觉得 ...

  9. Error: Cannot find module 'gulp-clone'问题的解决

    安装完gulp环境,并且配置好gulpfile.js,执行静态文件压缩和代码混淆时,出现如下错误: Error: Cannot find module 'gulp-clone' Error: Cann ...

  10. p1154 地平线

    题目描述 Farmer John的牛们认为,太阳升起的那一刻是一天中最美好的,在那时她们可以看到远方城市模糊的轮廓.显然,这些轮廓其实是城市里建筑物模糊的影子. 建筑物的影子实在太模糊了,牛们只好把它 ...