4.Mysql驱动

来源:互联网 发布:两只重量级老虎知乎 编辑:程序博客网 时间:2024/06/01 09:28

  关于mysql的数据库驱动,网上有开源的git代码,https://github.com/dizzyd/erlang-mysql-driver

  erlang先跟mysql建立tcp连接登录,然后在上面执行SQL命令。首先看mysql.erl模块的start和start_link函数,最终进入start1中启动gen_server,所以mysql驱动的分发中心是一个gen_server。在init初始化中,启动了一个连接进程mysql_conn,并加入gen_server的连接池里。进入mysql_conn:start,发现它首先创建了mysql_recv进程接收mysql返回的信息,然后从mysql_auth进行登录验证。
  关于mysql模块与mysql_conn的关系,我们可以从mysql:fetch函数看起。从fetch追踪,进入到get_next_conn,然后从连接池中取出空闲中的mysql_conn进程,如果所有mysql_conn进程都在繁忙,则重置列表,该次请求会进行对应的mysql_conn进程中队列中等待。但是我们注意fetch函数使用了gen_server:call的同步操作,这样线程池的作用就发挥不出来了?当然不会。
  我们再进入fetch_queries函数(fetch最终会执行到此处),看到执行完mysql_conn:fetch后,进程直接进入{noreply, State1}挂起状态,而我们调用该次fecth操作的进程依然在等着,而mysql_conn进程跟mysql通信结束后,会把结果通过gen_server:reply方法返回给调用者。这样最终阻塞的地方就是我们的mysql_conn进程。而mysql进程作为分发进程,并不会被阻塞。
  因此我们使用mysql驱动时,可以开一个mysql的分发进程,多个mysql_conn的通信进程。
  mysql:start(...).lists:foreach(fun(_) ->  mysql:connect(...)    end, lists:seq(10)).
  上面一段代码中,就启动了11个mysql_conn通信进程(mysql:start启动时已经有一个)。
0 0
原创粉丝点击