openresty 安装后, 默认包含 lua-resty-mysql
, 我就是用的这个连接的 mysql, 很好用.
当一个 request 进来过后, 一般这么用:
local mysql = require "resty.mysql" local db = mysql:new() local cfg = { ... } db:connect(cfg) local res = db:query("select * from users") ngx.say(json.encode(res))
但是如果我 require 的一个文件中也需要连接 mysql, 怎么办?
刚开始我这么用的:
a.lua
local Email = require("email") local item = Email:get_item(5)
email.lua
local mysql = require("resty.mysql") local db = mysql:new db:connect(cfg) function Email:get_item(id) local res = db:query("select * from emails where id = " .. id) local item = res[1] return item end
一个 request 过来后, 直接报错:
> 2013/11/14 19:30:09 [error] 5290#0: *425 lua entry thread aborted: runtime > error: attempt to yield across C-call boundary
出现这个原因是因为 require 的文件中, 不能直接有 mysql io 操作.
看下 春哥 的回复:
Hello! 2013/11/14 wxianfeng: > 最新测试, 发现同时在两个lua文件中 db:connect(cfg) 不成功, 报下面错误: > > 2013/11/14 19:30:09 [error] 5290#0: *425 lua entry thread aborted: runtime > error: attempt to yield across C-call boundary > 这个错误是说你使用的某个 C 函数实现的 Lua 原语(比如 require 和 loadfile 之类)直接触发了 resty.mysql 的 I/O 操作(例如 connect 之类)。你应当避免让 require 和 loadfile 等操作直接触发 mysql 的 I/O 操作(比如把 mysql 相关的操作都放在你自己的 Lua 函数里,而不是放在 Lua 模块文件(.lua 文件)的顶层上)。
最后我把 email.lua 中连接 mysql 的操作, 放到一个函数中 解决.
local mysql = require("resty.mysql") local db = mysql:new local function connect_db() db:connect(cfg) end function Email:get_item(id) connect_db() local res = db:query("select * from emails where id = " .. id) local item = res[1] return item end