一、nginx+lua两种设置全局lua脚本(so模块)加载路径的方法

    在nginx+lua的程序架构中,如果我们要调用很多成型的工具类lua文件,或者自己写好的可公用的lua module,可以把它放在磁盘上一个共用的目录(不和代码放在一起),并且这个目录也不是lua的安装目录(lua在程序执行时会自动尝试去加载安装目录里的lua文件,比如/usr/lib/lua/5.1/),可以有两种方式实现自动搜索。

1. 在lua脚本中设置目录

比如在lua代码中执行:

package.path = '/opt/golbal_lua/?.lua;/opt/now_project_lua/?.lua;;'    --搜索lua模块
package.cpath= '/opt/golbal_so/?.so;/opt/now_project_so/?.so;'         --搜索so模块

    当在代码里面执行require("cjson");会搜索到上面的目录,即package.path即是指定lua程序中require搜索的路径。require函数像dofile一样载入文件为一个Chunk并执行,其还具有两个好处,一个是会按模式加载文件;另一个是不会重复载入相同的文件。

    package.path和package.cpath的区别是一个是lua模块的路径;一个是so模块的路径。lua程序在查找的时候会先找lua文件,然后再查找.so文件。

2. 在nginx配置文件中加上目录

    可以在nginx配置文件中加上目录:nginx.conf中server外层增加配置、。

lua_package_path    "/opt/golbal_lua/?.lua;/opt/now_project_lua/?.lua;;";
lua_package_cpath   "/opt/golbal_so/?.so;/opt/now_project_so/?.so;;";

    这样在程序中require出现找不到对就的在lua或者so文件时,会看到报错的顺序如下:

[error] 19962#0: ../resty/string.lua:4: module 'ffi' not found:
no field package.preload['ffi']
no file '/opt/golbal_lua/ffi.lua'
no file '/opt/now_project_lua/ffi.lua'
no file './ffi.lua'
no file '/opt/golbal_so/ffi.so'
no file '/opt/now_project_so/ffi.lua'
no file './ffi.so'

二、Lua多个lua_package_path的问题nginx: [emerg] lua_package_path directive is duplicate

    在nginx配置lua项目的时候,有时可能不只有一个lua项目,而不同的lua项目存在于不同的 lua 代码目录中,但在nginx的配置文件中只能使用一个lua_package_path 配置来指定lua代码包的路径地址。

    这时如果配置多个 lua_package_path 的话 nginx 配置检查就会报错:

nginx: [emerg] "lua_package_path" directive is duplicate in /data/nginx/conf/vhosts/***.conf

    怎么解决这个问题呢?其实这个真的不是问题!因为在lua项目代码中可以自己配置自己的lua_package_path。关于两种配置全局lua脚本(so模块)加载路径,这个就可以完美解决这个问题。

    在nginx中可以指定一个项目的lua_package_path,从而在nginx可以直接使用access_by_lua_block 来调用lua模块。而其它的项目可以使用content_by_lua_file来指定调用的lua文件,再在这个指定的lua文件(lua项目入口)中使用package.path的值即可。