本文转自:http://blog.csdn.net/qinyushuang/article/details/44857995
语法和使用场景
语法: lua_code_cache on | off使用的上下文:http, server, location, location if
作用:lua_code_cache是nginx_lua模块的一条指令。它为 *_by_lua_file(如 set_by_lua_file 和 content_by_lua_file) 这些指令以及Lua模块, 开启或关闭Lua代码缓存.(nginx_lua模块说明:http://wiki.nginx.org/HttpLuaModule#lua_code_cache)
如果关闭,每个ngx_lua处理的请求将运行在一个独立的Lua VM实例里,0.9.3版本后有效. 所以 set_by_lua_file, content_by_lua_file, access_by_lua_file, 等等指令引用的Lua文件将不再缓存到内存, 并且所有Lua模块每次都会从头重新加载. 这样开发者就可以避免改代码然后重启nginx的操作.
但是, 那些直接写在 nginx.conf 里的代码比如由 set_by_lua, content_by_lua, access_by_lua, and rewrite_by_lua 指定的代码不会在你编辑他们时实时更新,因为只有发送HUP信号通知Nginx才会正确重新加载Nginx的config文件。
即使打开了代码缓存, 那些*_by_lua_file指令里由 dofile 或 loadfile 加载的Lua文件也无法被缓存 (除非你自己手动缓存了他们). 通常你可以用 init_by_lua 或 init_by_lua_file 其中一种指令来加载所有这些无法被缓存 的文件,或把这些文件做成真正的Lua模块并用require加载.
生产环境下千万别关闭Lua代码缓存,只能用在开发模式下,因为对性能有十分大的影响(每次IO读取和编译Lua代码消耗很大, 简单的hello world都会慢一个数量级)
常见问题
网上有很多小伙伴们遇到过和我一样的问题:当lua_code_cache开关打开时,当使用content_by_lua 引入外部的lua文件,并且在lua文件中有对应的内容输出,只有第一次运行脚本的时候正常,如果再次运行,浏览器就会提示500 服务器内部错误。或者第一次请求有响应数据,第二次提示响应数据为空。问题的原因:
类似这种问题的原因常见的错误是你使用的 lua文件的模块滥用 Lua 全局变量来存放其内部状态信息,而不是模块 table 本身。而在lua_code_cache on 时,全局变量的生命期是每请求的,所以会出现这种情况:
第一个请求调用 require 加载了你用lua文件写的模块,而你的该模块把内部状态保存在了和第一个请求相关联的某些全局变量中。
后续的各次请求调用 require 时直接返回了步骤 1 中已经加载过的lua模块所对应的 table.
但此时后续请求的全局变量都是干净的(和第一个请求无关),于是该lua模块无法得到它需要的内部状态数据,出现访问未初始化变量的错误。
解决方式和建议:
总是使用下面的形式来加载 Lua 模块:local foo = require "foo" -- This is correct!
而不是简单地
require "foo" -- This is wrong!!
在你自己的 Lua 模块中避免使用 Lua 全局变量(对于必需的文件范围的变量,可以使用 local 在最外层作用域定义之)。
你可以使用下面文档中的办法来检查你的 .lua 文件中是否有使用 Lua 全局变量:
http://lua-users.org/wiki/DetectingUndefinedVariables
可以使用这篇文章中介绍到的基于 luac 命令行工具的静态代码检查方式来检查是否有使用lua全局变量,即
luac -p -l yourprogram.lua | grep ETGLOBAL
上述内容是对下面内容的一个总结(如果看明白了,下面可以不用看了)。
lua_code_cache 问题:
从这里拿的:https://groups.google.com/forum/#!topic/openresty/W0dvD5Wm0Bw
|