当前位置: 首页 > news >正文

OpenResty使用Lua笔记

文章目录

  • 一、基础
    • 1、常用
    • 2、使用局部变量
    • 3、模块化
  • 二、性能提升
    • 1、使用fft调用shell
    • 2、不要在循环中拼接字符串
    • 3、不要频繁修改table
    • 4、不要在table中用nil
    • 5、做好异常处理
    • 6、ngx.var 的性能提升
  • 三、拓展
    • 1、加载字符串为动态方法

一、基础

1、常用

OpenResty 中文官网:https://openresty.org/cn/

包管理:https://opm.openresty.org/

(1)Lua 的下标从 1 开始

(2)使用 … 来拼接字符串

2、使用局部变量

在 Lua 中,变量默认是全局的,会被放到名为 _G 的 table 中。不加 local 的变量会在全局表中查找,这是昂贵的操作。如果再加上一些变量名的拼写错误,就会造成难以定位的 bug。

建议总是使用 local 来声明变量,即使在 require module 的时候也是一样:

-- Recommended 
local xxx = require('xxx')-- Avoid
require('xxx')local ngx_re = require "ngx.re"
local ngx = require "ngx"
--No
local function foo()local ok, err = ngx.timer.at(delay, handler)
end--Yes
local timer_at = ngx.timer.atlocal function foo()local ok, err = timer_at(delay, handler)
end
-- 为了风格的统一,require 和 ngx 也需要 local 化:
--No
local core = require("apisix.core")
local timer_at = ngx.timer.atlocal function foo()local ok, err = timer_at(delay, handler)
end--Yes
local ngx = ngx
local require = require
local core = require("apisix.core")
local timer_at = ngx.timer.atlocal function foo()local ok, err = timer_at(delay, handler)
end

3、模块化

-- hello.lua定义一个对象,并返回
local _M = {}_M.color = {red = 1,blue = 2,green = 3}return _M
location / {content_by_lua_block {-- 引入hello,并用一个变量接收,这个变量就可以调用对象的方法和变量了local hello = require "hello"ngx.say(hello.color.green)}
}

二、性能提升

1、使用fft调用shell

-- 不要用阻塞的lua语法
os.execute("kill -HUP " .. pid) 
os.execute(" cp test.exe /tmp ")
os.execute(" openssl genrsa -des3 -out private.pem 2048 ")-- 使用lua-resty-signal 这个 OpenResty 自带的库
local resty_signal = require "resty.signal"
local pid = 12345
local ok, err = resty_signal.kill(pid, "KILL")-- 使用基于 ngx.pipe 的 lua-resty-shell 库
$ resty -e 'local shell = require "resty.shell"
local ok, stdout, stderr, reason, status =shell.run([[echo "hello, world"]])ngx.say(stdout) '

2、不要在循环中拼接字符串

-- 不要在循环中拼接字符串
$ resty -e 'local begin = ngx.now()
local s = ""
-- for 循环,使用 .. 进行字符串拼接
for i = 1, 100000 dos = s .. "a"
end
ngx.update_time()
print(ngx.now() - begin)
'-- 用table进行优化
$ resty -e 'local begin = ngx.now()
local t = {}
-- for 循环,使用数组来保存字符串,自己维护数组的长度
for i = 1, 100000 dot[i] = "a"
end
local s =  table.concat(t, "")
ngx.update_time()
print(ngx.now() - begin)
'-- 或者自己定义数组索引
$ resty -e 'local begin = ngx.now()
local t = {}
local index = 1
for i = 1, 100000 dot[index] = "a"index = index + 1
end
local response = table.concat(t, "")
ngx.say(response)
'

3、不要频繁修改table

-- 预先创建table,然后增删改,性能是很差的,原因在于每次新增和删除数组元素的时候,都会涉及到数组的空间分配、resize 和 rehash。
local t = {}
local color = {first = "red", "blue", third = "green", "yellow"}-- 如果涉及对table的频繁修改,考虑初始化table的容量,这样就不需要使用table.insert等方法,直接通过下标设置值即可
-- table.new(narray, nhash) 两个参数分别代表table里是array还是hash的 
-- table.new(10, 0) 或者 table.new(0, 10) 这样的,后者是 hash 性质的 table
local new_tab = require "table.new"
local t = new_tab(100, 0)
for i = 1, 100 dot[i] = i
end-- 可以考虑对table进行重用
-- 用 table.new(narray, nhash) 生了一个长度为 100 的数组,clear 后,长度还是 100。
-- table.clear方法就是将table所有的内容设为了nil
local ok, clear_tab = pcall(require, "table.clear")if not ok thenclear_tab = function (tab)for k, _ in pairs(tab) dotab[k] = nilendendend

