我有一个lua Web服务,它需要使用MySql。如果我尝试从lua控制台访问MySql,我会获得成功,就像你可以看到的那样:
$lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> local luasql = require('luasql.mysql')
> local json = require('json')
> mysql = assert(luasql.mysql())
> ret = {}
> db_name = "luaTest"
> db_host = "localhost"
> db_user = "root"
> db_pass = ""
> con = assert(mysql:connect(db_name, db_user, db_pass, db_host))
> cur = assert(con:execute("SELECT version()"))
> ret["driver_version"] = luasql._MYSQLVERSION
> ret["copyright"] = luasql._COPYRIGHT
> ret["description"] = luasql._DESCRIPTION
> ret["version"] = luasql._VERSION
> con:close()
> mysql:close()
> print(json.encode(ret))
{"copyright":"Copyright (C) 2003-2008 Kepler Project","version":"LuaSQL 2.1.2","driver_version":"5.5.29-MariaDB","description":"LuaSQL is a simple interface from Lua to a DBMS"}
我的代码是我的服务器(文件:/etc/nginx/www/ademar/app.lua):
local sinatra = require('sinatra')
local json = require('json')
local luasql = require('luasql.mysql')
local app = sinatra.app:new()
app:post("/signin", function()
ret = {}
mysql = assert(luasql.mysql())
db_name = "luaTest"
db_host = "localhost"
db_user = "root"
db_pass = ""
con = assert(mysql:connect(db_name, db_user, db_pass, db_host))
cur = assert(con:execute("SELECT version()"))
ret["driver_version"] = luasql._MYSQLVERSION
ret["copyright"] = luasql._COPYRIGHT
ret["description"] = luasql._DESCRIPTION
ret["version"] = luasql._VERSION
con:close()
mysql:close()
return json.encode(ret)
end)
app:run()
如果我尝试用$curl -X POST http://127.0.0.1/signin
运行它我得到一个html错误,在服务器日志上我得到它:
2014/01/11 17:32:20 [error] 5104#0: *2 lua entry thread aborted: runtime error: error loading module 'luasql.mysql' from file '/usr/lib/lua/5.1/luasql/mysql.so':
/usr/lib/lua/5.1/luasql/mysql.so: undefined symbol: luaL_openlib
stack traceback:
coroutine 0:
[C]: ?
[C]: in function 'require'
/etc/nginx/www/ademar/app.lua:3: in function </etc/nginx/www/ademar/app.lua:1>, client: 127.0.0.1, server: adem.ar, request: "POST /signin HTTP/1.1", host: "127.0.0.1"
我的Nginx conf:
$cat nginx.conf
user nginx www-data;
worker_processes 1;
pid /var/run/nginx.pid;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
和
$cat sites-enabled/xicoh.conf
lua_package_path './?.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua;/usr/lib/lua/5.1/?.lua;/usr/lib/lua/5.1/?/init.lua;;';
lua_package_cpath './?.so;/usr/lib/lua/5.1/?.so;/usr/lib/lua/5.1/loadall.so;;';
server {
listen 80;
server_name adem.ar;
charset utf-8;
root /etc/nginx/www/ademar;
location / {
default_type 'text/plain';
content_by_lua_file "/etc/nginx/www/ademar/app.lua";
}
error_page 500 502 503 504 /50x.html;
location = /50x.html { root html; }
}
lua console中的一些变量:
package.path = ./?.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua;/usr/lib/lua/5.1/?.lua;/usr/lib/lua/5.1/?/init.lua
package.cpath = ./?.so;/usr/lib/lua/5.1/?.so;/usr/lib/lua/5.1/loadall.so.
LD_LIBRARY_PATH = nil
和nginx脚本:
package.path = ./?.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua;/usr/lib/lua/5.1/?.lua;/usr/lib/lua/5.1/?/init.lua;/usr/local/openresty/nginx/lualib/?.lua;/usr/local/openresty/nginx/lualib/?/init.lua;./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua;
package.cpath = ./?.so;/usr/lib/lua/5.1/?.so;/usr/lib/lua/5.1/loadall.so;/usr/local/openresty/nginx/lualib/?.so;./?.so;/usr/local/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so;
LD_LIBRARY_PATH = nil
答案 0 :(得分:0)
luaL_openlib是一个在Lua 5.0中但不在5.1中的函数。在5.1中,它被luaL_register取代。所以您安装的luasql很可能是Lua 5.0,而您(根据您的包路径)假设您的系统上安装了Lua 5.1。
如果您根本没有安装5.0(也不是nginx下的某个地方),可能是路径差异?如果mysql.so链接到另一个.so或需要一个Lua模块(谁知道mysql做了什么,它可能会调用Lua的要求),但是在两个环境中看到的路径不同,它可能会找到错误的lib:lib可能正在使用5.0 luaL_openlib。或者,不同的环境(例如用户权限)使得mysql的行为不同,例如查找不同的lib。从脚本中打印package.path
和package.cpath
以及os.getenv("LD_LIBRARY_PATH")
。
好的,所以我在github上检查了luasql / mysql模块的源代码。版本2.2.x(6年前发布)和更早版本使用旧的luaL_openlib(必须用于Lua 5.0),尽管提交日志表明存在5.1的兼容性文件。可能你的mysql.so版本是为5.0构建的。版本2.3使用仅在Lua 5.2中的luaL_setfuncs,因此可能还需要使用一个构建设置来告诉编译器使用5.1头文件并链接到5.1。