1.当我们require "foo"后,会在整个大环境的_G table里生成一个table类型的全局变量foo,里面存放了foo库里定义的函数与变量,我们依赖foo这个全局变量来调用需要的函数和变量,
与此同时,require "foo"还会在package.loaded这个table里生成具有相同值的table类型变量foo,require调用还会返回这个值(这里我们并没有存储这个返回值)
2.ngx_lua模块在开启lua_code_cache这个指令的时候会缓存需要加载的lua库,所以当第一个请求触发了这段code的执行时,生成了全局变量foo,以及package.loaded["foo"]变量(如1所述),后续的请求都将不再生成这个全局变量foo,而是直接从package.loaded["foo"]中读取缓存了的foo库
3.ngx_lua模块的设计理念就是要隔离不同请求之间的全局变量,所以全局变量的生命期和一个请求的生命期是一样的,从这点理解,我们就能解释为什么第二次请求时,通过foo.func(var)方式调用函数时会出现foo为nil的错误了(理由如2所述)
4.综上所述,我们在编写lua库的时候不要依赖module函数,它能解决一定的书写错误问题(如遗漏local声明),却引入了更大的问题(如污染了全局空间),建议使用官方lua库的编码方式来编写库代码,以及通过local foo = require "foo"的方式来加载库代码