关键字:Erlang,进程池,开源

1.情景

    项目中有很多连接zookeeper的地方,都是各自连接,保存pid或者monitor,并在terminate或DOWN的时候对连接进行关闭或者重连。可以考虑采用Erlang进程池,对进程进行统一管理。

    2种需要采用进程池的情景:

    1.大量的普通Erlang进程:虽然vm默认可以创建很多,笔者的机器可以创建大概2w个进程(进程默认大小32k,可以调整vm参数设置更大)。但不意味着可以无限使用,有时候需要对进程进行管理,避免无限制的使用。

    2.重型Erlang进程:简单的说,就是启动成本较大的进程,可以采用在进程池避免反复的启动和关闭,方便管理。


2.进程池解决的问题

    归纳如下:

    1.初始化。

    2.管理(进程的进出)。

    3.控制(最小,最大的数量)。


3.开源的Erlang进程池

    1.poolboy

    2.hottub

    3.pooly

    4.gen_server_pool。


4.一个进程池的实现例子:Learn Your Some Erlang


这篇文章讲述了如何使用 OTP 实现进程池,文章讲的很清楚,这里再补充一下整个程序的流程:

1 首先调用 ppool_supersup 的 start_link 方法创建超级监控进程。

2 调用 ppool_supersup:start_pool 创建 ppool_sub 监控进程,而在ppool_sub 的 init 方法中又会创建 ppool_serv 进程,在 ppool_serv 的 init 方法中向自己发送消息,然后引起 handle_info 得到调用,在这里创建 worker_sup 监控进程。之所以要在 ppool_serv 中启动 woker_sup 。是因为 ppool_serv 要和 worker_sup 通信,因此要保存 worker_sup 的进程 ID。

源码请移步:https://bitbucket.org/ferd/learn-you-some-erlang/src/2dc0db607000/ppool-1.0?at=default


5.重型进程池poolboy


    poolboy,代码量很小,3个程序文件400行的代码。poolboy_sup(supervisor)是挂在poolboy(gen_fsm)下的,poolboy_sup下维护N个工作进程(Worker),进程的 checkin 和 checkout 通过 gen_fsm 来维护,采用 gen_fsm 的方式,设计比较精巧,支持 max_overflow 和 full 后的等待超时。

6.固定型进程池hottub


例子如下:

hottub:start_link(demo, 5, demo_worker, start_link, []).
hottub:call(demo, {add, 5, 5}).
hottub:cast(demo, {print, "what up from a pool"}).
hottub:stop(demo).

    hottub 是一个固定个数的线程池,在运行过程中不可增加。在 hottub 中处理checkout_worker,checkin_worker,进程会被复用,也会可能产生阻塞的情况,比较适合轻量级的业务。


7.最完备的进程池pooly


    参数支持如下:

    1。initial_pool_size:初始个数。

    2。max_pool_size:最大个数。

    3。min_pool_size:最小个数。

    4。idle_timeout:超时时间。

    5。acquire_increment:额定增长。

    pooly 比较独特的是采用pooly_member(gen_fsm)来维护进程的激活和超时,和poolboy一样,采用gen_fsm的形式来管理work进程。和ppool一样有一个超级监控进程pool_sup,为了支持多个进程池。


总结:

    这几个进程池各有特色,实现的方式也不尽相同。没有最好的,只有最合适的。




参考资料:

1.http://cryolite.iteye.com/blog/1545171 《关于erlang的进程池》

thomesca(北蔡):http://blog.csdn.net/thomescai (转载请保留)

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