
- 类 型
- 脚本语言
- 研究时间
- 1993年
- 外文名
- lua
- 研究地点
- 巴西里约热内卢天主教大学
-
2022-05-15 09:20:35
前言
lua是一夸小巧,灵活且高效的脚本语言,用标准C语言编写并以源代码形式开发,在很多业务场景下配合适当的设计,可以带来意想不到的效果;
举个常见的例子,现在几乎很多公司都会用到nginx作为代理服务器,假如现在有这么个需求,需要做黑名单过滤,或者在网关这一层做流控,这该怎么做呢?
实现思路
- 直接在nginx做配置黑名单,通过编写逻辑块实现;
- 在服务端(Java)中编写过滤器,在过滤器中统一拦截;
- 在服务端(Java)中编写拦截器,在拦截器中统一拦截;
这里列举了3种实现的思路,至于实现方案,可能还有更多,但是我们想想,在nginx中编写逻辑块貌似不是很多人擅长的;在代码层面做不是不可以,而是这样一来,在涉及到高并发的业务高峰期,这必然会对后端服务造成较大的压力,那么还有没有其他更好的处理办法呢?
这就是要说的lua,即nginx作为网关仍然作为代理服务器,由于nginx可以集成lua,于是使用lua进行配合,来完成上面的业务实现的设计;
ngx_lua模块概念
- ngx_lua模块由淘宝技术团队开发,通过将lua解释器集成进Nginx;
- 可采用lua脚本实现业务逻辑,由于lua的紧凑、快速以及内建协程,所以在保证高并发服务能力的同时极大地降低了业务逻辑实现成本; </
更多相关内容 -
最新天龙LUA
2018-10-25 23:39:29最新天龙LUA,可以使用。喜欢的人拿去. -
luac逆向工具
2018-08-22 13:07:12luac编译之后的逆向,亲测可用 详细亲看:https://blog.csdn.net/liujiayu2/article/details/81940701 -
lua反编译工具
2018-05-10 16:24:46lua反编译工具包括lua 5.1 与 lua 5.2 包括lua.exe luac.exe luadec.exe 等 可以用此工具加密lua为luac 也可以解密luac为lua -
luac解密工具
2018-05-10 16:05:001代码中此处可能需要修改vcvarsall.bat文件位置 call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64 ...2只有用luac加密的资源才能解密 3需要vs环境自带java环境 -
IntelliJ-IDEA-Lua-IDE-WoW-API:与IntelliJ IDEA的Lua IDE插件一起使用的WoW Lua API
2021-02-03 18:03:10IntelliJ-IDEA-Lua-IDE-WoW-API:与IntelliJ IDEA的Lua IDE插件一起使用的WoW Lua API -
Lua-5.3.4 Win64安装包
2018-03-03 23:32:21安装教程:http://blog.csdn.net/chinarcsdn/article/details/78667262 -
LuaStudio破解版
2017-04-28 09:50:56轻量化lua编辑工具 -
Unity 万能游戏框架 热更(lua)
2018-12-19 15:03:12Unity3d,游戏框架,Lua热更,状态机,UI框架.可以用于初始项目,直接在上面堆逻辑就好。 -
基于lua语言的 skynet实战教程
2018-09-21 19:49:04lua 是skynet框架的业务逻辑的书写层。skynet一半以上的代码是由lua写成。该套餐课程主要包括Lua从入门到精通以及Linux百万级高并发框架Skynet教程。 -
罗技脚本编程G-series Lua API 参考文档(中文版)
2017-12-06 15:12:57罗技脚本编程G-series Lua API 参考文档(中文版),主要是用在罗技G系列的鼠标和键盘的宏编程,实用性比较高,大家互相交流学习! -
lua http 例子代码
2015-06-08 15:58:47自己写的一个简单的用lua 请求http的例子,在scite环境下可以运行(绝对可以运行)包括所需的lua socket库(socket.lua http.lua.core.dll 等),放心下载,不用谢我,我的名字叫:雷锋。 -
lua-5.3.4_Win64_bin.zip
2017-10-20 15:32:11lua-5.3.4_Win64_bin.zip Windows64位,编译好的lua,直接用 -
c#调用脚本语言Lua——简单Demo
2015-02-08 10:50:16c#调用脚本语言Lua——简单Demo 配置: 1. 下载c#下的Lua支持类库。下载地址:http://files.luaforge.net/releases/luainterface/luainterface/2.0.3 将(lua51.dll\LuaInterface.dll)引用自己的项目中。 2. 修改... -
Lua 5.3 中文手册
2015-03-05 11:01:26lua5.3中文手册 作者 Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes 译者 云风 方便手机和pad看 原址 : http://cloudwu.github.io/lua53doc/manual.html -
Openresty集成prometheus_lua和skywalking_lua笔记
2022-04-25 13:40:24skywalking-nginx-lua nginx-lua-prometheus Openresty部署-Docker方式 创建目录 mkdir -pv /data/openresty/lua_lib mkdir -pv /data/openresty/nginx/{logs/vhosts/upstream} 下载对应lua文件到/data/openresty/...Github文档
Openresty部署-Docker方式
创建目录
mkdir -pv /data/openresty/lua_lib mkdir -pv /data/openresty/nginx/{logs/vhosts/upstream}
下载对应lua文件到/data/openresty/lua_lib目录, 结构如下
tree . ├── nginx-lua-prometheus │ ├── prometheus_keys.lua │ ├── prometheus.lua │ ├── prometheus_resty_counter.lua │ └── prometheus_test.lua ├── nginx-lua-prometheus-0.20220127.tar.gz ├── skywalking-nginx-lua │ ├── resty │ │ ├── http_headers.lua │ │ ├── http.lua │ │ └── jit-uuid.lua │ └── skywalking │ ├── client.lua │ ├── constants.lua │ ├── correlation_context.lua │ ├── correlation_context_test.lua │ ├── dependencies │ │ └── base64.lua │ ├── management.lua │ ├── segment.lua │ ├── segment_ref.lua │ ├── segment_ref_test.lua │ ├── span_layer.lua │ ├── span.lua │ ├── span_test.lua │ ├── tracer.lua │ ├── tracing_context.lua │ ├── tracing_context_test.lua │ ├── util.lua │ └── util_test.lua └── skywalking-nginx-lua-0.6.0.tar.gz
编辑nginx配置文件
nginx.conf
cat > /data/openresty/nginx/nginx.conf << 'EOF' user nobody; worker_processes auto; # Enables the use of JIT for regular expressions to speed-up their processing. pcre_jit on; error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 4096; } http { include mime.types; default_type application/octet-stream; lua_package_path "/usr/local/openresty/lualib/skywalking-nginx-lua/?.lua;/usr/local/openresty/lualib/nginx-lua-prometheus/?.lua;;"; lua_shared_dict tracing_buffer 100M; lua_shared_dict prometheus_metrics 100M; init_worker_by_lua_block { local metadata_buffer = ngx.shared.tracing_buffer metadata_buffer:set('serviceName', 'Openresty-test') metadata_buffer:set('serviceInstanceName', 'ccms-credit-front01-test') metadata_buffer:set('includeHostInEntrySpan', false) require("skywalking.util").set_randomseed() require("skywalking.client"):startBackendTimer("http://3.1.101.39:12800") skywalking_tracer = require("skywalking.tracer"); prometheus = require("prometheus").init("prometheus_metrics") metric_requests = prometheus:counter("nginx_http_requests_total", "Number of HTTP requests", {"server_name", "status"}) metric_latency = prometheus:histogram("nginx_http_request_duration_seconds", "HTTP request latency", {"server_name"}) metric_connections = prometheus:gauge("nginx_http_connections", "Number of HTTP connections", {"state"}) metric_requests_uri = prometheus:counter("nginx_http_requests_uri_total", "Number of HTTP requests_uri", {"server_name", "port", "uri", "status", "method"}) } log_by_lua_block { metric_requests:inc(1, {ngx.var.server_name, ngx.var.status}) metric_latency:observe(tonumber(ngx.var.request_time), {ngx.var.server_name}) metric_requests_uri:inc(1, {ngx.var.server_name,ngx.var.server_port,ngx.var.document_uri, ngx.var.status, ngx.var.request_method}) } # Enables or disables the use of underscores in client request header fields. # When the use of underscores is disabled, request header fields whose names contain underscores are marked as invalid and become subject to the ignore_invalid_headers directive. log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; log_format json '{"@timestamp":"$time_iso8601",' '"host":"$hostname",' '"server_ip":"$server_addr",' '"client_ip":"$remote_addr",' '"xff":"$http_x_forwarded_for",' '"domain":"$host",' '"url":"$uri",' '"referer":"$http_referer",' '"args":"$args",' '"upstreamtime":"$upstream_response_time",' '"responsetime":"$request_time",' '"request_method":"$request_method",' '"status":"$status",' '"size":"$body_bytes_sent",' #'"request_body":"$request_body",' '"request_length":"$request_length",' '"protocol":"$server_protocol",' '"upstreamhost":"$upstream_addr",' '"file_dir":"$request_filename",' '"http_user_agent":"$http_user_agent"' '}'; access_log logs/access.log json; # See Move default writable paths to a dedicated directory (#119) # https://github.com/openresty/docker-openresty/issues/119 client_body_temp_path /var/run/openresty/nginx-client-body; proxy_temp_path /var/run/openresty/nginx-proxy; fastcgi_temp_path /var/run/openresty/nginx-fastcgi; uwsgi_temp_path /var/run/openresty/nginx-uwsgi; scgi_temp_path /var/run/openresty/nginx-scgi; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; fastcgi_buffer_size 128k; fastcgi_buffers 8 128k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; client_header_buffer_size 128k; client_body_buffer_size 1m; underscores_in_headers on; include /etc/nginx/conf.d/*.conf; # Don't reveal OpenResty version to clients. # server_tokens off; } include /etc/nginx/upstream/*.conf; EOF
server-skywalking.conf
cat > /data/openresty/nginx/vhosts/credit.conf << 'EOF' server { listen 8901; listen [::]:8901; server_name localhost; location / { rewrite_by_lua_block { skywalking_tracer:start("credit-ROOT") } body_filter_by_lua_block { if ngx.arg[2] then skywalking_tracer:finish() end } log_by_lua_block { skywalking_tracer:prepareForReport() } root /opt/ccms-auto-deploy/front-bank-credit; index index.html index.htm; } location /login/ { rewrite_by_lua_block { skywalking_tracer:start("credit-login") } body_filter_by_lua_block { if ngx.arg[2] then skywalking_tracer:finish() end } log_by_lua_block { skywalking_tracer:prepareForReport() } proxy_pass http://3.1.101.55:11204/; proxy_redirect off; proxy_set_header HOST $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } access_log logs/ccms-credit-access.log json; } EOF
server-prometheus.conf
cat > /data/openresty/nginx/vhosts/prometheus.conf << 'EOF' server { listen 9145; server_name localhost; location /metrics { content_by_lua_block { metric_connections:set(ngx.var.connections_reading, {"reading"}) metric_connections:set(ngx.var.connections_waiting, {"waiting"}) metric_connections:set(ngx.var.connections_writing, {"writing"}) prometheus:collect() } } } EOF
编辑docker-compose容器编排文件
cat > /data/docker-compose/openresty/docker-compose.yml << 'EOF' version: "3" services: openresty: container_name: openresty hostname: openresty-01 image: openresty/openresty:1.19.9.1-centos7 network_mode: host restart: always volumes: - /etc/localtime:/etc/localtime - /data/openresty/lua_lib/nginx-lua-prometheus:/usr/local/openresty/lualib/nginx-lua-prometheus - /data/openresty/lua_lib/skywalking-nginx-lua:/usr/local/openresty/lualib/skywalking-nginx-lua - /data/openresty/nginx/nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf - /data/openresty/nginx/upstream:/etc/nginx/upstream - /data/openresty/nginx/vhosts:/etc/nginx/conf.d - /data/openresty/nginx/logs:/usr/local/openresty/nginx/logs - /opt/ccms-auto-deploy:/opt/ccms-auto-deploy deploy: resources: limits: memory: 4G EOF
启动
cd /data/docker-compose/openresty; docker-compose up -d
-
protoc-gen-lua protobuf
2016-03-03 19:40:34用于lua下的protobuf转化工具,可以很方便的转化为*_pb.lua文件 -
Nginx框架之Lua拓展
2021-11-01 20:35:49Lua脚本简述 nginx三大核心功能,包含静态资源、反向代理、api模块扩展,对于lua脚本的扩展,就是api模块扩展的一部分;并且nginx可以通过lua脚本直接调用redis服务器; Lua脚本简述 lua官网: The Programming ...目录
Lua脚本简述
nginx三大核心功能,包含静态资源、反向代理、api模块扩展,对于lua脚本的扩展,就是api模块扩展的一部分;并且nginx可以通过lua脚本直接调用redis服务器;
Lua脚本简述
lua官网:
Lua是一种功能强大,高效,轻量级,可嵌入的脚本语言,非常容易嵌入到我们应用程序中。Lua是动态类型的,通过使用基于寄存器的虚拟机解释字节码来运行,并具有增量垃圾收集的自动内存管理,使其成为配置,脚本和快速原型设计的理想选择。Lua旨在成为一种轻量级可嵌入脚本语言。它用于各种应用程序,从游戏到Web应用程序和图像处理。Lua 将简单的程序语法与基于关联阵列和可扩展语义的强大数据描述构造相结合。Lua 采用动态键入,通过基于注册的虚拟计算机解释字形码进行运行,并具有自动内存管理,可增加垃圾收集,非常适合配置、脚本和快速原型制作。应用在图像处理这些。
应用场景- 1. 许多工业应用 (例如, Adobe的Photoshop Lightroom)
- 2. 重点是嵌入式系统(例如, 巴西的数字电视的 Ginga中间件)
- 3. Lua目前 是游戏中领先的脚本语言,在游戏 (例如, 魔兽世界和愤怒的小鸟)中使用。
脚本特点
- 快,Lua是解释脚本语言领域中最快的语言。
- Lua是便携式的,在具有标准C编译器的所有平台中构建成开箱即用,可运行各种Unix和Windows, 移动设备(运行Android,iOS,BREW,Symbian,Windows Phone),嵌入式微处理器(如ARM和Rabbit,适用于Lego MindStorms等应用程序),IBM大型机等。
- 可嵌入,Lua是一种快速语言引擎,占用空间小,可以轻松嵌入到应用程序中。
- 简单而强大,提供实现功能的*元机制*,而不是直接在语言中提供大量功能。Lua不是纯粹的面对 象语言,提供了实现类和继承的元机制。
- 小,源包含大约24000行C,包含源代码和文档的Lua 5.3.5的tar包需要297K压缩和1.2M未压缩。 免费,MIT许可证,可以用于任何目的,包括商业目的,完全免费。
比js语言更加广泛。轻量级语言不能做的事情,没有什么大的框架,例如java中spring,这也是它其中的一个缺点把
安装Lua
比较简单
curl -R -O http://www.lua.org/ftp/lua-5.3.5.tar.gz tar zxf lua-5.3.5.tar.gz cd lua-5.3.5 make linux test
依赖不多,直接下载就行。
使用打印 hello world
$ lua Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio > print("hello, world") hello, world
lua小例子
新建mydata.lua文件- 定义一个外界可见的表
- 受保护的自定义数据内容
- function给_M定义一个方法,get_age,用来返回data中的数据
- 向外界暴露表
-- 定义一个外界可见的表 local _M = {} -- 受保护的自定义数据内容 local data = { dog = 5, cat = 3, pig = 1, } -- function给_M定义一个方法,get_age,用来返回data中的数据 function _M.get_age(name) return data[name] end -- end表示方法结束 -- 向外界暴露表 return _M
这个和js中的方法就很像了。
利用lua脚本实现 阶乘
-- defines a factorial function function fact (n) if n == 0 then return 1 else return n * fact(n-1) end end print("enter a number:") a = io.read("*number") -- read a number print(fact(a))
要运行 ,直接 使用 lua 文件就能运行起来
语法比Java要简略,缩进对齐,无大括号分号
Nginx增加Lua执行模块
Nginx嵌入Lua脚本语言
ngx_lua模块
不鼓励自己用Nginx构建这个模块,自己构建需要注意,Nginx,LuaJIT和OpenSSL官方发行版具有各种限制和长期存在的错误,这些错误可能会导致某些模块的功能被禁用,无法正常运行或运行速度变慢。如何编译, 参考 《Nginx嵌入Lua脚本语言操作》 手册。使用ngx_lua模块相当于使用Openresty,建议用官方版本OpenResty,它做了大量优化、集成了常用的第三方插件。OpenRestyOpenResty内部集成了大量精良的 Lua 库、第三方模块以及 大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。OpenResty是一款基于NGINX 和 LuaJIT 的Web 平台。OpenResty的安装参考《OpenResty安装操作》,比构建ngx_lua模块简单很多.Nginx嵌入Lua脚本语言
安装编译Nginx
- 安装依赖项
yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel # lua_jit wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz tar -xvf LuaJIT-2.0.5.tar.gz cd LuaJIT-2.0.5 make install
下载安装nginx和依赖项
cd ~ # nginx wget http://nginx.org/download/nginx-1.14.2.tar.gz tar -xvf nginx-1.14.2.tar.gz # ndk wget https://github.com/simplresty/ngx_devel_kit/archive/v0.3.0.zip unzip v0.3.0.zip # ngx_lua 模块 wget https://github.com/openresty/lua-nginx-module/archive/v0.10.14.zip unzip v0.10.14.zip # 安装nginx cd nginx-1.14.2 ./configure --prefix=/usr/local/nginx-1.14.2 \ --add-module=../ngx_devel_kit-0.3.0 \ --add-module=../lua-nginx-module-0.10.14
- 测试lua模块是否安装成功
- 创建一个文件夹存储lua脚本
mkdir /usr/local/nginx-1.14.2/lua_scripts
- 创建mydata.lua
-- mydata.lua local _M = {} local data = { dog = 3, cat = 4, pig = 5, } function _M.get_age(name) return data[name] end return _M
- nginx.conf文件
lua_package_path "/usr/local/nginx-1.14.2/lua_scripts/?.lua;;"; server { ... location /lua { content_by_lua_block { local mydata = require "mydata" ngx.say(mydata.get_age("dog")) } }
可能的错误
# 1、动态库找不到 ./sbin/nginx: error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory # 解决办法: echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf ldconfig # 2、warn提示 nginx: [alert] detected a LuaJIT version which is not OpenResty's; many optimizations will be disabled and performance will be compromised (see https://github.com/openresty/luajit2 for OpenResty's LuaJIT or, even better, consider using the OpenResty releases from https://openresty.org/en/download.html) # 告诉你,你不要用这个luajit版本,可以用openresty提供的luajit优化版本,或者干脆直接用openresty
安装lua_redis
wget https://codeload.github.com/openresty/lua-resty-redis/zip/master unzip master cd lua-resty-redis-master make && make install
都是lua集成的组件。
OpenResty 目录
包括nginx目录等。
ngx_lua支持的指令
指令分为配置指令、控制指令。 控制指令分为两种方式: lua脚本块*_by_lua_block lua脚本文件*_by_lua_file Lua脚本执行顺序,如右图从上至下:初始化、重写/访问、内容处理、日志输出四个阶段。
内容处理可以由上游服务或者Lua脚本语言来处理,用Lua脚本就大有可为了。在OpenResty中演示ngx_lua的指令
设置由set_by_lua,content_by_lua等指定的脚本使用的Lua模块搜索路径。类似java的classPath
预加载json模块
在location、location if上下文中使用。充当“内容处理程序”并执行指定的lua脚本内容,Lua代码可以进行API调用,并在独立的全局环境(即沙箱)中作为新的衍生协程执行
worker_processes 1; events { worker_connections 1024; } http { # 设置由set_by_lua, content_by_lua等指定的脚本使用的Lua模块搜索路径。类似java的classPath # 路径字符串采用标准的Lua路径形式,;; 可用于代表原始搜索路径。 lua_package_path "/usr/local/openresty/lua_scripts/?.lua;;"; # 申请一个名为dogs的10m字典内存,共享在所有工作进程中 lua_shared_dict dogs 10m; # 在服务器启动时预加载Lua模块,并利用现代操作系统的写时复制(COW)优化。 init_by_lua_block { -- 预加载json模块 require "cjson" -- 操作共享内存 local dogs = ngx.shared.dogs; dogs:set("Tom", 56) } server { listen 8080; location /lua { default_type text/html; # 在location、location if上下文中使用。充当“内容处理程序”并执行指定的lua脚本内容, # Lua代码可以进行API调用,并在独立的全局环境(即沙箱)中作为新的衍生协程执行 content_by_lua_block { local mydata = require "mydata" ngx.say(mydata.get_age("dog")) -- require关键字会返回init_by_lua_block中已经预加载了cjson模块 ngx.say(require "cjson".encode{dog = 5, cat = 6}) -- 读取共享内存中的信息 local dogs = ngx.shared.dogs; ngx.say(dogs:get("Tom")) } } } }
在运行的时候,需要去掉 nginx目录在运行
打造高性能后端接口
OpenResty Redis模块
OpenResty中默认嵌入了下列模块,包含Redis,所以要使用Redis非常简单。要使用Redis非常简单
-- 引入Redis模块 local redis = require("resty.redis") --创建实例 local red = redis:new() --建立连接 local ok, err = red:connect(“127.0.0.1”, 6379) --调用API进行处理 ok, err = red:set("msg", "hello world") local resp, err = red:get("msg")
这里 用local进行申请变量。 这是lua脚本 和js语言基本一致的地方。
这个模块要保证在linux上客户端存在redis,然后运行lua脚本。
在OpenResty 中 lualib /resty 中放在 这个目录下面的
- 在写lua脚本时需要引用 默认就是 lualib
local redis = require("resty.redis")
- 创建实例 建立连接,通过new方式
--创建实例 local red = redis:new() --设置超时(毫秒) red:set_timeout(1000) --建立连接 local ip = "127.0.0.1" local port = 6379 local ok, err = red:connect(ip, port)
- 发送数据并判断是否成功
if not ok then ngx.say("connect to redis error : ", err) return close_redis(red) end --调用API进行处理 ok, err = red:set("msg", "hello world") if not ok then ngx.say("set msg error : ", err) return close_redis(red) end
- 关闭redis
local function close_redis(red) if not red then return end --释放连接(Redis连接池实现) local pool_max_idle_time = 10000 --毫秒 local pool_size = 100 --连接池大小 local ok, err = red:set_keepalive(pool_max_idle_time, pool_size) if not ok then ngx.say("set keepalive error : ", err) end end
- 得到的数据为空处理
--得到的数据为空处理 if resp == ngx.null then resp = '' --比如默认值 end ngx.say("msg : ", resp) close_redis(red)
对于redis操作,lua脚本是没有事务的支持的。
在 nginx_lua_lib.conf配置上对应的location
请求得到数据
使用场景
降低tomcat的压力,非常有用的。根据不会走到web服务器上。 增大请求这些,是构建百万连接的重要一部分
OpenResty mysql模块
也是一样的 加载 mysql的驱动
local mysql = require("resty.mysql")
创建实例
local db, err = mysql:new() if not db then ngx.say("new mysql error : ", err) return end
设置超时时间(毫秒)
db:set_timeout(1000)
配置建立连接
local props = { host = "127.0.0.1", port = 3306, database = "mysql", user = "root", password = "123456" } local res, err, errno, sqlstate = db:connect(props) if not res then ngx.say("connect to mysql error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate) return close_db(db) end
删除表
local drop_table_sql = "drop table if exists test" res, err, errno, sqlstate = db:query(drop_table_sql) if not res then ngx.say("drop table error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate) return close_db(db) end
创建表
local create_table_sql = "create table test(id int primary key auto_increment, ch varchar(100))" res, err, errno, sqlstate = db:query(create_table_sql) if not res then ngx.say("create table error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate) return close_db(db) end
关闭连接
local function close_db(db) if not db then return end db:close() end
这里有个点安全机制,防止sql注入
--防止sql注入 local ch_param = ngx.req.get_uri_args()["ch"] or '' --使用ngx.quote_sql_str防止sql注入 local query_sql = "select id, ch from test where ch = " .. ngx.quote_sql_str(ch_param) res, err, errno, sqlstate = db:query(query_sql) if not res then ngx.say("select error : ", err, " , errno : ", errno, " , sqlstate : ", sqlstate) return close_db(db) end for i, row in ipairs(res) do for name, value in pairs(row) do ngx.say("select row ", i, " : ", name, " = ", value, "<br/>") end end
OpenResty http模块
OpenResty默认没有提供Http客户端,需要使用第三方提供,从github上搜索相应的客户端,比如lua-resty-http
cd /usr/local/openresty/lualib/resty/ sudo wget https://raw.githubusercontent.com/pintsized/lua-resty-http/master/lib/resty/http_headers.lua sudo wget https://raw.githubusercontent.com/pintsized/lua-resty-http/master/lib/resty/http.lua
这个模块可以调用第三方的服务。
local http = require("resty.http") --创建http客户端实例 local httpc = http.new() local resp, err = httpc:request_uri("http://www.baidu.com", { method = "GET", path = "/s?wd=123", headers = { ["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36" } }) if not resp then ngx.say("request error :", err) return end --获取状态码 ngx.status = resp.status --获取响应头 for k, v in pairs(resp.headers) do if k ~= "Transfer-Encoding" and k ~= "Connection" then ngx.header[k] = v end end --响应体 ngx.say(resp.body) httpc:close()
Lua模板渲染器
动态web网页开发是Web开发中一个常见的场景,Lua中也有许多模板引擎,我们通过lua-resty-template来完成动态页面的渲染。
cd /usr/local/openresty/lualib/resty/ wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template.lua mkdir /usr/local/openresty/lualib/resty/html cd /usr/local/openresty/lualib/resty/html wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template/html.lua
动态生成网页模板。
使用
nginx配置文件,添加模板解析路径
#首先匹配nginx下面的模板目录 set $template_location "/templates"; #然后匹配指定的模板根目录,我们这里是/usr/local/openresty/lua_scripts set $template_root "/usr/local/openresty/lua_scripts"; #或者通过root指令来切换路径 root /usr/local/openresty/lua_scripts;
lua内容,html_template.lua
local template = require("resty.template") local context = { title = "lua模板渲染", name = "hash同学", description = "<script>alert(1);</script>", age = 20, hobby = {"电影", "音乐", "阅读"}, score = {语文 = 90, 数学 = 80, 英语 = 70}, score2 = { {name = "语文", score = 90}, {name = "数学", score = 80}, {name = "英语", score = 70}, } } template.render("resty_template.html", context)
进行解析生成模板。
Nginx非阻塞与Lua协程的绝配
服务器有个设计原则:永远不能阻塞。nginx作为非常优秀的服务器,这点发挥的非常极致。在nginx里有很多的体现异步的地方。Lua嵌入会阻塞吗?-- foo本身是个协程,由nginx调用 function foo() -- 此处由nginx发起db的连接请求,因为异步这里先暂停协程 users = db.query('users', {name: name}); -- 当请求有响应得到处理时,继续执行协程,这些才运行 deal_with(users); end
通过nginx的异步机制和lua的协程,很容易实现这种同步写法,异步实现的模型,但对开发人员而言,不用关心内部做了什么。Lua协程
什么是协程?Lua协程,称为 协作式多线程 。Lua中的协程代表一个独立的执行线程,具有自己的堆栈、自己的局部变量、PC计数器和其自己的指令指针; 与java线程不同的是,协程只通过显式调用yield函数来暂停其执行。同一时间,多协程只运行其中一个,java多线程则可以运行多个。协程可以处于三种不同状态之一: 暂停,运行和死亡使用Lua协程coroutine.create(f) 创建一个新的协同程序并返回一个类型为thread的对象,并不启动协程。 coroutine.resume(co) 开始或继续执行协同程序co coroutine.yield 暂停执行调用协程,让出CPU coroutine.wrap(f) 类似create方法,创建一个协程但它不是返回协程本身,而是返回一个函数,当被调用时,它恢复协程
Nginx的API生成页面
可以通过Nginx的API服务功能来实现商品页面功能设计将需要的数据准备好,通过Lua访问Redis获取得,再由Lua生成json数据,交给Lua模板解析器,通过Lua模板解析器,来完成模板数据的动态生成。达到对一个商品页面的实现。
-
Lua:01---Lua语言介绍、运行Lua程序(lua解释器)
2020-08-11 10:34:43一、Lua语言介绍 Lua语言从一开始就被设计为能与C/C++及其他常用语言开发的软件集成在一起使用的语言,这种设计带来了非常多的好处: 一方面, Lua语言不需要在性能、与三方软件交互等C语言已经非常完善的方面...一、Lua语言介绍
- Lua语言从一开始就被设计为能与C/C++及其他常用语言开发的软件集成在一起使用的语言,这种设计带来了非常多的好处:
- 一方面, Lua语言不需要在性能、与三方软件交互等C语言已经非常完善的方面重复“造轮子”,可以直接依赖C语言实现上述特性,因而Lua语言非常精简
- 另一方面,通过引入安全的运行时环境、自动内存管理、良好的字符串 处理能力和可变长的多种数据类型, Lua 语言弥补了C语言在非面向硬件的高级抽象能力、 动态数据结构、鲁棒性、调试能力等方面的不足
- Lua语言强大的原因之一就在于它的标准库,这不是偶然,毕竟扩展性本身就是 Lua语言的主要能力之一。Lua语言中的许多特性为扩展性的实现提供了支持:动态类型使得一定 程度的多态成为了可能,自动内存管理简化了接口的实现(无须关心内存的分配/释放及处 理溢出),作为第一类值的函数支持高度的泛化,从而使得函数更加通用
- Lua语言除了是一门可扩展的语言外,还是一门胶水语言(glue language)。Lua 语言支 持组件化的软件开发方式,通过整合已有的高级组件构建新的应用。这些组件通常是通过 C/C++等编译型强类型语言编写的, Lua语言充当了整合和连接这些组件的角色。通常,组件(或对象)是对程序开发过程中相对稳定逻辑的具体底层(如小部件和数据结构)的抽象,这些逻辑占用了程序运行时的大部分 CPU 时间,而产品生命周期中可能经常发生变化的逻辑则可以使用 Lua 语言来实现。当然,除了整合组件外 Lua 语言也可以用来适配和改 造组件,甚至创建全新的组件
- Lua 语言并非这个世界上唯一的脚本语言,还有许多其他的脚本语言提供了类似的能力尽管如此, Lua语言的很多特性使它成为解决许多问题的首选,这些特性如下:
- 可扩展: Lua 语言具有卓越的可扩展’性 Lua 的可扩展性好到很多人认为 Lua 超越了编 程语言的范畴,其甚至可以成为一种用于构建领域专用语言( Domain-Specific Language,DSL )的工具包 Lua 从一开始就被设计为可扩展的,既支持使用 Lua 语言代码来扩展, 也支持使用外部的C语言代码来扩展。在这一点上有一个很好的例证: Lua 语言的大部分基础功能都是通过外部库实现的。我们可以很容易地将 Lua与C/C++、Java、C#和Python等结合在一起使用
- 简明: Lua 语言是一门精简的语言。尽管它本身具有的概念并不多,但每个概念都很强大。这样的特性使得 Lua 语言的学习成本很低,也有助于减小其本身的大小(其包含所有标准库的 Linux 64 位版本仅有 220 KB)
- 高效:Lua 语言的实现极为高效。独立的性能测试说明 Lua 语言是脚本语言中最快的语言之一
- 可移植:Lua 语言可以运行在我们昕说过的几乎所有平台之上, 包括所有的 UNIX 操作系统(Linux FreeBSD等)、 Window、Android、iOS、OS X、IBM大型机、游戏终端( PlayStation、Xbox、Wii 等) 、微处理器(如 Arduino )等、针对所有这些平台的 源码本质上是一样的, Lua 语言遵循 ANSI(ISO)C标准,并未使用条件编译来对不同平台进行代码的适配。因此,当需要适配新平台时,只要使用对应平台下的 ISO C 编译器重新编译 Lua 语言的源码就可以了
- Lua官网:http://www.lua.org/
二、Lua解释器的安装
- Lua解释器是用来运行Lua程序的,此处我们以ubuntu为例,来安装Lua解释器
- 可以到http://www.lua.org/ftp/中下载最新的Lua版本(此处我们以Lua 5.4.0为例)
安装过程
- 第一步:下载Lua源码包,并进入目录
wget http://www.lua.org/ftp/lua-5.4.0.tar.gz
- 第二步:解压源码包,并进入目录
tar zxf lua-5.4.0.tar.gz cd lua-5.4.0/ ls
- 第三步:编译
make linux test
- 第四步:之后会在src目录下生成两个可执行程序lua和luac
ls src/
- 第五步:安装Lua
sudo make install
- 安装完成之后:
- 头文件保存在/usr/local/include/目录下
- 可执行程序保存在/usr/local/bin/目录下
- 动态库安装在/usr/local/lib/目录下
- 还有一些内容也安装在/usr/l;ocal目录下
ls /usr/local/include/lua* ls /usr/local/bin/lua* ls /usr/local/lib/liblua*
- 第六步:刷新动态库链接
sudo ldconfig
- 第七步:查看lua安装的版本
lua -v
三、运行两个lua程序案例
演示案例1
- 建立一个hello.lua文件,内容如下:
print("Hello World")
- 运行效果如下:
演示案例2
- 下面的fact.lua程序用来求一个数的阶乘结果:
-- 定义一个计算阶乘的函数 function fact(n) if n == 0 then return 1 else return fact(n-1) * n end end print("enter a number:") -- 读取一个数字 a = io.read("*n") -- 打印结果 print(fact(a))
- 运行效果如下:
四、程序段
- 我们将Lua语言执行的每一段代码(例如,一个文件或交互模式下的一行)称为一个程序段(Chunk),即一组命令或表达式组成的序列
- 程序段既可以简单到只由一句表达式构成,也可以由多句表达式和函数定义(实际是赋值表达式)组成(例如计算阶乘的演示案例)
- 程序段在大小上并没有限制,事实上,由于Lua语言也可以被用作数据定义语言,所以几MB的程序段也很常见。Lua语言的解释器可以支持非常大的程序段
五、交互式解释器
- 除了将源码保存为文件,然后使用lua运行之外,还可以使用交互式模式的独立解释器
进入交互式解释器
- 在命令行下直接输入lua即可进入
- 进入之后输入的每一条命令都会在按下回车键之后立即执行
- 例如,我们输入下面的语句
退出交互式解释器
-
有两种方式退出交互式解释器:
-
输入EOF控制符(POSIX下为ctrl+D、Windows下为ctrl+Z)
-
或者调用操作系统的exit函数(执行os.exit())退出
-
-
例如,在Linux下输入ctrl+D退出:
- 或者执行os.exit()退出
- 更多关于lua交互式的使用,见下面完整介绍
六、Lua解释器完整介绍
- 下面列出了lua解释器的参数选项:
- 所有参数都是可选的
- 当不使用任何参数调用lua时,就进入了上面的交互式模式
交互式Lua
- 当不使用任何参数调用lua时,就进入了上面的交互式模式
- 在上面已经介绍了
Lua脚本
- lua解释器默认安装在/usr/local/bin/目录下,如下所示:
- 因此,当一个脚本的开头以"#!/usr/local/bin/lua"开始时,这是一个lua的脚本,这个脚本中可以执行lua程序
- 下面是一个名为lua_test.sh的脚本,内容如下:
#!/usr/local/bin/lua print("HelloWorld")
- 赋予其可执行权限,并运行:
chmod +x lua_test.sh ./lua_test.sh
与老版本中的兼容
- 从Lua 5.3版本开始,可以直接在交互式模式下输入表达式,Lua语言会输出表达式的值,例如
math.pi/4 a = 15 a ^ 2 a + 2
- 但是,在Lua 5.3之前,需要在表达式前面加上一个“=”号
a = 15 = a ^ 2 = a + 2
- 为了向下兼容,Lua 5.3之后的版本还是支持之前的语法
-e选项
- 该选项允许我们直接在命令行中输入代码
- 备注:在POSIX系统下需要使用双引号,以防止Shell错误地解析括号
- 例如:
lua -e "print(math.sin(12))"
-i选项
- -i选项可以让Lua解释器在执行完指定的程序段之后再进入交互模式
- 这一选项对于调试和手工测试很有用
- 例如,下面是一个prog.lua程序
print("Hello World") a = 15
- 现在我们输入下面的命令,让其执行完prog.lua程序再进入交互模式:
lua -i prog.lua
- 可以看到其打印了“Hello World”,然后打印a,可以看到a为15
-l选项
- 该选项用于加载库之后再进入交互式模式,与-i选项有点类似
- 例如,下面的命令先加载lib库,然后再执行x=10的赋值语句,并最终进入交互模式,进入之后打印x可以看到我10
lua -i -llib -e "x=10"
dofile()函数
- 进入交互式解释器之后,可以调用dofile()函数加载一个外部已经存在的lua文件
- 该函数在开发阶段也很有用。我们可以同时打开两个窗口,一个窗口使用文件编辑器编辑的代码(例如prog.lua),另一个窗口中使用交互式模式运行Lua语言解释器。当修改完代码并保存后,只要在Lua语言交互模式的提示符下执行dofile("prog.lua")就可以加载新代码
- 例如,下面有一个lib.lua文件,内容如下:
-- 定义了两个函数 function norm(x, y) return math.sqrt(x^2 + y^2) end function twice(x) return 2.0*x end
- 我们进入交互式解释器,然后在里面调用dofile()函数让其加载lib.lua文件的所有内容,之后就可以调用里面的函数了
;的使用
- 如果执行一行语句之后,在末尾加上了分号(;),那么这条语句的输出不会被打印,但是这条命令被执行了
- 例如:输入io.flush()默认会输出"true",可以在末尾加上;让其不打印消息
- 即使不打印消息,但是这条语句也是被执行了的
LUA_INIT_5_4、LUA_INIT环境变量
- lua解释器在处理参数前,会先查找系统中名为LUA_INIT_5_4环境变量(根据你Lua的版本而定,我的lua版本为5.4),如果查找不到再去查找LUA_INIT环境变量
- 如果这两个环境变量中的任意一个存在,如果:
- 这两个环境变量的内容为@filename,那么lua解释器就会运行这个文件
- 这两个环境变量的内容不是以@开头的,那么解释器就会认为这两个环境变量包含的是lua代码,会对其进行解释执行
- 这些环境变量使得我们可以灵活的配置独立解释器。例如,我们可以预先加载程序包(Package)、修改路径、定义自定义函数、对函数进行重命名或删除函数等等
lua解释器的程序参数
- lua在运行代码前会创建一个名为arg的表,这个表存储了所有的命令行参数。你可以把它想象为C语言中main函数的argv数组
- Lua语言也支持可变长参数,可以通过可变长参数表达式来获取,在脚本文件中,表达式...表示传递给脚本的所有参数(这些内容在后面介绍“可变长参数”的时候再介绍)
- 例如,下面我们需要调用lua来执行script脚本,并且给该脚本传入了3个参数a、b、c,那么
- arg[0]=script、arg[1]=a、arg[2]=b、arg[3]=c
lua script a b c
- 位于脚本之前的所有选项位于负数索引上,例如:
- arg[-3]=lua、arg[-2]=-e、arg[-1]=sin=mayj.sin、arg[0]=script、arg[1]=a、arg[2]=b、arg[3]=c
lua -e "sin=math.sin" script a b c
- Lua语言从一开始就被设计为能与C/C++及其他常用语言开发的软件集成在一起使用的语言,这种设计带来了非常多的好处:
-
现在最新版本lua,lua-5.2.3。
2014-08-27 16:56:58现在最新版本lua,lua-5.2.3。 -
cocos2d-x实战_lua卷
2017-01-07 17:49:02cocos2d-x实战_lua卷 -
Cocos2d-x之Lua核心编程配套代码
2016-03-21 10:00:11Cocos2dx Lua开发的核心技术。本书从Lua语言基础开始,全面介绍了Cocos2dx Lua的基础知识、基本应用和高级编程技术,并最终介绍了游戏的实战开发。全书贯穿理论结合实践的编写方式,各个章节都提供了配套实例。 -
source insight的lua语言支持包
2013-04-10 22:45:31Add Type按钮,文件类型名称为Lua File,确定后,在Document Options对话框的File filter一栏中输入*.lua,然后在Document Options对话框中的Parsing下面分别设置Language和Custom Tag Type:Language->Lua,Custom ... -
lua设计模式总结
2014-10-16 15:13:321、简单工厂模式lua实现 2、工厂方法模式lua实现 3、原型模式lua实现 4、建造者模式lua实现 5、单例模式lua实现 6、抽象工厂模式lua实现 结构型模式 1、装饰模式lua实现 2、代理模式lua实现 3、外观模式lua实现 4、... -
Lua实例代码大全
2013-07-15 11:27:17很全面的实例代码,luacurl网络连接、luafilesystem、luajson、luasocket、luasql、luatask、luaxml、md5 -
lua脚本
2022-03-21 18:01:00lua前言一、下载lua二、编译测试代码测试脚本总结 前言 提示:以下是本篇文章正文内容,下面案例可供参考 一、下载lua lua下载:试验中下载的是5.2.3,使用其他版本链接时可能会报错找不到符号 二、编译 该工程文件... -
lua脚本加密解密
2014-01-06 16:51:14lua脚本加密解密 -
lua安装
2022-03-15 08:01:151、大多数 GNU/Linux 发行版都能够通过命令直接安装lua可执行程序。 例如,在 Debian,Ubuntu 和它们的衍生产品上,你可以通过执行以下命令来安装: sudo apt-get install lua50 sudo apt-get install lua51 sudo ... -
Lua代码解释器
2016-08-24 10:04:01这个Lua解释器是我自己使用lua 5.1的源码编译的,我平时写lua程序就用这个运行,小巧轻便,可用来配置Sublime Text3的lua运行环境 -
安装Windows Lua5.1 x86|x64 开发环境(Windows & Lua & LuaRocks & msvc)
2020-09-23 20:33:47安装Windows Lua5.1 开发环境1. 二进制版本问题2.兼容安装原版x86 Lua5.13.重新编译安装x64 Lua5.13.1 环境 1. 二进制版本问题 通过LuaRocks安装的C-Module都是通过本地编译做成的dll,且依赖本地的C编译器,且链接的...