Nginx version
The OpenResty version is much behind the standard Nginx version, so the functions supported by the newer Nginx may not be supported by OpenResty .
Nginx process model
After starting Nginx, we use ps to view related processes:
$ ps -ef --forest | grep nginx
root 32475 1 0 13:36 ? 00:00:00 nginx: master process /usr/sbin/nginx
-c /etc/nginx/nginx.conf
nginx 32476 32475 0 13:36 ? 00:00:00 _ nginx: worker process
nginx 32477 32475 0 13:36 ? 00:00:00 _ nginx: worker process
nginx 32479 32475 0 13:36 ? 00:00:00 _ nginx: worker process
nginx 32480 32475 0 13:36 ? 00:00:00 _ nginx: worker process
nginx 32481 32475 0 13:36 ? 00:00:00 _ nginx: cache manager process
nginx 32482 32475 0 13:36 ? 00:00:00 _ nginx: cache loader process
Nginx has one and only one Master process to perform some high-privilege operations, such as reading configuration and binding ports, etc., but it is not responsible for processing requests, and the number of Worker processes is generally consistent with the number of logical cores of the host CPU. When Nginx starts or reloads, the Master process will fork out a set of Worker processes, which are independent of each other, a bit like the tabs of the Chrome browser, and a crash of one will not affect the others.
Formally such an architecture endows Nginx with the capability of binary hot upgrade.
Hot upgrade starts a new Master process and gradually shuts down Worker processes by sending USR2 and WINCH semaphores to the old Master process. At this time, if you need to roll back, you can still send the HUP semaphore to the old Master. If you are sure that you do not need to roll back, you can send the KILL semaphore to the old Master to exit.
Nginx architecture official document: https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/
Nginx execution stage
Nginx has 11 execution stages, which can be seen from the source code https://github.com/nginx/nginx/blob/master/src/http/ngx_http_core_module.h :
typedef enum {
NGX_HTTP_POST_READ_PHASE = 0,
NGX_HTTP_SERVER_REWRITE_PHASE,
NGX_HTTP_FIND_CONFIG_PHASE,
NGX_HTTP_REWRITE_PHASE,
NGX_HTTP_POST_REWRITE_PHASE,
NGX_HTTP_PREACCESS_PHASE,
NGX_HTTP_ACCESS_PHASE,
NGX_HTTP_POST_ACCESS_PHASE,
NGX_HTTP_PRECONTENT_PHASE,
NGX_HTTP_CONTENT_PHASE,
NGX_HTTP_LOG_PHASE
} ngx_http_phases;
The relationship between the command in OpenResty *_by_lua
and the four phases of Nginx is as follows:
This is also a picture that needs to be compared at all times during OpenResty development.
-
init_by_lua
Executed when the Nginx Master process is created, that is, it will only be executed once in the entire Nginx life cycleinit_by_lua
Lua modules and common read-only data are usually preloaded during the stage, which can take advantage of the COW (copy on write) feature of the operating system to save some memory .# this runs before forking out nginx worker processes: init_by_lua_block { require "cjson" } server { location = /api { content_by_lua_block { -- the following require() will just return -- the alrady loaded module from package.loaded: ngx.say(require "cjson".encode{dog = 5, cat = 6}) } } }
-
init_worker_by_lua
Executed when each Nginx Worker process is created, this anchor is often used to create timers (via ngx.timer.at Lua API).init_worker_by_lua ' local delay = 3 -- in seconds local new_timer = ngx.timer.at local log = ngx.log local ERR = ngx.ERR local check check = function(premature) if not premature then -- do the health check or other routine work local ok, err = new_timer(delay, check) if not ok then log(ERR, "failed to create timer: ", err) return end end end local hdl, err = new_timer(delay, check) if not hdl then log(ERR, "failed to create timer: ", err) return end ';
-
set_by_lua
The operation of the business code can usually
set_by_lua
be completed at each stage from the beginning, and it is recommended to split the business process according to different functions.set_by_lua
Directives are recommended for setting variables. -
rewrite_by_lua
Forward, redirect
-
access_by_lua
access, permissions
-
content_by_lua
Generate return content
-
header_filter_by_lua
Response header filtering
-
body_filter_by_lua
Response body filtering
-
log_by_lua
logging
The OpenResty lua-nginx-module document https://github.com/openresty/lua-nginx-module/blob/master/README.markdown has a very detailed description of the usage of each directive.
In particular, pay attention to the Nginx context supported by each anchor , which is the scope of the directives in the Nginx configuration file. Directives written in unsupported contexts will cause OpenResty to fail to start.
OpenResty Development Principles
- Configure nginx.conf as little as possible
- Avoid using the cooperation of multiple instructions such as if, set, and rewrite
- Try to use Lua script to control the behavior of Nginx