[code.openresty] Openresty指令集-下

log_by_lua

语法: log_by_lua <lua-script-str>

上下文: http,server,location,location if

时期: log

注意v0.9.17版本开始,不建议 使用这个指令,使用log_by_lua_block 代替。

log请求处理阶段运行<lua-script-str>的Lua源代码。这并不会替换当前的访问日志。只是在它之前执行而已。

主要下面的API方法在这个上下文中目前是被禁用的:

下面是一个收集$upstream_response_time平均数据的例子:


      lua_shared_dict log_dict 5M;

      server {
          location / {
              proxy_pass http://mybackend;

              log_by_lua'
                  local log_dict = ngx.shared.log_dict
                  local upstream_time = tonumber(ngx.var.upstream_response_time)

                  local sum = log_dict:get("upstream_time-sum") or 0
                  sum = sum + upstream_time
                  log_dict:set("upstream_time-sum",sum)

                  local newval,err = log_dict:incr("upstream_time-nb",1)
                  if not newval and err == "not found" then
                        log_dict:add("upstream_time-nb",0)
                        log_dict:incr("upstream_time-nb",1)
                  end
              ';
          }

          location = /status {
              content_by_lua_block {
                  local log_dict = ngx.shared.log_dict
                  local sum = log_dict:get("upstream_time-sum")
                  local nb = log_dict:get("upstream_time-nb")

                  if nb and sum then
                      ngx.say("average upstream response time: ", sum / nb, "(",nb," reqs)")
                  else
                      ngx.say("no data yet")
                  end
              }
          }
      }

这个指令首先从v0.5.0rc31版本被介绍。

log_by_lua_block

语法: log_by_lua_block { lua-script }

上下文: http,server,location,location if

时期: log

log_by_lua指令相似,除了这个指令将Lua源代码直接通过一对大括号 ({}) 包含起来而不是Nginx字符串(需要特殊字符转码)。

例如:


        log_by_lua_block {
            print("I need no extra escaping here, for example: \r\nblah")
        }

这个指令首先在v0.9.17版本中被介绍。

log_by_lua_file

语法: log_by_lua_file <path-to-lua-script-file>

上下文: http,server,location,location if

时期: log

log_by_lua等价,除了<path-to-lua-script-file>指定包含Lua代码的文件,或者,从v0.5.0rc32版本开始,Lua/LuaJIT bytecode被排除了。

当给出一个相对的地址例如foo/bar.lua,它们会将其根据server prefix路径转化为一个绝对地址,server prefix路径是在启动Nginx服务器时在命令行参数-p PATH里面指定的。

这个指令首先在v0.5.0rc31版本中被介绍。

balancer_by_lua_block

语法: balancer_by_lua_block { lua-script }

上下文: upstream

时期: content

这个指令作为一个upstream均衡器运行Lua代码,可以在upstream {}配置块定义的所有upstream实体中使用。

例如:


  upstream foo {
      server 127.0.0.1;
      balancer_by_lua_block {
          -- 使用Lua在这里来做一些有趣的事
          -- 作为一个动态的均衡器
      }
  }

  server {
      location / {
          proxy_pass http://foo;
      }
  }

由此产生的Lua负载均衡器可以和现有的nginx upstream模块一起使用,例如: ngx_proxyngx_fastcgi

另外,这个Lua负载均衡器可以和标准upstream连接池机制一同工作,例如,标准keepalive指令。
只要确保这个keepalive 指令在一个单独的upstream{}配置块中的balancer_by_lua_block后面 使用。

这个Lua负载均衡器可以完全忽略掉定义在upstream{}块中定义的servers列表并且从一个完全动态的server列表(即使在每个请求中改变)中选择,通过lua-resty-core库中的ngx.balancer模块。

当nginx的upstream机制重试请求中指令指定的条件,如proxy_next_upstream指令,这个指令注册的Lua代码处理器可能在一个单独的downstream请求中被调用不止一次。

这个上下文中执行的Lua代码并不支持yielding,所以可能yield的Lua APIs(例如 cosockets 和 "light threads")在这个上下文中是被禁用的。通过在早期阶段处理程序(如:access_by_lua*)处理这种操作和通过ngx.ctx table传递结果给这个上下文的解决方法可以绕过这个限制。

这个指令首先在v0.10.0版本中被介绍。

