erlang的稳定连接池

连接池很好写,基本架构就是一个manager,在manager启动的时候负责创建链接并把连接存储到一个地方,然后每次请求过来都给出一个有效的连接。

 

为了保证效率,我采用了ets表,而没有用进程字典和queue作为存储连接的地方,为什么呢?因为ets表可以并发读和并发写,进程字典和queue速度是比ets快,但是只能有manager去访问,这样无形当中就形成了性能瓶颈,ets则可以N多个进程同时去读,没有瓶颈,在并发的情况下比进程字典和queue快了不是1倍2倍。

 

在erlang中大部分数据库driver的连接都是一个进程,我们拿到的都是这个进程的PID,拿postgresql的driver举例子。他的单个连接可以支持并发访问,所以连接池不需要加锁。

 

当我们给其他进程连接的时候,由于未知错误导致这个数据库连接进程挂掉了怎么办?所以我们需要一个supervisor进程来监督这些连接。每当有个连接死掉的话,就通知supervisor让他去重启,所以我们的重启策略就是永久的也就是permanent,然后由于所有的链接都是一样的所以监控策略就是simple_one_for_one,每5秒中重启10次就dawn掉整个supervisor。

 

当我们一个连接挂掉,我们要求重启的时候也能通知manager,告诉他替换新的连接,所以我们还需要在每次重启前执行一段代码,这样就需要个worker,由他负责启动连接替换旧的连接,然后把新链接注册到supervisor上。

 

当supervisor挂掉后怎么确保manager也重启呢?我的做法是把manager注册到最顶层的supervisor上,然后supervisor link到manager上,这样保证了manager和supervisor任何一个挂掉,整个连接池都会重启。

 

真个架构最终形态应该是:


erlang的稳定连接池_第1张图片
 

具体的代码在这里:postgresql pool

你可能感兴趣的:(erlang的稳定连接池)