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;;";

openresty开发系列32--openresty执行流程之1初始化阶段的更多相关文章

  1. openresty开发系列35--openresty执行流程之5内容content阶段

    openresty开发系列35--openresty执行流程之5内容content阶段 content 阶段 ---init阶段---重写赋值---重写rewrite---access content ...

  2. openresty开发系列33--openresty执行流程之2重写赋值阶段

    openresty开发系列33--openresty执行流程之2重写赋值阶段 一)重写赋值阶段 1)set_by_lua 语法:set_by_lua $res <lua-script-str&g ...

  3. openresty开发系列36--openresty执行流程之6日志模块处理阶段

    openresty开发系列36--openresty执行流程之6日志模块处理阶段 一)header_filter_by_lua 语法:header_filter_by_lua <lua-scri ...

  4. openresty开发系列34--openresty执行流程之4访问阶段

    openresty开发系列34--openresty执行流程之4访问阶段 访问阶段 用途:访问权限限制 返回403 nginx:allow 允许,deny 禁止 allow ip:deny ip: 涉 ...

  5. openresty开发系列33--openresty执行流程之3重写rewrite和重定向

    openresty开发系列33--openresty执行流程之3重写rewrite和重定向 重写rewrite阶段 1)重定向2)内部,伪静态 先介绍一下if,rewrite指令 一)if指令语法:i ...

  6. openresty开发系列31--openresty执行流程

    openresty开发系列31--openresty执行流程 我们先看个例子 location /test {    set $a 32;    echo $a;    set $a 56;    e ...

  7. openresty开发系列28--openresty中操作mysql

    openresty开发系列28--openresty中操作mysql Mysql客户端   应用中最常使用的就是数据库了,尤其mysql数据库,那openresty lua如何操作mysql呢?   ...

  8. openresty开发系列24--openresty中lua的引入及使用

    openresty开发系列24--openresty中lua的引入及使用 openresty 引入 lua 一)openresty中nginx引入lua方式 1)xxx_by_lua   ---> ...

  9. openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息

    openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息 为了实现业务系统针对不同地区IP访问,展示包含不同地区信息的业务交互界面.很多情况下系统需要根据用户访问的IP信息 ...

随机推荐

  1. 函数式接口(Functional Interface)

    原文链接:https://www.cnblogs.com/runningTurtle/p/7092632.html 阅读目录 什么是函数式接口(Functional Interface) 函数式接口用 ...

  2. 总结一下NDK crash排查步骤

    总结一下NDK crash排查步骤: 先在PC上跑通算法 用Visual Studio写算法的testbed,确保算法能跑通 抓log adb logcat -c; adb logcat > 1 ...

  3. Python包模块化调用方式详解

    Python包模块化调用方式详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一般来说,编程语言中,库.包.模块是同一种概念,是代码组织方式. Python中只有一种模块对象类型 ...

  4. poi读写doc和docx

    https://www.cnblogs.com/always-online/p/4800131.html POI是 Apache 旗下一款读写计算机中的 word 以及 excel 文件的工具. po ...

  5. mysql-5.7.18 免安装版安装配置(Windows)

    mysql-5.7.18 免安装版安装配置(Windows) 一.在Mysql官网下载Mysql-5.7.18的ZIP文件 下载链接为:https://dev.mysql.com/downloads/ ...

  6. gcc分步骤编译的记录

  7. 讨论SQL语句中主副表之间的关系

    在公司这么多些时间,自己在写SQL语句这方面的功夫实在是太差劲了,有时候自己写出来的SQL语句自己都不知道能不能使用,只是自己写出来的SQL语句是不报错的,但是,这对于真正意义上的SQL语句还差的真的 ...

  8. LeetCode 1219. Path with Maximum Gold

    原题链接在这里:https://leetcode.com/problems/path-with-maximum-gold/ 题目: In a gold mine grid of size m * n, ...

  9. python接口自动化—封装获取常量的类

    背景: 一.执行case的过程: 首先需要,我们能够通过excel获取单元格的内容.获取内容时,首先需要知道获取的数据是哪一行的,这行数据中需要拿那些参数,比如case 名称.请求url.请求方式.h ...

  10. 检验多个xsd的xml是否合法

    Java - 使用 XSD 校验 XML https://www.cnblogs.com/huey/p/4600817.html 这种方法不支持多个xsd文件,会报错 可以使用XMLBeans Too ...