balancer_by_lua_file

语法: balancer_by_lua_file <path-to-lua-script-file>

上下文: upstream

时期: content

balancer_by_lua_block等价,除了通过<path-to-lua-script-file>指定包含Lua代码的文件,后者,从v0.5.0rc32版本开始, Lua/LuaJIT bytecode被排除了。

当给定一个相对地址如foo/bar.lua,它们会相对于server prefix转成绝对地址,server prefix路径是在启动Nginx服务器时通过命令行里面的-p PATH参数定义的。

这个指令首先在v0.10.0版本中被介绍。

lua_need_request_body

语法: lua_need_request_body <on|off>

默认: off

上下文: http,server,location,location if

时期: denpends on usage

决定在执行 rewrite/access/access_by_lua*之前是否强制读取request body数据。Nginx内核默认情况下不读取client的reqeust body,所以如果需要request body,所以这个指令应该被转换为on或者在lua代码里调用ngx.req.read_body方法。

为了通过$request_body变量来读取request body数据,client_body_buffer_size必须要和client_max_body_size有同样的值。这是因为当content长度超过了client_body_buffer_size但是比client_max_body_size要少,Nginx会缓存数据到磁盘的一个临时文件上,这样会导致$request_body变量为空值。

如果当前location包含 rewrite_by_lua*指令,那么request body会在rewrite_by_lua*代码运行(rewrite时期也是一样)之前被读取。
同样的,如果只指定了 content_by_lua,request body将不会被读取知道content处理的Lua代码将要运行(例如,request body将会在content时期被读取)。

不过建议,要使用ngx.req.read_bodyngx.req.discard_body方法来更好的控制request body读取的过程。

这个同时适用于access_by_lua*

ssl_certificate_by_lua_block

语法: ssl_certificate_by_lua_block { lua-script }

上下文: server

时期: right-before-SSL-handshake

当Nginx要准备开始downstream SSL(https)连接握手的时候,这个指令运行用户的Lua代码。

这个对于设置SSL证书链和根据每个请求对应的私钥特别管用。对于从远程加载非阻塞的握手配置也是非常有用(例如, 使用cosocket API)。并且在这里也可以在纯Lua里面给每一个请求做OCSP stapling处理。

另一个典型用例是在这个上下文中来非阻塞的做SSL握手的流量控制。例如:使用lua-resty-limit-traffic#readme库的帮助。

另外在client端的SSL握手请求时也可以做一些有趣的事情,例如拒绝老的SSL client使用 SSLv3协议甚至选择更低的。

lua-resty-core库里面提供的ngx.sslngx.ocspLua模块在这个上下文中特别有用。你可以使用这两个模块提供的Lua API来操纵SSL证书链和启动当前SSL链接的私钥。

然而,当NGINX/OpenSSL通过SSL session IDs或者TLS session tickets对当前的SSL连接成功恢复了SSL session,这个Lua处理器并不运行。换句话说,这个Lua处理器仅仅在Nginx乣初始化一个完整的SSL握手时运行。

下面是一个在同一时间使用ngx.ssl模块的小例子:


    server {
        listen 443 ssl;
        server_name test.com;

        ssl_certificate_by_lua_block {
            print("About to initiate a new SSL handshake!")
        }

        location / {
            root html;
        }
    }

查看ngx.sslngx.ocspLua模块的官方文档的复杂的例子。

用户Lua代码里未捕获的Lua异常会立即终止当前的SSL session,ngx.exit调用是用了一个error code例如ngx.ERROR也是如此。

Lua代码执行上下文 确实 支持yielding,所以可能yield的Lua APIs(如 cosockets,sleeping,和“light threads”)在这个上下问中是可用的。

注意,无论如何,你使用需要配置ssl_certificatessl_certificate_key指令,即使你不会使用这个静态证书和私钥。这是因为Nginx core需要他们的appearance否则你在启动Nginx时会看到这个错误:

    nginx: [emerg] no ssl configured for the server

这个指令目前需要以下nginx核心补丁,才能正常工作:

http://mailman.nginx.org/pipermail/nginx-devel/2016-January/007748.html

在OpenResty 1.9.72(或更高)版本捆绑的Nginx核心已经应用了这个补丁。

除此之外,至少需要OpenSSL 1.0.2e指令工作。

