Erlang PoolBoy 源码分析

问题存疑:

  • 1.如何释放使用过的进程,被再次利用
  • 答:通过try after 的方式,try checkout锁定一个进程,after 用完之后释放被锁定的进程
  • 2.如果出现初始进程不够了,如果处理
  • 答:如果不够用,判定max_overflow参数,确定是否需要重新创建进程,或者将此使用者放入等待列表中,一旦有新释放的,就马上给他使用,受超时器的影响
  • 3.创建新的进程,是如何释放的 答:如果此进程是弹性创建的,则直接释放此进程,如果是work中的进程,则释放使用权
  • 4.如果达到最大的创建进程数,又是如何处理的 答:根据block参数确定,是否忽略或者加入等待列表中
  • 5.如果创建的进程 答:poolboy_sup 通过sample_one_by_one参数形式,动态调用supervisor:start_child创建进程池中的进程
  • 6.为什么需要将初始创建的进程和poolboy进程link起来,有何用意 答:这样就可以将所有的逻辑全部集中在poolboy进程,只是将poolboy_sup当作一个中间件来使用创建进程池中的进程

queue 队列

支持先进先出或者后进先出模式

基本思路

  • 1.通过一个外部sup启动一个poolboy进程,poolboy进程再启动一个poolboy_sup进程
  • 2.poolboy_sup 就是这个进程池,然后启动若干个进程,但是poolboy进程操纵poolboy_sup进程创建很多个进程,然后将这些进程全部保存在poolboy进程
  • poolboy进程并且与poolboy_sup进程创建的进程进行link
  • 当外部进程需要进程时直接从poolboy进程入口,然后使用,并且poolboy进程还监控所有使用的外部进程
  • 当外部进程down掉后,poolboy进行善后操作,每一个外部进程独享poolboy进程中的一个进程
  • 通过try after 方法,先独享进程,用完后,再释放进程
  • link的还有一个操作,就是处理poolboy进程池中进程挂掉的情况,先关闭此进程,并进行善后操作,然后,重新启用一个新的进程,带起挂掉的进程
  • 主要的接口就是checkout和checkin的两个接口创建
  • 数据结构采用queue,有两种方式可选,fifo(先进先出),fofi(后进先出)的方式,遍历整个进程池
  • 还采用了一种动态创建进程的机制,就是说,如果发现现有创建的进程不够用了,那就需要创建一个临时的进程,满足使用,当使用完之后,再释放此进程
  • 如果在释放的时候,发现还有等待的进程,则继续使用释放的进程,进行执行

启动

  • 1.创建两个数据结构,wait:queue:new 保存等待的进程吃中分配的进程,monitors=ets:new()创建一个监控使用进程池中进程的数据
  • 2.创建poolboy_sup 监督进程,采用sample_one_by_one 启动,后面采用supervisor:start_child(Sup,Args)启动进程
  • 3.设置启动参数:
  • worker_module:启动进程池的进程模块名
  • size:进程池中常见size个进程
  • max_overflow:最多可以弹性创建进程的数量
  • starategy:lifo|fifo 后进先出|先进先出模式 (一版来说,进程池中的进程没有区别的)
  • Block:true 允许进程获取等待 false 不允许进程获取等待,在checkout接口中设置
  • 4.启动进程池进程 supervisor:start_child(Sup,Args)启动子进程,填充进程池

使用

调用poolboy:transaction(PoolName,Query)

  • 工作机制:
  • 1.首先调用checkout获取进程池中的一个进程,调用的是call同步的方法执行,并设置超时时间 2.使用完毕之后,调用checkin释放进程使用
  • 3.如果出现进程池没有进程,就可以通过max_overflow参数配置,确认是否可以生成新的进程以供使用
  • 4.如果没有,则可以通过Block参数,确认是否可以将当前请求放入waiting中,只要有进程释放,就将此进程返回
  • 5.进程使用完毕,则释放此进程的使用权,清理监控数据列表,然后判定是否弹性创建,决定是否释放,如果有等待进程,则将此进程使用权转移使用

异常处理

  • 1.使用进程挂掉:调用down的handle_info,清理监控列表和工作列表,以及等待列表
  • 2.进程池中进程挂掉:删除监控,重新生成一个进程

执行函数

  • checkout 获取一个可用进程
  • checkin 释放一个使用进程
  • transaction 一个完整的获取和释放进程过程

可能的不足之处

短暂 I/O 任务(比如数据库访问)的大型 worker 池会因为太多迁入和迁出活动而拖垮单个 poolboy 管理器。

  • 参考:
  • Erlang 池管理 maestro Erlang:https://www.oschina.net/p/maestro-erlang
{!-- PGC_COLUMN --}

© 著作权归作者所有

作者:648789030

原文:https://my.oschina.net/gaoxepro/blog/3004170

Erlang PoolBoy 源码分析

相关推荐