openresty開發系列32--openresty執行流程之初始化階段
一)初始化階段
1)init_by_lua init_by_lua_block init_by_lua_file
語法:init_by_lua <lua-script-str>
語境:http
階段:loading-config
當nginx master進程在加載nginx配置文件時運行指定的lua腳本,
一般用來註冊lua的全局變量或在服務器啓動時預加載lua模塊:
[root@node5 conf]# cat nginx.conf
worker_processes 4;
error_log logs/error.log;
error_log logs/debug.log debug;
events {
worker_connections 1024;
}
http {
include mime.types;
#default_type application/octet-stream;
default_type text/html;
charset utf-8;
sendfile on;
# 關閉lua緩存,不須要每次重啓才生效,會犧牲必定性能
lua_code_cache on;
lua_shared_dict shared_data 10m;
keepalive_timeout 65;
init_by_lua_block {
cjson = require "cjson"
}
server {
listen 80;
server_name www.server1.com;
resolver 8.8.8.8;
lua_ssl_verify_depth 2;
lua_ssl_trusted_certificate "/etc/ssl/certs/ca-bundle.crt";
location = /api {
content_by_lua_block {
ngx.say(cjson.encode({dog = 5, cat = 6}))
}
}
location / {
root html;
index index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
從這段配置代碼,咱們能夠看出,其實這個指令就是初始化一些lua的全局變量,以便後續的代碼使用。
初始化lua_shared_dict共享數據:
lua_shared_dict dogs 1m;
init_by_lua_block {
local dogs = ngx.shared.dogs;
dogs:set("Tom", 50)
dogs:set("flag",1)
}
server {
location = /api {
content_by_lua_block {
local dogs = ngx.shared.dogs;
ngx.say(dogs:get("Tom"))
}
}
}
lua_shared_dict的內容不會在nginx reload時被清除。因此若是你不想在init_by_lua中重複初始化共享數據,
那麼你須要在你的共享內存中設置一個標誌位並在init_by_lua中進行檢查。
由於這個階段的lua代碼是在nginx forks出任何worker進程以前運行,
數據和代碼的加載將享受由操做系統提供的copy-on-write的特性,從而節約了大量的內存。
不要在這個階段初始化你的私有lua全局變量,由於使用lua全局變量會照成性能損失,
而且可能致使全局命名空間被污染。
這個階段只支持一些小的LUA Nginx API設置:ngx.log和print、ngx.shared.DICT;
2)init_worker_by_lua
語法:init_worker_by_lua <lua-script-str>
語境:http
階段:starting-worker
在每一個nginx worker進程啓動時調用指定的lua代碼。
用於啓動一些定時任務,好比心跳檢查,定時拉取服務器配置等等;此處的任務是跟Worker進程數量有關係的,
好比有2個Worker進程那麼就會啓動兩個徹底同樣的定時任務。
a、nginx.conf配置文件中的http部分添加以下代碼
init_worker_by_lua_file /usr/local/lua/init_worker.lua;
------------------------------------
b、/usr/local/lua/init_worker.lua;
local count = 0
local delayInSeconds = 3
local heartbeatCheck = nil
heartbeatCheck = function(args)
count = count + 1
ngx.log(ngx.ERR, "do check ", count)
local ok, err = ngx.timer.at(delayInSeconds, heartbeatCheck)
if not ok then
ngx.log(ngx.ERR, "failed to startup heartbeart worker...", err)
end
end
heartbeatCheck()
# 觀察日誌:
# tail logs/debug.log
...
2019/08/23 19:09:18 [error] 77617#0: *431 [lua] init_worker.lua:7: heartbeatcheck(): do check 1, context: init_worker_by_lua*
2019/08/23 19:09:18 [error] 77618#0: *432 [lua] init_worker.lua:7: heartbeatcheck(): do check 1, context: init_worker_by_lua*
2019/08/23 19:09:18 [error] 77619#0: *433 [lua] init_worker.lua:7: heartbeatcheck(): do check 1, context: init_worker_by_lua*
2019/08/23 19:09:18 [error] 77620#0: *434 [lua] init_worker.lua:7: heartbeatcheck(): do check 1, context: init_worker_by_lua*
2019/08/23 19:09:21 [error] 77620#0: *436 [lua] init_worker.lua:7: do check 2, context: ngx.timer
2019/08/23 19:09:21 [error] 77617#0: *438 [lua] init_worker.lua:7: do check 2, context: ngx.timer
2019/08/23 19:09:21 [error] 77618#0: *437 [lua] init_worker.lua:7: do check 2, context: ngx.timer
2019/08/23 19:09:21 [error] 77619#0: *435 [lua] init_worker.lua:7: do check 2, context: ngx.timer
2019/08/23 19:09:24 [error] 77619#0: *439 [lua] init_worker.lua:7: do check 3, context: ngx.timer
2019/08/23 19:09:24 [error] 77617#0: *442 [lua] init_worker.lua:7: do check 3, context: ngx.timer
2019/08/23 19:09:24 [error] 77620#0: *441 [lua] init_worker.lua:7: do check 3, context: ngx.timer
...
ngx.timer.at:延時調用相應的回調方法;ngx.timer.at(秒單位延時,回調函數,回調函數的參數列表);
能夠將延時設置爲0即獲得一個當即執行的任務,任務不會在當前請求中執行不會阻塞當前請求,
而是在一個輕量級線程中執行。
另外根據實際狀況設置以下指令
lua_max_pending_timers 1024; #最大等待任務數
lua_max_running_timers 256; #最大同時運行任務數
3)lua_package_path
語法:lua_package_path <lua-style-path-str>
默認:由lua的環境變量決定
適用上下文:http
設置lua代碼的尋找目錄。
例如:lua_package_path "/opt/nginx/conf/www/?.lua;;";html