这个指令首先在v0.10.0版本中被介绍。

ssl_certificate_by_lua_file

语法: ssl_certificate_by_lua_file <path-to-lua-script-file>

上下文: server

时期: right-before-SSL-handshake

ssl_certificate_by_lua_block等价除了通过 <path-to-lua-script-file>指定的文件包含Lua代码,从v0.5.0rc32版本开始, Lua/LuaJIT bytecode被排除了。

当给定了一个相对地址如foo/bar.lua,他们会将其相对server prefix路径转换为绝对路径,这个server prefix是在启动Nginx服务器时通过命令行参数中的-p PATH指定的。

这个指令首先在v0.10.0版本中被介绍。

ssl_session_fetch_by_lua_block

语法: ssl_session_fetch_by_lua_block { lua-script }

上下文: http

时期: right-before-SSL-handshake

这个指令运行Lua代码来查找和加载SSL会话(若有的话),根据的是为downstream当前SSL握手请求提供的session ID。

lua-resty-core库里的ngx.ssl.sessionLua模块提供用来获取当前会话ID和加载缓存的SSL session数据的Lua API。

可能会yield的Lua APIs,例如 ngx.sleepcosockets在这个上下文中是可用的。

这个钩子,和ssl_session_store_by_lua*钩子一起,可以在纯Lua中用来实现分布式缓存机制(例如,基于cosocket API),如果找到一个缓存的SSL session并且被加载到当前SSL连接上下文中,SSL session恢复可以被立即启动,并且绕过整个SSL握手的过程,这个过程占用非常昂贵的CPU时间。

请注意,TLS session tickets是非常不同的并且当session tickets被使用到时这是client的责任来缓存SSL session状态。
不需要经过这个钩子(也不需要ssl_session_store_by_lua_block钩子),基于TLS session tickets的SSL session恢复会自动发生。
这个钩子主要用于通过或多或少的通过SSL client通过session IDs来做SSL sessions。

当同时指定了ssl_certificate_by_lua*,这个钩子通常在ssl_certificate_by_lua*之前运行。当SSL session被找到并且被当前SSL连接顺利加载,SSL会话恢复会发生并且会完全绕过ssl_certificate_by_lua*钩子。在这种情况下,Nginx也会绕过ssl_session_store_by_lua_block钩子,因为明显的原因。

为了使用一个现代的web浏览器本地测试这个钩子,你可以暂时把下面一行放在你的https服务块中来禁用TLS session ticket支持:

    ssl_session_tickets off;

但是不要忘了在你对外发布你的网站时注释掉这行。

如果你使用OpenRestyofficial pre-built packages 1.11.2.1或者更新版,那么一切都是正常工作的。

如果你使用不是由OpenResty提供的OpenSSL库,那么你需要在OpenSSL 1.0.2h或更新版使用下面的补丁:

https://github.com/openresty/openresty/blob/master/patches/openssl-1.0.2h-sess_set_get_cb_yield.patch

如果你使用OpenResty1.11.2.1或者更新版携带的Nginx核心,那么需要为标准的Nginx核心1.11.2或者更新版使用下面的补丁:

http://openresty.org/download/nginx-1.11.2-nonblocking_ssl_handshake_hooks.patch

这个指令首先在v0.10.6版本中被介绍。

注意:从v0.10.7版本开始,这个指令只允许在 http context 里使用。
(这是因为SSL session恢复是在server名称dispatch之前发生)

ssl_session_fetch_by_lua_file

语法: ssl_session_fetch_by_lua_file <path-to-lua-script-file>

上下文: http

时期: right-before-SSL-handshake

ssl_session_fetch_by_lua_block等价,除了通过<path-to-lua-script-file>指定包含Lua代码的文件,更准确的说, Lua/LuaJIT bytecode被排除了。

当给定一个相对地址如 foo/bar.lua ,他们会根据server prefix将其转换为绝对地址,server prefix是在启动Nginx服务器时通过命令行参数里面的-p PATH来指定的。

这个指令在v0.10.6版本中被首次介绍。

注意:从v.0.10.7版本开始,这个指令只允许在 http context 中使用。
(这是因为SSL session恢复在server名称dispatch之前发生)

ssl_session_store_by_lua_block

语法: ssl_session_store_by_lua_block { lua-script }

上下文: http

时期: right-after-SSL-handshake