4、不要在table中用nil

-- 一定不要在数组中使用 nil:
--No
local t = {1, 2, nil, 3}-- 如果一定要使用空值,请用 ngx.null 来表示:
--Yes
local t = {1, 2, ngx.null, 3}

5、做好异常处理

对于有错误信息返回的函数,我们必须对错误信息进行判断和处理:

--No
local sock = ngx.socket.tcp()
local ok = sock:connect("www.baidu.com", 80)
ngx.say("successfully connected to baidu!")--Yes
local sock = ngx.socket.tcp()
localok, err = sock:connect("www.google.com", 80)
if not ok thenngx.say("failed to connect to google: ", err)return
end
ngx.say("successfully connected to google!")

而如果是自己编写的函数,错误信息要作为第二个参数,用字符串的格式返回:

--No
local function foo()local ok, err = func()if not ok thenreturn falseendreturn true
end--No
local function foo()local ok, err = func()if not ok thenreturn false, {msg = err}endreturn true
end--Yes
local function foo()local ok, err = func()if not ok thenreturn false, "failed to call func(): " .. errendreturn true
end

6、ngx.var 的性能提升

ngx.var 是一个性能损耗比较大的操作,在实际使用时,我们需要用 ngx.ctx 来做一层缓存

-- lua-var-nginx-module模块,性能比起ngx.var 提升了 5 倍。它采用的是 FFI 的方式,所以,你需要在编译 OpenResty 的时候,先加上编译选项
./configure --prefix=/opt/openresty \--add-module=/path/to/lua-var-nginx-module-- 然后,使用 luarocks 的方式来安装 lua 库:
luarocks install lua-resty-ngxvar-- 这里调用的方法也很简单,只需要一行 fetch 函数的调用就可以了。它的效果完全等价于原有的 ngx.var.remote_addr,来获取到终端的 IP 地址:
content_by_lua_block {local var = require("resty.ngxvar")ngx.say(var.fetch("remote_addr"))
}

三、拓展

1、加载字符串为动态方法

可以把 s 这个包含函数的字符串,改成可以由用户指定的形式,并加上执行它的条件,这样其实就是 FaaS 的原型了。

resty -e 'local s = [[return function()ngx.say("hello world")
end
]]
local  func1 = loadstring(s)
local ret, func = pcall(func1)
func()'

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 题解|2023暑期杭电多校02
  • 关键路径-matlab
  • 【BUG】已解决:IndexError: list index out of range
  • 今日科技圈最新时事新闻(2024年7月12日
  • C++——类和对象(下)
  • k8s入门:从安装到实际应用
  • 【Linux杂货铺】期末总结篇3:用户账户管理命令 | 组账户管理命令
  • redis-缓存三剑客
  • FreeRTOS的中断管理、临界资源保护、任务调度
  • 2024CAIP省赛
  • 【吊打面试官系列-ZooKeeper面试题】简述 Zookeeper 文件系统?
  • 安全运营概述
  • 【学习】美国虚拟信用卡申请流程
  • 【解决】多个网卡导致nacos注册的服务ip有误问题
  • Java-排序~查找算法
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • ES6简单总结(搭配简单的讲解和小案例)
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • isset在php5.6-和php7.0+的一些差异
  • Kibana配置logstash,报表一体化
  • laravel 用artisan创建自己的模板
  • Mysql优化
  • PAT A1050
  • Sass 快速入门教程
  • uni-app项目数字滚动
  • vue.js框架原理浅析
  • 从tcpdump抓包看TCP/IP协议
  • 回顾 Swift 多平台移植进度 #2
  • 目录与文件属性:编写ls
  • 使用Gradle第一次构建Java程序
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • 移动端高清、多屏适配方案
  • # 移动硬盘误操作制作为启动盘数据恢复问题
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #NOIP 2014# day.2 T2 寻找道路
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • (03)光刻——半导体电路的绘制
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (windows2012共享文件夹和防火墙设置
  • (搬运以学习)flask 上下文的实现
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (每日一问)基础知识:堆与栈的区别
  • (七)Appdesigner-初步入门及常用组件的使用方法说明
  • (万字长文)Spring的核心知识尽揽其中
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • (转)scrum常见工具列表
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .NET DataGridView数据绑定说明
  • .Net IOC框架入门之一 Unity
  • .NET/C# 使用反射注册事件
  • .NET开源、简单、实用的数据库文档生成工具