Hello!
2014-07-17 23:52 GMT-07:00 GreenFaith:
> 之前用 MariaDb, 跑 Resty-MySQL ReadMe 上的 Demo,
> 通过 netstat 和 ab 压测发现一旦 -c 使用的参数大于1,连接就不能进入连接池。
> 并且也没有任何报错。(将 ngx.say 改成 print )
>
> 于是切换数据库到 mysql 5.7,问题依旧。
> 不过,用 drizzle_pass 方式使用,连接池有效。
常见问题及调试方法:
1. 你在测试时配置了 lua_code_cache off,即禁用了 Lua 代码缓存,此时连接池的生命期是每请求的,因为
cosocket 连接池是在 Lua VM 里面分配的,而在禁用 Lua 代码缓存时,Lua VM 是每请求一个实例。ngx_drizzle
模块的连接池实现并不受 Lua 代码缓存的影响(出于显而易见的原因)。调试的办法是启用 lua_code_cache(默认开启)。
2. 你调用 set_keepalive() 方法时传入的 max_idle 参数较短(比如示例代码里的 10
秒),这意味着空闲连接在连接池里只会最久逗留这么长的时间,超过就被自动关闭(除非在此之前又为其他请求所复用)。于是你手工在命令行上先运行
ab,再运行 netstat 命令时,这中间的时间窗口很容易超出 max_idle 限制。而 ngx_drizzle 模块并没有 max
idle 保护这个功能。调试的办法是使用 0 作为 max_idle,让连接池里的空闲连接永不过期(除非 MySQL server
自己主动关闭或者 nginx 进程退出)。
3. 你使用的 MySQL 查询会返回多个结果集,而默认 query() 方法只会读取并返回第一个结果集,你需要在 query() 方法返回
"again" 这个错误字符串时,自己继续调用 read_result() 方法,直至不再返回 "again"
错误串。如果你在没有读取所有结果集之前就调用 set_keepalive()
方法,连接池一般会拒绝接收这样的连接,因为该连接的读取缓冲区里还有未读完的数据,此时允许其他会话复用该连接的话,会导致难以调试的错误。调试的办法是,总是对
set_keepalive() 的返回值进行恰当的错误处理,并把错误记入 nginx 错误日志。
请仔细检查以上三项。
Regards,
-agentzh