这个指令运行Lua代码来获取和保存SSL session(如果有的话),根据为当前downstream的SSL握手请求提供的session ID。这个被保存或者被缓存的SSL session数据可以被用来将来的SSL连接来恢复SSL session而不需要经历完成的SSL握手过程(这个过程是非常耗CPU时间的)。

可能会yield的Lua API,例如ngx.sleepcosockets在这个上下文中是 禁用 的。然而你仍然可以使用ngx.timer.atAPI来创建一个0延迟的定时器来异步的保存SSL session数据到外部的设备中(如redis或者memcached)。

lua-resty-core库中的ngx.ssl.sessionLua模块提供的Lua API获取当前session ID和相关的session状态数据。

为了使用现代的web浏览器在本地容易的测试这个钩子,你可以临时在你的https服务器块中使用下面的行来禁用TLS session ticket的支持:

    ssl_session_tickets off;

但是不要忘记在你公布你的网站的时候注释掉这行。

这个指令首先在v0.10.6版本中被介绍。

注意:从v0.10.7版本开始,这个指令紧紧允许在 http content 中被使用(这是因为SSL session恢复发生在server名称dispatch之前)。

ssl_session_store_by_lua_file

语法: ssl_session_store_by_lua_file <path-to-lua-script-file>

上下文: http

时期: right-after-SSL-handshake

ssl_session_store_by_lua_block等价,除了通过<path-to-lua-script-file>指定包含Lua代码的文件,精确来说,Lua/LuaJIT bytecode被排除了。

当给定一个相对的地址如foo/bar.lua,他们会根据server prefix来将其转换为绝对地址,server prefix路径通过启动Nginx服务器时通过命令行参数里面的-p PATH来指定。

这个指令首先在 v0.10.6 版本中被介绍。

注意:从 v0.10.7 版本开始,这个指令只允许在 http context 中被使用。
(因为SSL session恢复发生在server名称dispatch之前)

lua_shared_dict

语法: lua_shared_dict <name> <size>

默认: no

上下文: http

时期: denpends on usage

声明一个共享的内存区域,<name>,基于Lua字典 ngx.shared.<name>作为一个存储器来提供共享存储。

共享内存区总是被当前nginx服务器实例的所有nginx工作进程共享。

这个<size>参数接受大小单位例如km:


    http {
        lua_shared_dict dogs 10m;
        ...
    }

硬编码的最小大小为8KB然而实际最小值依据实际的用户数据集(一些人也从12KB开始)

查看ngx.shared.DICT的细节。

这个指令首先在 v0.3.1rc22版本中被介绍。

lua_socket_connect_timeout

语法: lua_socket_connect_timeout <time>

默认: lua_socket_connect_timeout 60s

上下文: http,server,location

这个指令控制用于TCP/unix-domain 套接字对象connect 方法的默认的超时值,并且能够被settimeout或者settimeouts方法来覆盖。

这个<time>参数可以是一个整数,附带一个可选的时间单位,例如s (second), ms (millisecond), m (minute)。默认的时间单位是s,例如, "second".默认的时间是 60s

这个指令首先在v0.5.0rc1版本中被介绍。

lua_socket_send_timeout

语法: lua_socket_send_timeout <time>

默认: lua_socket_send_timeout 60s

上下文: http,server,location

控制用于TCP/unix-domain套接字对象send方法的默认的超时值,并且能够被settimeout或者settimeouts方法来覆盖。

这个<time>参数可以是一个整数,附带一个可选的时间单位,例如s (second), ms (millisecond), m (minute)。默认的时间单位是s,例如, "second".默认的时间是 60s

这个指令首先在v0.5.0rc1版本中被介绍。

lua_socket_send_lowat

语法: lua_socket_send_lowat <size>

默认: lua_socket_send_lowat 0

上下文: http,server,location

控制cosocket send buffer的lowat (low water)值。

lua_socket_read_timeout

语法: lua_socket_read_timeout <time>

默认: lua_socket_read_timeout 60s

上下文: http,server,location

时期: depends on usage

这个指令控制在TCP/unix-domain socket 对象receive方法的默认的超时值并且通过receiveuntil方法返回迭代函数。这个设置可以被
settimeout或者settimeouts方法覆盖。

这个<time>参数可以是一个整数,附带一个可选的时间单位,例如s (second), ms (millisecond), m (minute)。默认的时间单位是s,例如, "second".默认的时间是 60s

这个指令首先在v0.5.0rc1版本中被介绍。

lua_socket_buffer_size

语法: lua_socket_buffer_size <size>

默认: lua_socket_buffer_size 4k/8k

上下文: http,server,location

指定通过cosocket读取操作所使用的缓冲区的大小。

这个缓冲区不需要大到在同一个时间把所有的东西都hold主,这是因为cosocket 100%支持非缓存的读和解析。所以即使1 byte 缓冲大小也应该在所有地方正常工作但是表现会很糟。

这个指令首先在v0.5.0rc1版本中被介绍。

lua_socket_pool_size

语法: lua_socket_pool_size <size>

默认: lua_socket_pool_size 30

上下文: http,server,location

为每一个与远程服务器关联的cosocket连接池指定大小限制(根据连接数)。(如:由主机端口对或者unix域socket文件路径来鉴定)

默认每个池30个连接。

当连接池超过可用的大小限制,在池中最近最少使用的(空闲)连接将被关闭来为当前连接腾出地方。

注意这个cosocket连接池是每个nginx工作进程的而不是每个nginx服务器实例,所以这里指定的size大小同样也适用于每个单独的nginx工作进程。

这个指令首先在v0.5.0rc1版本中被介绍。

lua_socket_keepalive_timeout

语法: lua_socket_keepalive_timeout <time>

默认: lua_socket_keepalive_timeout 60s

上下文 http,server,location

改指令控制在cosocket内置连接池中连接的最大空闲时间。当达到这个超时时间,空闲连接将被关闭并且从池中移除。这个何止可以被cosocket对象 setkeepalive方法覆盖。

这个<time>参数可以是个整数,携带一个可选的时间单位,例如s (second), ms (millisecond), m (minute)。默认的时间单位是s,例如, "second".默认的时间是 60s

这个指令首先在v0.5.0rc1版本中被介绍。

log_socket_log_errors

语法: lua_socket_log_errors on|off

默认: lua_socket_log_errors on

上下文: http,server,location

这个指令可以被用来开关错误日志当TCP或者UDP cosockets发生错误时。如果你已经做了适当的错误处理并且在你的Lua代码里面记录了,那么推荐将这个指令off来放着数据flush到你的nginx错误log文件里(这通常是非常昂贵的)。

这个指令首先在v0.5.13版本中被介绍。

lua_ssl_ciphers

语法: lua_ssl_ciphers <ciphers>

默认: lua_ssl_ciphers DEFAULT

上下文: http,server,location

tcpsock:sslhandshake方法中指定为请求启用SSL/TLS服务器的密码。这个指定的密码是OpenSSL库中可以理解的格式。

使用“openssl ciphers”命令可以看到完成的列表。

这个指令首先在v0.9.11版本中被介绍。

lua_ssl_crl

语法: lua_ssl_crl <file>

默认: no

上下文: http,server,location

指定一个使用PEM格式的撤销的证书(CRL)文件用来在tcpsock:sslhandshake方法中验证SSL/TLS服务器的证书。

这个指令首先在v0.9.11版本中被介绍。

lua_ssl_protocols

语法: lua_ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2]

默认: lua_ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2

上下文: http,server,location

tcpsock:sslhandshake方法中为SSL/TLS服务器的请求开启指定的协议。

这个指令首先在v0.9.11版本中被介绍。

lua_ssl_trusted_certificate

语法: lua_ssl_trusted_certificate <file>

默认: no

上下文: http,server,location

tcpsock:sslhandshake方法中指定一个文件路径含有PEM格式的受信任的CA证书用来验证SSL/TLS服务器。

这个指令首先在v0.9.11版本中被介绍。

lua_ssl_verfy_depth

语法: lua_ssl_verfy_depth <number>

默认: lua_ssl_verfy_depth 1

上下文: http,server,location

设置验证服务器证书链中的深度。

这个指令首先在v0.9.11版本中被介绍。

另外请参见lua_ssl_trusted_certificate.

lua_http10_buffering

语法: lua_http10_buffering on|off

默认: lua_http10_buffering on

上下文: http,server,location,location-if

启用或者禁用HTTP 1.0(或更老版本)请求的自动响应缓存。这种缓冲机制主要用于HTTP 1.0 keep-alive,这个依赖于响应头中的适当的Content-Length

如果在发送headers之前Lua代码显示的设置一个Content-Length响应头(显示的通过ngx.send_headers 或者隐式的通过ngx.say或者ngx.print调用),那么即使这个指令设置为 on 那么HTTP 1.0响应缓存也被会禁用。

为了以流媒体的方式输出一个很大的响应数据(例如通过ngx.flush调用),这个指令必须关闭以减少内存的使用。

这个指令默认情况下是设置为 on

这个指令首先在v0.5.0rc19版本中被介绍。

rewrite_by_lua_no_postpone

语法 rewrite_by_lua_no_postpone on|off

默认 rewrite_by_lua_no_postpone off

上下文: http

控制是否禁用推迟rewrite_by_lua* 指令在rewirte请求处理阶段的末尾执行。在默认情况下,这个指令是设置为off的并且Lua代码是在rewrite阶段的末尾推迟执行的。

这个指令首先在v0.5.0rc19版本中被介绍。

access_by_lua_no_postpone

语法: access_by_lua_no_postpone on|off

默认: access_by_lua_no_postpone off

上下文: http

控制是否禁用推迟access_by_lua*指令在access请求处理阶段的末尾执行。在默认情况下,这个指令是设置为off的并且Lua代码是在access阶段的末尾推迟执行的。

这个指令首先在v0.9.20版本中被介绍。

lua_transform_underscores_in_response_headers

语法: lua_transform_underscores_in_response_headers on|off

默认: lua_transform_underscores_in_response_headers on

上下文: http,server,location,location-if

控制是否转换在ngx.header.HEADER API中指定的响应头名称下划线(_)为横线(-)。

这个指令首先在v0.5.0rc32版本中被介绍。

lua_check_client_abort

语法: lua_check_client_abort on|off

默认: lua_check_client_abort off

上下文: http,server,location,location-if

这个指令控制是否检查过早的客户端连接终止。

当这个指令开启,ngx_lua模块将会监控在downstream连接的过早的连接关闭事件并且当发生这种事件时,它会调用用户的Lua回调函数(通过ngx.on_abort注册的),或者当这里没有注册用户回调方法时,会仅仅停止并清除掉在当前请求的请求处理器中的所有的Lua "light threads"。

根据当前的实现,然而,如果在Lua代码通过ngx.req.socket结束读取请求body数据之前,客户端关闭了连接,那么ngx_lua将既不会关闭所有运行的"light threads"也不会调用用户的回调(如果ngx.on_abort被调用了)。而是,在ngx.req.socket的读取操作会仅仅返回"client aborted"的错误信息作为第二个返回值(第一个返回值肯定是nil)。

当TCP keepalive被禁用,它是依靠客户端方优雅的关闭socket(通过发送一个FIN包或者类似的)。对于(soft)实时web程序,强烈推荐在你系统的TCP栈实现配置TCP keepalive支持来即时检查“半开”TCP连接。

例如,在Linux上,你可以在你的nginx.conf文件中配置标准的listen指令,如下所示:

    listen 80 so_keepalive=2s:2s:8

在FreeBSD上,你只能为TCP keepalive调整系统级的配置,例如:


      # sysctl net.inet.tcp.keepintvl=2000
      # sysctl net.inet.tcp.keepidle=2000

这个指令首先在v0.7.4版本中被介绍。

参阅ngx.on_abort

lua_max_pending_timers

语法: lua_max_pending_timers <count>

默认: lua_max_pending_timers 1024

上下文: http

控制允许使用的最大数量的等待计时器。

等待计时器是那些还没有过期的计时器。

当超过这个限制,ngx.timer.at调用会立刻返回nil和错误字符串"too many pending timers"。

这个指令首先在v0.8.0版本中被介绍。

lua_max_running_timers

语法: lua_max_running_timers <count>

默认: lua_max_running_timers 256

上下文: http

控制允许使用的最大数量的运行计数器。

运行计时器是那些用户回调函数仍然运行的。

当超过这个限制,Nginx会停止运行新定时器到期的回调并且记录一个错误信息 “N lua_max_running_timers are not enough” ,"N"是这个指令的当前值。

这个指令首先在v0.8.0版本中被介绍。

推荐阅读更多精彩内容